This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Committed: Add target specific reloc processing to readelf
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Mon, 22 Jun 2009 09:45:44 +0100
- Subject: Committed: Add target specific reloc processing to readelf
Hi Guys,
I am applying the patch below to add support for target specific
reloc processing to readelf. This is to support the display of
DWARF2 location lists for the MN10300 port, although I expect that
the functionality may well be extended in the future to other
ports.
The MN10300 port generates a special R_MN10300_SYM_DIFF reloc for
parts of the .debug_loc section. This inserts the difference between
the values of two symbols and it has to be done this way because
linker relaxation may change the address of either of them.
Tested with an mn10300-elf toolchain and no regressions.
Cheers
Nick
binutils/ChangeLog
2009-06-22 Nick Clifton <nickc@redhat.com>
* readelf.c (target_specific_reloc_handling): New function:
Processes relocs in a target specific manner.
(debug_apply_relocations): Use the new function.
* dwarf.c (display_debug_loc): End the dump with a blank line.
(struct debug_display): Enable reloc processing for .debug_aranges
and .debug_loc sections.
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.447
diff -c -3 -p -r1.447 readelf.c
*** binutils/readelf.c 12 Jun 2009 13:54:44 -0000 1.447
--- binutils/readelf.c 22 Jun 2009 08:26:39 -0000
*************** uncompress_section_contents (unsigned ch
*** 8337,8342 ****
--- 8338,8391 ----
#endif /* HAVE_ZLIB_H */
}
+ /* Check to see if the given reloc needs to be handled in a target specific
+ manner. If so then process the reloc and return TRUE otherwise return
+ FALSE. */
+
+ static bfd_boolean
+ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+ unsigned char * start,
+ Elf_Internal_Sym * symtab)
+ {
+ unsigned int reloc_type = get_reloc_type (reloc->r_info);
+
+ switch (elf_header.e_machine)
+ {
+ case EM_MN10300:
+ case EM_CYGNUS_MN10300:
+ {
+ static Elf_Internal_Sym * saved_sym = NULL;
+
+ switch (reloc_type)
+ {
+ case 34: /* R_MN10300_ALIGN */
+ return TRUE;
+ case 33: /* R_MN10300_SYM_DIFF */
+ saved_sym = symtab + get_reloc_symindex (reloc->r_info);
+ return TRUE;
+ case 1: /* R_MN10300_32 */
+ if (saved_sym != NULL)
+ {
+ bfd_vma value;
+
+ value = reloc->r_addend
+ + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+ - saved_sym->st_value);
+
+ byte_put (start + reloc->r_offset, value, 4);
+
+ saved_sym = NULL;
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+ return FALSE;
+ }
+
/* Apply relocations to a debug section. */
static void
*************** debug_apply_relocations (void * file,
*** 8401,8411 ****
reloc_type = get_reloc_type (rp->r_info);
! if (is_none_reloc (reloc_type))
continue;
!
! if (is_32bit_abs_reloc (reloc_type)
! || is_32bit_pcrel_reloc (reloc_type))
reloc_size = 4;
else if (is_64bit_abs_reloc (reloc_type)
|| is_64bit_pcrel_reloc (reloc_type))
--- 8450,8461 ----
reloc_type = get_reloc_type (rp->r_info);
! if (target_specific_reloc_handling (rp, start, symtab))
continue;
! else if (is_none_reloc (reloc_type))
! continue;
! else if (is_32bit_abs_reloc (reloc_type)
! || is_32bit_pcrel_reloc (reloc_type))
reloc_size = 4;
else if (is_64bit_abs_reloc (reloc_type)
|| is_64bit_pcrel_reloc (reloc_type))
Index: binutils/dwarf.c
===================================================================
RCS file: /cvs/src/src/binutils/dwarf.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 dwarf.c
*** binutils/dwarf.c 24 Apr 2009 18:28:59 -0000 1.45
--- binutils/dwarf.c 22 Jun 2009 08:26:40 -0000
*************** display_debug_loc (struct dwarf_section
*** 3254,3259 ****
--- 3254,3260 ----
if (start < section_end)
warn (_("There are %ld unused bytes at the end of section %s\n"),
(long) (section_end - start), section->name);
+ putchar ('\n');
return 1;
}
*************** struct dwarf_section_display debug_displ
*** 4865,4871 ****
{ { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0 },
display_debug_abbrev, &do_debug_abbrevs, 0, 0 },
{ { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0 },
! display_debug_aranges, &do_debug_aranges, 0, 0 },
{ { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0 },
display_debug_frames, &do_debug_frames, 1, 0 },
{ { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0 },
--- 4866,4872 ----
{ { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0 },
display_debug_abbrev, &do_debug_abbrevs, 0, 0 },
{ { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0 },
! display_debug_aranges, &do_debug_aranges, 1, 0 },
{ { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0 },
display_debug_frames, &do_debug_frames, 1, 0 },
{ { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0 },
*************** struct dwarf_section_display debug_displ
*** 4881,4887 ****
{ { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0 },
display_debug_str, &do_debug_str, 0, 0 },
{ { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0 },
! display_debug_loc, &do_debug_loc, 0, 0 },
{ { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0 },
display_debug_pubnames, &do_debug_pubnames, 0, 0 },
{ { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0 },
--- 4882,4888 ----
{ { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0 },
display_debug_str, &do_debug_str, 0, 0 },
{ { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0 },
! display_debug_loc, &do_debug_loc, 1, 0 },
{ { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0 },
display_debug_pubnames, &do_debug_pubnames, 0, 0 },
{ { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0 },