This is the mail archive of the binutils@sources.redhat.com 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]

[PATCH/RFA]: readelf extnsion to dump mips GOT


Hi, 

The existing version of readelf doesn't support MIPS GOT dump.
The attached patch is against 2002-09-05. It adds --mips-got for a
MIPS GOT dump to readelf, just  like  'elfdump -Dg' on IRIX.

This function is usable for debugging dynamic link and reading 
disassemble codes.

In this patch, SUPPORT_MIPSGOT is used to distinguish MIPS GOT
support codes. If you don't prefer to use SUPPORT_MIPSGOT, remove
it.  

Regards.

[readelf]
	* readelf.c (SUPPORT_MIPSGOT): Define it to turn on MIPS GOT
	dump. (do_mips_got): New variable. (dump_mips_got): Likewise. 
	(options): Add an new entry for option "mips-got". (usage):
	Display an new option. (parse_args): Handle an new option.
	(mips_dyn_symtab_nr): New variable. (mips_local_gotno):
	Likewise. (mips_gotsym): Likewise. (dump_mips_got): New
	function. (process_mips_specific): Record
	MIPS_DYN_SYMTAB_NR, MIPS_LOCAL_GOTNO and MIPS_GOTSYM. 
	Call DUMP_MIPS_GOT, if needed.

---
Hiroyuki Machida
Sony Corp.
*** readelf.c.orig	Tue Sep 10 18:13:21 2002
--- readelf.c	Wed Sep 11 14:36:09 2002
***************
*** 43,48 ****
--- 43,50 ----
  #include "elf/internal.h"
  #include "elf/dwarf2.h"
  
+ #define  SUPPORT_MIPSGOT
+ 
  /* The following headers use the elf/reloc-macros.h file to
     automatically generate relocation recognition functions
     such as elf_mips_reloc_type()  */
*************** int                     do_debug_loc;
*** 137,142 ****
--- 139,147 ----
  int                     do_arch;
  int                     do_notes;
  int			is_32bit_elf;
+ #ifdef	SUPPORT_MIPSGOT
+ int			do_mips_got;
+ #endif
  
  /* A dynamic array of flags indicating which sections require dumping.  */
  char *			dump_sects = NULL;
*************** static int		  process_corefile_note_segm
*** 267,272 ****
--- 272,280 ----
  static int		  process_corefile_contents	 PARAMS ((FILE *));
  static int		  process_arch_specific		 PARAMS ((FILE *));
  static int		  process_gnu_liblist		 PARAMS ((FILE *));
+ #ifdef  SUPPORT_MIPSGOT
+ static int		  dump_mips_got			 PARAMS ((FILE *));
+ #endif
  
  typedef int Elf32_Word;
  
*************** struct option options [] =
*** 2279,2284 ****
--- 2287,2295 ----
  #ifdef SUPPORT_DISASSEMBLY
    {"instruction-dump", required_argument, 0, 'i'},
  #endif
+ #ifdef  SUPPORT_MIPSGOT
+   {"mips-got", no_argument, 0, 'g'},
+ #endif
  
    {"version",          no_argument, 0, 'v'},
    {"wide",             no_argument, 0, 'W'},
*************** usage ()
*** 2317,2322 ****
--- 2328,2336 ----
    -i --instruction-dump=<number>\n\
                           Disassemble the contents of section <number>\n"));
  #endif
+ #ifdef  SUPPORT_MIPSGOT
+   fprintf (stdout, _("  -g --mips-got          Display the MIPS Global Offset Table\n"));
+ #endif
    fprintf (stdout, _("\
    -I --histogram         Display histogram of bucket list lengths\n\
    -W --wide              Allow output width to exceed 80 characters\n\
*************** parse_args (argc, argv)
*** 2369,2375 ****
      usage ();
  
    while ((c = getopt_long
! 	  (argc, argv, "ersuahnldSDAIw::x:i:vVW", options, NULL)) != EOF)
      {
        char *    cp;
        int	section;
--- 2383,2389 ----
      usage ();
  
    while ((c = getopt_long
! 	  (argc, argv, "ersuahnldSDAIwg::x:i:vVW", options, NULL)) != EOF)
      {
        char *    cp;
        int	section;
*************** parse_args (argc, argv)
*** 2383,2388 ****
--- 2397,2408 ----
  	  usage ();
  	  break;
  
+ #ifdef  SUPPORT_MIPSGOT
+ 	case 'g':
+ 	  do_mips_got ++;
+ 	  do_arch ++;
+ 	  break;
+ #endif
  	case 'a':
  	  do_syms ++;
  	  do_reloc ++;
*************** parse_args (argc, argv)
*** 2395,2400 ****
--- 2415,2423 ----
  	  do_histogram ++;
  	  do_arch ++;
  	  do_notes ++;
+ #ifdef  SUPPORT_MIPSGOT
+ 	  do_mips_got ++;
+ #endif
  	  break;
  	case 'e':
  	  do_header ++;
*************** parse_args (argc, argv)
*** 2430,2435 ****
--- 2453,2461 ----
  	  break;
  	case 'I':
  	  do_histogram ++;
+ #ifdef  SUPPORT_MIPSGOT
+ 	  do_mips_got ++;
+ #endif
  	  break;
  	case 'n':
  	  do_notes ++;
*************** parse_args (argc, argv)
*** 2620,2628 ****
--- 2646,2660 ----
  	}
      }
  
+ #ifdef  SUPPORT_MIPSGOT
+   if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
+       && !do_segments && !do_header && !do_dump && !do_version
+       && !do_histogram && !do_debugging && !do_arch && !do_notes && !do_mips_got)
+ #else
    if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
        && !do_segments && !do_header && !do_dump && !do_version
        && !do_histogram && !do_debugging && !do_arch && !do_notes)
+ #endif
      usage ();
    else if (argc < 3)
      {
*************** process_section_contents (file)
*** 9088,9093 ****
--- 9120,9265 ----
    return 1;
  }
  
+ #ifdef  SUPPORT_MIPSGOT
+ int mips_dyn_symtab_nr = 0;
+ int mips_local_gotno = 0;
+ int mips_gotsym = 0;
+ int
+ dump_mips_got(FILE *file)
+ {
+   Elf32_Internal_Shdr *    section;
+   Elf32_Internal_Shdr *    got_section = 0;
+ 
+   unsigned long		  dynstr_size = 0;
+   unsigned int i;
+   int             bytes;
+   int             addr;
+   unsigned char * data;
+   unsigned char * start;
+   int ent;
+   char *name=0;
+   int wordsize;
+ 
+   if (elf_header.e_ident [EI_CLASS] == ELFCLASS32)
+     wordsize = 4;
+   else
+     wordsize = 8;
+ 
+   for (i = 0, section = section_headers;
+        i < elf_header.e_shnum;
+        i ++, section ++)
+     {
+       name = SECTION_NAME (section);
+       if (section->sh_type == SHT_STRTAB
+ 	       && strcmp (name, ".dynstr") == 0)
+ 	dynstr_size = section->sh_size;
+       else if ( !strcmp(name, ".got"))
+ 	got_section = section;
+     }
+   if ( got_section == 0 )
+     return 0;
+ 
+   bytes = got_section->sh_size;
+ 
+   if (bytes == 0)
+     {
+       printf (_("\nSection '%s' has no data to dump.\n"),
+ 	      SECTION_NAME (got_section));
+       return 0;
+     }
+   else
+     printf (_("\nDump of MIPS Global Offset Table '%s':\n"), SECTION_NAME (got_section));
+ 
+ 
+   printf(" %4s  %6s   %10s ", "Ent#","Gp Off", "Addr"); 
+   if (wordsize==4)
+     printf("   %4s ", "Value");
+   else
+     printf("   %8s ", "Value");
+ 
+   printf("DynSym [Ent#, Val, Name]\n");
+ 
+   addr = got_section->sh_addr;
+   start = get_data (NULL, file, got_section->sh_offset, bytes, _("section data"));
+   
+   if (!start)
+     return 0;
+ 
+   data = start;
+   ent = 0;
+   while (bytes)
+     {
+       int j;
+       int lbytes;
+ 
+       lbytes = (bytes > wordsize ? wordsize : bytes);
+ 
+       printf (" %4d ", ent);
+       printf (" %6d ", -32752+ent*wordsize);
+       printf ("  0x%8.8x ", addr);
+ 
+       switch (elf_header.e_ident [EI_DATA])
+ 	{
+ 	case ELFDATA2LSB:
+ 	  for (j = (wordsize-1); j >= 0; j --)
+ 	    {
+ 	      if (j < lbytes)
+ 		printf ("%2.2x", data [j]);
+ 	      else
+ 		printf ("  ");
+ 	    }
+ 	  break;
+ 
+ 	case ELFDATA2MSB:
+ 	  for (j = 0; j < wordsize; j++)
+ 	    {
+ 	      if (j < lbytes)
+ 		printf ("%2.2x", data [j]);
+ 	      else
+ 		printf ("  ");
+ 	    }
+ 	  break;
+ 	}
+ 
+       if ( ent<mips_local_gotno) {
+ 	printf (" (local) ");
+       }
+       else {
+ 	int kk;
+ 	kk  = ent -  mips_local_gotno +mips_gotsym;
+ 	
+         if (kk< mips_dyn_symtab_nr) 
+           {
+ #if 1
+ 	    printf (" [%4d ", kk);
+ 	    print_vma (dynamic_symbols[kk].st_value, LONG_HEX);
+ #else
+ 	    printf (" [%4d 0x%8.8x", kk, dynamic_symbols[kk].st_value);
+ #endif
+ 	    if ( dynamic_symbols[kk].st_name < dynstr_size )
+ 	      printf(" %s", dynamic_strings + dynamic_symbols[kk].st_name);
+ 	    else 
+ 	      printf(" (invalid offset %ld)", dynamic_symbols[kk].st_name);
+ 	    printf(" ]");
+           } 
+         else
+ 	  printf(" (no dyn_symtab)");
+       }
+ 
+       putchar ('\n');
+       ent ++;
+ 
+       data  += lbytes;
+       addr  += lbytes;
+       bytes -= lbytes;
+     }
+ 
+   free (start);
+ 
+   return 1;
+ }
+ #endif
+ 
  static void
  process_mips_fpe_exception (mask)
       int mask;
*************** process_mips_specific (file)
*** 9144,9152 ****
--- 9316,9339 ----
        case DT_MIPS_CONFLICTNO:
  	conflictsno = entry->d_un.d_val;
  	break;
+ #ifdef  SUPPORT_MIPSGOT
+       case DT_MIPS_SYMTABNO:
+ 	mips_dyn_symtab_nr = entry->d_un.d_val;
+ 	break;
+       case DT_MIPS_LOCAL_GOTNO:
+ 	mips_local_gotno = entry->d_un.d_val;
+ 	break;
+       case DT_MIPS_GOTSYM:
+ 	mips_gotsym = entry->d_un.d_val;
+ 	break;
+ #endif
        default:
  	break;
        }
+ #ifdef  SUPPORT_MIPSGOT
+     if (do_mips_got)
+ 	dump_mips_got(file);
+ #endif
  
    if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
      {

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