Updated Bulgarian translation for the binutils/ directory
[binutils-gdb.git] / gdb / build-id.c
blob32fbe178a23aad3e18aad4729a507d18590448ba
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"
30 /* See build-id.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
37 is NULL). */
38 if (abfd == nullptr)
39 return nullptr;
41 if (!bfd_check_format (abfd, bfd_object)
42 && !bfd_check_format (abfd, bfd_core))
43 return NULL;
45 if (abfd->build_id != NULL)
46 return abfd->build_id;
48 /* No build-id */
49 return NULL;
52 /* See build-id.h. */
54 int
55 build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
57 const struct bfd_build_id *found;
58 int retval = 0;
60 found = build_id_bfd_get (abfd);
62 if (found == NULL)
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)));
70 else
71 retval = 1;
73 return retval;
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,
84 const char *suffix)
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 ())
91 original_link_view
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
103 upper bound. */
105 for (unsigned seqno = 0; seqno < 10; seqno++)
107 std::string link (original_link_view);
109 if (seqno > 0)
110 string_appendf (link, ".%u", seqno);
112 link += suffix;
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)
127 struct stat sb;
128 int res = target_fileio_stat (nullptr, link_on_target, &sb,
129 &target_errno);
131 if (res != 0 && target_errno != FILEIO_ENOSYS)
133 separate_debug_file_debug_printf ("path doesn't exist");
134 break;
136 else if (res != 0 && target_errno == FILEIO_ENOSYS)
137 supports_target_stat = TRIBOOL_FALSE;
138 else
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,
158 &target_errno);
159 if (link_target.has_value ()
160 || target_errno == FILEIO_EINVAL)
161 filename = link.c_str ();
162 else
164 separate_debug_file_debug_printf ("path doesn't exist");
165 break;
169 else
171 struct stat buf;
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");
179 break;
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");
195 continue;
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);
204 continue;
207 if (!build_id_verify (debug_bfd.get(), build_id_len, build_id))
209 separate_debug_file_debug_printf ("build-id does not match");
210 continue;
213 separate_debug_file_debug_printf ("found a match");
214 return debug_bfd;
217 separate_debug_file_debug_printf ("no suitable file found");
218 return {};
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,
227 const char *suffix)
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/";
249 if (size > 0)
251 size--;
252 string_appendf (link, "%02x/", (unsigned) *data++);
255 while (size-- > 0)
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)
261 return debug_bfd;
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,
277 suffix);
278 if (debug_bfd != NULL)
279 return debug_bfd;
283 return {};
286 /* See build-id.h. */
288 gdb_bfd_ref_ptr
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. */
296 gdb_bfd_ref_ptr
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. */
304 std::string
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,
318 build_id->data));
319 /* Prevent looping on a stripped .debug file. */
320 if (abfd != NULL
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 "
328 "debug info"),
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 ();