Add translations for various sub-directories
[binutils-gdb.git] / gdb / build-id.c
blob43a80dd3978d0cacb3876a72ba515139f4aa88a2
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/>. */
20 #include "bfd.h"
21 #include "gdb_bfd.h"
22 #include "build-id.h"
23 #include "gdbsupport/gdb_vecs.h"
24 #include "symfile.h"
25 #include "objfiles.h"
26 #include "filenames.h"
27 #include "gdbcore.h"
28 #include "cli/cli-style.h"
29 #include "gdbsupport/scoped_fd.h"
30 #include "debuginfod-support.h"
31 #include "extension.h"
33 /* See build-id.h. */
35 const struct bfd_build_id *
36 build_id_bfd_get (bfd *abfd)
38 /* Dynamic objfiles such as ones created by JIT reader API
39 have no underlying bfd structure (that is, objfile->obfd
40 is NULL). */
41 if (abfd == nullptr)
42 return nullptr;
44 if (!bfd_check_format (abfd, bfd_object)
45 && !bfd_check_format (abfd, bfd_core))
46 return NULL;
48 if (abfd->build_id != NULL)
49 return abfd->build_id;
51 /* No build-id */
52 return NULL;
55 /* See build-id.h. */
57 int
58 build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
60 const struct bfd_build_id *found;
61 int retval = 0;
63 found = build_id_bfd_get (abfd);
65 if (found == NULL)
66 warning (_("File \"%ps\" has no build-id, file skipped"),
67 styled_string (file_name_style.style (),
68 bfd_get_filename (abfd)));
69 else if (!build_id_equal (found, check_len, check))
70 warning (_("File \"%ps\" has a different build-id, file skipped"),
71 styled_string (file_name_style.style (),
72 bfd_get_filename (abfd)));
73 else
74 retval = 1;
76 return retval;
79 /* Helper for build_id_to_debug_bfd. ORIGINAL_LINK with SUFFIX appended is
80 a path to a potential build-id-based separate debug file, potentially a
81 symlink to the real file. If the file exists and matches BUILD_ID,
82 return a BFD reference to it. */
84 static gdb_bfd_ref_ptr
85 build_id_to_debug_bfd_1 (const std::string &original_link,
86 size_t build_id_len, const bfd_byte *build_id,
87 const char *suffix)
89 tribool supports_target_stat = TRIBOOL_UNKNOWN;
91 /* Drop the 'target:' prefix if the target filesystem is local. */
92 std::string_view original_link_view (original_link);
93 if (is_target_filename (original_link) && target_filesystem_is_local ())
94 original_link_view
95 = original_link_view.substr (strlen (TARGET_SYSROOT_PREFIX));
97 /* The upper bound of '10' here is completely arbitrary. The loop should
98 terminate via 'break' when either (a) a readable symlink is found, or
99 (b) a non-existing entry is found.
101 However, for remote targets, we rely on the remote returning sane
102 error codes. If a remote sends back the wrong error code then it
103 might trick GDB into thinking that the symlink exists, but points to a
104 missing file, in which case GDB will try the next seqno. We don't
105 want a broken remote to cause GDB to spin here forever, hence a fixed
106 upper bound. */
108 for (unsigned seqno = 0; seqno < 10; seqno++)
110 std::string link (original_link_view);
112 if (seqno > 0)
113 string_appendf (link, ".%u", seqno);
115 link += suffix;
117 separate_debug_file_debug_printf ("Trying %s...", link.c_str ());
119 gdb::unique_xmalloc_ptr<char> filename_holder;
120 const char *filename = nullptr;
121 if (is_target_filename (link))
123 gdb_assert (link.length () >= strlen (TARGET_SYSROOT_PREFIX));
124 const char *link_on_target
125 = link.c_str () + strlen (TARGET_SYSROOT_PREFIX);
127 fileio_error target_errno;
128 if (supports_target_stat != TRIBOOL_FALSE)
130 struct stat sb;
131 int res = target_fileio_stat (nullptr, link_on_target, &sb,
132 &target_errno);
134 if (res != 0 && target_errno != FILEIO_ENOSYS)
136 separate_debug_file_debug_printf ("path doesn't exist");
137 break;
139 else if (res != 0 && target_errno == FILEIO_ENOSYS)
140 supports_target_stat = TRIBOOL_FALSE;
141 else
143 supports_target_stat = TRIBOOL_TRUE;
144 filename = link.c_str ();
148 if (supports_target_stat == TRIBOOL_FALSE)
150 gdb_assert (filename == nullptr);
152 /* Connecting to a target that doesn't support 'stat'. Try
153 'readlink' as an alternative. This isn't ideal, but is
154 maybe better than nothing. Returns EINVAL if the path
155 isn't a symbolic link, which hints that the path is
156 available -- there are other errors e.g. ENOENT for when
157 the path doesn't exist, but we just assume that anything
158 other than EINVAL indicates the path doesn't exist. */
159 std::optional<std::string> link_target
160 = target_fileio_readlink (nullptr, link_on_target,
161 &target_errno);
162 if (link_target.has_value ()
163 || target_errno == FILEIO_EINVAL)
164 filename = link.c_str ();
165 else
167 separate_debug_file_debug_printf ("path doesn't exist");
168 break;
172 else
174 struct stat buf;
176 /* The `access' call below automatically dereferences LINK, but
177 we want to stop incrementing SEQNO once we find a symlink
178 that doesn't exist. */
179 if (lstat (link.c_str (), &buf) != 0)
181 separate_debug_file_debug_printf ("path doesn't exist");
182 break;
185 /* Can LINK be accessed, or if LINK is a symlink, can the file
186 pointed too be accessed? Do this as lrealpath() is
187 expensive, even for the usually non-existent files. */
188 if (access (link.c_str (), F_OK) == 0)
190 filename_holder.reset (lrealpath (link.c_str ()));
191 filename = filename_holder.get ();
195 if (filename == nullptr)
197 separate_debug_file_debug_printf ("unable to compute real path");
198 continue;
201 /* We expect to be silent on the non-existing files. */
202 gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget);
204 if (debug_bfd == NULL)
206 separate_debug_file_debug_printf ("unable to open `%s`", filename);
207 continue;
210 if (!build_id_verify (debug_bfd.get(), build_id_len, build_id))
212 separate_debug_file_debug_printf ("build-id does not match");
213 continue;
216 separate_debug_file_debug_printf ("found a match");
217 return debug_bfd;
220 separate_debug_file_debug_printf ("no suitable file found");
221 return {};
224 /* Common code for finding BFDs of a given build-id. This function
225 works with both debuginfo files (SUFFIX == ".debug") and executable
226 files (SUFFIX == "").
228 The build-id will be split into a single byte sub-directory, followed by
229 the remaining build-id bytes as the filename, i.e. we use the lookup
230 format: `.build-id/xx/yy....zz`. As a consequence, if BUILD_ID_LEN is
231 less than 2 (bytes), no results will be found as there are not enough
232 bytes to form the `yy....zz` part of the lookup filename. */
234 static gdb_bfd_ref_ptr
235 build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
236 const char *suffix)
238 SEPARATE_DEBUG_FILE_SCOPED_DEBUG_ENTER_EXIT;
240 if (build_id_len < 2)
242 /* Zero length build-ids are ignored by bfd. */
243 gdb_assert (build_id_len > 0);
244 separate_debug_file_debug_printf
245 ("Ignoring short build-id `%s' for build-id based lookup",
246 bin2hex (build_id, build_id_len).c_str ());
247 return {};
250 /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
251 cause "/.build-id/..." lookups. */
253 std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec
254 = dirnames_to_char_ptr_vec (debug_file_directory.c_str ());
256 for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
258 const gdb_byte *data = build_id;
259 size_t size = build_id_len;
261 /* Compute where the file named after the build-id would be.
263 If debugdir is "/usr/lib/debug" and the build-id is abcdef, this will
264 give "/usr/lib/debug/.build-id/ab/cdef.debug". */
265 std::string link = debugdir.get ();
266 link += "/.build-id/";
268 gdb_assert (size > 1);
269 size--;
270 string_appendf (link, "%02x/", (unsigned) *data++);
272 while (size-- > 0)
273 string_appendf (link, "%02x", (unsigned) *data++);
275 gdb_bfd_ref_ptr debug_bfd
276 = build_id_to_debug_bfd_1 (link, build_id_len, build_id, suffix);
277 if (debug_bfd != NULL)
278 return debug_bfd;
280 /* Try to look under the sysroot as well. If the sysroot is
281 "/the/sysroot", it will give
282 "/the/sysroot/usr/lib/debug/.build-id/ab/cdef.debug".
284 If the sysroot is 'target:' and the target filesystem is local to
285 GDB then 'target:/path/to/check' becomes '/path/to/check' which
286 we just checked above. */
288 if (!gdb_sysroot.empty ()
289 && (gdb_sysroot != TARGET_SYSROOT_PREFIX
290 || !target_filesystem_is_local ()))
292 link = gdb_sysroot + link;
293 debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id,
294 suffix);
295 if (debug_bfd != NULL)
296 return debug_bfd;
300 return {};
303 /* See build-id.h. */
305 gdb_bfd_ref_ptr
306 build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id)
308 return build_id_to_bfd_suffix (build_id_len, build_id, ".debug");
311 /* Find and open a BFD for an executable file given a build-id. If no BFD
312 can be found, return NULL. The returned reference to the BFD must be
313 released by the caller. */
315 static gdb_bfd_ref_ptr
316 build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id)
318 return build_id_to_bfd_suffix (build_id_len, build_id, "");
321 /* See build-id.h. */
323 std::string
324 find_separate_debug_file_by_buildid (struct objfile *objfile,
325 deferred_warnings *warnings)
327 const struct bfd_build_id *build_id;
329 build_id = build_id_bfd_get (objfile->obfd.get ());
330 if (build_id != NULL)
332 SEPARATE_DEBUG_FILE_SCOPED_DEBUG_START_END
333 ("looking for separate debug info (build-id) for %s",
334 objfile_name (objfile));
336 gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size,
337 build_id->data));
338 /* Prevent looping on a stripped .debug file. */
339 if (abfd != NULL
340 && filename_cmp (bfd_get_filename (abfd.get ()),
341 objfile_name (objfile)) == 0)
343 separate_debug_file_debug_printf
344 ("\"%s\": separate debug info file has no debug info",
345 bfd_get_filename (abfd.get ()));
346 warnings->warn (_("\"%ps\": separate debug info file has no "
347 "debug info"),
348 styled_string (file_name_style.style (),
349 bfd_get_filename (abfd.get ())));
351 else if (abfd != NULL)
352 return std::string (bfd_get_filename (abfd.get ()));
355 return std::string ();
358 /* See build-id.h. */
360 gdb_bfd_ref_ptr
361 find_objfile_by_build_id (program_space *pspace,
362 const bfd_build_id *build_id,
363 const char *expected_filename)
365 gdb_bfd_ref_ptr abfd;
367 for (unsigned attempt = 0, max_attempts = 1;
368 attempt < max_attempts && abfd == nullptr;
369 ++attempt)
371 /* Try to find the executable (or shared object) by looking for a
372 (sym)link on disk from the build-id to the object file. */
373 abfd = build_id_to_exec_bfd (build_id->size, build_id->data);
375 if (abfd != nullptr || attempt > 0)
376 break;
378 /* Attempt to query debuginfod for the executable. This will only
379 get run during the first attempt, if an extension language hook
380 (see below) asked for a second attempt then we will have already
381 broken out of the loop above. */
382 gdb::unique_xmalloc_ptr<char> path;
383 scoped_fd fd = debuginfod_exec_query (build_id->data, build_id->size,
384 expected_filename, &path);
385 if (fd.get () >= 0)
387 abfd = gdb_bfd_open (path.get (), gnutarget);
389 if (abfd == nullptr)
390 warning (_("\"%ps\" from debuginfod cannot be opened as bfd: %s"),
391 styled_string (file_name_style.style (), path.get ()),
392 gdb_bfd_errmsg (bfd_get_error (), nullptr).c_str ());
393 else if (!build_id_verify (abfd.get (), build_id->size,
394 build_id->data))
395 abfd = nullptr;
398 if (abfd != nullptr)
399 break;
401 ext_lang_missing_file_result ext_result
402 = ext_lang_find_objfile_from_buildid (pspace, build_id,
403 expected_filename);
404 if (!ext_result.filename ().empty ())
406 /* The extension identified the file for us. */
407 abfd = gdb_bfd_open (ext_result.filename ().c_str (), gnutarget);
408 if (abfd == nullptr)
410 warning (_("\"%ps\" from extension cannot be opened as bfd: %s"),
411 styled_string (file_name_style.style (),
412 ext_result.filename ().c_str ()),
413 gdb_bfd_errmsg (bfd_get_error (), nullptr).c_str ());
414 break;
417 /* If the extension gave us a path to a file then we always
418 assume that it is the correct file, we do no additional check
419 of its build-id. */
421 else if (ext_result.try_again ())
423 /* The extension might have installed the file in the expected
424 location, we should try again. */
425 max_attempts = 2;
426 continue;
430 return abfd;