]> git.pld-linux.org Git - packages/gdb.git/blame - gdb-6.6-buildid-locate.patch
- BR: libselinux-devel (because of attach-fail-reasons-5of5 patch)
[packages/gdb.git] / gdb-6.6-buildid-locate.patch
CommitLineData
f412e1b4 1Index: gdb-7.4.50.20120120/gdb/corelow.c
3a58abaf 2===================================================================
f412e1b4
PS
3--- gdb-7.4.50.20120120.orig/gdb/corelow.c 2012-01-10 17:30:44.000000000 +0100
4+++ gdb-7.4.50.20120120/gdb/corelow.c 2012-01-21 00:02:58.720401792 +0100
5@@ -46,6 +46,9 @@
3a58abaf 6 #include "filenames.h"
51a5ef0f
PS
7 #include "progspace.h"
8 #include "objfiles.h"
3a58abaf
AM
9+#include "auxv.h"
10+#include "elf/common.h"
3a58abaf
AM
11+#include "gdbcmd.h"
12
3a58abaf 13 #ifndef O_LARGEFILE
f412e1b4
PS
14 #define O_LARGEFILE 0
15@@ -273,6 +276,52 @@ add_to_thread_list (bfd *abfd, asection
6ed6bacf 16 inferior_ptid = ptid; /* Yes, make it current. */
3a58abaf
AM
17 }
18
19+static int build_id_core_loads = 1;
20+
21+static void
22+build_id_locate_exec (int from_tty)
23+{
24+ CORE_ADDR at_entry;
25+ struct build_id *build_id;
26+ char *exec_filename, *debug_filename;
27+ char *build_id_filename;
7566401a 28+ struct cleanup *back_to;
3a58abaf 29+
7566401a 30+ if (exec_bfd != NULL || symfile_objfile != NULL)
3a58abaf
AM
31+ return;
32+
33+ if (target_auxv_search (&current_target, AT_ENTRY, &at_entry) <= 0)
34+ return;
35+
36+ build_id = build_id_addr_get (at_entry);
37+ if (build_id == NULL)
38+ return;
39+
7566401a
ER
40+ /* SYMFILE_OBJFILE should refer to the main executable (not only to its
41+ separate debug info file). gcc44+ keeps .eh_frame only in the main
42+ executable without its duplicate .debug_frame in the separate debug info
43+ file - such .eh_frame would not be found if SYMFILE_OBJFILE would refer
44+ directly to the separate debug info file. */
45+
3a58abaf 46+ exec_filename = build_id_to_filename (build_id, &build_id_filename, 0);
7566401a 47+ back_to = make_cleanup (xfree, build_id_filename);
3a58abaf 48+
7566401a 49+ if (exec_filename != NULL)
3a58abaf 50+ {
7566401a
ER
51+ make_cleanup (xfree, exec_filename);
52+ exec_file_attach (exec_filename, from_tty);
53+ symbol_file_add_main (exec_filename, from_tty);
54+ if (symfile_objfile != NULL)
55+ symfile_objfile->flags |= OBJF_BUILD_ID_CORE_LOADED;
3a58abaf
AM
56+ }
57+ else
7566401a 58+ debug_print_missing (_("the main executable file"), build_id_filename);
3a58abaf 59+
7566401a 60+ do_cleanups (back_to);
3a58abaf
AM
61+
62+ /* No automatic SOLIB_ADD as the libraries would get read twice. */
63+}
64+
65 /* This routine opens and sets up the core file bfd. */
66
67 static void
f412e1b4 68@@ -375,6 +424,12 @@ core_open (char *filename, int from_tty)
3a58abaf
AM
69 push_target (&core_ops);
70 discard_cleanups (old_chain);
71
72+ /* Find the build_id identifiers. If it gets executed after
73+ POST_CREATE_INFERIOR we would clash with asking to discard the already
74+ loaded VDSO symbols. */
75+ if (build_id_core_loads != 0)
76+ build_id_locate_exec (from_tty);
77+
3a58abaf 78 /* Do this before acknowledging the inferior, so if
51a5ef0f
PS
79 post_create_inferior throws (can happen easilly if you're loading
80 a core file with the wrong exec), we aren't left with threads
f412e1b4 81@@ -934,4 +989,11 @@ _initialize_corelow (void)
3a58abaf
AM
82 init_core_ops ();
83
84 add_target (&core_ops);
85+
86+ add_setshow_boolean_cmd ("build-id-core-loads", class_files,
87+ &build_id_core_loads, _("\
88+Set whether CORE-FILE loads the build-id associated files automatically."), _("\
89+Show whether CORE-FILE loads the build-id associated files automatically.."),
90+ NULL, NULL, NULL,
91+ &setlist, &showlist);
92 }
f412e1b4 93Index: gdb-7.4.50.20120120/gdb/doc/gdb.texinfo
3a58abaf 94===================================================================
f412e1b4
PS
95--- gdb-7.4.50.20120120.orig/gdb/doc/gdb.texinfo 2012-01-21 00:02:36.000000000 +0100
96+++ gdb-7.4.50.20120120/gdb/doc/gdb.texinfo 2012-01-21 00:02:41.619463607 +0100
97@@ -16015,6 +16015,27 @@ information files.
3a58abaf
AM
98
99 @end table
100
101+You can also adjust the current verbosity of the @dfn{build id} locating.
102+
103+@table @code
104+
105+@kindex set build-id-verbose
106+@item set build-id-verbose 0
107+No additional messages are printed.
108+
109+@item set build-id-verbose 1
110+Missing separate debug filenames are printed.
111+
112+@item set build-id-verbose 2
113+Missing separate debug filenames are printed and also all the parsing of the
114+binaries to find their @dfn{build id} content is printed.
115+
116+@kindex show build-id-verbose
117+@item show build-id-verbose
118+Show the current verbosity value for the @dfn{build id} content locating.
119+
120+@end table
121+
122 @cindex @code{.gnu_debuglink} sections
123 @cindex debug link sections
124 A debug link is a special section of the executable file named
f412e1b4 125Index: gdb-7.4.50.20120120/gdb/solib-svr4.c
3a58abaf 126===================================================================
f412e1b4
PS
127--- gdb-7.4.50.20120120.orig/gdb/solib-svr4.c 2012-01-04 09:17:11.000000000 +0100
128+++ gdb-7.4.50.20120120/gdb/solib-svr4.c 2012-01-21 00:02:41.620463603 +0100
129@@ -1227,9 +1227,52 @@ svr4_read_so_list (CORE_ADDR lm, struct
130 continue;
131 }
132
133- strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
134- new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
135- strcpy (new->so_original_name, new->so_name);
136+ {
137+ struct build_id *build_id;
138+
139+ strncpy (new->so_original_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
140+ new->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
141+ /* May get overwritten below. */
142+ strcpy (new->so_name, new->so_original_name);
143+
144+ build_id = build_id_addr_get (new->lm_info->l_ld);
145+ if (build_id != NULL)
146+ {
147+ char *name, *build_id_filename;
148+
149+ /* Missing the build-id matching separate debug info file
150+ would be handled while SO_NAME gets loaded. */
151+ name = build_id_to_filename (build_id, &build_id_filename, 0);
152+ if (name != NULL)
153+ {
154+ strncpy (new->so_name, name, SO_NAME_MAX_PATH_SIZE - 1);
155+ new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
156+ xfree (name);
157+ }
158+ else
159+ {
160+ debug_print_missing (new->so_name, build_id_filename);
161+
162+ /* In the case the main executable was found according to
163+ its build-id (from a core file) prevent loading
164+ a different build of a library with accidentally the
165+ same SO_NAME.
166+
167+ It suppresses bogus backtraces (and prints "??" there
168+ instead) if the on-disk files no longer match the
169+ running program version. */
170+
171+ if (symfile_objfile != NULL
172+ && (symfile_objfile->flags
173+ & OBJF_BUILD_ID_CORE_LOADED) != 0)
174+ new->so_name[0] = 0;
175+ }
176+
177+ xfree (build_id_filename);
178+ xfree (build_id);
179+ }
180+ }
181+
182 xfree (buffer);
3a58abaf 183
f412e1b4
PS
184 /* If this entry has no name, or its name matches the name
185Index: gdb-7.4.50.20120120/gdb/elfread.c
3a58abaf 186===================================================================
f412e1b4
PS
187--- gdb-7.4.50.20120120.orig/gdb/elfread.c 2012-01-21 00:02:33.000000000 +0100
188+++ gdb-7.4.50.20120120/gdb/elfread.c 2012-01-21 00:02:41.621463599 +0100
189@@ -44,6 +44,11 @@
6ed6bacf
AM
190 #include "gdbthread.h"
191 #include "regcache.h"
f412e1b4 192 #include "bcache.h"
3a58abaf 193+#include "libbfd.h"
51a5ef0f
PS
194+#include "gdbcore.h"
195+#include "gdbcmd.h"
196+#include "observer.h"
6ed6bacf 197+#include <sys/stat.h>
3a58abaf 198
51a5ef0f
PS
199 extern void _initialize_elfread (void);
200
f412e1b4 201@@ -1076,16 +1081,65 @@ elf_gnu_ifunc_resolver_return_stop (stru
6ed6bacf 202 update_breakpoint_locations (b, sals, sals_end);
3a58abaf
AM
203 }
204
3a58abaf
AM
205+#define BUILD_ID_VERBOSE_NONE 0
206+#define BUILD_ID_VERBOSE_FILENAMES 1
207+#define BUILD_ID_VERBOSE_BINARY_PARSE 2
208+static int build_id_verbose = BUILD_ID_VERBOSE_FILENAMES;
209+static void
210+show_build_id_verbose (struct ui_file *file, int from_tty,
211+ struct cmd_list_element *c, const char *value)
212+{
213+ fprintf_filtered (file, _("Verbosity level of the build-id locator is %s.\n"),
214+ value);
215+}
216+
217 struct build_id
218 {
219 size_t size;
220 gdb_byte data[1];
221 };
222
223-/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */
6ed6bacf
AM
224+/* Locate NT_GNU_BUILD_ID and return its matching debug filename.
225+ FIXME: NOTE decoding should be unified with the BFD core notes decoding. */
226+
3a58abaf
AM
227+struct build_id *
228+build_id_buf_get (bfd *templ, gdb_byte *buf, bfd_size_type size)
229+{
230+ bfd_byte *p;
231+
232+ p = buf;
233+ while (p < buf + size)
234+ {
235+ /* FIXME: bad alignment assumption. */
236+ Elf_External_Note *xnp = (Elf_External_Note *) p;
237+ size_t namesz = H_GET_32 (templ, xnp->namesz);
238+ size_t descsz = H_GET_32 (templ, xnp->descsz);
239+ bfd_byte *descdata = xnp->name + BFD_ALIGN (namesz, 4);
240+
241+ if (H_GET_32 (templ, xnp->type) == NT_GNU_BUILD_ID
242+ && namesz == sizeof "GNU"
243+ && memcmp (xnp->name, "GNU", sizeof "GNU") == 0)
244+ {
245+ size_t size = descsz;
246+ gdb_byte *data = (void *) descdata;
247+ struct build_id *retval;
248+
249+ retval = xmalloc (sizeof *retval - 1 + size);
250+ retval->size = size;
251+ memcpy (retval->data, data, size);
252+
253+ return retval;
254+ }
255+ p = descdata + BFD_ALIGN (descsz, 4);
256+ }
257+ return NULL;
258+}
259+
260+/* Separate debuginfo files have corrupted PHDR but SHDR is correct there.
261+ Locate NT_GNU_BUILD_ID from ABFD and return its content. */
262
263 static struct build_id *
264-build_id_bfd_get (bfd *abfd)
265+build_id_bfd_shdr_get (bfd *abfd)
266 {
267 struct build_id *retval;
268
f412e1b4 269@@ -1101,6 +1155,348 @@ build_id_bfd_get (bfd *abfd)
3a58abaf
AM
270 return retval;
271 }
272
273+/* Core files may have missing (corrupt) SHDR but PDHR is correct there.
274+ bfd_elf_bfd_from_remote_memory () has too much overhead by
275+ allocating/reading all the available ELF PT_LOADs. */
276+
277+static struct build_id *
278+build_id_phdr_get (bfd *templ, bfd_vma loadbase, unsigned e_phnum,
279+ Elf_Internal_Phdr *i_phdr)
280+{
281+ int i;
282+ struct build_id *retval = NULL;
283+
284+ for (i = 0; i < e_phnum; i++)
285+ if (i_phdr[i].p_type == PT_NOTE && i_phdr[i].p_filesz > 0)
286+ {
287+ Elf_Internal_Phdr *hdr = &i_phdr[i];
288+ gdb_byte *buf;
289+ int err;
290+
291+ buf = xmalloc (hdr->p_filesz);
292+ err = target_read_memory (loadbase + i_phdr[i].p_vaddr, buf,
293+ hdr->p_filesz);
294+ if (err == 0)
295+ retval = build_id_buf_get (templ, buf, hdr->p_filesz);
296+ else
297+ retval = NULL;
298+ xfree (buf);
299+ if (retval != NULL)
300+ break;
301+ }
302+ return retval;
303+}
304+
305+/* First we validate the file by reading in the ELF header and checking
306+ the magic number. */
307+
308+static inline bfd_boolean
309+elf_file_p (Elf64_External_Ehdr *x_ehdrp64)
310+{
311+ gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr));
312+ gdb_assert (offsetof (Elf64_External_Ehdr, e_ident)
313+ == offsetof (Elf32_External_Ehdr, e_ident));
314+ gdb_assert (sizeof (((Elf64_External_Ehdr *) 0)->e_ident)
315+ == sizeof (((Elf32_External_Ehdr *) 0)->e_ident));
316+
317+ return ((x_ehdrp64->e_ident[EI_MAG0] == ELFMAG0)
318+ && (x_ehdrp64->e_ident[EI_MAG1] == ELFMAG1)
319+ && (x_ehdrp64->e_ident[EI_MAG2] == ELFMAG2)
320+ && (x_ehdrp64->e_ident[EI_MAG3] == ELFMAG3));
321+}
322+
323+/* Translate an ELF file header in external format into an ELF file header in
324+ internal format. */
325+
326+#define H_GET_WORD(bfd, ptr) (is64 ? H_GET_64 (bfd, (ptr)) \
327+ : H_GET_32 (bfd, (ptr)))
328+#define H_GET_SIGNED_WORD(bfd, ptr) (is64 ? H_GET_S64 (bfd, (ptr)) \
329+ : H_GET_S32 (bfd, (ptr)))
330+
331+static void
332+elf_swap_ehdr_in (bfd *abfd,
333+ const Elf64_External_Ehdr *src64,
334+ Elf_Internal_Ehdr *dst)
335+{
336+ int is64 = bfd_get_arch_size (abfd) == 64;
337+#define SRC(field) (is64 ? src64->field \
338+ : ((const Elf32_External_Ehdr *) src64)->field)
339+
340+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
341+ memcpy (dst->e_ident, SRC (e_ident), EI_NIDENT);
342+ dst->e_type = H_GET_16 (abfd, SRC (e_type));
343+ dst->e_machine = H_GET_16 (abfd, SRC (e_machine));
344+ dst->e_version = H_GET_32 (abfd, SRC (e_version));
345+ if (signed_vma)
346+ dst->e_entry = H_GET_SIGNED_WORD (abfd, SRC (e_entry));
347+ else
348+ dst->e_entry = H_GET_WORD (abfd, SRC (e_entry));
349+ dst->e_phoff = H_GET_WORD (abfd, SRC (e_phoff));
350+ dst->e_shoff = H_GET_WORD (abfd, SRC (e_shoff));
351+ dst->e_flags = H_GET_32 (abfd, SRC (e_flags));
352+ dst->e_ehsize = H_GET_16 (abfd, SRC (e_ehsize));
353+ dst->e_phentsize = H_GET_16 (abfd, SRC (e_phentsize));
354+ dst->e_phnum = H_GET_16 (abfd, SRC (e_phnum));
355+ dst->e_shentsize = H_GET_16 (abfd, SRC (e_shentsize));
356+ dst->e_shnum = H_GET_16 (abfd, SRC (e_shnum));
357+ dst->e_shstrndx = H_GET_16 (abfd, SRC (e_shstrndx));
358+
359+#undef SRC
360+}
361+
362+/* Translate an ELF program header table entry in external format into an
363+ ELF program header table entry in internal format. */
364+
365+void
366+elf_swap_phdr_in (bfd *abfd,
367+ const Elf64_External_Phdr *src64,
368+ Elf_Internal_Phdr *dst)
369+{
370+ int is64 = bfd_get_arch_size (abfd) == 64;
371+#define SRC(field) (is64 ? src64->field \
372+ : ((const Elf32_External_Phdr *) src64)->field)
373+
374+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
375+
376+ dst->p_type = H_GET_32 (abfd, SRC (p_type));
377+ dst->p_flags = H_GET_32 (abfd, SRC (p_flags));
378+ dst->p_offset = H_GET_WORD (abfd, SRC (p_offset));
379+ if (signed_vma)
380+ {
381+ dst->p_vaddr = H_GET_SIGNED_WORD (abfd, SRC (p_vaddr));
382+ dst->p_paddr = H_GET_SIGNED_WORD (abfd, SRC (p_paddr));
383+ }
384+ else
385+ {
386+ dst->p_vaddr = H_GET_WORD (abfd, SRC (p_vaddr));
387+ dst->p_paddr = H_GET_WORD (abfd, SRC (p_paddr));
388+ }
389+ dst->p_filesz = H_GET_WORD (abfd, SRC (p_filesz));
390+ dst->p_memsz = H_GET_WORD (abfd, SRC (p_memsz));
391+ dst->p_align = H_GET_WORD (abfd, SRC (p_align));
392+
393+#undef SRC
394+}
395+
396+#undef H_GET_SIGNED_WORD
397+#undef H_GET_WORD
398+
399+static Elf_Internal_Phdr *
400+elf_get_phdr (bfd *templ, bfd_vma ehdr_vma, unsigned *e_phnum_pointer,
401+ bfd_vma *loadbase_pointer)
402+{
403+ /* sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr) */
404+ Elf64_External_Ehdr x_ehdr64; /* Elf file header, external form */
405+ Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
406+ bfd_size_type x_phdrs_size;
407+ gdb_byte *x_phdrs_ptr;
408+ Elf_Internal_Phdr *i_phdrs;
409+ int err;
410+ unsigned int i;
411+ bfd_vma loadbase;
412+ int loadbase_set;
413+
414+ gdb_assert (templ != NULL);
415+ gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr));
416+
417+ /* Read in the ELF header in external format. */
418+ err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr64, sizeof x_ehdr64);
419+ if (err)
420+ {
421+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
422+ warning (_("build-id: Error reading ELF header at address 0x%lx"),
423+ (unsigned long) ehdr_vma);
424+ return NULL;
425+ }
426+
427+ /* Now check to see if we have a valid ELF file, and one that BFD can
428+ make use of. The magic number must match, the address size ('class')
429+ and byte-swapping must match our XVEC entry. */
430+
431+ if (! elf_file_p (&x_ehdr64)
432+ || x_ehdr64.e_ident[EI_VERSION] != EV_CURRENT
433+ || !((bfd_get_arch_size (templ) == 64
434+ && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS64)
435+ || (bfd_get_arch_size (templ) == 32
436+ && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS32)))
437+ {
438+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
439+ warning (_("build-id: Unrecognized ELF header at address 0x%lx"),
440+ (unsigned long) ehdr_vma);
441+ return NULL;
442+ }
443+
444+ /* Check that file's byte order matches xvec's */
445+ switch (x_ehdr64.e_ident[EI_DATA])
446+ {
447+ case ELFDATA2MSB: /* Big-endian */
448+ if (! bfd_header_big_endian (templ))
449+ {
450+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
451+ warning (_("build-id: Unrecognized "
452+ "big-endian ELF header at address 0x%lx"),
453+ (unsigned long) ehdr_vma);
454+ return NULL;
455+ }
456+ break;
457+ case ELFDATA2LSB: /* Little-endian */
458+ if (! bfd_header_little_endian (templ))
459+ {
460+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
461+ warning (_("build-id: Unrecognized "
462+ "little-endian ELF header at address 0x%lx"),
463+ (unsigned long) ehdr_vma);
464+ return NULL;
465+ }
466+ break;
467+ case ELFDATANONE: /* No data encoding specified */
468+ default: /* Unknown data encoding specified */
469+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
470+ warning (_("build-id: Unrecognized "
471+ "ELF header endianity at address 0x%lx"),
472+ (unsigned long) ehdr_vma);
473+ return NULL;
474+ }
475+
476+ elf_swap_ehdr_in (templ, &x_ehdr64, &i_ehdr);
477+
478+ /* The file header tells where to find the program headers.
479+ These are what we use to actually choose what to read. */
480+
481+ if (i_ehdr.e_phentsize != (bfd_get_arch_size (templ) == 64
482+ ? sizeof (Elf64_External_Phdr)
483+ : sizeof (Elf32_External_Phdr))
484+ || i_ehdr.e_phnum == 0)
485+ {
486+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
487+ warning (_("build-id: Invalid ELF program headers from the ELF header "
488+ "at address 0x%lx"), (unsigned long) ehdr_vma);
489+ return NULL;
490+ }
491+
492+ x_phdrs_size = (bfd_get_arch_size (templ) == 64 ? sizeof (Elf64_External_Phdr)
493+ : sizeof (Elf32_External_Phdr));
494+
495+ i_phdrs = xmalloc (i_ehdr.e_phnum * (sizeof *i_phdrs + x_phdrs_size));
496+ x_phdrs_ptr = (void *) &i_phdrs[i_ehdr.e_phnum];
497+ err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs_ptr,
498+ i_ehdr.e_phnum * x_phdrs_size);
499+ if (err)
500+ {
501+ free (i_phdrs);
502+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
503+ warning (_("build-id: Error reading "
504+ "ELF program headers at address 0x%lx"),
505+ (unsigned long) (ehdr_vma + i_ehdr.e_phoff));
506+ return NULL;
507+ }
508+
509+ loadbase = ehdr_vma;
510+ loadbase_set = 0;
511+ for (i = 0; i < i_ehdr.e_phnum; ++i)
512+ {
513+ elf_swap_phdr_in (templ, (Elf64_External_Phdr *)
514+ (x_phdrs_ptr + i * x_phdrs_size), &i_phdrs[i]);
515+ /* IA-64 vDSO may have two mappings for one segment, where one mapping
516+ is executable only, and one is read only. We must not use the
517+ executable one (PF_R is the first one, PF_X the second one). */
518+ if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R))
519+ {
520+ /* Only the first PT_LOAD segment indicates the file bias.
521+ Next segments may have P_VADDR arbitrarily higher.
522+ If the first segment has P_VADDR zero any next segment must not
523+ confuse us, the first one sets LOADBASE certainly enough. */
524+ if (!loadbase_set && i_phdrs[i].p_offset == 0)
525+ {
526+ loadbase = ehdr_vma - i_phdrs[i].p_vaddr;
527+ loadbase_set = 1;
528+ }
529+ }
530+ }
531+
532+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE)
533+ warning (_("build-id: Found ELF header at address 0x%lx, loadbase 0x%lx"),
534+ (unsigned long) ehdr_vma, (unsigned long) loadbase);
535+
536+ *e_phnum_pointer = i_ehdr.e_phnum;
537+ *loadbase_pointer = loadbase;
538+ return i_phdrs;
539+}
540+
541+/* BUILD_ID_ADDR_GET gets ADDR located somewhere in the object.
542+ Find the first section before ADDR containing an ELF header.
543+ We rely on the fact the sections from multiple files do not mix.
544+ FIXME: We should check ADDR is contained _inside_ the section with possibly
545+ missing content (P_FILESZ < P_MEMSZ). These omitted sections are currently
546+ hidden by _BFD_ELF_MAKE_SECTION_FROM_PHDR. */
547+
548+static CORE_ADDR build_id_addr;
549+struct build_id_addr_sect
550+ {
551+ struct build_id_addr_sect *next;
552+ asection *sect;
553+ };
554+static struct build_id_addr_sect *build_id_addr_sect;
555+
556+static void build_id_addr_candidate (bfd *abfd, asection *sect, void *obj)
557+{
558+ if (build_id_addr >= bfd_section_vma (abfd, sect))
559+ {
560+ struct build_id_addr_sect *candidate;
561+
562+ candidate = xmalloc (sizeof *candidate);
563+ candidate->next = build_id_addr_sect;
564+ build_id_addr_sect = candidate;
565+ candidate->sect = sect;
566+ }
567+}
568+
569+struct build_id *
570+build_id_addr_get (CORE_ADDR addr)
571+{
572+ struct build_id_addr_sect *candidate;
573+ struct build_id *retval = NULL;
574+ Elf_Internal_Phdr *i_phdr = NULL;
575+ bfd_vma loadbase = 0;
576+ unsigned e_phnum = 0;
577+
578+ if (core_bfd == NULL)
579+ return NULL;
580+
581+ build_id_addr = addr;
582+ gdb_assert (build_id_addr_sect == NULL);
583+ bfd_map_over_sections (core_bfd, build_id_addr_candidate, NULL);
584+
585+ /* Sections are sorted in the high-to-low VMAs order.
586+ Stop the search on the first ELF header we find.
587+ Do not continue the search even if it does not contain NT_GNU_BUILD_ID. */
588+
589+ for (candidate = build_id_addr_sect; candidate != NULL;
590+ candidate = candidate->next)
591+ {
592+ i_phdr = elf_get_phdr (core_bfd,
593+ bfd_section_vma (core_bfd, candidate->sect),
594+ &e_phnum, &loadbase);
595+ if (i_phdr != NULL)
596+ break;
597+ }
598+
599+ if (i_phdr != NULL)
600+ {
601+ retval = build_id_phdr_get (core_bfd, loadbase, e_phnum, i_phdr);
602+ xfree (i_phdr);
603+ }
604+
605+ while (build_id_addr_sect != NULL)
606+ {
607+ candidate = build_id_addr_sect;
608+ build_id_addr_sect = candidate->next;
609+ xfree (candidate);
610+ }
611+
612+ return retval;
613+}
614+
615 /* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value. */
616
617 static int
f412e1b4 618@@ -1115,7 +1511,7 @@ build_id_verify (const char *filename, s
3a58abaf
AM
619 if (abfd == NULL)
620 return 0;
621
622- found = build_id_bfd_get (abfd);
623+ found = build_id_bfd_shdr_get (abfd);
624
625 if (found == NULL)
626 warning (_("File \"%s\" has no build-id, file skipped"), filename);
f412e1b4 627@@ -1133,14 +1529,15 @@ build_id_verify (const char *filename, s
3a58abaf
AM
628 return retval;
629 }
630
631-static char *
632-build_id_to_debug_filename (struct build_id *build_id)
633+char *
634+build_id_to_filename (struct build_id *build_id, char **link_return,
635+ int add_debug_suffix)
636 {
ab050a48
BZ
637 char *link, *debugdir, *retval = NULL;
638+ char *link_all = NULL;
3a58abaf
AM
639
640 /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
ab050a48
BZ
641- link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
642- + 2 * build_id->size + (sizeof ".debug" - 1) + 1);
6ed6bacf 643+ link = xmalloc (strlen (debug_file_directory) + 2 * build_id->size + 50);
ab050a48
BZ
644
645 /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
646 cause "/.build-id/..." lookups. */
f412e1b4 647@@ -1151,6 +1548,8 @@ build_id_to_debug_filename (struct build
6ed6bacf
AM
648 char *s, *debugdir_end;
649 gdb_byte *data = build_id->data;
650 size_t size = build_id->size;
651+ unsigned seqno;
652+ struct stat statbuf_trash;
653
654 while (*debugdir == DIRNAME_SEPARATOR)
655 debugdir++;
f412e1b4 656@@ -1171,39 +1570,242 @@ build_id_to_debug_filename (struct build
ab050a48
BZ
657 *s++ = '/';
658 while (size-- > 0)
659 s += sprintf (s, "%02x", (unsigned) *data++);
660- strcpy (s, ".debug");
6ed6bacf
AM
661-
662- /* lrealpath() is expensive even for the usually non-existent files. */
663- if (access (link, F_OK) == 0)
664- retval = lrealpath (link);
ab050a48 665
6ed6bacf
AM
666- if (retval != NULL && !build_id_verify (retval, build_id))
667+ for (seqno = 0;; seqno++)
668 {
669- xfree (retval);
670- retval = NULL;
671+ char *s2;
672+
673+ if (seqno)
674+ {
675+ /* There can be multiple build-id symlinks pointing to real files
676+ with the same build-id (such as hard links). Some of the real
677+ files may not be installed. */
678+
679+ s2 = s + sprintf (s, ".%u", seqno);
680+ }
681+ else
682+ s2 = s;
683+
684+ if (add_debug_suffix)
685+ strcpy (s2, ".debug");
686+ else
687+ *s2 = 0;
688+
689+ /* `access' automatically dereferences LINK. */
690+ if (lstat (link, &statbuf_trash) != 0)
691+ {
692+ /* Stop increasing SEQNO. */
693+ break;
694+ }
695+
696+ retval = lrealpath (link);
697+
698+ if (retval != NULL && !build_id_verify (retval, build_id))
699+ {
700+ xfree (retval);
701+ retval = NULL;
702+ }
703+
704+ if (retval)
705+ break;
ab050a48 706 }
3a58abaf 707
ab050a48
BZ
708 if (retval != NULL)
709- break;
710+ {
711+ /* LINK_ALL is not used below in this non-NULL RETVAL case. */
712+ break;
713+ }
714+
715+ if (link_all == NULL)
716+ link_all = xstrdup (link);
717+ else
718+ {
719+ size_t len_orig = strlen (link_all);
720+
721+ link_all = xrealloc (link_all, len_orig + 1 + strlen (link) + 1);
722+
723+ /* Use whitespace instead of DIRNAME_SEPARATOR to be compatible with
724+ its possible use as an argument for installation command. */
725+ link_all[len_orig] = ' ';
726+
727+ strcpy (&link_all[len_orig + 1], link);
728+ }
3a58abaf 729
ab050a48 730 debugdir = debugdir_end;
3a58abaf 731 }
ab050a48 732 while (*debugdir != 0);
3a58abaf
AM
733
734+ if (link_return != NULL)
ab050a48
BZ
735+ {
736+ if (retval != NULL)
737+ {
738+ *link_return = link;
739+ link = NULL;
740+ }
741+ else
742+ {
743+ *link_return = link_all;
744+ link_all = NULL;
745+ }
746+ }
747+ xfree (link);
748+ xfree (link_all);
749+
750+ return retval;
751+}
3a58abaf 752+
3a58abaf
AM
753+/* This MISSING_FILEPAIR_HASH tracker is used only for the duplicite messages
754+ Try to install the hash file ...
755+ avoidance. */
756+
757+struct missing_filepair
758+ {
759+ char *binary;
760+ char *debug;
761+ char data[1];
762+ };
763+
764+static struct htab *missing_filepair_hash;
765+static struct obstack missing_filepair_obstack;
766+
767+static void *
768+missing_filepair_xcalloc (size_t nmemb, size_t nmemb_size)
769+{
770+ void *retval;
771+ size_t size = nmemb * nmemb_size;
772+
773+ retval = obstack_alloc (&missing_filepair_obstack, size);
774+ memset (retval, 0, size);
ab050a48
BZ
775 return retval;
776 }
777
3a58abaf
AM
778+static hashval_t
779+missing_filepair_hash_func (const struct missing_filepair *elem)
780+{
781+ hashval_t retval = 0;
782+
783+ retval ^= htab_hash_string (elem->binary);
784+ if (elem->debug != NULL)
785+ retval ^= htab_hash_string (elem->debug);
786+
787+ return retval;
788+}
789+
790+static int
791+missing_filepair_eq (const struct missing_filepair *elem1,
792+ const struct missing_filepair *elem2)
793+{
794+ return strcmp (elem1->binary, elem2->binary) == 0
7566401a
ER
795+ && ((elem1->debug == NULL) == (elem2->debug == NULL))
796+ && (elem1->debug == NULL || strcmp (elem1->debug, elem2->debug) == 0);
3a58abaf
AM
797+}
798+
799+static void
800+missing_filepair_change (void)
801+{
802+ if (missing_filepair_hash != NULL)
803+ {
804+ obstack_free (&missing_filepair_obstack, NULL);
805+ /* All their memory came just from missing_filepair_OBSTACK. */
806+ missing_filepair_hash = NULL;
807+ }
808+}
809+
810+static void
811+debug_print_executable_changed (void)
812+{
813+ missing_filepair_change ();
814+}
815+
816+/* Notify user the file BINARY with (possibly NULL) associated separate debug
817+ information file DEBUG is missing. DEBUG may or may not be the build-id
818+ file such as would be:
819+ /usr/lib/debug/.build-id/dd/b1d2ce632721c47bb9e8679f369e2295ce71be.debug
820+ */
821+
822+void
823+debug_print_missing (const char *binary, const char *debug)
824+{
825+ size_t binary_len0 = strlen (binary) + 1;
826+ size_t debug_len0 = debug ? strlen (debug) + 1 : 0;
7566401a 827+ struct missing_filepair missing_filepair_find;
3a58abaf
AM
828+ struct missing_filepair *missing_filepair;
829+ struct missing_filepair **slot;
830+
831+ if (build_id_verbose < BUILD_ID_VERBOSE_FILENAMES)
832+ return;
833+
834+ if (missing_filepair_hash == NULL)
835+ {
836+ obstack_init (&missing_filepair_obstack);
837+ missing_filepair_hash = htab_create_alloc (64,
838+ (hashval_t (*) (const void *)) missing_filepair_hash_func,
839+ (int (*) (const void *, const void *)) missing_filepair_eq, NULL,
840+ missing_filepair_xcalloc, NULL);
841+ }
842+
7566401a
ER
843+ /* Use MISSING_FILEPAIR_FIND first instead of calling obstack_alloc with
844+ obstack_free in the case of a (rare) match. The problem is ALLOC_F for
845+ MISSING_FILEPAIR_HASH allocates from MISSING_FILEPAIR_OBSTACK maintenance
846+ structures for MISSING_FILEPAIR_HASH. Calling obstack_free would possibly
847+ not to free only MISSING_FILEPAIR but also some such structures (allocated
848+ during the htab_find_slot call). */
849+
850+ missing_filepair_find.binary = (char *) binary;
851+ missing_filepair_find.debug = (char *) debug;
852+ slot = (struct missing_filepair **) htab_find_slot (missing_filepair_hash,
853+ &missing_filepair_find,
854+ INSERT);
855+
856+ /* While it may be still printed duplicitely with the missing debuginfo file
857+ * it is due to once printing about the binary file build-id link and once
858+ * about the .debug file build-id link as both the build-id symlinks are
859+ * located in the debuginfo package. */
860+
861+ if (*slot != NULL)
862+ return;
863+
3a58abaf
AM
864+ missing_filepair = obstack_alloc (&missing_filepair_obstack,
865+ sizeof (*missing_filepair) - 1
866+ + binary_len0 + debug_len0);
867+ missing_filepair->binary = missing_filepair->data;
868+ memcpy (missing_filepair->binary, binary, binary_len0);
869+ if (debug != NULL)
870+ {
871+ missing_filepair->debug = missing_filepair->binary + binary_len0;
872+ memcpy (missing_filepair->debug, debug, debug_len0);
873+ }
874+ else
875+ missing_filepair->debug = NULL;
876+
3a58abaf
AM
877+ *slot = missing_filepair;
878+
879+ /* We do not collect and flush these messages as each such message
880+ already requires its own separate lines. */
881+
882+ fprintf_unfiltered (gdb_stdlog,
883+ _("Missing separate debuginfo for %s\n"), binary);
884+ if (debug != NULL)
885+ fprintf_unfiltered (gdb_stdlog, _("Try to install the hash file %s\n"),
886+ debug);
887+}
888+
889 static char *
51a5ef0f
PS
890-find_separate_debug_file_by_buildid (struct objfile *objfile)
891+find_separate_debug_file_by_buildid (struct objfile *objfile,
892+ char **build_id_filename_return)
3a58abaf 893 {
3a58abaf 894 struct build_id *build_id;
3a58abaf
AM
895
896- build_id = build_id_bfd_get (objfile->obfd);
51a5ef0f
PS
897+ if (build_id_filename_return)
898+ *build_id_filename_return = NULL;
899+
3a58abaf
AM
900+ build_id = build_id_bfd_shdr_get (objfile->obfd);
901 if (build_id != NULL)
902 {
903 char *build_id_name;
904
905- build_id_name = build_id_to_debug_filename (build_id);
51a5ef0f
PS
906+ build_id_name = build_id_to_filename (build_id, build_id_filename_return,
907+ 1);
3a58abaf
AM
908 xfree (build_id);
909 /* Prevent looping on a stripped .debug file. */
6ed6bacf 910 if (build_id_name != NULL
f412e1b4 911@@ -1214,7 +1816,7 @@ find_separate_debug_file_by_buildid (str
3a58abaf
AM
912 xfree (build_id_name);
913 }
914 else if (build_id_name != NULL)
915- return build_id_name;
51a5ef0f
PS
916+ return build_id_name;
917 }
918 return NULL;
919 }
f412e1b4 920@@ -1434,9 +2036,10 @@ elf_symfile_read (struct objfile *objfil
6ed6bacf
AM
921 `.note.gnu.build-id'. */
922 else if (!objfile_has_partial_symbols (objfile))
51a5ef0f
PS
923 {
924- char *debugfile;
925+ char *debugfile, *build_id_filename;
926
927- debugfile = find_separate_debug_file_by_buildid (objfile);
928+ debugfile = find_separate_debug_file_by_buildid (objfile,
929+ &build_id_filename);
930
931 if (debugfile == NULL)
932 debugfile = find_separate_debug_file_by_debuglink (objfile);
f412e1b4 933@@ -1448,6 +2051,12 @@ elf_symfile_read (struct objfile *objfil
51a5ef0f
PS
934 symbol_file_add_separate (abfd, symfile_flags, objfile);
935 xfree (debugfile);
936 }
937+ /* Check if any separate debug info has been extracted out. */
938+ else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink")
939+ != NULL)
940+ debug_print_missing (objfile->name, build_id_filename);
941+
942+ xfree (build_id_filename);
3a58abaf 943 }
51a5ef0f 944 }
3a58abaf 945
f412e1b4 946@@ -1931,4 +2540,16 @@ _initialize_elfread (void)
6ed6bacf
AM
947
948 elf_objfile_gnu_ifunc_cache_data = register_objfile_data ();
949 gnu_ifunc_fns_p = &elf_gnu_ifunc_fns;
51a5ef0f
PS
950+
951+ add_setshow_zinteger_cmd ("build-id-verbose", no_class, &build_id_verbose,
952+ _("\
953+Set debugging level of the build-id locator."), _("\
954+Show debugging level of the build-id locator."), _("\
955+Level 1 (default) enables printing the missing debug filenames,\n\
956+level 2 also prints the parsing of binaries to find the identificators."),
957+ NULL,
958+ show_build_id_verbose,
959+ &setlist, &showlist);
960+
961+ observer_attach_executable_changed (debug_print_executable_changed);
3a58abaf 962 }
f412e1b4 963Index: gdb-7.4.50.20120120/gdb/symfile.h
3a58abaf 964===================================================================
f412e1b4
PS
965--- gdb-7.4.50.20120120.orig/gdb/symfile.h 2012-01-21 00:02:33.000000000 +0100
966+++ gdb-7.4.50.20120120/gdb/symfile.h 2012-01-21 00:02:41.621463599 +0100
967@@ -614,6 +614,13 @@ void free_symfile_segment_data (struct s
51a5ef0f
PS
968
969 extern struct cleanup *increment_reading_symtab (void);
3a58abaf
AM
970
971+/* build-id support. */
972+struct build_id;
973+extern struct build_id *build_id_addr_get (CORE_ADDR addr);
974+extern char *build_id_to_filename (struct build_id *build_id,
975+ char **link_return, int add_debug_suffix);
976+extern void debug_print_missing (const char *binary, const char *debug);
977+
978 /* From dwarf2read.c */
979
f412e1b4
PS
980 /* Names for a dwarf2 debugging section. The field NORMAL is the normal
981Index: gdb-7.4.50.20120120/gdb/testsuite/lib/gdb.exp
3a58abaf 982===================================================================
f412e1b4
PS
983--- gdb-7.4.50.20120120.orig/gdb/testsuite/lib/gdb.exp 2012-01-21 00:02:36.000000000 +0100
984+++ gdb-7.4.50.20120120/gdb/testsuite/lib/gdb.exp 2012-01-21 00:02:41.622463596 +0100
985@@ -1385,6 +1385,16 @@ proc default_gdb_start { } {
3a58abaf
AM
986 warning "Couldn't set the width to 0."
987 }
988 }
989+ # Turn off the missing warnings as the testsuite does not expect it.
990+ send_gdb "set build-id-verbose 0\n"
991+ gdb_expect 10 {
992+ -re "$gdb_prompt $" {
993+ verbose "Disabled the missing debug infos warnings." 2
994+ }
995+ timeout {
996+ warning "Could not disable the missing debug infos warnings.."
997+ }
998+ }
999 return 0;
1000 }
1001
f412e1b4 1002Index: gdb-7.4.50.20120120/gdb/testsuite/lib/mi-support.exp
7566401a 1003===================================================================
f412e1b4
PS
1004--- gdb-7.4.50.20120120.orig/gdb/testsuite/lib/mi-support.exp 2012-01-12 23:28:34.000000000 +0100
1005+++ gdb-7.4.50.20120120/gdb/testsuite/lib/mi-support.exp 2012-01-21 00:02:41.622463596 +0100
1006@@ -212,6 +212,16 @@ proc default_mi_gdb_start { args } {
1007 warning "Couldn't set the width to 0."
1008 }
d566d21e 1009 }
1010+ # Turn off the missing warnings as the testsuite does not expect it.
1011+ send_gdb "190-gdb-set build-id-verbose 0\n"
1012+ gdb_expect 10 {
1013+ -re ".*190-gdb-set build-id-verbose 0\r\n190\\\^done\r\n$mi_gdb_prompt$" {
1014+ verbose "Disabled the missing debug infos warnings." 2
1015+ }
1016+ timeout {
1017+ warning "Could not disable the missing debug infos warnings.."
1018+ }
1019+ }
f412e1b4
PS
1020 # If allowing the inferior to have its own PTY then assign the inferior
1021 # its own terminal device here.
1022 if { $separate_inferior_pty } {
1023Index: gdb-7.4.50.20120120/gdb/objfiles.h
7566401a 1024===================================================================
f412e1b4
PS
1025--- gdb-7.4.50.20120120.orig/gdb/objfiles.h 2012-01-04 09:17:09.000000000 +0100
1026+++ gdb-7.4.50.20120120/gdb/objfiles.h 2012-01-21 00:02:41.623463593 +0100
1027@@ -433,6 +433,10 @@ struct objfile
7566401a 1028
f412e1b4 1029 #define OBJF_MAINLINE (1 << 5)
7566401a
ER
1030
1031+/* This file was loaded according to the BUILD_ID_CORE_LOADS rules. */
1032+
1033+#define OBJF_BUILD_ID_CORE_LOADED (1 << 12)
1034+
51a5ef0f 1035 /* The object file that contains the runtime common minimal symbols
6ed6bacf 1036 for SunOS4. Note that this objfile has no associated BFD. */
7566401a 1037
This page took 0.231636 seconds and 4 git commands to generate.