|
|
static int do_dynamic; | static int do_dynamic; |
static int do_syms; | static int do_syms; |
static int do_reloc; | static int do_reloc; |
|
static int do_direct; |
static int do_sections; | static int do_sections; |
static int do_section_groups; | static int do_section_groups; |
static int do_section_details; | static int do_section_details; |
|
|
case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */ | case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */ |
| |
case DT_VERSYM: return "VERSYM"; | case DT_VERSYM: return "VERSYM"; |
|
case DT_SUSE_DIRECT: return "SUSE_DIRECT"; |
| |
case DT_TLSDESC_GOT: return "TLSDESC_GOT"; | case DT_TLSDESC_GOT: return "TLSDESC_GOT"; |
case DT_TLSDESC_PLT: return "TLSDESC_PLT"; | case DT_TLSDESC_PLT: return "TLSDESC_PLT"; |
|
|
{"symbols", no_argument, 0, 's'}, | {"symbols", no_argument, 0, 's'}, |
{"syms", no_argument, 0, 's'}, | {"syms", no_argument, 0, 's'}, |
{"relocs", no_argument, 0, 'r'}, | {"relocs", no_argument, 0, 'r'}, |
|
{"direct", no_argument, 0, 'y'}, |
{"notes", no_argument, 0, 'n'}, | {"notes", no_argument, 0, 'n'}, |
{"dynamic", no_argument, 0, 'd'}, | {"dynamic", no_argument, 0, 'd'}, |
{"arch-specific", no_argument, 0, 'A'}, | {"arch-specific", no_argument, 0, 'A'}, |
|
|
--symbols An alias for --syms\n\ | --symbols An alias for --syms\n\ |
-n --notes Display the core notes (if present)\n\ | -n --notes Display the core notes (if present)\n\ |
-r --relocs Display the relocations (if present)\n\ | -r --relocs Display the relocations (if present)\n\ |
|
-y --direct Display direct linkage table (if present)\n\ |
-u --unwind Display the unwind info (if present)\n\ | -u --unwind Display the unwind info (if present)\n\ |
-d --dynamic Display the dynamic section (if present)\n\ | -d --dynamic Display the dynamic section (if present)\n\ |
-V --version-info Display the version sections (if present)\n\ | -V --version-info Display the version sections (if present)\n\ |
|
|
usage (); | usage (); |
| |
while ((c = getopt_long | while ((c = getopt_long |
(argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF) |
(argc, argv, "erysuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF) |
{ | { |
char *cp; | char *cp; |
int section; | int section; |
|
|
case 'a': | case 'a': |
do_syms++; | do_syms++; |
do_reloc++; | do_reloc++; |
|
do_direct++; |
do_unwind++; | do_unwind++; |
do_dynamic++; | do_dynamic++; |
do_header++; | do_header++; |
|
|
case 'r': | case 'r': |
do_reloc++; | do_reloc++; |
break; | break; |
|
case 'y': |
|
do_direct++; |
|
break; |
case 'u': | case 'u': |
do_unwind++; | do_unwind++; |
break; | break; |
|
|
if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections | if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections |
&& !do_segments && !do_header && !do_dump && !do_version | && !do_segments && !do_header && !do_dump && !do_version |
&& !do_histogram && !do_debugging && !do_arch && !do_notes | && !do_histogram && !do_debugging && !do_arch && !do_notes |
&& !do_section_groups) |
&& !do_section_groups && !do_direct) |
usage (); | usage (); |
else if (argc < 3) | else if (argc < 3) |
{ | { |
|
|
return 1; | return 1; |
} | } |
| |
|
static void |
|
print_dt_needed_name (int idx) |
|
{ |
|
const char *name = NULL; |
|
Elf_Internal_Dyn *entry; |
|
|
|
idx &= DT_SUSE_DIRECT_MASK; |
|
|
|
switch (idx) |
|
{ |
|
case 0: |
|
name = _("<self>"); |
|
break; |
|
case DT_SUSE_DIRECT_UNKNOWN: |
|
name = _("<unknown>"); |
|
break; |
|
default: |
|
idx--; |
|
|
|
for (entry = dynamic_section; |
|
entry < dynamic_section + dynamic_nent && idx > 0; |
|
entry++) |
|
if (entry->d_tag == DT_NEEDED) |
|
idx--; |
|
|
|
if (idx == 0) |
|
{ |
|
if (VALID_DYNAMIC_NAME (entry->d_un.d_val)) |
|
name = GET_DYNAMIC_NAME (entry->d_un.d_val); |
|
else |
|
name = NULL; |
|
} |
|
break; |
|
} |
|
|
|
if (!name) |
|
name = _("<out-of-range>"); |
|
if (do_wide) |
|
printf ("%s", name); |
|
else |
|
printf ("%-25s", name); |
|
} |
|
|
|
static int |
|
process_direct (FILE *file) |
|
{ |
|
unsigned int i; |
|
unsigned int si; |
|
char *strtab; |
|
unsigned char *directtab; |
|
Elf_Internal_Sym *symtab = NULL; |
|
Elf_Internal_Sym *psym; |
|
Elf_Internal_Shdr *direct = NULL; |
|
Elf_Internal_Shdr *dynsym = NULL; |
|
Elf_Internal_Shdr *section; |
|
|
|
if (!do_direct) |
|
return 1; |
|
if (!dynamic_symbols || !dynamic_section || !dynamic_strings) |
|
return 1; |
|
|
|
for (i = 0, section = section_headers; |
|
i < elf_header.e_shnum; |
|
i++, section++) |
|
{ |
|
if (section->sh_type == SHT_DYNSYM) |
|
dynsym = section; |
|
if (!strcmp (SECTION_NAME (section), ".suse.direct")) |
|
direct = section; |
|
} |
|
if (!dynsym || !direct) |
|
return 1; |
|
|
|
symtab = GET_ELF_SYMBOLS (file, dynsym); |
|
if (!symtab) |
|
return 1; |
|
|
|
directtab = get_data (NULL, file, direct->sh_offset, |
|
direct->sh_size, 1, _("direct linkage table")); |
|
if (!symtab) |
|
{ |
|
free (symtab); |
|
return 1; |
|
} |
|
|
|
if (dynsym->sh_link == elf_header.e_shstrndx) |
|
strtab = string_table; |
|
else |
|
{ |
|
Elf_Internal_Shdr *string_sec; |
|
|
|
string_sec = SECTION_HEADER (dynsym->sh_link); |
|
|
|
strtab = get_data (NULL, file, string_sec->sh_offset, |
|
string_sec->sh_size, 1, _("string table")); |
|
} |
|
|
|
assert (strtab != NULL); |
|
|
|
printf (_("\nDirect relocations for image:\n")); |
|
printf (_(" Num: Index Vague Binding Symbol\n")); |
|
for (si = 0, psym = symtab; |
|
si < dynsym->sh_size / dynsym->sh_entsize; |
|
si++, psym++) |
|
{ |
|
unsigned int field; |
|
printf ("%6d: ", si); |
|
field = byte_get (directtab + (si * 2), 2); |
|
printf ("[0x%.4x] ", field); |
|
printf ("%s", (field & DT_SUSE_DIRECT_VAGUE) ? "Vague" : " "); |
|
printf (" "); |
|
print_dt_needed_name (field); |
|
printf (" "); |
|
print_symbol (25, strtab + psym->st_name); |
|
printf ("\n"); |
|
} |
|
|
|
|
|
free (symtab); |
|
if (strtab != string_table) |
|
free (strtab); |
|
|
|
return 1; |
|
} |
|
|
|
|
/* Process the unwind section. */ | /* Process the unwind section. */ |
| |
#include "unwind-ia64.h" | #include "unwind-ia64.h" |
|
|
| |
process_relocs (file); | process_relocs (file); |
| |
|
process_direct (file); |
|
|
process_unwind (file); | process_unwind (file); |
| |
process_symbol_table (file); | process_symbol_table (file); |