1 /* build-id-related functions.
3 Copyright (C) 1991-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #include "gdbsupport/gdb_vecs.h"
26 #include "filenames.h"
28 #include "cli/cli-style.h"
32 const struct bfd_build_id
*
33 build_id_bfd_get (bfd
*abfd
)
35 /* Dynamic objfiles such as ones created by JIT reader API
36 have no underlying bfd structure (that is, objfile->obfd
41 if (!bfd_check_format (abfd
, bfd_object
)
42 && !bfd_check_format (abfd
, bfd_core
))
45 if (abfd
->build_id
!= NULL
)
46 return abfd
->build_id
;
55 build_id_verify (bfd
*abfd
, size_t check_len
, const bfd_byte
*check
)
57 const struct bfd_build_id
*found
;
60 found
= build_id_bfd_get (abfd
);
63 warning (_("File \"%ps\" has no build-id, file skipped"),
64 styled_string (file_name_style
.style (),
65 bfd_get_filename (abfd
)));
66 else if (!build_id_equal (found
, check_len
, check
))
67 warning (_("File \"%ps\" has a different build-id, file skipped"),
68 styled_string (file_name_style
.style (),
69 bfd_get_filename (abfd
)));
76 /* Helper for build_id_to_debug_bfd. ORIGINAL_LINK with SUFFIX appended is
77 a path to a potential build-id-based separate debug file, potentially a
78 symlink to the real file. If the file exists and matches BUILD_ID,
79 return a BFD reference to it. */
81 static gdb_bfd_ref_ptr
82 build_id_to_debug_bfd_1 (const std::string
&original_link
,
83 size_t build_id_len
, const bfd_byte
*build_id
,
86 tribool supports_target_stat
= TRIBOOL_UNKNOWN
;
88 /* Drop the 'target:' prefix if the target filesystem is local. */
89 std::string_view
original_link_view (original_link
);
90 if (is_target_filename (original_link
) && target_filesystem_is_local ())
92 = original_link_view
.substr (strlen (TARGET_SYSROOT_PREFIX
));
94 /* The upper bound of '10' here is completely arbitrary. The loop should
95 terminate via 'break' when either (a) a readable symlink is found, or
96 (b) a non-existing entry is found.
98 However, for remote targets, we rely on the remote returning sane
99 error codes. If a remote sends back the wrong error code then it
100 might trick GDB into thinking that the symlink exists, but points to a
101 missing file, in which case GDB will try the next seqno. We don't
102 want a broken remote to cause GDB to spin here forever, hence a fixed
105 for (unsigned seqno
= 0; seqno
< 10; seqno
++)
107 std::string
link (original_link_view
);
110 string_appendf (link
, ".%u", seqno
);
114 separate_debug_file_debug_printf ("Trying %s...", link
.c_str ());
116 gdb::unique_xmalloc_ptr
<char> filename_holder
;
117 const char *filename
= nullptr;
118 if (is_target_filename (link
))
120 gdb_assert (link
.length () >= strlen (TARGET_SYSROOT_PREFIX
));
121 const char *link_on_target
122 = link
.c_str () + strlen (TARGET_SYSROOT_PREFIX
);
124 fileio_error target_errno
;
125 if (supports_target_stat
!= TRIBOOL_FALSE
)
128 int res
= target_fileio_stat (nullptr, link_on_target
, &sb
,
131 if (res
!= 0 && target_errno
!= FILEIO_ENOSYS
)
133 separate_debug_file_debug_printf ("path doesn't exist");
136 else if (res
!= 0 && target_errno
== FILEIO_ENOSYS
)
137 supports_target_stat
= TRIBOOL_FALSE
;
140 supports_target_stat
= TRIBOOL_TRUE
;
141 filename
= link
.c_str ();
145 if (supports_target_stat
== TRIBOOL_FALSE
)
147 gdb_assert (filename
== nullptr);
149 /* Connecting to a target that doesn't support 'stat'. Try
150 'readlink' as an alternative. This isn't ideal, but is
151 maybe better than nothing. Returns EINVAL if the path
152 isn't a symbolic link, which hints that the path is
153 available -- there are other errors e.g. ENOENT for when
154 the path doesn't exist, but we just assume that anything
155 other than EINVAL indicates the path doesn't exist. */
156 std::optional
<std::string
> link_target
157 = target_fileio_readlink (nullptr, link_on_target
,
159 if (link_target
.has_value ()
160 || target_errno
== FILEIO_EINVAL
)
161 filename
= link
.c_str ();
164 separate_debug_file_debug_printf ("path doesn't exist");
173 /* The `access' call below automatically dereferences LINK, but
174 we want to stop incrementing SEQNO once we find a symlink
175 that doesn't exist. */
176 if (lstat (link
.c_str (), &buf
) != 0)
178 separate_debug_file_debug_printf ("path doesn't exist");
182 /* Can LINK be accessed, or if LINK is a symlink, can the file
183 pointed too be accessed? Do this as lrealpath() is
184 expensive, even for the usually non-existent files. */
185 if (access (link
.c_str (), F_OK
) == 0)
187 filename_holder
.reset (lrealpath (link
.c_str ()));
188 filename
= filename_holder
.get ();
192 if (filename
== nullptr)
194 separate_debug_file_debug_printf ("unable to compute real path");
198 /* We expect to be silent on the non-existing files. */
199 gdb_bfd_ref_ptr debug_bfd
= gdb_bfd_open (filename
, gnutarget
);
201 if (debug_bfd
== NULL
)
203 separate_debug_file_debug_printf ("unable to open `%s`", filename
);
207 if (!build_id_verify (debug_bfd
.get(), build_id_len
, build_id
))
209 separate_debug_file_debug_printf ("build-id does not match");
213 separate_debug_file_debug_printf ("found a match");
217 separate_debug_file_debug_printf ("no suitable file found");
221 /* Common code for finding BFDs of a given build-id. This function
222 works with both debuginfo files (SUFFIX == ".debug") and executable
223 files (SUFFIX == ""). */
225 static gdb_bfd_ref_ptr
226 build_id_to_bfd_suffix (size_t build_id_len
, const bfd_byte
*build_id
,
229 SEPARATE_DEBUG_FILE_SCOPED_DEBUG_ENTER_EXIT
;
231 /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
232 cause "/.build-id/..." lookups. */
234 std::vector
<gdb::unique_xmalloc_ptr
<char>> debugdir_vec
235 = dirnames_to_char_ptr_vec (debug_file_directory
.c_str ());
237 for (const gdb::unique_xmalloc_ptr
<char> &debugdir
: debugdir_vec
)
239 const gdb_byte
*data
= build_id
;
240 size_t size
= build_id_len
;
242 /* Compute where the file named after the build-id would be.
244 If debugdir is "/usr/lib/debug" and the build-id is abcdef, this will
245 give "/usr/lib/debug/.build-id/ab/cdef.debug". */
246 std::string link
= debugdir
.get ();
247 link
+= "/.build-id/";
252 string_appendf (link
, "%02x/", (unsigned) *data
++);
256 string_appendf (link
, "%02x", (unsigned) *data
++);
258 gdb_bfd_ref_ptr debug_bfd
259 = build_id_to_debug_bfd_1 (link
, build_id_len
, build_id
, suffix
);
260 if (debug_bfd
!= NULL
)
263 /* Try to look under the sysroot as well. If the sysroot is
264 "/the/sysroot", it will give
265 "/the/sysroot/usr/lib/debug/.build-id/ab/cdef.debug".
267 If the sysroot is 'target:' and the target filesystem is local to
268 GDB then 'target:/path/to/check' becomes '/path/to/check' which
269 we just checked above. */
271 if (!gdb_sysroot
.empty ()
272 && (gdb_sysroot
!= TARGET_SYSROOT_PREFIX
273 || !target_filesystem_is_local ()))
275 link
= gdb_sysroot
+ link
;
276 debug_bfd
= build_id_to_debug_bfd_1 (link
, build_id_len
, build_id
,
278 if (debug_bfd
!= NULL
)
286 /* See build-id.h. */
289 build_id_to_debug_bfd (size_t build_id_len
, const bfd_byte
*build_id
)
291 return build_id_to_bfd_suffix (build_id_len
, build_id
, ".debug");
294 /* See build-id.h. */
297 build_id_to_exec_bfd (size_t build_id_len
, const bfd_byte
*build_id
)
299 return build_id_to_bfd_suffix (build_id_len
, build_id
, "");
302 /* See build-id.h. */
305 find_separate_debug_file_by_buildid (struct objfile
*objfile
,
306 deferred_warnings
*warnings
)
308 const struct bfd_build_id
*build_id
;
310 build_id
= build_id_bfd_get (objfile
->obfd
.get ());
311 if (build_id
!= NULL
)
313 SEPARATE_DEBUG_FILE_SCOPED_DEBUG_START_END
314 ("looking for separate debug info (build-id) for %s",
315 objfile_name (objfile
));
317 gdb_bfd_ref_ptr
abfd (build_id_to_debug_bfd (build_id
->size
,
319 /* Prevent looping on a stripped .debug file. */
321 && filename_cmp (bfd_get_filename (abfd
.get ()),
322 objfile_name (objfile
)) == 0)
324 separate_debug_file_debug_printf
325 ("\"%s\": separate debug info file has no debug info",
326 bfd_get_filename (abfd
.get ()));
327 warnings
->warn (_("\"%ps\": separate debug info file has no "
329 styled_string (file_name_style
.style (),
330 bfd_get_filename (abfd
.get ())));
332 else if (abfd
!= NULL
)
333 return std::string (bfd_get_filename (abfd
.get ()));
336 return std::string ();