diff options
author | Nick Clifton <nickc@redhat.com> | 2015-05-15 11:21:38 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-05-15 11:24:33 +0100 |
commit | d1c4b12b9d48d9266b78e2c22d70aa25830b9f8f (patch) | |
tree | 3f096548d3838f9387b3b8b7175a6a231f335c76 /binutils | |
parent | 4bc0608a8b693f033555aa5705fdd5fc44cb9a9a (diff) | |
download | gdb-d1c4b12b9d48d9266b78e2c22d70aa25830b9f8f.zip gdb-d1c4b12b9d48d9266b78e2c22d70aa25830b9f8f.tar.gz gdb-d1c4b12b9d48d9266b78e2c22d70aa25830b9f8f.tar.bz2 |
Fix PR18374 by making readelf and objdump ignore end-of-list markers in the .debug_loc section if there are relocations against them.
PR binutils/18374
bin * dwarf.h (struct dwarf_section): Add reloc_info and num_relocs
fields.
(struct dwarf_section_display): Change bitfield to boolean.
(reloc_at): Add prototype.
* dwarf.c (display_loc_list): Ignore list terminators if there are
relocs against them.
(display_debug_loc): Issue a warning if there are relocs against
the .debug_loc section.
(display_displays): Initialise reloc_info and num_relocs fields.
* objdump.c (load_specific_debug_section): Initialise reloc_info
and num_relocs fields.
(reloc_at): New function.
* readelf.c (is_32bit_abs_reloc): Add IA64's R_IA64_DIS32LSB
reloc.
(reloc_at): New function.
(apply_relocations): Add relocs_return and num_relocs_return
parameters. Fill them in with the loaded relocs if non-NULL.
(dump_section_as_bytes): Update call to apply_relocations.
(load_specific_debug_section): Initialise reloc_info and
num_relocs fields.
tests * binutils-all/pr18374.s: New test file.
* binutils-all/readelf.exp: Assemble and run the new test.
* binutils-all/readelf.pr18374: Expected output from readelf.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 24 | ||||
-rw-r--r-- | binutils/dwarf.c | 168 | ||||
-rw-r--r-- | binutils/dwarf.h | 12 | ||||
-rw-r--r-- | binutils/objdump.c | 42 | ||||
-rw-r--r-- | binutils/readelf.c | 61 | ||||
-rw-r--r-- | binutils/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/pr18374.s | 234 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/readelf.exp | 16 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/readelf.pr18374 | 14 |
9 files changed, 492 insertions, 86 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 84beb7e..5d017a1 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -8,6 +8,30 @@ uncompressed size. Don't check the zlib header. (load_specific_debug_section): Updated. +2015-05-15 Nick Clifton <nickc@redhat.com> + + PR binutils/18374 + * dwarf.h (struct dwarf_section): Add reloc_info and num_relocs + fields. + (struct dwarf_section_display): Change bitfield to boolean. + (reloc_at): Add prototype. + * dwarf.c (display_loc_list): Ignore list terminators if there are + relocs against them. + (display_debug_loc): Issue a warning if there are relocs against + the .debug_loc section. + (display_displays): Initialise reloc_info and num_relocs fields. + * objdump.c (load_specific_debug_section): Initialise reloc_info + and num_relocs fields. + (reloc_at): New function. + * readelf.c (is_32bit_abs_reloc): Add IA64's R_IA64_DIS32LSB + reloc. + (reloc_at): New function. + (apply_relocations): Add relocs_return and num_relocs_return + parameters. Fill them in with the loaded relocs if non-NULL. + (dump_section_as_bytes): Update call to apply_relocations. + (load_specific_debug_section): Initialise reloc_info and + num_relocs fields. + 2015-05-13 H.J. Lu <hongjiu.lu@intel.com> * elfedit.c (elf_class): Return ELF_CLASS_BOTH by default. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 96d959a..71b0e97 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -4367,6 +4367,8 @@ display_loc_list (struct dwarf_section *section, while (1) { + unsigned long off = offset + (start - *start_ptr); + if (start + 2 * pointer_size > section_end) { warn (_("Location list starting at offset 0x%lx is not terminated.\n"), @@ -4374,7 +4376,7 @@ display_loc_list (struct dwarf_section *section, break; } - printf (" %8.8lx ", offset + (start - *start_ptr)); + printf (" %8.8lx ", off); /* Note: we use sign extension here in order to be sure that we can detect the -1 escape value. Sign extension into the top 32 bits of a 32-bit @@ -4385,8 +4387,18 @@ display_loc_list (struct dwarf_section *section, if (begin == 0 && end == 0) { - printf (_("<End of list>\n")); - break; + /* PR 18374: In a object file we can have a location list that + starts with a begin and end of 0 because there are relocations + that need to be applied to the addresses. Actually applying + the relocations now does not help as they will probably resolve + to 0, since the object file has not been fully linked. Real + end of list markers will not have any relocations against them. */ + if (! reloc_at (section, off) + && ! reloc_at (section, off + pointer_size)) + { + printf (_("<End of list>\n")); + break; + } } /* Check base address specifiers. */ @@ -4607,7 +4619,6 @@ display_debug_loc (struct dwarf_section *section, void *file) unsigned int first = 0; unsigned int i; unsigned int j; - unsigned int k; int seen_first_offset = 0; int locs_sorted = 1; unsigned char *next; @@ -4683,13 +4694,16 @@ display_debug_loc (struct dwarf_section *section, void *file) if (!locs_sorted) array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int)); printf (_("Contents of the %s section:\n\n"), section->name); - printf (_(" Offset Begin End Expression\n")); + if (reloc_at (section, 0)) + printf (_(" Warning: This section has relocations - addresses seen here may not be accurate.\n\n")); + printf (_(" Offset Begin End Expression\n")); seen_first_offset = 0; for (i = first; i < num_debug_info_entries; i++) { unsigned long offset; unsigned long base_address; + unsigned int k; int has_frame_base; if (!locs_sorted) @@ -7561,76 +7575,76 @@ dwarf_select_sections_all (void) struct dwarf_section_display debug_displays[] = { - { { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0, 0, NULL }, - display_debug_abbrev, &do_debug_abbrevs, 0 }, - { { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0, 0, NULL }, - display_debug_aranges, &do_debug_aranges, 1 }, - { { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0, 0, NULL }, - display_debug_frames, &do_debug_frames, 1 }, - { { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0, abbrev, NULL }, - display_debug_info, &do_debug_info, 1 }, - { { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0, 0, NULL }, - display_debug_lines, &do_debug_lines, 1 }, - { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0, 0, NULL }, - display_debug_pubnames, &do_debug_pubnames, 0 }, - { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0, NULL }, - display_debug_gnu_pubnames, &do_debug_pubnames, 0 }, - { { ".eh_frame", "", NULL, NULL, 0, 0, 0, NULL }, - display_debug_frames, &do_debug_frames, 1 }, - { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_macinfo, &do_debug_macinfo, 0 }, - { { ".debug_macro", ".zdebug_macro", NULL, NULL, 0, 0, 0, NULL }, - display_debug_macro, &do_debug_macinfo, 1 }, - { { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0, 0, NULL }, - display_debug_str, &do_debug_str, 0 }, - { { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0, 0, NULL }, - display_debug_loc, &do_debug_loc, 1 }, - { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0, 0, NULL }, - display_debug_pubnames, &do_debug_pubtypes, 0 }, - { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0, NULL }, - display_debug_gnu_pubnames, &do_debug_pubtypes, 0 }, - { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0, 0, NULL }, - display_debug_ranges, &do_debug_ranges, 1 }, - { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0, NULL }, - display_debug_not_supported, NULL, 0 }, - { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0, NULL }, - display_debug_not_supported, NULL, 0 }, - { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0, abbrev, NULL }, - display_debug_types, &do_debug_info, 1 }, - { { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0, 0, NULL }, - display_debug_not_supported, NULL, 0 }, - { { ".gdb_index", "", NULL, NULL, 0, 0, 0, NULL }, - display_gdb_index, &do_gdb_index, 0 }, - { { ".trace_info", "", NULL, NULL, 0, 0, trace_abbrev, NULL }, - display_trace_info, &do_trace_info, 1 }, - { { ".trace_abbrev", "", NULL, NULL, 0, 0, 0, NULL }, - display_debug_abbrev, &do_trace_abbrevs, 0 }, - { { ".trace_aranges", "", NULL, NULL, 0, 0, 0, NULL }, - display_debug_aranges, &do_trace_aranges, 0 }, - { { ".debug_info.dwo", ".zdebug_info.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL }, - display_debug_info, &do_debug_info, 1 }, - { { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_abbrev, &do_debug_abbrevs, 0 }, - { { ".debug_types.dwo", ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL }, - display_debug_types, &do_debug_info, 1 }, - { { ".debug_line.dwo", ".zdebug_line.dwo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_lines, &do_debug_lines, 1 }, - { { ".debug_loc.dwo", ".zdebug_loc.dwo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_loc, &do_debug_loc, 1 }, - { { ".debug_macro.dwo", ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_macro, &do_debug_macinfo, 1 }, - { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_macinfo, &do_debug_macinfo, 0 }, - { { ".debug_str.dwo", ".zdebug_str.dwo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_str, &do_debug_str, 1 }, - { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0, NULL }, - display_debug_str_offsets, NULL, 0 }, - { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0, NULL }, - display_debug_str_offsets, NULL, 0 }, - { { ".debug_addr", ".zdebug_addr", NULL, NULL, 0, 0, 0, NULL }, - display_debug_addr, &do_debug_addr, 1 }, - { { ".debug_cu_index", "", NULL, NULL, 0, 0, 0, NULL }, - display_cu_index, &do_debug_cu_index, 0 }, - { { ".debug_tu_index", "", NULL, NULL, 0, 0, 0, NULL }, - display_cu_index, &do_debug_cu_index, 0 }, + { { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_abbrev, &do_debug_abbrevs, FALSE }, + { { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_aranges, &do_debug_aranges, TRUE }, + { { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_frames, &do_debug_frames, TRUE }, + { { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0, abbrev, NULL, 0, NULL }, + display_debug_info, &do_debug_info, TRUE }, + { { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_lines, &do_debug_lines, TRUE }, + { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_pubnames, &do_debug_pubnames, FALSE }, + { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_gnu_pubnames, &do_debug_pubnames, FALSE }, + { { ".eh_frame", "", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_frames, &do_debug_frames, TRUE }, + { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_macinfo, &do_debug_macinfo, FALSE }, + { { ".debug_macro", ".zdebug_macro", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_macro, &do_debug_macinfo, TRUE }, + { { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_str, &do_debug_str, FALSE }, + { { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_loc, &do_debug_loc, TRUE }, + { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_pubnames, &do_debug_pubtypes, FALSE }, + { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_gnu_pubnames, &do_debug_pubtypes, FALSE }, + { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_ranges, &do_debug_ranges, TRUE }, + { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_not_supported, NULL, FALSE }, + { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_not_supported, NULL, FALSE }, + { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0, abbrev, NULL, 0, NULL }, + display_debug_types, &do_debug_info, TRUE }, + { { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_not_supported, NULL, FALSE }, + { { ".gdb_index", "", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_gdb_index, &do_gdb_index, FALSE }, + { { ".trace_info", "", NULL, NULL, 0, 0, trace_abbrev, NULL, 0, NULL }, + display_trace_info, &do_trace_info, TRUE }, + { { ".trace_abbrev", "", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_abbrev, &do_trace_abbrevs, FALSE }, + { { ".trace_aranges", "", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_aranges, &do_trace_aranges, FALSE }, + { { ".debug_info.dwo", ".zdebug_info.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL, 0, NULL }, + display_debug_info, &do_debug_info, TRUE }, + { { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_abbrev, &do_debug_abbrevs, FALSE }, + { { ".debug_types.dwo", ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL, 0, NULL }, + display_debug_types, &do_debug_info, TRUE }, + { { ".debug_line.dwo", ".zdebug_line.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_lines, &do_debug_lines, TRUE }, + { { ".debug_loc.dwo", ".zdebug_loc.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_loc, &do_debug_loc, TRUE }, + { { ".debug_macro.dwo", ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_macro, &do_debug_macinfo, TRUE }, + { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_macinfo, &do_debug_macinfo, FALSE }, + { { ".debug_str.dwo", ".zdebug_str.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_str, &do_debug_str, TRUE }, + { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_str_offsets, NULL, FALSE }, + { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_str_offsets, NULL, FALSE }, + { { ".debug_addr", ".zdebug_addr", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_debug_addr, &do_debug_addr, TRUE }, + { { ".debug_cu_index", "", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_cu_index, &do_debug_cu_index, FALSE }, + { { ".debug_tu_index", "", NULL, NULL, 0, 0, 0, NULL, 0, NULL }, + display_cu_index, &do_debug_cu_index, FALSE }, }; diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 0e661d4..e679320 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -124,6 +124,11 @@ struct dwarf_section dwarf_vma address; dwarf_size_type size; enum dwarf_section_display_enum abbrev_sec; + + /* Used by clients to help them implement the reloc_at callback. */ + void * reloc_info; + unsigned long num_relocs; + /* A spare field for random use. */ void *user_data; }; @@ -135,7 +140,7 @@ struct dwarf_section_display struct dwarf_section section; int (*display) (struct dwarf_section *, void *); int *enabled; - unsigned int relocate : 1; + bfd_boolean relocate; }; extern struct dwarf_section_display debug_displays []; @@ -217,3 +222,8 @@ extern void * xcmalloc (size_t, size_t); extern void * xcrealloc (void *, size_t, size_t); extern dwarf_vma read_leb128 (unsigned char *, unsigned int *, bfd_boolean, const unsigned char * const); + +/* A callback into the client. Retuns TRUE if there is a + relocation against the given debug section at the given + offset. */ +extern bfd_boolean reloc_at (struct dwarf_section *, dwarf_vma); diff --git a/binutils/objdump.c b/binutils/objdump.c index f87c9c3..f51b6f5 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -2278,6 +2278,8 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, if (section->start != NULL) return 1; + section->reloc_info = NULL; + section->num_relocs = 0; section->address = bfd_get_section_vma (abfd, sec); section->size = bfd_get_section_size (sec); section->start = NULL; @@ -2308,11 +2310,49 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, section->name); return 0; } - } + + long reloc_size; + + reloc_size = bfd_get_reloc_upper_bound (abfd, sec); + if (reloc_size > 0) + { + unsigned long reloc_count; + arelent **relocs; + + relocs = (arelent **) xmalloc (reloc_size); + + reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, NULL); + if (reloc_count == 0) + free (relocs); + else + { + section->reloc_info = relocs; + section->num_relocs = reloc_count; + } + } + } return 1; } +bfd_boolean +reloc_at (struct dwarf_section * dsec, dwarf_vma offset) +{ + arelent ** relocs; + arelent * rp; + + if (dsec == NULL || dsec->reloc_info == NULL) + return FALSE; + + relocs = (arelent **) dsec->reloc_info; + + for (; (rp = * relocs) != NULL; ++ relocs) + if (rp->address == offset) + return TRUE; + + return FALSE; +} + int load_debug_section (enum dwarf_section_display_enum debug, void *file) { diff --git a/binutils/readelf.c b/binutils/readelf.c index e7090ff..e299e1b 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -11302,7 +11302,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) case EM_H8_300H: return reloc_type == 1; /* R_H8_DIR32. */ case EM_IA_64: - return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */ + return reloc_type == 0x65 /* R_IA64_SECREL32LSB. */ + || reloc_type == 0x25; /* R_IA64_DIR32LSB. */ case EM_IP2K_OLD: case EM_IP2K: return reloc_type == 2; /* R_IP2K_32. */ @@ -11696,19 +11697,51 @@ is_none_reloc (unsigned int reloc_type) return FALSE; } +/* Returns TRUE if there is a relocation against + section NAME at OFFSET bytes. */ + +bfd_boolean +reloc_at (struct dwarf_section * dsec, dwarf_vma offset) +{ + Elf_Internal_Rela * relocs; + Elf_Internal_Rela * rp; + + if (dsec == NULL || dsec->reloc_info == NULL) + return FALSE; + + relocs = (Elf_Internal_Rela *) dsec->reloc_info; + + for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp) + if (rp->r_offset == offset) + return TRUE; + + return FALSE; +} + /* Apply relocations to a section. Note: So far support has been added only for those relocations which can be found in debug sections. + If RELOCS_RETURN is non-NULL then returns in it a pointer to the + loaded relocs. It is then the caller's responsibility to free them. FIXME: Add support for more relocations ? */ static void -apply_relocations (void * file, - const Elf_Internal_Shdr * section, - unsigned char * start, bfd_size_type size) +apply_relocations (void * file, + const Elf_Internal_Shdr * section, + unsigned char * start, + bfd_size_type size, + void ** relocs_return, + unsigned long * num_relocs_return) { Elf_Internal_Shdr * relsec; unsigned char * end = start + size; + if (relocs_return != NULL) + { + * (Elf_Internal_Rela **) relocs_return = NULL; + * num_relocs_return = 0; + } + if (elf_header.e_type != ET_REL) return; @@ -11860,7 +11893,15 @@ apply_relocations (void * file, } free (symtab); - free (relocs); + + if (relocs_return) + { + * (Elf_Internal_Rela **) relocs_return = relocs; + * num_relocs_return = num_relocs; + } + else + free (relocs); + break; } } @@ -11999,7 +12040,7 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, if (relocate) { - apply_relocations (file, section, start, section->sh_size); + apply_relocations (file, section, start, section->sh_size, NULL, NULL); } else { @@ -12194,7 +12235,13 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, return 0; if (debug_displays [debug].relocate) - apply_relocations ((FILE *) file, sec, section->start, section->size); + apply_relocations ((FILE *) file, sec, section->start, section->size, + & section->reloc_info, & section->num_relocs); + else + { + section->reloc_info = NULL; + section->num_relocs = 0; + } return 1; } diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog index 8b1e3b4..ad8d8ad 100644 --- a/binutils/testsuite/ChangeLog +++ b/binutils/testsuite/ChangeLog @@ -4,6 +4,13 @@ with "$OBJDUMP -W". * binutils-all/libdw2-compressedgabi.out: Updated. +2015-05-15 Nick Clifton <nickc@redhat.com> + + PR binutils/18374 + * binutils-all/pr18374.s: New test file. + * binutils-all/readelf.exp: Assemble and run the new test. + * binutils-all/readelf.pr18374: Expected output from readelf. + 2015-05-12 H.J. Lu <hongjiu.lu@intel.com> * binutils-all/elfedit-1.d: Also skip x86_64-*-nacl*. diff --git a/binutils/testsuite/binutils-all/pr18374.s b/binutils/testsuite/binutils-all/pr18374.s new file mode 100644 index 0000000..793fb70 --- /dev/null +++ b/binutils/testsuite/binutils-all/pr18374.s @@ -0,0 +1,234 @@ + .section .debug_info,"",%progbits + .4byte 0x77 + .2byte 0x4 + .4byte .Ldebug_abbrev0 + .byte 0x4 + .uleb128 0x1 + .4byte .LASF3 + .byte 0xc + .ascii "x.c\000" + .4byte .LASF4 + .4byte .Ltext0 + .4byte .Letext0 + .4byte .Ldebug_line0 + .uleb128 0x2 + .ascii "foo\000" + .byte 0x1 + .byte 0x2 + .4byte .LFB0 + .4byte .LFE0 + .uleb128 0x1 + .byte 0x9c + .4byte 0x64 + .uleb128 0x3 + .ascii "b\000" + .byte 0x1 + .byte 0x2 + .4byte 0x64 + .4byte .LLST0 + .uleb128 0x4 + .4byte .LASF0 + .byte 0x1 + .byte 0x2 + .4byte 0x66 + .4byte .LLST1 + .uleb128 0x5 + .ascii "ptr\000" + .byte 0x1 + .byte 0x4 + .4byte 0x6d + .uleb128 0x1 + .byte 0x50 + .byte 0 + .uleb128 0x6 + .byte 0x4 + .uleb128 0x7 + .byte 0x4 + .byte 0x7 + .4byte .LASF1 + .uleb128 0x8 + .byte 0x4 + .4byte 0x73 + .uleb128 0x7 + .byte 0x1 + .byte 0x8 + .4byte .LASF2 + .byte 0 + + .section .debug_abbrev,"",%progbits +.Ldebug_abbrev0: + .uleb128 0x1 + .uleb128 0x11 + .byte 0x1 + .uleb128 0x25 + .uleb128 0xe + .uleb128 0x13 + .uleb128 0xb + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x1b + .uleb128 0xe + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x6 + .uleb128 0x10 + .uleb128 0x17 + .byte 0 + .byte 0 + .uleb128 0x2 + .uleb128 0x2e + .byte 0x1 + .uleb128 0x3f + .uleb128 0x19 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x27 + .uleb128 0x19 + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x6 + .uleb128 0x40 + .uleb128 0x18 + .uleb128 0x2117 + .uleb128 0x19 + .uleb128 0x1 + .uleb128 0x13 + .byte 0 + .byte 0 + .uleb128 0x3 + .uleb128 0x5 + .byte 0 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0x17 + .byte 0 + .byte 0 + .uleb128 0x4 + .uleb128 0x5 + .byte 0 + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0x17 + .byte 0 + .byte 0 + .uleb128 0x5 + .uleb128 0x34 + .byte 0 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0x18 + .byte 0 + .byte 0 + .uleb128 0x6 + .uleb128 0xf + .byte 0 + .uleb128 0xb + .uleb128 0xb + .byte 0 + .byte 0 + .uleb128 0x7 + .uleb128 0x24 + .byte 0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .byte 0 + .byte 0 + .uleb128 0x8 + .uleb128 0xf + .byte 0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .byte 0 + .byte 0 + .byte 0 + + .section .debug_loc,"",%progbits +.Ldebug_loc0: +.LLST0: + .4byte .LVL0 + .4byte .LVL2 + .2byte 0x1 + .byte 0x50 + .4byte .LVL2 + .4byte .LFE0 + .2byte 0x4 + .byte 0xf3 + .uleb128 0x1 + .byte 0x50 + .byte 0x9f + .4byte 0 + .4byte 0 +.LLST1: + .4byte .LVL0 + .4byte .LVL1 + .2byte 0x1 + .byte 0x51 + .4byte .LVL1 + .4byte .LVL2 + .2byte 0x3 + .byte 0x71 + .sleb128 -1 + .byte 0x9f + .4byte .LVL2 + .4byte .LVL3 + .2byte 0xb + .byte 0x70 + .sleb128 0 + .byte 0x20 + .byte 0xf3 + .uleb128 0x1 + .byte 0x51 + .byte 0x22 + .byte 0x70 + .sleb128 0 + .byte 0x22 + .byte 0x9f + .4byte .LVL3 + .4byte .LFE0 + .2byte 0xb + .byte 0x70 + .sleb128 0 + .byte 0x20 + .byte 0x70 + .sleb128 0 + .byte 0x22 + .byte 0xf3 + .uleb128 0x1 + .byte 0x51 + .byte 0x22 + .byte 0x9f + .4byte 0 + .4byte 0 diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp index 3c6472b..58e140c 100644 --- a/binutils/testsuite/binutils-all/readelf.exp +++ b/binutils/testsuite/binutils-all/readelf.exp @@ -356,3 +356,19 @@ if ![is_remote host] { } readelf_test -n $tempfile readelf.n {} + +# PR 18374 - Check that relocations against the .debug_loc section +# do not prevent readelf from displaying all the location lists. +if {![binutils_assemble $srcdir/$subdir/pr18374.s tmpdir/pr18374.o]} then { + perror "could not assemble PR18374 test file" + unresolved "readelf - failed to assemble" + return +} + +if ![is_remote host] { + set tempfile tmpdir/pr18374.o +} else { + set tempfile [remote_download host tmpdir/pr18374.o] +} + +readelf_test --debug-dump=loc $tempfile readelf.pr18374 {} diff --git a/binutils/testsuite/binutils-all/readelf.pr18374 b/binutils/testsuite/binutils-all/readelf.pr18374 new file mode 100644 index 0000000..5be90f1 --- /dev/null +++ b/binutils/testsuite/binutils-all/readelf.pr18374 @@ -0,0 +1,14 @@ +Contents of the .*ebug_loc section: + + Warning: This section has relocations - addresses seen here may not be accurate. + + Offset Begin End Expression + 0+0 0+0 0+0 .* + 0000000b 0+0 0+0 .* + 00000019 <End of list> + 00000021 0+0 0+0 .* + 0000002c 0+0 0+0 .* + 00000039 0+0 0+0 .* + 0000004e 0+0 0+0 .* + 00000063 <End of list> +#pass |