Add -j/--display-section option to readelf.
This commit is contained in:
parent
31c21e2c13
commit
8e8d0b63ff
6 changed files with 287 additions and 133 deletions
|
@ -1,5 +1,9 @@
|
||||||
-*- text -*-
|
-*- text -*-
|
||||||
|
|
||||||
|
* Readelf now has a -j/--display-section option which takes the name or index
|
||||||
|
of a section and displays its contents according to its type. The option can
|
||||||
|
be used multiple times on the command line to display multiple sections.
|
||||||
|
|
||||||
* Base register 0 is now printed as "0" instead of "%r0" in s390 disassembly.
|
* Base register 0 is now printed as "0" instead of "%r0" in s390 disassembly.
|
||||||
|
|
||||||
* When objdump or readelf are used to display the contents of a .eh_frame
|
* When objdump or readelf are used to display the contents of a .eh_frame
|
||||||
|
|
|
@ -5012,6 +5012,7 @@ readelf [@option{-a}|@option{--all}]
|
||||||
[@option{-x} <number or name>|@option{--hex-dump=}<number or name>]
|
[@option{-x} <number or name>|@option{--hex-dump=}<number or name>]
|
||||||
[@option{-p} <number or name>|@option{--string-dump=}<number or name>]
|
[@option{-p} <number or name>|@option{--string-dump=}<number or name>]
|
||||||
[@option{-R} <number or name>|@option{--relocated-dump=}<number or name>]
|
[@option{-R} <number or name>|@option{--relocated-dump=}<number or name>]
|
||||||
|
[@option{-j} <number or name>|@option{--display-section=}<number or name>]
|
||||||
[@option{-z}|@option{--decompress}]
|
[@option{-z}|@option{--decompress}]
|
||||||
[@option{-c}|@option{--archive-index}]
|
[@option{-c}|@option{--archive-index}]
|
||||||
[@option{-w[lLiaprmfFsoORtUuTgAck]}|
|
[@option{-w[lLiaprmfFsoORtUuTgAck]}|
|
||||||
|
@ -5270,6 +5271,8 @@ displayed.
|
||||||
Displays the contents of the indicated section as a hexadecimal bytes.
|
Displays the contents of the indicated section as a hexadecimal bytes.
|
||||||
A number identifies a particular section by index in the section table;
|
A number identifies a particular section by index in the section table;
|
||||||
any other string identifies all sections with that name in the object file.
|
any other string identifies all sections with that name in the object file.
|
||||||
|
This option can be repeated multiple times on the command line in
|
||||||
|
order to request multiple hex dumps.
|
||||||
|
|
||||||
@item -R <number or name>
|
@item -R <number or name>
|
||||||
@itemx --relocated-dump=<number or name>
|
@itemx --relocated-dump=<number or name>
|
||||||
|
@ -5278,12 +5281,31 @@ bytes. A number identifies a particular section by index in the
|
||||||
section table; any other string identifies all sections with that name
|
section table; any other string identifies all sections with that name
|
||||||
in the object file. The contents of the section will be relocated
|
in the object file. The contents of the section will be relocated
|
||||||
before they are displayed.
|
before they are displayed.
|
||||||
|
This option can be repeated multiple times on the command line in
|
||||||
|
order to request multiple relocated dumps.
|
||||||
|
|
||||||
@item -p <number or name>
|
@item -p <number or name>
|
||||||
@itemx --string-dump=<number or name>
|
@itemx --string-dump=<number or name>
|
||||||
Displays the contents of the indicated section as printable strings.
|
Displays the contents of the indicated section as printable strings.
|
||||||
A number identifies a particular section by index in the section table;
|
A number identifies a particular section by index in the section table;
|
||||||
any other string identifies all sections with that name in the object file.
|
any other string identifies all sections with that name in the object file.
|
||||||
|
This option can be repeated multiple times on the command line in
|
||||||
|
order to request multiple string dumps.
|
||||||
|
|
||||||
|
@item -j <number or name>
|
||||||
|
@itemx --display-section
|
||||||
|
Displays the contents of the indicated section according to its
|
||||||
|
section header type. Sections containing relocations will be
|
||||||
|
displayed as if the @option{--relocations} option had been used,
|
||||||
|
sections contains symbols will be displayed as if the @option{--syms}
|
||||||
|
option had been used and so on.
|
||||||
|
|
||||||
|
A number identifies a particular section by index in the section
|
||||||
|
table; any other string identifies all sections with that name in the
|
||||||
|
input file(s).
|
||||||
|
|
||||||
|
This option can be repeated multiple times on the command line in
|
||||||
|
order to request multiple section dumps.
|
||||||
|
|
||||||
@item -z
|
@item -z
|
||||||
@itemx --decompress
|
@itemx --decompress
|
||||||
|
|
|
@ -63,6 +63,20 @@ warn (const char *message, ...)
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
inform (const char *message, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
/* Try to keep info messages in sync with the program's normal output. */
|
||||||
|
fflush (stdout);
|
||||||
|
|
||||||
|
va_start (args, message);
|
||||||
|
fprintf (stderr, _("%s: Info: "), program_name);
|
||||||
|
vfprintf (stderr, message, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
void (*byte_put) (unsigned char *, uint64_t, unsigned int);
|
void (*byte_put) (unsigned char *, uint64_t, unsigned int);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
extern void error (const char *, ...) ATTRIBUTE_PRINTF_1;
|
extern void error (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||||||
extern void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
|
extern void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||||||
|
extern void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||||||
|
|
||||||
extern void (*byte_put) (unsigned char *, uint64_t, unsigned int);
|
extern void (*byte_put) (unsigned char *, uint64_t, unsigned int);
|
||||||
extern void byte_put_little_endian (unsigned char *, uint64_t, unsigned int);
|
extern void byte_put_little_endian (unsigned char *, uint64_t, unsigned int);
|
||||||
|
|
|
@ -188,12 +188,15 @@ typedef struct elf_section_list
|
||||||
|
|
||||||
/* Flag bits indicating particular types of dump. */
|
/* Flag bits indicating particular types of dump. */
|
||||||
#define HEX_DUMP (1 << 0) /* The -x command line switch. */
|
#define HEX_DUMP (1 << 0) /* The -x command line switch. */
|
||||||
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
|
#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
|
||||||
|
#endif
|
||||||
#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
|
#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
|
||||||
#define STRING_DUMP (1 << 3) /* The -p command line switch. */
|
#define STRING_DUMP (1 << 3) /* The -p command line switch. */
|
||||||
#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
|
#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
|
||||||
#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
|
#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
|
||||||
#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
|
#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
|
||||||
|
#define AUTO_DUMP (1 << 7) /* The -j command line switch. */
|
||||||
|
|
||||||
typedef unsigned char dump_type;
|
typedef unsigned char dump_type;
|
||||||
|
|
||||||
|
@ -402,6 +405,9 @@ static const char * get_symbol_version_string
|
||||||
(Filedata *, bool, const char *, size_t, unsigned,
|
(Filedata *, bool, const char *, size_t, unsigned,
|
||||||
Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
|
Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
|
||||||
|
|
||||||
|
static bool process_notes_at
|
||||||
|
(Filedata *, Elf_Internal_Shdr *, uint64_t, uint64_t, uint64_t);
|
||||||
|
|
||||||
#define UNKNOWN -1
|
#define UNKNOWN -1
|
||||||
|
|
||||||
static inline const char *
|
static inline const char *
|
||||||
|
@ -5414,7 +5420,6 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type)
|
||||||
case SHT_SYMTAB: return "SYMTAB";
|
case SHT_SYMTAB: return "SYMTAB";
|
||||||
case SHT_STRTAB: return "STRTAB";
|
case SHT_STRTAB: return "STRTAB";
|
||||||
case SHT_RELA: return "RELA";
|
case SHT_RELA: return "RELA";
|
||||||
case SHT_RELR: return "RELR";
|
|
||||||
case SHT_HASH: return "HASH";
|
case SHT_HASH: return "HASH";
|
||||||
case SHT_DYNAMIC: return "DYNAMIC";
|
case SHT_DYNAMIC: return "DYNAMIC";
|
||||||
case SHT_NOTE: return "NOTE";
|
case SHT_NOTE: return "NOTE";
|
||||||
|
@ -5422,20 +5427,27 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type)
|
||||||
case SHT_REL: return "REL";
|
case SHT_REL: return "REL";
|
||||||
case SHT_SHLIB: return "SHLIB";
|
case SHT_SHLIB: return "SHLIB";
|
||||||
case SHT_DYNSYM: return "DYNSYM";
|
case SHT_DYNSYM: return "DYNSYM";
|
||||||
|
/* 12 and 13 are not defined. */
|
||||||
case SHT_INIT_ARRAY: return "INIT_ARRAY";
|
case SHT_INIT_ARRAY: return "INIT_ARRAY";
|
||||||
case SHT_FINI_ARRAY: return "FINI_ARRAY";
|
case SHT_FINI_ARRAY: return "FINI_ARRAY";
|
||||||
case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
|
case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
|
||||||
case SHT_GNU_HASH: return "GNU_HASH";
|
|
||||||
case SHT_GROUP: return "GROUP";
|
case SHT_GROUP: return "GROUP";
|
||||||
case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
|
case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
|
||||||
|
case SHT_RELR: return "RELR";
|
||||||
|
/* End of generic section types. */
|
||||||
|
|
||||||
|
/* OS specific section types: */
|
||||||
case SHT_GNU_verdef: return "VERDEF";
|
case SHT_GNU_verdef: return "VERDEF";
|
||||||
case SHT_GNU_verneed: return "VERNEED";
|
case SHT_GNU_verneed: return "VERNEED";
|
||||||
case SHT_GNU_versym: return "VERSYM";
|
case SHT_GNU_versym: return "VERSYM";
|
||||||
|
case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
|
||||||
case 0x6ffffff0: return "VERSYM";
|
case 0x6ffffff0: return "VERSYM";
|
||||||
|
case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
|
||||||
|
case SHT_GNU_HASH: return "GNU_HASH";
|
||||||
|
case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
|
||||||
case 0x6ffffffc: return "VERDEF";
|
case 0x6ffffffc: return "VERDEF";
|
||||||
case 0x7ffffffd: return "AUXILIARY";
|
case 0x7ffffffd: return "AUXILIARY";
|
||||||
case 0x7fffffff: return "FILTER";
|
case 0x7fffffff: return "FILTER";
|
||||||
case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
|
if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
|
||||||
|
@ -5595,6 +5607,7 @@ static struct option options[] =
|
||||||
{"help", no_argument, 0, 'H'},
|
{"help", no_argument, 0, 'H'},
|
||||||
{"file-header", no_argument, 0, 'h'},
|
{"file-header", no_argument, 0, 'h'},
|
||||||
{"histogram", no_argument, 0, 'I'},
|
{"histogram", no_argument, 0, 'I'},
|
||||||
|
{"display-section", required_argument, 0, 'j'},
|
||||||
{"lint", no_argument, 0, 'L'},
|
{"lint", no_argument, 0, 'L'},
|
||||||
{"enable-checks", no_argument, 0, 'L'},
|
{"enable-checks", no_argument, 0, 'L'},
|
||||||
{"program-headers", no_argument, 0, 'l'},
|
{"program-headers", no_argument, 0, 'l'},
|
||||||
|
@ -5729,6 +5742,9 @@ usage (FILE * stream)
|
||||||
Dump the relocated contents of section <number|name>\n"));
|
Dump the relocated contents of section <number|name>\n"));
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
-z --decompress Decompress section before dumping it\n"));
|
-z --decompress Decompress section before dumping it\n"));
|
||||||
|
fprintf (stream, _("\n\
|
||||||
|
-j --display-section=<name|number>\n\
|
||||||
|
Display the contents of the indicated section. Can be repeated\n"));
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
-w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
|
-w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
|
||||||
f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
|
f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
|
||||||
|
@ -5893,7 +5909,7 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
|
||||||
usage (stderr);
|
usage (stderr);
|
||||||
|
|
||||||
while ((c = getopt_long
|
while ((c = getopt_long
|
||||||
(argc, argv, "ACDHILNPR:STU:VWXacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
|
(argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
@ -5976,6 +5992,9 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
|
||||||
do_follow_links = true;
|
do_follow_links = true;
|
||||||
dump_any_debugging = true;
|
dump_any_debugging = true;
|
||||||
break;
|
break;
|
||||||
|
case 'j':
|
||||||
|
request_dump (dumpdata, AUTO_DUMP);
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
request_dump (dumpdata, HEX_DUMP);
|
request_dump (dumpdata, HEX_DUMP);
|
||||||
break;
|
break;
|
||||||
|
@ -8877,6 +8896,86 @@ static struct
|
||||||
{ "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
|
{ "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static relocation_type
|
||||||
|
rel_type_from_sh_type (unsigned int sh_type)
|
||||||
|
{
|
||||||
|
switch (sh_type)
|
||||||
|
{
|
||||||
|
case SHT_RELA: return reltype_rela;
|
||||||
|
case SHT_REL: return reltype_rel;
|
||||||
|
case SHT_RELR: return reltype_relr;
|
||||||
|
default: return reltype_unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
display_relocations (Elf_Internal_Shdr * section,
|
||||||
|
Filedata * filedata)
|
||||||
|
{
|
||||||
|
if (section->sh_type != SHT_RELA
|
||||||
|
&& section->sh_type != SHT_REL
|
||||||
|
&& section->sh_type != SHT_RELR)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint64_t rel_size = section->sh_size;
|
||||||
|
|
||||||
|
if (rel_size == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (filedata->is_separate)
|
||||||
|
printf (_("\nIn linked file '%s' relocation section "),
|
||||||
|
filedata->file_name);
|
||||||
|
else
|
||||||
|
printf (_("\nRelocation section "));
|
||||||
|
|
||||||
|
if (filedata->string_table == NULL)
|
||||||
|
printf ("%d", section->sh_name);
|
||||||
|
else
|
||||||
|
printf ("'%s'", printable_section_name (filedata, section));
|
||||||
|
|
||||||
|
uint64_t num_rela = rel_size / section->sh_entsize;
|
||||||
|
uint64_t rel_offset = section->sh_offset;
|
||||||
|
|
||||||
|
printf (ngettext (" at offset %#" PRIx64
|
||||||
|
" contains %" PRIu64 " entry:\n",
|
||||||
|
" at offset %#" PRIx64
|
||||||
|
" contains %" PRId64 " entries:\n",
|
||||||
|
num_rela),
|
||||||
|
rel_offset, num_rela);
|
||||||
|
|
||||||
|
relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
|
||||||
|
|
||||||
|
if (section->sh_link == 0
|
||||||
|
|| section->sh_link >= filedata->file_header.e_shnum)
|
||||||
|
/* Symbol data not available. */
|
||||||
|
return dump_relocations (filedata, rel_offset, rel_size,
|
||||||
|
NULL, 0, NULL, 0, rel_type,
|
||||||
|
false /* is_dynamic */);
|
||||||
|
|
||||||
|
Elf_Internal_Shdr * symsec = filedata->section_headers + section->sh_link;
|
||||||
|
|
||||||
|
if (symsec->sh_type != SHT_SYMTAB
|
||||||
|
&& symsec->sh_type != SHT_DYNSYM)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Elf_Internal_Sym * symtab;
|
||||||
|
uint64_t nsyms;
|
||||||
|
uint64_t strtablen = 0;
|
||||||
|
char * strtab = NULL;
|
||||||
|
|
||||||
|
if (!get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool res = dump_relocations (filedata, rel_offset, rel_size,
|
||||||
|
symtab, nsyms, strtab, strtablen,
|
||||||
|
rel_type,
|
||||||
|
symsec->sh_type == SHT_DYNSYM);
|
||||||
|
free (strtab);
|
||||||
|
free (symtab);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/* Process the reloc section. */
|
/* Process the reloc section. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -8968,72 +9067,8 @@ process_relocs (Filedata * filedata)
|
||||||
i < filedata->file_header.e_shnum;
|
i < filedata->file_header.e_shnum;
|
||||||
i++, section++)
|
i++, section++)
|
||||||
{
|
{
|
||||||
if ( section->sh_type != SHT_RELA
|
if (display_relocations (section, filedata))
|
||||||
&& section->sh_type != SHT_REL
|
found = true;
|
||||||
&& section->sh_type != SHT_RELR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
rel_offset = section->sh_offset;
|
|
||||||
rel_size = section->sh_size;
|
|
||||||
|
|
||||||
if (rel_size)
|
|
||||||
{
|
|
||||||
relocation_type rel_type;
|
|
||||||
uint64_t num_rela;
|
|
||||||
|
|
||||||
if (filedata->is_separate)
|
|
||||||
printf (_("\nIn linked file '%s' relocation section "),
|
|
||||||
filedata->file_name);
|
|
||||||
else
|
|
||||||
printf (_("\nRelocation section "));
|
|
||||||
|
|
||||||
if (filedata->string_table == NULL)
|
|
||||||
printf ("%d", section->sh_name);
|
|
||||||
else
|
|
||||||
printf ("'%s'", printable_section_name (filedata, section));
|
|
||||||
|
|
||||||
num_rela = rel_size / section->sh_entsize;
|
|
||||||
printf (ngettext (" at offset %#" PRIx64
|
|
||||||
" contains %" PRIu64 " entry:\n",
|
|
||||||
" at offset %#" PRIx64
|
|
||||||
" contains %" PRId64 " entries:\n",
|
|
||||||
num_rela),
|
|
||||||
rel_offset, num_rela);
|
|
||||||
|
|
||||||
rel_type = section->sh_type == SHT_RELA ? reltype_rela :
|
|
||||||
section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
|
|
||||||
|
|
||||||
if (section->sh_link != 0
|
|
||||||
&& section->sh_link < filedata->file_header.e_shnum)
|
|
||||||
{
|
|
||||||
Elf_Internal_Shdr *symsec;
|
|
||||||
Elf_Internal_Sym *symtab;
|
|
||||||
uint64_t nsyms;
|
|
||||||
uint64_t strtablen = 0;
|
|
||||||
char *strtab = NULL;
|
|
||||||
|
|
||||||
symsec = filedata->section_headers + section->sh_link;
|
|
||||||
if (symsec->sh_type != SHT_SYMTAB
|
|
||||||
&& symsec->sh_type != SHT_DYNSYM)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!get_symtab (filedata, symsec,
|
|
||||||
&symtab, &nsyms, &strtab, &strtablen))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dump_relocations (filedata, rel_offset, rel_size,
|
|
||||||
symtab, nsyms, strtab, strtablen,
|
|
||||||
rel_type,
|
|
||||||
symsec->sh_type == SHT_DYNSYM);
|
|
||||||
free (strtab);
|
|
||||||
free (symtab);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dump_relocations (filedata, rel_offset, rel_size,
|
|
||||||
NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! found)
|
if (! found)
|
||||||
|
@ -14098,6 +14133,77 @@ print_symbol_table_heading (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
dump_symbol_section (Elf_Internal_Shdr * section,
|
||||||
|
Filedata * filedata)
|
||||||
|
{
|
||||||
|
if (section->sh_entsize == 0)
|
||||||
|
{
|
||||||
|
printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
|
||||||
|
printable_section_name (filedata, section));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t num_syms = section->sh_size / section->sh_entsize;
|
||||||
|
|
||||||
|
if (filedata->is_separate)
|
||||||
|
printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
|
||||||
|
" contains %" PRIu64 " entry:\n",
|
||||||
|
"\nIn linked file '%s' symbol section '%s'"
|
||||||
|
" contains %" PRIu64 " entries:\n",
|
||||||
|
num_syms),
|
||||||
|
filedata->file_name,
|
||||||
|
printable_section_name (filedata, section),
|
||||||
|
num_syms);
|
||||||
|
else
|
||||||
|
printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
|
||||||
|
" entry:\n",
|
||||||
|
"\nSymbol table '%s' contains %" PRIu64
|
||||||
|
" entries:\n",
|
||||||
|
num_syms),
|
||||||
|
printable_section_name (filedata, section),
|
||||||
|
num_syms);
|
||||||
|
|
||||||
|
print_symbol_table_heading ();
|
||||||
|
|
||||||
|
Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
|
||||||
|
if (symtab == NULL)
|
||||||
|
/* An error message will have already been displayed. */
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char * strtab = NULL;
|
||||||
|
uint64_t strtab_size = 0;
|
||||||
|
|
||||||
|
if (section->sh_link == filedata->file_header.e_shstrndx)
|
||||||
|
{
|
||||||
|
strtab = filedata->string_table;
|
||||||
|
strtab_size = filedata->string_table_length;
|
||||||
|
}
|
||||||
|
else if (section->sh_link < filedata->file_header.e_shnum)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr * string_sec;
|
||||||
|
|
||||||
|
string_sec = filedata->section_headers + section->sh_link;
|
||||||
|
|
||||||
|
strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
|
||||||
|
1, string_sec->sh_size,
|
||||||
|
_("string table"));
|
||||||
|
strtab_size = strtab != NULL ? string_sec->sh_size : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t si;
|
||||||
|
|
||||||
|
for (si = 0; si < num_syms; si++)
|
||||||
|
print_symbol (filedata, si, symtab, section, strtab, strtab_size);
|
||||||
|
|
||||||
|
free (symtab);
|
||||||
|
|
||||||
|
if (strtab != filedata->string_table)
|
||||||
|
free (strtab);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dump the symbol table. */
|
/* Dump the symbol table. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -14152,74 +14258,13 @@ process_symbol_table (Filedata * filedata)
|
||||||
i < filedata->file_header.e_shnum;
|
i < filedata->file_header.e_shnum;
|
||||||
i++, section++)
|
i++, section++)
|
||||||
{
|
{
|
||||||
char * strtab = NULL;
|
|
||||||
uint64_t strtab_size = 0;
|
|
||||||
Elf_Internal_Sym * symtab;
|
|
||||||
uint64_t si, num_syms;
|
|
||||||
|
|
||||||
if ((section->sh_type != SHT_SYMTAB
|
if ((section->sh_type != SHT_SYMTAB
|
||||||
&& section->sh_type != SHT_DYNSYM)
|
&& section->sh_type != SHT_DYNSYM)
|
||||||
|| (!do_syms
|
|| (!do_syms
|
||||||
&& section->sh_type == SHT_SYMTAB))
|
&& section->sh_type == SHT_SYMTAB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (section->sh_entsize == 0)
|
dump_symbol_section (section, filedata);
|
||||||
{
|
|
||||||
printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
|
|
||||||
printable_section_name (filedata, section));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_syms = section->sh_size / section->sh_entsize;
|
|
||||||
|
|
||||||
if (filedata->is_separate)
|
|
||||||
printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
|
|
||||||
" contains %" PRIu64 " entry:\n",
|
|
||||||
"\nIn linked file '%s' symbol section '%s'"
|
|
||||||
" contains %" PRIu64 " entries:\n",
|
|
||||||
num_syms),
|
|
||||||
filedata->file_name,
|
|
||||||
printable_section_name (filedata, section),
|
|
||||||
num_syms);
|
|
||||||
else
|
|
||||||
printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
|
|
||||||
" entry:\n",
|
|
||||||
"\nSymbol table '%s' contains %" PRIu64
|
|
||||||
" entries:\n",
|
|
||||||
num_syms),
|
|
||||||
printable_section_name (filedata, section),
|
|
||||||
num_syms);
|
|
||||||
|
|
||||||
print_symbol_table_heading ();
|
|
||||||
|
|
||||||
symtab = get_elf_symbols (filedata, section, & num_syms);
|
|
||||||
if (symtab == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (section->sh_link == filedata->file_header.e_shstrndx)
|
|
||||||
{
|
|
||||||
strtab = filedata->string_table;
|
|
||||||
strtab_size = filedata->string_table_length;
|
|
||||||
}
|
|
||||||
else if (section->sh_link < filedata->file_header.e_shnum)
|
|
||||||
{
|
|
||||||
Elf_Internal_Shdr * string_sec;
|
|
||||||
|
|
||||||
string_sec = filedata->section_headers + section->sh_link;
|
|
||||||
|
|
||||||
strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
|
|
||||||
1, string_sec->sh_size,
|
|
||||||
_("string table"));
|
|
||||||
strtab_size = strtab != NULL ? string_sec->sh_size : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (si = 0; si < num_syms; si++)
|
|
||||||
print_symbol (filedata, si, symtab, section,
|
|
||||||
strtab, strtab_size);
|
|
||||||
|
|
||||||
free (symtab);
|
|
||||||
if (strtab != filedata->string_table)
|
|
||||||
free (strtab);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (do_syms)
|
else if (do_syms)
|
||||||
|
@ -17016,6 +17061,65 @@ process_section_contents (Filedata * filedata)
|
||||||
if (filedata->is_separate && ! process_links)
|
if (filedata->is_separate && ! process_links)
|
||||||
dump &= DEBUG_DUMP;
|
dump &= DEBUG_DUMP;
|
||||||
|
|
||||||
|
if (dump & AUTO_DUMP)
|
||||||
|
{
|
||||||
|
switch (section->sh_type)
|
||||||
|
{
|
||||||
|
case SHT_PROGBITS:
|
||||||
|
/* FIXME: There are lots of different type of section that have
|
||||||
|
SHT_PROGBITS set in their header - code, debug info, etc. So
|
||||||
|
we should check the section's name and interpret its contents
|
||||||
|
that way, rather than just defaulting to a byte dump. */
|
||||||
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
|
res &= disassemble_section (section, filedata);
|
||||||
|
#else
|
||||||
|
res &= dump_section_as_bytes (section, filedata, false);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_DYNSYM:
|
||||||
|
case SHT_SYMTAB:
|
||||||
|
res &= dump_symbol_section (section, filedata);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_STRTAB:
|
||||||
|
res &= dump_section_as_strings (section, filedata);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_RELA:
|
||||||
|
case SHT_REL:
|
||||||
|
case SHT_RELR:
|
||||||
|
res &= display_relocations (section, filedata);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_NOTE:
|
||||||
|
res &= process_notes_at (filedata, section, section->sh_offset,
|
||||||
|
section->sh_size, section->sh_addralign);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_NULL:
|
||||||
|
inform (_("Unable to display section %d - it has a NULL type\n"), i);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_NOBITS:
|
||||||
|
inform (_("Unable to display section %d - it has no contents\n"), i);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SHT_HASH:
|
||||||
|
case SHT_DYNAMIC:
|
||||||
|
case SHT_GROUP:
|
||||||
|
case SHT_GNU_ATTRIBUTES:
|
||||||
|
/* FIXME: Implement these. */
|
||||||
|
/* Fall through. */
|
||||||
|
default:
|
||||||
|
/* FIXME: Add Proc and OS specific section types ? */
|
||||||
|
warn (_("Unable to determine how to dump section %d (type %#x)\n"),
|
||||||
|
i, section->sh_type);
|
||||||
|
res = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
if (dump & DISASS_DUMP)
|
if (dump & DISASS_DUMP)
|
||||||
{
|
{
|
||||||
|
@ -17622,7 +17726,8 @@ display_arm_attribute (unsigned char * p,
|
||||||
|
|
||||||
static unsigned char *
|
static unsigned char *
|
||||||
display_gnu_attribute (unsigned char * p,
|
display_gnu_attribute (unsigned char * p,
|
||||||
unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
|
unsigned char * (* display_proc_gnu_attribute)
|
||||||
|
(unsigned char *, unsigned int, const unsigned char * const),
|
||||||
const unsigned char * const end)
|
const unsigned char * const end)
|
||||||
{
|
{
|
||||||
unsigned int tag;
|
unsigned int tag;
|
||||||
|
|
|
@ -634,3 +634,11 @@ readelf_find_size $tempfile 2
|
||||||
# Make sure that readelf can decode the contents.
|
# Make sure that readelf can decode the contents.
|
||||||
readelf_test -wi $tempfile dw5-op.W
|
readelf_test -wi $tempfile dw5-op.W
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Test the -j/--display-section option.
|
||||||
|
# Check that multiple options accumulate.
|
||||||
|
# Check that both numbers and names can be used.
|
||||||
|
readelf_test {-j .rela.debug_info --display-section=.rel.debug_info} $tempfile display-section.r
|
||||||
|
readelf_test --display-section=0 $tempfile display-section.0
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue