This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH/RFA]: readelf extnsion to dump mips GOT
- From: Hiroyuki Machida <machida at sm dot sony dot co dot jp>
- To: binutils at sources dot redhat dot com
- Date: Mon, 04 Nov 2002 23:16:41 +0900 (JST)
- Subject: [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)
{