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.
This commit is contained in:
parent
4bc0608a8b
commit
d1c4b12b9d
@ -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.
|
||||
|
168
binutils/dwarf.c
168
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 },
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*.
|
||||
|
234
binutils/testsuite/binutils-all/pr18374.s
Normal file
234
binutils/testsuite/binutils-all/pr18374.s
Normal file
@ -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
|
@ -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 {}
|
||||
|
14
binutils/testsuite/binutils-all/readelf.pr18374
Normal file
14
binutils/testsuite/binutils-all/readelf.pr18374
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user