]> git.pld-linux.org Git - packages/gdb.git/blob - gdb-6.6-buildid-locate.patch
updated source url to https
[packages/gdb.git] / gdb-6.6-buildid-locate.patch
1 From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
2 From: Fedora GDB patches <invalid@email.com>
3 Date: Fri, 27 Oct 2017 21:07:50 +0200
4 Subject: gdb-6.6-buildid-locate.patch
5
6 ;; New locating of the matching binaries from the pure core file (build-id).
7 ;;=push+jan
8
9 diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
10 --- a/bfd/libbfd-in.h
11 +++ b/bfd/libbfd-in.h
12 @@ -127,7 +127,7 @@ static inline char *
13  bfd_strdup (const char *str)
14  {
15    size_t len = strlen (str) + 1;
16 -  char *buf = bfd_malloc (len);
17 +  char *buf = (char *) bfd_malloc (len);
18    if (buf != NULL)
19      memcpy (buf, str, len);
20    return buf;
21 diff --git a/bfd/libbfd.h b/bfd/libbfd.h
22 --- a/bfd/libbfd.h
23 +++ b/bfd/libbfd.h
24 @@ -132,7 +132,7 @@ static inline char *
25  bfd_strdup (const char *str)
26  {
27    size_t len = strlen (str) + 1;
28 -  char *buf = bfd_malloc (len);
29 +  char *buf = (char *) bfd_malloc (len);
30    if (buf != NULL)
31      memcpy (buf, str, len);
32    return buf;
33 diff --git a/gdb/build-id.c b/gdb/build-id.c
34 --- a/gdb/build-id.c
35 +++ b/gdb/build-id.c
36 @@ -24,13 +24,71 @@
37  #include "gdbsupport/gdb_vecs.h"
38  #include "symfile.h"
39  #include "objfiles.h"
40 +#include <sys/stat.h>
41 +#include "elf-bfd.h"
42 +#include "elf/common.h"
43 +#include "elf/external.h"
44 +#include "elf/internal.h"
45  #include "filenames.h"
46 +#include "gdb_bfd.h"
47 +#include "gdbcmd.h"
48  #include "gdbcore.h"
49 +#include "libbfd.h"
50 +#include "objfiles.h"
51 +#include "observable.h"
52 +#include "symfile.h"
53 +
54 +#define BUILD_ID_VERBOSE_NONE 0
55 +#define BUILD_ID_VERBOSE_FILENAMES 1
56 +#define BUILD_ID_VERBOSE_BINARY_PARSE 2
57 +static int build_id_verbose = BUILD_ID_VERBOSE_FILENAMES;
58 +static void
59 +show_build_id_verbose (struct ui_file *file, int from_tty,
60 +                      struct cmd_list_element *c, const char *value)
61 +{
62 +  fprintf_filtered (file, _("Verbosity level of the build-id locator is %s.\n"),
63 +                   value);
64 +}
65 +/* Locate NT_GNU_BUILD_ID and return its matching debug filename.
66 +   FIXME: NOTE decoding should be unified with the BFD core notes decoding.  */
67 +
68 +static struct bfd_build_id *
69 +build_id_buf_get (bfd *templ, gdb_byte *buf, bfd_size_type size)
70 +{
71 +  bfd_byte *p;
72 +
73 +  p = buf;
74 +  while (p < buf + size)
75 +    {
76 +      /* FIXME: bad alignment assumption.  */
77 +      Elf_External_Note *xnp = (Elf_External_Note *) p;
78 +      size_t namesz = H_GET_32 (templ, xnp->namesz);
79 +      size_t descsz = H_GET_32 (templ, xnp->descsz);
80 +      bfd_byte *descdata = (gdb_byte *) xnp->name + BFD_ALIGN (namesz, 4);
81 +
82 +      if (H_GET_32 (templ, xnp->type) == NT_GNU_BUILD_ID
83 +         && namesz == sizeof "GNU"
84 +         && memcmp (xnp->name, "GNU", sizeof "GNU") == 0)
85 +       {
86 +         size_t sz = descsz;
87 +         gdb_byte *data = (gdb_byte *) descdata;
88 +         struct bfd_build_id *retval;
89 +
90 +         retval = (struct bfd_build_id *) xmalloc (sizeof *retval - 1 + sz);
91 +         retval->size = sz;
92 +         memcpy (retval->data, data, sz);
93 +
94 +         return retval;
95 +       }
96 +      p = descdata + BFD_ALIGN (descsz, 4);
97 +    }
98 +  return NULL;
99 +}
100  
101  /* See build-id.h.  */
102  
103  const struct bfd_build_id *
104 -build_id_bfd_get (bfd *abfd)
105 +build_id_bfd_shdr_get (bfd *abfd)
106  {
107    if (!bfd_check_format (abfd, bfd_object)
108        && !bfd_check_format (abfd, bfd_core))
109 @@ -43,6 +101,348 @@ build_id_bfd_get (bfd *abfd)
110    return NULL;
111  }
112  
113 +/* Core files may have missing (corrupt) SHDR but PDHR is correct there.
114 +   bfd_elf_bfd_from_remote_memory () has too much overhead by
115 +   allocating/reading all the available ELF PT_LOADs.  */
116 +
117 +static struct bfd_build_id *
118 +build_id_phdr_get (bfd *templ, bfd_vma loadbase, unsigned e_phnum,
119 +                  Elf_Internal_Phdr *i_phdr)
120 +{
121 +  int i;
122 +  struct bfd_build_id *retval = NULL;
123 +
124 +  for (i = 0; i < e_phnum; i++)
125 +    if (i_phdr[i].p_type == PT_NOTE && i_phdr[i].p_filesz > 0)
126 +      {
127 +       Elf_Internal_Phdr *hdr = &i_phdr[i];
128 +       gdb_byte *buf;
129 +       int err;
130 +
131 +       buf = (gdb_byte *) xmalloc (hdr->p_filesz);
132 +       err = target_read_memory (loadbase + i_phdr[i].p_vaddr, buf,
133 +                                 hdr->p_filesz);
134 +       if (err == 0)
135 +         retval = build_id_buf_get (templ, buf, hdr->p_filesz);
136 +       else
137 +         retval = NULL;
138 +       xfree (buf);
139 +       if (retval != NULL)
140 +         break;
141 +      }
142 +  return retval;
143 +}
144 +
145 +/* First we validate the file by reading in the ELF header and checking
146 +   the magic number.  */
147 +
148 +static inline bfd_boolean
149 +elf_file_p (Elf64_External_Ehdr *x_ehdrp64)
150 +{
151 +  gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr));
152 +  gdb_assert (offsetof (Elf64_External_Ehdr, e_ident)
153 +             == offsetof (Elf32_External_Ehdr, e_ident));
154 +  gdb_assert (sizeof (((Elf64_External_Ehdr *) 0)->e_ident)
155 +             == sizeof (((Elf32_External_Ehdr *) 0)->e_ident));
156 +
157 +  return ((x_ehdrp64->e_ident[EI_MAG0] == ELFMAG0)
158 +         && (x_ehdrp64->e_ident[EI_MAG1] == ELFMAG1)
159 +         && (x_ehdrp64->e_ident[EI_MAG2] == ELFMAG2)
160 +         && (x_ehdrp64->e_ident[EI_MAG3] == ELFMAG3));
161 +}
162 +
163 +/* Translate an ELF file header in external format into an ELF file header in
164 +   internal format.  */
165 +
166 +#define H_GET_WORD(bfd, ptr) (is64 ? H_GET_64 (bfd, (ptr))             \
167 +                                  : H_GET_32 (bfd, (ptr)))
168 +#define H_GET_SIGNED_WORD(bfd, ptr) (is64 ? H_GET_S64 (bfd, (ptr))     \
169 +                                         : H_GET_S32 (bfd, (ptr)))
170 +
171 +static void
172 +elf_swap_ehdr_in (bfd *abfd,
173 +                 const Elf64_External_Ehdr *src64,
174 +                 Elf_Internal_Ehdr *dst)
175 +{
176 +  int is64 = bfd_get_arch_size (abfd) == 64;
177 +#define SRC(field) (is64 ? src64->field \
178 +                        : ((const Elf32_External_Ehdr *) src64)->field)
179 +
180 +  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
181 +  memcpy (dst->e_ident, SRC (e_ident), EI_NIDENT);
182 +  dst->e_type = H_GET_16 (abfd, SRC (e_type));
183 +  dst->e_machine = H_GET_16 (abfd, SRC (e_machine));
184 +  dst->e_version = H_GET_32 (abfd, SRC (e_version));
185 +  if (signed_vma)
186 +    dst->e_entry = H_GET_SIGNED_WORD (abfd, SRC (e_entry));
187 +  else
188 +    dst->e_entry = H_GET_WORD (abfd, SRC (e_entry));
189 +  dst->e_phoff = H_GET_WORD (abfd, SRC (e_phoff));
190 +  dst->e_shoff = H_GET_WORD (abfd, SRC (e_shoff));
191 +  dst->e_flags = H_GET_32 (abfd, SRC (e_flags));
192 +  dst->e_ehsize = H_GET_16 (abfd, SRC (e_ehsize));
193 +  dst->e_phentsize = H_GET_16 (abfd, SRC (e_phentsize));
194 +  dst->e_phnum = H_GET_16 (abfd, SRC (e_phnum));
195 +  dst->e_shentsize = H_GET_16 (abfd, SRC (e_shentsize));
196 +  dst->e_shnum = H_GET_16 (abfd, SRC (e_shnum));
197 +  dst->e_shstrndx = H_GET_16 (abfd, SRC (e_shstrndx));
198 +
199 +#undef SRC
200 +}
201 +
202 +/* Translate an ELF program header table entry in external format into an
203 +   ELF program header table entry in internal format.  */
204 +
205 +static void
206 +elf_swap_phdr_in (bfd *abfd,
207 +                 const Elf64_External_Phdr *src64,
208 +                 Elf_Internal_Phdr *dst)
209 +{
210 +  int is64 = bfd_get_arch_size (abfd) == 64;
211 +#define SRC(field) (is64 ? src64->field                                        \
212 +                        : ((const Elf32_External_Phdr *) src64)->field)
213 +
214 +  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
215 +
216 +  dst->p_type = H_GET_32 (abfd, SRC (p_type));
217 +  dst->p_flags = H_GET_32 (abfd, SRC (p_flags));
218 +  dst->p_offset = H_GET_WORD (abfd, SRC (p_offset));
219 +  if (signed_vma)
220 +    {
221 +      dst->p_vaddr = H_GET_SIGNED_WORD (abfd, SRC (p_vaddr));
222 +      dst->p_paddr = H_GET_SIGNED_WORD (abfd, SRC (p_paddr));
223 +    }
224 +  else
225 +    {
226 +      dst->p_vaddr = H_GET_WORD (abfd, SRC (p_vaddr));
227 +      dst->p_paddr = H_GET_WORD (abfd, SRC (p_paddr));
228 +    }
229 +  dst->p_filesz = H_GET_WORD (abfd, SRC (p_filesz));
230 +  dst->p_memsz = H_GET_WORD (abfd, SRC (p_memsz));
231 +  dst->p_align = H_GET_WORD (abfd, SRC (p_align));
232 +
233 +#undef SRC
234 +}
235 +
236 +#undef H_GET_SIGNED_WORD
237 +#undef H_GET_WORD
238 +
239 +static Elf_Internal_Phdr *
240 +elf_get_phdr (bfd *templ, bfd_vma ehdr_vma, unsigned *e_phnum_pointer,
241 +              bfd_vma *loadbase_pointer)
242 +{
243 +  /* sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)  */
244 +  Elf64_External_Ehdr x_ehdr64;        /* Elf file header, external form */
245 +  Elf_Internal_Ehdr i_ehdr;    /* Elf file header, internal form */
246 +  bfd_size_type x_phdrs_size;
247 +  gdb_byte *x_phdrs_ptr;
248 +  Elf_Internal_Phdr *i_phdrs;
249 +  int err;
250 +  unsigned int i;
251 +  bfd_vma loadbase;
252 +  int loadbase_set;
253 +
254 +  gdb_assert (templ != NULL);
255 +  gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr));
256 +
257 +  /* Read in the ELF header in external format.  */
258 +  err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr64, sizeof x_ehdr64);
259 +  if (err)
260 +    {
261 +      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
262 +        warning (_("build-id: Error reading ELF header at address 0x%lx"),
263 +                (unsigned long) ehdr_vma);
264 +      return NULL;
265 +    }
266 +
267 +  /* Now check to see if we have a valid ELF file, and one that BFD can
268 +     make use of.  The magic number must match, the address size ('class')
269 +     and byte-swapping must match our XVEC entry.  */
270 +
271 +  if (! elf_file_p (&x_ehdr64)
272 +      || x_ehdr64.e_ident[EI_VERSION] != EV_CURRENT
273 +      || !((bfd_get_arch_size (templ) == 64
274 +            && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS64)
275 +           || (bfd_get_arch_size (templ) == 32
276 +              && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS32)))
277 +    {
278 +      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
279 +        warning (_("build-id: Unrecognized ELF header at address 0x%lx"),
280 +                (unsigned long) ehdr_vma);
281 +      return NULL;
282 +    }
283 +
284 +  /* Check that file's byte order matches xvec's */
285 +  switch (x_ehdr64.e_ident[EI_DATA])
286 +    {
287 +    case ELFDATA2MSB:          /* Big-endian */
288 +      if (! bfd_header_big_endian (templ))
289 +       {
290 +         if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
291 +           warning (_("build-id: Unrecognized "
292 +                      "big-endian ELF header at address 0x%lx"),
293 +                    (unsigned long) ehdr_vma);
294 +         return NULL;
295 +       }
296 +      break;
297 +    case ELFDATA2LSB:          /* Little-endian */
298 +      if (! bfd_header_little_endian (templ))
299 +       {
300 +         if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
301 +           warning (_("build-id: Unrecognized "
302 +                      "little-endian ELF header at address 0x%lx"),
303 +                    (unsigned long) ehdr_vma);
304 +         return NULL;
305 +       }
306 +      break;
307 +    case ELFDATANONE:          /* No data encoding specified */
308 +    default:                   /* Unknown data encoding specified */
309 +      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
310 +       warning (_("build-id: Unrecognized "
311 +                  "ELF header endianity at address 0x%lx"),
312 +                (unsigned long) ehdr_vma);
313 +      return NULL;
314 +    }
315 +
316 +  elf_swap_ehdr_in (templ, &x_ehdr64, &i_ehdr);
317 +
318 +  /* The file header tells where to find the program headers.
319 +     These are what we use to actually choose what to read.  */
320 +
321 +  if (i_ehdr.e_phentsize != (bfd_get_arch_size (templ) == 64
322 +                             ? sizeof (Elf64_External_Phdr)
323 +                            : sizeof (Elf32_External_Phdr))
324 +      || i_ehdr.e_phnum == 0)
325 +    {
326 +      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
327 +       warning (_("build-id: Invalid ELF program headers from the ELF header "
328 +                  "at address 0x%lx"), (unsigned long) ehdr_vma);
329 +      return NULL;
330 +    }
331 +
332 +  x_phdrs_size = (bfd_get_arch_size (templ) == 64 ? sizeof (Elf64_External_Phdr)
333 +                                               : sizeof (Elf32_External_Phdr));
334 +
335 +  i_phdrs = (Elf_Internal_Phdr *) xmalloc (i_ehdr.e_phnum * (sizeof *i_phdrs + x_phdrs_size));
336 +  x_phdrs_ptr = (gdb_byte *) &i_phdrs[i_ehdr.e_phnum];
337 +  err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs_ptr,
338 +                           i_ehdr.e_phnum * x_phdrs_size);
339 +  if (err)
340 +    {
341 +      free (i_phdrs);
342 +      if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
343 +        warning (_("build-id: Error reading "
344 +                  "ELF program headers at address 0x%lx"),
345 +                (unsigned long) (ehdr_vma + i_ehdr.e_phoff));
346 +      return NULL;
347 +    }
348 +
349 +  loadbase = ehdr_vma;
350 +  loadbase_set = 0;
351 +  for (i = 0; i < i_ehdr.e_phnum; ++i)
352 +    {
353 +      elf_swap_phdr_in (templ, (Elf64_External_Phdr *)
354 +                              (x_phdrs_ptr + i * x_phdrs_size), &i_phdrs[i]);
355 +      /* IA-64 vDSO may have two mappings for one segment, where one mapping
356 +        is executable only, and one is read only.  We must not use the
357 +        executable one (PF_R is the first one, PF_X the second one).  */
358 +      if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R))
359 +       {
360 +         /* Only the first PT_LOAD segment indicates the file bias.
361 +            Next segments may have P_VADDR arbitrarily higher.
362 +            If the first segment has P_VADDR zero any next segment must not
363 +            confuse us, the first one sets LOADBASE certainly enough.  */
364 +         if (!loadbase_set && i_phdrs[i].p_offset == 0)
365 +           {
366 +             loadbase = ehdr_vma - i_phdrs[i].p_vaddr;
367 +             loadbase_set = 1;
368 +           }
369 +       }
370 +    }
371 +
372 +  if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
373 +    warning (_("build-id: Found ELF header at address 0x%lx, loadbase 0x%lx"),
374 +            (unsigned long) ehdr_vma, (unsigned long) loadbase);
375 +
376 +  *e_phnum_pointer = i_ehdr.e_phnum;
377 +  *loadbase_pointer = loadbase;
378 +  return i_phdrs;
379 +}
380 +
381 +/* BUILD_ID_ADDR_GET gets ADDR located somewhere in the object.
382 +   Find the first section before ADDR containing an ELF header.
383 +   We rely on the fact the sections from multiple files do not mix.
384 +   FIXME: We should check ADDR is contained _inside_ the section with possibly
385 +   missing content (P_FILESZ < P_MEMSZ).  These omitted sections are currently
386 +   hidden by _BFD_ELF_MAKE_SECTION_FROM_PHDR.  */
387 +
388 +static CORE_ADDR build_id_addr;
389 +struct build_id_addr_sect
390 +  {
391 +    struct build_id_addr_sect *next;
392 +    asection *sect;
393 +  };
394 +static struct build_id_addr_sect *build_id_addr_sect;
395 +
396 +static void build_id_addr_candidate (bfd *abfd, asection *sect, void *obj)
397 +{
398 +  if (build_id_addr >= bfd_section_vma (sect))
399 +    {
400 +      struct build_id_addr_sect *candidate;
401 +
402 +      candidate = (struct build_id_addr_sect *) xmalloc (sizeof *candidate);
403 +      candidate->next = build_id_addr_sect;
404 +      build_id_addr_sect = candidate;
405 +      candidate->sect = sect;
406 +    }
407 +}
408 +
409 +struct bfd_build_id *
410 +build_id_addr_get (CORE_ADDR addr)
411 +{
412 +  struct build_id_addr_sect *candidate;
413 +  struct bfd_build_id *retval = NULL;
414 +  Elf_Internal_Phdr *i_phdr = NULL;
415 +  bfd_vma loadbase = 0;
416 +  unsigned e_phnum = 0;
417 +
418 +  if (core_bfd == NULL)
419 +    return NULL;
420 +
421 +  build_id_addr = addr;
422 +  gdb_assert (build_id_addr_sect == NULL);
423 +  bfd_map_over_sections (core_bfd, build_id_addr_candidate, NULL);
424 +
425 +  /* Sections are sorted in the high-to-low VMAs order.
426 +     Stop the search on the first ELF header we find.
427 +     Do not continue the search even if it does not contain NT_GNU_BUILD_ID.  */
428 +
429 +  for (candidate = build_id_addr_sect; candidate != NULL;
430 +       candidate = candidate->next)
431 +    {
432 +      i_phdr = elf_get_phdr (core_bfd,
433 +                            bfd_section_vma (candidate->sect),
434 +                            &e_phnum, &loadbase);
435 +      if (i_phdr != NULL)
436 +       break;
437 +    }
438 +
439 +  if (i_phdr != NULL)
440 +    {
441 +      retval = build_id_phdr_get (core_bfd, loadbase, e_phnum, i_phdr);
442 +      xfree (i_phdr);
443 +    }
444 +
445 +  while (build_id_addr_sect != NULL)
446 +    {
447 +      candidate = build_id_addr_sect;
448 +      build_id_addr_sect = candidate->next;
449 +      xfree (candidate);
450 +    }
451 +
452 +  return retval;
453 +}
454 +
455  /* See build-id.h.  */
456  
457  int
458 @@ -51,7 +451,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
459    const struct bfd_build_id *found;
460    int retval = 0;
461  
462 -  found = build_id_bfd_get (abfd);
463 +  found = build_id_bfd_shdr_get (abfd);
464  
465    if (found == NULL)
466      warning (_("File \"%s\" has no build-id, file skipped"),
467 @@ -66,56 +466,159 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
468    return retval;
469  }
470  
471 +static char *
472 +link_resolve (const char *symlink, int level)
473 +{
474 +  char buf[PATH_MAX + 1], *target, *retval;
475 +  ssize_t got;
476 +
477 +  if (level > 10)
478 +    return xstrdup (symlink);
479 +
480 +  got = readlink (symlink, buf, sizeof (buf));
481 +  if (got < 0 || got >= sizeof (buf))
482 +    return xstrdup (symlink);
483 +  buf[got] = '\0';
484 +
485 +  if (IS_ABSOLUTE_PATH (buf))
486 +    target = xstrdup (buf);
487 +  else
488 +    {
489 +      const std::string dir (ldirname (symlink));
490 +
491 +      target = xstrprintf ("%s"
492 +#ifndef HAVE_DOS_BASED_FILE_SYSTEM
493 +                          "/"
494 +#else /* HAVE_DOS_BASED_FILE_SYSTEM */
495 +                          "\\"
496 +#endif /* HAVE_DOS_BASED_FILE_SYSTEM */
497 +                          "%s", dir.c_str(), buf);
498 +    }
499 +
500 +  retval = link_resolve (target, level + 1);
501 +  xfree (target);
502 +  return retval;
503 +}
504 +
505  /* Helper for build_id_to_debug_bfd.  LINK is a path to a potential
506     build-id-based separate debug file, potentially a symlink to the real file.
507     If the file exists and matches BUILD_ID, return a BFD reference to it.  */
508  
509  static gdb_bfd_ref_ptr
510 -build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len,
511 -                        const bfd_byte *build_id)
512 +build_id_to_debug_bfd_1 (const std::string &orig_link, size_t build_id_len,
513 +                        const bfd_byte *build_id, char **link_return)
514  {
515 +  gdb_bfd_ref_ptr ret_bfd = {};
516 +  std::string ret_link;
517 +
518    if (separate_debug_file_debug)
519      {
520 -      printf_unfiltered (_("  Trying %s..."), link.c_str ());
521 +      printf_unfiltered (_("  Trying %s..."), orig_link.c_str ());
522        gdb_flush (gdb_stdout);
523      }
524  
525 -  /* lrealpath() is expensive even for the usually non-existent files.  */
526 -  gdb::unique_xmalloc_ptr<char> filename;
527 -  if (access (link.c_str (), F_OK) == 0)
528 -    filename.reset (lrealpath (link.c_str ()));
529 -
530 -  if (filename == NULL)
531 +  for (unsigned seqno = 0;; seqno++)
532      {
533 -      if (separate_debug_file_debug)
534 -       printf_unfiltered (_(" no, unable to compute real path\n"));
535 +      std::string link = orig_link;
536  
537 -      return {};
538 -    }
539 +      if (seqno > 0)
540 +       {
541 +         /* There can be multiple build-id symlinks pointing to real files
542 +            with the same build-id (such as hard links).  Some of the real
543 +            files may not be installed.  */
544  
545 -  /* We expect to be silent on the non-existing files.  */
546 -  gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename.get (), gnutarget, -1);
547 +         string_appendf (link, ".%u", seqno);
548 +       }
549  
550 -  if (debug_bfd == NULL)
551 -    {
552 -      if (separate_debug_file_debug)
553 -       printf_unfiltered (_(" no, unable to open.\n"));
554 +      ret_link = link;
555 +
556 +      struct stat statbuf_trash;
557 +
558 +      /* `access' automatically dereferences LINK.  */
559 +      if (lstat (link.c_str (), &statbuf_trash) != 0)
560 +       {
561 +         /* Stop increasing SEQNO.  */
562 +         break;
563 +       }
564 +
565 +      /* lrealpath() is expensive even for the usually non-existent files.  */
566 +      gdb::unique_xmalloc_ptr<char> filename;
567 +
568 +      if (access (link.c_str (), F_OK) == 0)
569 +       filename.reset (lrealpath (link.c_str ()));
570 +
571 +      if (filename == NULL)
572 +       {
573 +         if (separate_debug_file_debug)
574 +           printf_unfiltered (_(" no, unable to compute real path\n"));
575 +
576 +         continue;
577 +       }
578  
579 -      return {};
580 +      /* We expect to be silent on the non-existing files.  */
581 +      gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename.get (), gnutarget, -1);
582 +
583 +      if (debug_bfd == NULL)
584 +       {
585 +         if (separate_debug_file_debug)
586 +           printf_unfiltered (_(" no, unable to open.\n"));
587 +
588 +         continue;
589 +       }
590 +
591 +      if (!build_id_verify (debug_bfd.get(), build_id_len, build_id))
592 +       {
593 +         if (separate_debug_file_debug)
594 +           printf_unfiltered (_(" no, build-id does not match.\n"));
595 +
596 +         continue;
597 +       }
598 +
599 +      ret_bfd = debug_bfd;
600 +      break;
601      }
602  
603 -  if (!build_id_verify (debug_bfd.get(), build_id_len, build_id))
604 +  std::string link_all;
605 +
606 +  if (ret_bfd != NULL)
607      {
608        if (separate_debug_file_debug)
609 -       printf_unfiltered (_(" no, build-id does not match.\n"));
610 -
611 -      return {};
612 +       printf_unfiltered (_(" yes!\n"));
613 +    }
614 +  else
615 +    {
616 +      /* If none of the real files is found report as missing file
617 +        always the non-.%u-suffixed file.  */
618 +      std::string link0 = orig_link;
619 +
620 +      /* If the symlink has target request to install the target.
621 +        BASE-debuginfo.rpm contains the symlink but BASE.rpm may be missing.
622 +        https://bugzilla.redhat.com/show_bug.cgi?id=981154  */
623 +      std::string link0_resolved (link_resolve (link0.c_str (), 0));
624 +
625 +      if (link_all.empty ())
626 +       link_all = link0_resolved;
627 +      else
628 +       {
629 +         /* Use whitespace instead of DIRNAME_SEPARATOR to be compatible with
630 +            its possible use as an argument for installation command.  */
631 +         link_all += " " + link0_resolved;
632 +       }
633      }
634  
635 -  if (separate_debug_file_debug)
636 -    printf_unfiltered (_(" yes!\n"));
637 +  if (link_return != NULL)
638 +    {
639 +      if (ret_bfd != NULL)
640 +       {
641 +         *link_return = xstrdup (ret_link.c_str ());
642 +       }
643 +      else
644 +       {
645 +         *link_return = xstrdup (link_all.c_str ());
646 +       }
647 +    }
648  
649 -  return debug_bfd;
650 +  return ret_bfd;
651  }
652  
653  /* Common code for finding BFDs of a given build-id.  This function
654 @@ -124,7 +627,7 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len,
655  
656  static gdb_bfd_ref_ptr
657  build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
658 -                       const char *suffix)
659 +                       const char *suffix, char **link_return)
660  {
661    /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
662       cause "/.build-id/..." lookups.  */
663 @@ -147,16 +650,17 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
664        if (size > 0)
665         {
666           size--;
667 -         string_appendf (link, "%02x/", (unsigned) *data++);
668 +         string_appendf (link, "%02x", (unsigned) *data++);
669         }
670 -
671 +      if (size > 0)
672 +       link += "/";
673        while (size-- > 0)
674         string_appendf (link, "%02x", (unsigned) *data++);
675  
676        link += suffix;
677  
678        gdb_bfd_ref_ptr debug_bfd
679 -       = build_id_to_debug_bfd_1 (link, build_id_len, build_id);
680 +       = build_id_to_debug_bfd_1 (link, build_id_len, build_id, link_return);
681        if (debug_bfd != NULL)
682         return debug_bfd;
683  
684 @@ -170,7 +674,8 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
685        if (strcmp (gdb_sysroot, TARGET_SYSROOT_PREFIX) != 0)
686         {
687           link = gdb_sysroot + link;
688 -         debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id);
689 +         debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id,
690 +                                              link_return);
691           if (debug_bfd != NULL)
692             return debug_bfd;
693         }
694 @@ -179,38 +684,208 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
695    return {};
696  }
697  
698 +char *
699 +build_id_to_filename (const struct bfd_build_id *build_id, char **link_return)
700 +{
701 +  gdb_bfd_ref_ptr abfd;
702 +  char *result;
703 +  
704 +  abfd = build_id_to_exec_bfd (build_id->size, build_id->data, link_return);
705 +  if (abfd == NULL)
706 +    return NULL;
707 +
708 +  result = xstrdup (bfd_get_filename (abfd.get ()));
709 +  return result;
710 +}
711 +
712 +/* This MISSING_FILEPAIR_HASH tracker is used only for the duplicite messages
713 +     Try to install the hash file ...
714 +   avoidance.  */
715 +
716 +struct missing_filepair
717 +  {
718 +    char *binary;
719 +    char *debug;
720 +    char data[1];
721 +  };
722 +
723 +static struct htab *missing_filepair_hash;
724 +static struct obstack missing_filepair_obstack;
725 +
726 +static void *
727 +missing_filepair_xcalloc (size_t nmemb, size_t nmemb_size)
728 +{
729 +  void *retval;
730 +  size_t size = nmemb * nmemb_size;
731 +
732 +  retval = obstack_alloc (&missing_filepair_obstack, size);
733 +  memset (retval, 0, size);
734 +  return retval;
735 +}
736 +
737 +static hashval_t
738 +missing_filepair_hash_func (const struct missing_filepair *elem)
739 +{
740 +  hashval_t retval = 0;
741 +
742 +  retval ^= htab_hash_string (elem->binary);
743 +  if (elem->debug != NULL)
744 +    retval ^= htab_hash_string (elem->debug);
745 +
746 +  return retval;
747 +}
748 +
749 +static int
750 +missing_filepair_eq (const struct missing_filepair *elem1,
751 +                      const struct missing_filepair *elem2)
752 +{
753 +  return strcmp (elem1->binary, elem2->binary) == 0
754 +         && ((elem1->debug == NULL) == (elem2->debug == NULL))
755 +         && (elem1->debug == NULL || strcmp (elem1->debug, elem2->debug) == 0);
756 +}
757 +
758 +static void
759 +missing_filepair_change (void)
760 +{
761 +  if (missing_filepair_hash != NULL)
762 +    {
763 +      obstack_free (&missing_filepair_obstack, NULL);
764 +      /* All their memory came just from missing_filepair_OBSTACK.  */
765 +      missing_filepair_hash = NULL;
766 +    }
767 +}
768 +
769 +static void
770 +debug_print_executable_changed (void)
771 +{
772 +  missing_filepair_change ();
773 +}
774 +
775 +/* Notify user the file BINARY with (possibly NULL) associated separate debug
776 +   information file DEBUG is missing.  DEBUG may or may not be the build-id
777 +   file such as would be:
778 +     /usr/lib/debug/.build-id/dd/b1d2ce632721c47bb9e8679f369e2295ce71be.debug
779 +   */
780 +
781 +void
782 +debug_print_missing (const char *binary, const char *debug)
783 +{
784 +  size_t binary_len0 = strlen (binary) + 1;
785 +  size_t debug_len0 = debug ? strlen (debug) + 1 : 0;
786 +  struct missing_filepair missing_filepair_find;
787 +  struct missing_filepair *missing_filepair;
788 +  struct missing_filepair **slot;
789 +
790 +  if (build_id_verbose < BUILD_ID_VERBOSE_FILENAMES)
791 +    return;
792 +
793 +  if (missing_filepair_hash == NULL)
794 +    {
795 +      obstack_init (&missing_filepair_obstack);
796 +      missing_filepair_hash = htab_create_alloc (64,
797 +       (hashval_t (*) (const void *)) missing_filepair_hash_func,
798 +       (int (*) (const void *, const void *)) missing_filepair_eq, NULL,
799 +       missing_filepair_xcalloc, NULL);
800 +    }
801 +
802 +  /* Use MISSING_FILEPAIR_FIND first instead of calling obstack_alloc with
803 +     obstack_free in the case of a (rare) match.  The problem is ALLOC_F for
804 +     MISSING_FILEPAIR_HASH allocates from MISSING_FILEPAIR_OBSTACK maintenance
805 +     structures for MISSING_FILEPAIR_HASH.  Calling obstack_free would possibly
806 +     not to free only MISSING_FILEPAIR but also some such structures (allocated
807 +     during the htab_find_slot call).  */
808 +
809 +  missing_filepair_find.binary = (char *) binary;
810 +  missing_filepair_find.debug = (char *) debug;
811 +  slot = (struct missing_filepair **) htab_find_slot (missing_filepair_hash,
812 +                                                     &missing_filepair_find,
813 +                                                     INSERT);
814 +
815 +  /* While it may be still printed duplicitely with the missing debuginfo file
816 +   * it is due to once printing about the binary file build-id link and once
817 +   * about the .debug file build-id link as both the build-id symlinks are
818 +   * located in the debuginfo package.  */
819 +
820 +  if (*slot != NULL)
821 +    return;
822 +
823 +  missing_filepair = (struct missing_filepair *) obstack_alloc (&missing_filepair_obstack,
824 +                                                               sizeof (*missing_filepair) - 1
825 +                                                               + binary_len0 + debug_len0);
826 +  missing_filepair->binary = missing_filepair->data;
827 +  memcpy (missing_filepair->binary, binary, binary_len0);
828 +  if (debug != NULL)
829 +    {
830 +      missing_filepair->debug = missing_filepair->binary + binary_len0;
831 +      memcpy (missing_filepair->debug, debug, debug_len0);
832 +    }
833 +  else
834 +    missing_filepair->debug = NULL;
835 +
836 +  *slot = missing_filepair;
837 +
838 +  /* We do not collect and flush these messages as each such message
839 +     already requires its own separate lines.  */
840 +
841 +  fprintf_unfiltered (gdb_stdlog,
842 +                     _("Missing separate debuginfo for %s\n"), binary);
843 +  if (debug != NULL)
844 +    fprintf_unfiltered (gdb_stdlog, _("Try to install the hash file %s\n"),
845 +                       debug);
846 +}
847 +
848  /* See build-id.h.  */
849  
850  gdb_bfd_ref_ptr
851 -build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id)
852 +build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id,
853 +                      char **link_return)
854  {
855 -  return build_id_to_bfd_suffix (build_id_len, build_id, ".debug");
856 +  return build_id_to_bfd_suffix (build_id_len, build_id, ".debug",
857 +                                link_return);
858  }
859  
860  /* See build-id.h.  */
861  
862  gdb_bfd_ref_ptr
863 -build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id)
864 +build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id,
865 +                     char **link_return)
866  {
867 -  return build_id_to_bfd_suffix (build_id_len, build_id, "");
868 +  return build_id_to_bfd_suffix (build_id_len, build_id, "", link_return);
869  }
870  
871  /* See build-id.h.  */
872  
873  std::string
874 -find_separate_debug_file_by_buildid (struct objfile *objfile)
875 +find_separate_debug_file_by_buildid (struct objfile *objfile,
876 +                       gdb::unique_xmalloc_ptr<char> *build_id_filename_return)
877  {
878    const struct bfd_build_id *build_id;
879  
880 -  build_id = build_id_bfd_get (objfile->obfd);
881 +  if (build_id_filename_return)
882 +    *build_id_filename_return = NULL;
883 +
884 +  build_id = build_id_bfd_shdr_get (objfile->obfd);
885    if (build_id != NULL)
886      {
887        if (separate_debug_file_debug)
888         printf_unfiltered (_("\nLooking for separate debug info (build-id) for "
889                              "%s\n"), objfile_name (objfile));
890  
891 +      char *build_id_filename_cstr = NULL;
892        gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size,
893 -                                                  build_id->data));
894 +                                                   build_id->data,
895 +             (!build_id_filename_return ? NULL : &build_id_filename_cstr)));
896 +      if (build_id_filename_return)
897 +       {
898 +         if (!build_id_filename_cstr)
899 +           gdb_assert (!*build_id_filename_return);
900 +         else
901 +           {
902 +             *build_id_filename_return = gdb::unique_xmalloc_ptr<char> (build_id_filename_cstr);
903 +             build_id_filename_cstr = NULL;
904 +           }
905 +       }
906 +
907        /* Prevent looping on a stripped .debug file.  */
908        if (abfd != NULL
909           && filename_cmp (bfd_get_filename (abfd.get ()),
910 @@ -223,3 +898,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile)
911  
912    return std::string ();
913  }
914 +
915 +extern void _initialize_build_id (void);
916 +
917 +void
918 +_initialize_build_id (void)
919 +{
920 +  add_setshow_zinteger_cmd ("build-id-verbose", no_class, &build_id_verbose,
921 +                           _("\
922 +Set debugging level of the build-id locator."), _("\
923 +Show debugging level of the build-id locator."), _("\
924 +Level 1 (default) enables printing the missing debug filenames,\n\
925 +level 2 also prints the parsing of binaries to find the identificators."),
926 +                           NULL,
927 +                           show_build_id_verbose,
928 +                           &setlist, &showlist);
929 +
930 +  gdb::observers::executable_changed.attach (debug_print_executable_changed);
931 +}
932 diff --git a/gdb/build-id.h b/gdb/build-id.h
933 --- a/gdb/build-id.h
934 +++ b/gdb/build-id.h
935 @@ -23,9 +23,10 @@
936  #include "gdb_bfd.h"
937  #include "gdbsupport/rsp-low.h"
938  
939 -/* Locate NT_GNU_BUILD_ID from ABFD and return its content.  */
940 +/* Separate debuginfo files have corrupted PHDR but SHDR is correct there.
941 +   Locate NT_GNU_BUILD_ID from ABFD and return its content.  */
942  
943 -extern const struct bfd_build_id *build_id_bfd_get (bfd *abfd);
944 +extern const struct bfd_build_id *build_id_bfd_shdr_get (bfd *abfd);
945  
946  /* Return true if ABFD has NT_GNU_BUILD_ID matching the CHECK value.
947     Otherwise, issue a warning and return false.  */
948 @@ -38,21 +39,26 @@ extern int build_id_verify (bfd *abfd,
949     can be found, return NULL.  */
950  
951  extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len,
952 -                                             const bfd_byte *build_id);
953 +                                             const bfd_byte *build_id,
954 +                                             char **link_return);
955 +
956 +extern char *build_id_to_filename (const struct bfd_build_id *build_id,
957 +                                  char **link_return);
958  
959  /* Find and open a BFD for an executable file given a build-id.  If no BFD
960     can be found, return NULL.  The returned reference to the BFD must be
961     released by the caller.  */
962  
963  extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len,
964 -                                            const bfd_byte *build_id);
965 +                                            const bfd_byte *build_id,
966 +                                            char **link_return);
967  
968  /* Find the separate debug file for OBJFILE, by using the build-id
969     associated with OBJFILE's BFD.  If successful, returns the file name for the
970     separate debug file, otherwise, return an empty string.  */
971  
972 -extern std::string find_separate_debug_file_by_buildid
973 -  (struct objfile *objfile);
974 +extern std::string find_separate_debug_file_by_buildid (struct objfile *objfile,
975 +                      gdb::unique_xmalloc_ptr<char> *build_id_filename_return);
976  
977  /* Return an hex-string representation of BUILD_ID.  */
978  
979 diff --git a/gdb/coffread.c b/gdb/coffread.c
980 --- a/gdb/coffread.c
981 +++ b/gdb/coffread.c
982 @@ -709,7 +709,8 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
983    /* Try to add separate debug file if no symbols table found.   */
984    if (!objfile_has_partial_symbols (objfile))
985      {
986 -      std::string debugfile = find_separate_debug_file_by_buildid (objfile);
987 +      std::string debugfile = find_separate_debug_file_by_buildid (objfile,
988 +                                                                  NULL);
989  
990        if (debugfile.empty ())
991         debugfile = find_separate_debug_file_by_debuglink (objfile);
992 diff --git a/gdb/corelow.c b/gdb/corelow.c
993 --- a/gdb/corelow.c
994 +++ b/gdb/corelow.c
995 @@ -22,6 +22,10 @@
996  #include <signal.h>
997  #include <fcntl.h>
998  #include "frame.h"             /* required by inferior.h */
999 +#include "auxv.h"
1000 +#include "build-id.h"
1001 +#include "elf/common.h"
1002 +#include "gdbcmd.h"
1003  #include "inferior.h"
1004  #include "infrun.h"
1005  #include "symtab.h"
1006 @@ -322,6 +326,8 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
1007      inferior_ptid = ptid;                      /* Yes, make it current.  */
1008  }
1009  
1010 +static bool build_id_core_loads = true;
1011 +
1012  /* Issue a message saying we have no core to debug, if FROM_TTY.  */
1013  
1014  static void
1015 @@ -358,19 +364,25 @@ core_file_command (const char *filename, int from_tty)
1016  static void
1017  locate_exec_from_corefile_build_id (bfd *abfd, int from_tty)
1018  {
1019 -  const bfd_build_id *build_id = build_id_bfd_get (abfd);
1020 +  const bfd_build_id *build_id = build_id_bfd_shdr_get (abfd);
1021    if (build_id == nullptr)
1022      return;
1023  
1024 +  char *build_id_filename;
1025    gdb_bfd_ref_ptr execbfd
1026 -    = build_id_to_exec_bfd (build_id->size, build_id->data);
1027 +    = build_id_to_exec_bfd (build_id->size, build_id->data,
1028 +                           &build_id_filename);
1029  
1030    if (execbfd != nullptr)
1031      {
1032        exec_file_attach (bfd_get_filename (execbfd.get ()), from_tty);
1033        symbol_file_add_main (bfd_get_filename (execbfd.get ()),
1034                             symfile_add_flag (from_tty ? SYMFILE_VERBOSE : 0));
1035 +      if (symfile_objfile != NULL)
1036 +       symfile_objfile->flags |= OBJF_BUILD_ID_CORE_LOADED;
1037      }
1038 +  else
1039 +    debug_print_missing (BUILD_ID_MAIN_EXECUTABLE_FILENAME, build_id_filename);
1040  }
1041  
1042  /* See gdbcore.h.  */
1043 @@ -998,4 +1010,11 @@ void
1044  _initialize_corelow (void)
1045  {
1046    add_target (core_target_info, core_target_open, filename_completer);
1047 +
1048 +  add_setshow_boolean_cmd ("build-id-core-loads", class_files,
1049 +                          &build_id_core_loads, _("\
1050 +Set whether CORE-FILE loads the build-id associated files automatically."), _("\
1051 +Show whether CORE-FILE loads the build-id associated files automatically."),
1052 +                          NULL, NULL, NULL,
1053 +                          &setlist, &showlist);
1054  }
1055 diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
1056 --- a/gdb/doc/gdb.texinfo
1057 +++ b/gdb/doc/gdb.texinfo
1058 @@ -20862,6 +20862,27 @@ information files.
1059  
1060  @end table
1061  
1062 +You can also adjust the current verbosity of the @dfn{build id} locating.
1063 +
1064 +@table @code
1065 +
1066 +@kindex set build-id-verbose
1067 +@item set build-id-verbose 0
1068 +No additional messages are printed.
1069 +
1070 +@item set build-id-verbose 1
1071 +Missing separate debug filenames are printed.
1072 +
1073 +@item set build-id-verbose 2
1074 +Missing separate debug filenames are printed and also all the parsing of the
1075 +binaries to find their @dfn{build id} content is printed.
1076 +
1077 +@kindex show build-id-verbose
1078 +@item show build-id-verbose
1079 +Show the current verbosity value for the @dfn{build id} content locating.
1080 +
1081 +@end table
1082 +
1083  @cindex @code{.gnu_debuglink} sections
1084  @cindex debug link sections
1085  A debug link is a special section of the executable file named
1086 diff --git a/gdb/dwarf-index-cache.c b/gdb/dwarf-index-cache.c
1087 --- a/gdb/dwarf-index-cache.c
1088 +++ b/gdb/dwarf-index-cache.c
1089 @@ -94,7 +94,7 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
1090      return;
1091  
1092    /* Get build id of objfile.  */
1093 -  const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
1094 +  const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd);
1095    if (build_id == nullptr)
1096      {
1097        if (debug_index_cache)
1098 @@ -112,7 +112,8 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
1099  
1100    if (dwz != nullptr)
1101      {
1102 -      const bfd_build_id *dwz_build_id = build_id_bfd_get (dwz->dwz_bfd.get ());
1103 +      const bfd_build_id *dwz_build_id
1104 +       = build_id_bfd_shdr_get (dwz->dwz_bfd.get ());
1105  
1106        if (dwz_build_id == nullptr)
1107         {
1108 diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
1109 --- a/gdb/dwarf2read.c
1110 +++ b/gdb/dwarf2read.c
1111 @@ -2718,7 +2718,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
1112      }
1113  
1114    if (dwz_bfd == NULL)
1115 -    dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
1116 +    dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid, NULL);
1117  
1118    if (dwz_bfd == NULL)
1119      error (_("could not find '.gnu_debugaltlink' file for %s"),
1120 @@ -6276,7 +6276,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
1121  static gdb::array_view<const gdb_byte>
1122  get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
1123  {
1124 -  const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
1125 +  const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd);
1126    if (build_id == nullptr)
1127      return {};
1128  
1129 @@ -6289,7 +6289,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
1130  static gdb::array_view<const gdb_byte>
1131  get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz)
1132  {
1133 -  const bfd_build_id *build_id = build_id_bfd_get (dwz->dwz_bfd.get ());
1134 +  const bfd_build_id *build_id = build_id_bfd_shdr_get (dwz->dwz_bfd.get ());
1135    if (build_id == nullptr)
1136      return {};
1137  
1138 diff --git a/gdb/elfread.c b/gdb/elfread.c
1139 --- a/gdb/elfread.c
1140 +++ b/gdb/elfread.c
1141 @@ -1299,7 +1299,9 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
1142            && objfile->separate_debug_objfile == NULL
1143            && objfile->separate_debug_objfile_backlink == NULL)
1144      {
1145 -      std::string debugfile = find_separate_debug_file_by_buildid (objfile);
1146 +      gdb::unique_xmalloc_ptr<char> build_id_filename;
1147 +      std::string debugfile
1148 +       = find_separate_debug_file_by_buildid (objfile, &build_id_filename);
1149  
1150        if (debugfile.empty ())
1151         debugfile = find_separate_debug_file_by_debuglink (objfile);
1152 @@ -1311,8 +1313,12 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
1153           symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
1154                                     symfile_flags, objfile);
1155         }
1156 -       else
1157 -         has_dwarf2 = false;
1158 +      /* Check if any separate debug info has been extracted out.  */
1159 +      else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink")
1160 +              != NULL)
1161 +       debug_print_missing (objfile_name (objfile), build_id_filename.get ());
1162 +      else
1163 +       has_dwarf2 = false;
1164      }
1165  
1166    /* Read the CTF section only if there is no DWARF info.  */
1167 diff --git a/gdb/objfiles.h b/gdb/objfiles.h
1168 --- a/gdb/objfiles.h
1169 +++ b/gdb/objfiles.h
1170 @@ -627,6 +627,10 @@ struct objfile
1171    htab_up static_links;
1172  };
1173  
1174 +/* This file was loaded according to the BUILD_ID_CORE_LOADS rules.  */
1175 +
1176 +#define OBJF_BUILD_ID_CORE_LOADED static_cast<enum objfile_flag>(1 << 12)
1177 +
1178  /* Declarations for functions defined in objfiles.c */
1179  
1180  extern struct gdbarch *get_objfile_arch (const struct objfile *);
1181 diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
1182 --- a/gdb/python/py-objfile.c
1183 +++ b/gdb/python/py-objfile.c
1184 @@ -132,7 +132,7 @@ objfpy_get_build_id (PyObject *self, void *closure)
1185  
1186    try
1187      {
1188 -      build_id = build_id_bfd_get (objfile->obfd);
1189 +      build_id = build_id_bfd_shdr_get (objfile->obfd);
1190      }
1191    catch (const gdb_exception &except)
1192      {
1193 @@ -600,7 +600,7 @@ objfpy_lookup_objfile_by_build_id (const char *build_id)
1194        /* Don't return separate debug files.  */
1195        if (objfile->separate_debug_objfile_backlink != NULL)
1196         continue;
1197 -      obfd_build_id = build_id_bfd_get (objfile->obfd);
1198 +      obfd_build_id = build_id_bfd_shdr_get (objfile->obfd);
1199        if (obfd_build_id == NULL)
1200         continue;
1201        if (objfpy_build_id_matches (obfd_build_id, build_id))
1202 diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
1203 --- a/gdb/solib-svr4.c
1204 +++ b/gdb/solib-svr4.c
1205 @@ -45,6 +45,7 @@
1206  #include "auxv.h"
1207  #include "gdb_bfd.h"
1208  #include "probe.h"
1209 +#include "build-id.h"
1210  
1211  static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
1212  static int svr4_have_link_map_offsets (void);
1213 @@ -1344,9 +1345,51 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
1214           continue;
1215         }
1216  
1217 -      strncpy (newobj->so_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1);
1218 -      newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
1219 -      strcpy (newobj->so_original_name, newobj->so_name);
1220 +      {
1221 +       struct bfd_build_id *build_id;
1222 +
1223 +       strncpy (newobj->so_original_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1);
1224 +       newobj->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
1225 +       /* May get overwritten below.  */
1226 +       strcpy (newobj->so_name, newobj->so_original_name);
1227 +
1228 +       build_id = build_id_addr_get (((lm_info_svr4 *) newobj->lm_info)->l_ld);
1229 +       if (build_id != NULL)
1230 +         {
1231 +           char *name, *build_id_filename;
1232 +
1233 +           /* Missing the build-id matching separate debug info file
1234 +              would be handled while SO_NAME gets loaded.  */
1235 +           name = build_id_to_filename (build_id, &build_id_filename);
1236 +           if (name != NULL)
1237 +             {
1238 +               strncpy (newobj->so_name, name, SO_NAME_MAX_PATH_SIZE - 1);
1239 +               newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
1240 +               xfree (name);
1241 +             }
1242 +           else
1243 +             {
1244 +               debug_print_missing (newobj->so_name, build_id_filename);
1245 +
1246 +               /* In the case the main executable was found according to
1247 +                  its build-id (from a core file) prevent loading
1248 +                  a different build of a library with accidentally the
1249 +                  same SO_NAME.
1250 +
1251 +                  It suppresses bogus backtraces (and prints "??" there
1252 +                  instead) if the on-disk files no longer match the
1253 +                  running program version.  */
1254 +
1255 +               if (symfile_objfile != NULL
1256 +                   && (symfile_objfile->flags
1257 +                       & OBJF_BUILD_ID_CORE_LOADED) != 0)
1258 +                 newobj->so_name[0] = 0;
1259 +             }
1260 +
1261 +           xfree (build_id_filename);
1262 +           xfree (build_id);
1263 +         }
1264 +      }
1265  
1266        /* If this entry has no name, or its name matches the name
1267          for the main executable, don't include it in the list.  */
1268 diff --git a/gdb/symfile.h b/gdb/symfile.h
1269 --- a/gdb/symfile.h
1270 +++ b/gdb/symfile.h
1271 @@ -532,12 +532,17 @@ void expand_symtabs_matching
1272  void map_symbol_filenames (symbol_filename_ftype *fun, void *data,
1273                            int need_fullname);
1274  
1275 +
1276  /* Target-agnostic function to load the sections of an executable into memory.
1277  
1278     ARGS should be in the form "EXECUTABLE [OFFSET]", where OFFSET is an
1279     optional offset to apply to each section.  */
1280  extern void generic_load (const char *args, int from_tty);
1281  
1282 +/* build-id support.  */
1283 +extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr);
1284 +extern void debug_print_missing (const char *binary, const char *debug);
1285 +
1286  /* From dwarf2read.c */
1287  
1288  /* Names for a dwarf2 debugging section.  The field NORMAL is the normal
1289 diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
1290 --- a/gdb/testsuite/gdb.base/corefile.exp
1291 +++ b/gdb/testsuite/gdb.base/corefile.exp
1292 @@ -311,3 +311,33 @@ gdb_test_multiple "core-file $corefile" $test {
1293         pass $test
1294      }
1295  }
1296 +
1297 +
1298 +# Test auto-loading of binary files through build-id from the core file.
1299 +set buildid [build_id_debug_filename_get $binfile]
1300 +set wholetest "binfile found by build-id"
1301 +if {$buildid == ""} {
1302 +    untested "$wholetest (binary has no build-id)"
1303 +} else {
1304 +    gdb_exit
1305 +    gdb_start
1306 +
1307 +    regsub {\.debug$} $buildid {} buildid
1308 +    set debugdir [standard_output_file ${testfile}-debugdir]
1309 +    file delete -force -- $debugdir
1310 +    file mkdir $debugdir/[file dirname $buildid]
1311 +    file copy $binfile $debugdir/$buildid
1312 +
1313 +    set test "show debug-file-directory"
1314 +    gdb_test_multiple $test $test {
1315 +       -re "The directory where separate debug symbols are searched for is \"(.*)\"\\.\r\n$gdb_prompt $" {
1316 +           set debugdir_orig $expect_out(1,string)
1317 +           pass $test
1318 +       }
1319 +    }
1320 +    gdb_test_no_output "set debug-file-directory $debugdir:$debugdir_orig" "set debug-file-directory"
1321 +    gdb_test "show build-id-core-loads" {Whether CORE-FILE loads the build-id associated files automatically is on\.}
1322 +    gdb_test "core-file $corefile" "\r\nProgram terminated with .*" "core-file without executable"
1323 +    gdb_test "info files" "Local exec file:\r\n\[ \t\]*`[string_to_regexp $debugdir/$buildid]', file type .*"
1324 +    pass $wholetest
1325 +}
1326 diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.exp b/gdb/testsuite/gdb.base/new-ui-pending-input.exp
1327 --- a/gdb/testsuite/gdb.base/new-ui-pending-input.exp
1328 +++ b/gdb/testsuite/gdb.base/new-ui-pending-input.exp
1329 @@ -62,6 +62,7 @@ proc test_command_line_new_ui_pending_input {} {
1330      set options ""
1331      append options " -iex \"set height 0\""
1332      append options " -iex \"set width 0\""
1333 +    append options " -iex \"set build-id-verbose 0\""
1334      append options " -iex \"new-ui console $extra_tty_name\""
1335      append options " -ex \"b $bpline\""
1336      append options " -ex \"run\""
1337 diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
1338 --- a/gdb/testsuite/lib/gdb.exp
1339 +++ b/gdb/testsuite/lib/gdb.exp
1340 @@ -1891,6 +1891,17 @@ proc default_gdb_start { } {
1341         }
1342      }
1343  
1344 +    # Turn off the missing warnings as the testsuite does not expect it.
1345 +    send_gdb "set build-id-verbose 0\n"
1346 +    gdb_expect 10 {
1347 +       -re "$gdb_prompt $" {
1348 +           verbose "Disabled the missing debug infos warnings." 2
1349 +       }
1350 +       timeout {
1351 +           warning "Could not disable the missing debug infos warnings.."
1352 +       }
1353 +    }
1354 +
1355      gdb_debug_init
1356      return 0
1357  }
1358 diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
1359 --- a/gdb/testsuite/lib/mi-support.exp
1360 +++ b/gdb/testsuite/lib/mi-support.exp
1361 @@ -309,6 +309,16 @@ proc default_mi_gdb_start { args } {
1362             warning "Couldn't set the width to 0."
1363         }
1364      }
1365 +    # Turn off the missing warnings as the testsuite does not expect it.
1366 +    send_gdb "190-gdb-set build-id-verbose 0\n"
1367 +    gdb_expect 10 {
1368 +       -re ".*190-gdb-set build-id-verbose 0\r\n190\\\^done\r\n$mi_gdb_prompt$" {
1369 +           verbose "Disabled the missing debug infos warnings." 2
1370 +       }
1371 +       timeout {
1372 +           warning "Could not disable the missing debug infos warnings.."
1373 +       }
1374 +    }
1375  
1376      if { $separate_inferior_pty } {
1377         mi_create_inferior_pty
This page took 0.279273 seconds and 3 git commands to generate.