This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 },

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]