X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=ba9529a4899edf09c51dad034bd281221616b79f;hb=c8286bd1e88747fcdf7f8ae1f90210449b621df6;hp=095310914a162053fe28b9722be0effabfe147d1;hpb=91a106e65e4ecec7cd92024af03b319a630c8e84;p=binutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index 095310914a1..ba9529a4899 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -58,14 +58,18 @@ #include "elf/d30v.h" #include "elf/dlx.h" #include "elf/fr30.h" +#include "elf/frv.h" #include "elf/h8.h" #include "elf/hppa.h" #include "elf/i386.h" +#include "elf/i370.h" #include "elf/i860.h" #include "elf/i960.h" #include "elf/ia64.h" +#include "elf/ip2k.h" #include "elf/m32r.h" #include "elf/m68k.h" +#include "elf/m68hc11.h" #include "elf/mcore.h" #include "elf/mips.h" #include "elf/mmix.h" @@ -78,6 +82,7 @@ #include "elf/sh.h" #include "elf/sparc.h" #include "elf/v850.h" +#include "elf/vax.h" #include "elf/x86-64.h" #include "elf/xstormy16.h" @@ -156,7 +161,7 @@ print_mode; /* Forward declarations for dumb compilers. */ static void print_vma PARAMS ((bfd_vma, print_mode)); -static void print_symbol PARAMS ((int, char *)); +static void print_symbol PARAMS ((int, const char *)); static bfd_vma (* byte_get) PARAMS ((unsigned char *, int)); static bfd_vma byte_get_little_endian PARAMS ((unsigned char *, int)); static bfd_vma byte_get_big_endian PARAMS ((unsigned char *, int)); @@ -166,7 +171,7 @@ static const char * get_ppc64_dynamic_type PARAMS ((unsigned long)); static const char * get_parisc_dynamic_type PARAMS ((unsigned long)); static const char * get_dynamic_type PARAMS ((unsigned long)); static int slurp_rela_relocs PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **, unsigned long *)); -static int slurp_rel_relocs PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rel **, unsigned long *)); +static int slurp_rel_relocs PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **, unsigned long *)); static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int)); static char * get_file_type PARAMS ((unsigned)); static char * get_machine_name PARAMS ((unsigned)); @@ -215,21 +220,21 @@ static int * get_dynamic_data PARAMS ((FILE *, unsigned static int get_32bit_dynamic_segment PARAMS ((FILE *)); static int get_64bit_dynamic_segment PARAMS ((FILE *)); #ifdef SUPPORT_DISASSEMBLY -static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *)); +static int disassemble_section PARAMS ((Elf_Internal_Shdr *, FILE *)); #endif -static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *)); -static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *)); -static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int prescan_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_pubnames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_frames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_macinfo PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_str PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); -static int display_debug_loc PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); +static int dump_section PARAMS ((Elf_Internal_Shdr *, FILE *)); +static int display_debug_section PARAMS ((Elf_Internal_Shdr *, FILE *)); +static int display_debug_info PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_not_supported PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int prescan_debug_info PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_lines PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_pubnames PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_abbrev PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_aranges PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_frames PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_macinfo PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_str PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_loc PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *)); static void load_debug_str PARAMS ((FILE *)); static void free_debug_str PARAMS ((void)); @@ -256,11 +261,12 @@ static const char * get_osabi_name PARAMS ((unsigned int)); static int guess_is_rela PARAMS ((unsigned long)); static const char * get_note_type PARAMS ((unsigned int)); static const char * get_netbsd_elfcore_note_type PARAMS ((unsigned int)); -static int process_note PARAMS ((Elf32_Internal_Note *)); +static int process_note PARAMS ((Elf_Internal_Note *)); static int process_corefile_note_segment PARAMS ((FILE *, bfd_vma, bfd_vma)); static int process_corefile_note_segments PARAMS ((FILE *)); static int process_corefile_contents PARAMS ((FILE *)); static int process_arch_specific PARAMS ((FILE *)); +static int process_gnu_liblist PARAMS ((FILE *)); typedef int Elf32_Word; @@ -400,7 +406,7 @@ byte_get_little_endian (field, size) case 8: /* We want to extract data from an 8 byte wide field and place it into a 4 byte wide field. Since this is a little - endian source we can juts use the 4 byte extraction code. */ + endian source we can just use the 4 byte extraction code. */ /* Fall through. */ #endif case 4: @@ -522,17 +528,17 @@ print_vma (vma, mode) /* Display a symbol on stdout. If do_wide is not true then format the symbol to be at most WIDTH characters, - truhncating as necessary. If WIDTH is negative then + truncating as necessary. If WIDTH is negative then format the string to be exactly - WIDTH characters, truncating or padding as necessary. */ static void print_symbol (width, symbol) int width; - char * symbol; + const char * symbol; { if (do_wide) - printf (symbol); + printf ("%s", symbol); else if (width < 0) printf ("%-*.*s", width, width, symbol); else @@ -633,6 +639,7 @@ guess_is_rela (e_machine) case EM_CYGNUS_MN10300: case EM_FR30: case EM_CYGNUS_FR30: + case EM_CYGNUS_FRV: case EM_SH: case EM_ALPHA: case EM_MCORE: @@ -646,6 +653,9 @@ guess_is_rela (e_machine) case EM_S390_OLD: case EM_MMIX: case EM_XSTORMY16: + case EM_VAX: + case EM_IP2K: + case EM_IP2K_OLD: return TRUE; case EM_MMA: @@ -665,7 +675,6 @@ guess_is_rela (e_machine) case EM_68HC05: case EM_SVX: case EM_ST19: - case EM_VAX: default: warn (_("Don't know about relocations on this machine architecture\n")); return FALSE; @@ -752,10 +761,10 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp) FILE *file; unsigned long rel_offset; unsigned long rel_size; - Elf_Internal_Rel **relsp; + Elf_Internal_Rela **relsp; unsigned long *nrelsp; { - Elf_Internal_Rel *rels; + Elf_Internal_Rela *rels; unsigned long nrels; unsigned int i; @@ -770,7 +779,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp) nrels = rel_size / sizeof (Elf32_External_Rel); - rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel)); + rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela)); if (rels == NULL) { @@ -782,6 +791,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp) { rels[i].r_offset = BYTE_GET (erels[i].r_offset); rels[i].r_info = BYTE_GET (erels[i].r_info); + rels[i].r_addend = 0; } free (erels); @@ -797,7 +807,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp) nrels = rel_size / sizeof (Elf64_External_Rel); - rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel)); + rels = (Elf_Internal_Rela *) malloc (nrels * sizeof (Elf_Internal_Rela)); if (rels == NULL) { @@ -809,6 +819,7 @@ slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp) { rels[i].r_offset = BYTE_GET8 (erels[i].r_offset); rels[i].r_info = BYTE_GET8 (erels[i].r_info); + rels[i].r_addend = 0; } free (erels); @@ -830,8 +841,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) int is_rela; { unsigned int i; - Elf_Internal_Rel * rels; - Elf_Internal_Rela * relas; + Elf_Internal_Rela * rels; if (is_rela == UNKNOWN) @@ -839,7 +849,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) if (is_rela) { - if (!slurp_rela_relocs (file, rel_offset, rel_size, &relas, &rel_size)) + if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size)) return 0; } else @@ -895,16 +905,8 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) bfd_vma type2 = (bfd_vma) NULL; bfd_vma type3 = (bfd_vma) NULL; - if (is_rela) - { - offset = relas [i].r_offset; - info = relas [i].r_info; - } - else - { - offset = rels [i].r_offset; - info = rels [i].r_info; - } + offset = rels [i].r_offset; + info = rels [i].r_info; if (is_32bit_elf) { @@ -973,6 +975,11 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) rtype = elf_i386_reloc_type (type); break; + case EM_68HC11: + case EM_68HC12: + rtype = elf_m68hc11_reloc_type (type); + break; + case EM_68K: rtype = elf_m68k_reloc_type (type); break; @@ -1031,6 +1038,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) rtype = elf_fr30_reloc_type (type); break; + case EM_CYGNUS_FRV: + rtype = elf_frv_reloc_type (type); + break; + case EM_MCORE: rtype = elf_mcore_reloc_type (type); break; @@ -1101,6 +1112,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) rtype = elf_x86_64_reloc_type (type); break; + case EM_S370: + rtype = i370_reloc_type (type); + break; + case EM_S390_OLD: case EM_S390: rtype = elf_s390_reloc_type (type); @@ -1109,6 +1124,15 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) case EM_XSTORMY16: rtype = elf_xstormy16_reloc_type (type); break; + + case EM_VAX: + rtype = elf_vax_reloc_type (type); + break; + + case EM_IP2K: + case EM_IP2K_OLD: + rtype = elf_ip2k_reloc_type (type); + break; } if (rtype == NULL) @@ -1135,20 +1159,48 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) printf (is_32bit_elf ? " " : " "); if (psym->st_name == 0) - print_symbol (22, SECTION_NAME (section_headers + psym->st_shndx)); + { + const char *sec_name = ""; + char name_buf[40]; + + if (ELF_ST_TYPE (psym->st_info) == STT_SECTION) + { + bfd_vma sec_index = (bfd_vma) -1; + + if (psym->st_shndx < SHN_LORESERVE) + sec_index = psym->st_shndx; + else if (psym->st_shndx > SHN_LORESERVE) + sec_index = psym->st_shndx - (SHN_HIRESERVE + 1 + - SHN_LORESERVE); + + if (sec_index != (bfd_vma) -1) + sec_name = SECTION_NAME (section_headers + sec_index); + else if (psym->st_shndx == SHN_ABS) + sec_name = "ABS"; + else if (psym->st_shndx == SHN_COMMON) + sec_name = "COMMON"; + else + { + sprintf (name_buf, "
", + (unsigned int) psym->st_shndx); + sec_name = name_buf; + } + } + print_symbol (22, sec_name); + } else if (strtab == NULL) printf (_(""), psym->st_name); else print_symbol (22, strtab + psym->st_name); if (is_rela) - printf (" + %lx", (unsigned long) relas [i].r_addend); + printf (" + %lx", (unsigned long) rels [i].r_addend); } } else if (is_rela) { printf ("%*c", is_32bit_elf ? (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' '); - print_vma (relas[i].r_addend, LONG_HEX); + print_vma (rels[i].r_addend, LONG_HEX); } if (elf_header.e_machine == EM_SPARCV9 @@ -1185,10 +1237,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) } } - if (is_rela) - free (relas); - else - free (rels); + free (rels); return 1; } @@ -1371,6 +1420,12 @@ get_dynamic_type (type) case DT_USED: return "USED"; case DT_FILTER: return "FILTER"; + case DT_GNU_PRELINKED: return "GNU_PRELINKED"; + case DT_GNU_CONFLICT: return "GNU_CONFLICT"; + case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ"; + case DT_GNU_LIBLIST: return "GNU_LIBLIST"; + case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ"; + default: if ((type >= DT_LOPROC) && (type <= DT_HIPROC)) { @@ -1508,6 +1563,7 @@ get_machine_name (e_machine) case EM_MN10200: return "mn10200"; case EM_CYGNUS_FR30: case EM_FR30: return "Fujitsu FR30"; + case EM_CYGNUS_FRV: return "Fujitsu FR-V"; case EM_PJ_OLD: case EM_PJ: return "picoJava"; case EM_MMA: return "Fujitsu Multimedia Accelerator"; @@ -1544,6 +1600,8 @@ get_machine_name (e_machine) case EM_OPENRISC: case EM_OR32: return "OpenRISC"; case EM_DLX: return "OpenDLX"; + case EM_IP2K_OLD: + case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers"; default: sprintf (buff, _(": %x"), e_machine); return buff; @@ -1737,9 +1795,6 @@ get_machine_flags (e_flags, e_machine) case E_V850E_ARCH: strcat (buf, ", v850e"); break; - case E_V850EA_ARCH: - strcat (buf, ", v850ea"); - break; case E_V850_ARCH: strcat (buf, ", v850"); break; @@ -1784,8 +1839,11 @@ get_machine_flags (e_flags, e_machine) case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break; case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break; case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break; - case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break; case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break; + case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break; + case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break; + case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break; + case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break; case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break; case 0: /* We simply ignore the field in this case to avoid confusion: @@ -1908,6 +1966,15 @@ get_machine_flags (e_flags, e_machine) if ((e_flags & EF_IA_64_ABSOLUTE)) strcat (buf, ", absolute"); break; + + case EM_VAX: + if ((e_flags & EF_VAX_NONPIC)) + strcat (buf, ", non-PIC"); + if ((e_flags & EF_VAX_DFLOAT)) + strcat (buf, ", D-Float"); + if ((e_flags & EF_VAX_GFLOAT)) + strcat (buf, ", G-Float"); + break; } } @@ -2167,6 +2234,7 @@ get_section_type_name (sh_type) case 0x6ffffffc: return "VERDEF"; case 0x7ffffffd: return "AUXILIARY"; case 0x7fffffff: return "FILTER"; + case SHT_GNU_LIBLIST: return "GNU_LIBLIST"; default: if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC)) @@ -2206,6 +2274,8 @@ get_section_type_name (sh_type) } } +#define OPTION_DEBUG_DUMP 512 + struct option options [] = { {"all", no_argument, 0, 'a'}, @@ -2225,7 +2295,7 @@ struct option options [] = {"version-info", no_argument, 0, 'V'}, {"use-dynamic", no_argument, 0, 'D'}, {"hex-dump", required_argument, 0, 'x'}, - {"debug-dump", optional_argument, 0, 'w'}, + {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP}, {"unwind", no_argument, 0, 'u'}, #ifdef SUPPORT_DISASSEMBLY {"instruction-dump", required_argument, 0, 'i'}, @@ -2260,7 +2330,8 @@ usage () -A --arch-specific Display architecture specific information (if any).\n\ -D --use-dynamic Use the dynamic section info when displaying symbols\n\ -x --hex-dump= Dump the contents of section \n\ - -w --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str,=loc]\n\ + -w[liaprmfFso] or\n\ + --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str,=loc]\n\ Display the contents of DWARF2 debug sections\n")); #ifdef SUPPORT_DISASSEMBLY fprintf (stdout, _("\ @@ -2458,6 +2529,88 @@ parse_args (argc, argv) } } break; + case OPTION_DEBUG_DUMP: + do_dump ++; + if (optarg == 0) + do_debugging = 1; + else + { + static const char *debug_dump_opt[] + = { "line", "info", "abbrev", "pubnames", "ranges", + "macro", "frames", "frames-interp", "str", "loc", NULL }; + unsigned int index; + const char *p; + + do_debugging = 0; + + p = optarg; + while (*p) + { + for (index = 0; debug_dump_opt[index]; index++) + { + size_t len = strlen (debug_dump_opt[index]); + + if (strncmp (p, debug_dump_opt[index], len) == 0 + && (p[len] == ',' || p[len] == '\0')) + { + switch (p[0]) + { + case 'i': + do_debug_info = 1; + break; + + case 'a': + do_debug_abbrevs = 1; + break; + + case 'l': + if (p[1] == 'i') + do_debug_lines = 1; + else + do_debug_loc = 1; + break; + + case 'p': + do_debug_pubnames = 1; + break; + + case 'r': + do_debug_aranges = 1; + break; + + case 'f': + if (len > 6) + do_debug_frames_interp = 1; + do_debug_frames = 1; + break; + + case 'm': + do_debug_macinfo = 1; + break; + + case 's': + do_debug_str = 1; + break; + } + + p += len; + break; + } + } + + if (debug_dump_opt[index] == NULL) + { + warn (_("Unrecognized debug option '%s'\n"), p); + p = strchr (p, ','); + if (p == NULL) + break; + } + + if (*p == ',') + p++; + } + } + break; #ifdef SUPPORT_DISASSEMBLY case 'i': do_dump ++; @@ -2658,7 +2811,7 @@ get_32bit_program_headers (file, program_headers) { Elf32_External_Phdr * phdrs; Elf32_External_Phdr * external; - Elf32_Internal_Phdr * internal; + Elf_Internal_Phdr * internal; unsigned int i; phdrs = ((Elf32_External_Phdr *) @@ -2694,7 +2847,7 @@ get_64bit_program_headers (file, program_headers) { Elf64_External_Phdr * phdrs; Elf64_External_Phdr * external; - Elf64_Internal_Phdr * internal; + Elf_Internal_Phdr * internal; unsigned int i; phdrs = ((Elf64_External_Phdr *) @@ -2723,6 +2876,8 @@ get_64bit_program_headers (file, program_headers) return 1; } +/* Returns 1 if the program headers were loaded. */ + static int process_program_headers (file) FILE * file; @@ -2735,7 +2890,7 @@ process_program_headers (file) { if (do_segments) printf (_("\nThere are no program headers in this file.\n")); - return 1; + return 0; } if (do_segments && !do_header) @@ -2966,7 +3121,7 @@ get_32bit_section_headers (file, num) unsigned int num; { Elf32_External_Shdr * shdrs; - Elf32_Internal_Shdr * internal; + Elf_Internal_Shdr * internal; unsigned int i; shdrs = ((Elf32_External_Shdr *) @@ -3012,7 +3167,7 @@ get_64bit_section_headers (file, num) unsigned int num; { Elf64_External_Shdr * shdrs; - Elf64_Internal_Shdr * internal; + Elf_Internal_Shdr * internal; unsigned int i; shdrs = ((Elf64_External_Shdr *) @@ -3279,6 +3434,7 @@ process_section_headers (file) dynamic_symbols = NULL; dynamic_strings = NULL; dynamic_syminfo = NULL; + symtab_shndx_hdr = NULL; for (i = 0, section = section_headers; i < elf_header.e_shnum; @@ -3532,7 +3688,7 @@ process_relocs (file) } else { - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned long i; int found = 0; @@ -3549,11 +3705,11 @@ process_relocs (file) if (rel_size) { - Elf32_Internal_Shdr * strsec; - Elf_Internal_Sym * symtab; - char * strtab; - int is_rela; - unsigned long nsyms; + Elf_Internal_Shdr * strsec; + Elf_Internal_Sym * symtab; + char * strtab; + int is_rela; + unsigned long nsyms; printf (_("\nRelocation section ")); @@ -3570,7 +3726,7 @@ process_relocs (file) nsyms = 0; if (section->sh_link) { - Elf32_Internal_Shdr * symsec; + Elf_Internal_Shdr * symsec; symsec = SECTION_HEADER (section->sh_link); nsyms = symsec->sh_size / symsec->sh_entsize; @@ -3643,7 +3799,7 @@ static void find_symbol_for_address PARAMS ((struct unw_aux_info *, bfd_vma *)); static void dump_ia64_unwind PARAMS ((struct unw_aux_info *)); static int slurp_ia64_unwind_table PARAMS ((FILE *, struct unw_aux_info *, - Elf32_Internal_Shdr *)); + Elf_Internal_Shdr *)); static void find_symbol_for_address (aux, addr, symname, offset) @@ -3715,13 +3871,13 @@ dump_ia64_unwind (aux) print_vma (tp->start.offset, PREFIX_HEX); fputc ('-', stdout); print_vma (tp->end.offset, PREFIX_HEX); - printf ("), info at +0x%lx\n", + printf ("], info at +0x%lx\n", (unsigned long) (tp->info.offset - aux->seg_base)); head = aux->info + (tp->info.offset - aux->info_addr); stamp = BYTE_GET8 ((unsigned char *) head); - printf (" v%u, flags=0x%lx (%s%s ), len=%lu bytes\n", + printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n", (unsigned) UNW_VER (stamp), (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32), UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "", @@ -3744,12 +3900,12 @@ static int slurp_ia64_unwind_table (file, aux, sec) FILE *file; struct unw_aux_info *aux; - Elf32_Internal_Shdr *sec; + Elf_Internal_Shdr *sec; { unsigned long size, addr_size, nrelas, i; Elf_Internal_Phdr *prog_hdrs, *seg; struct unw_table_entry *tep; - Elf32_Internal_Shdr *relsec; + Elf_Internal_Shdr *relsec; Elf_Internal_Rela *rela, *rp; unsigned char *table, *tp; Elf_Internal_Sym *sym; @@ -3903,7 +4059,7 @@ static int process_unwind (file) FILE * file; { - Elf32_Internal_Shdr *sec, *unwsec = NULL, *strsec; + Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec; unsigned long i, addr_size, unwcount = 0, unwstart = 0; struct unw_aux_info aux; @@ -4164,6 +4320,7 @@ dynamic_segment_parisc_val (entry) print_vma (entry->d_un.d_ptr, PREFIX_HEX); break; } + putchar ('\n'); } static int @@ -4316,7 +4473,7 @@ process_dynamic_segment (file) i < dynamic_size; ++i, ++ entry) { - Elf32_Internal_Shdr section; + Elf_Internal_Shdr section; if (entry->d_tag != DT_SYMTAB) continue; @@ -4514,11 +4671,13 @@ process_dynamic_segment (file) if (do_dynamic) { printf (_("Flags:")); + if (entry->d_un.d_val == 0) printf (_(" None\n")); else { unsigned long int val = entry->d_un.d_val; + if (val & DTF_1_PARINIT) { printf (" PARINIT"); @@ -4540,11 +4699,13 @@ process_dynamic_segment (file) if (do_dynamic) { printf (_("Flags:")); + if (entry->d_un.d_val == 0) printf (_(" None\n")); else { unsigned long int val = entry->d_un.d_val; + if (val & DF_P1_LAZYLOAD) { printf (" LAZYLOAD"); @@ -4571,6 +4732,7 @@ process_dynamic_segment (file) else { unsigned long int val = entry->d_un.d_val; + if (val & DF_1_NOW) { printf (" NOW"); @@ -4728,6 +4890,8 @@ process_dynamic_segment (file) case DT_MOVESZ : case DT_INIT_ARRAYSZ: case DT_FINI_ARRAYSZ: + case DT_GNU_CONFLICTSZ: + case DT_GNU_LIBLISTSZ: if (do_dynamic) { print_vma (entry->d_un.d_val, UNSIGNED); @@ -4774,6 +4938,22 @@ process_dynamic_segment (file) case DT_BIND_NOW: /* The value of this entry is ignored. */ + if (do_dynamic) + putchar ('\n'); + break; + + case DT_GNU_PRELINKED: + if (do_dynamic) + { + struct tm * tmp; + time_t time = entry->d_un.d_val; + + tmp = gmtime (&time); + printf ("%04u-%02u-%02uT%02u:%02u:%02u\n", + tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + } break; default: @@ -4837,7 +5017,7 @@ static int process_version_sections (file) FILE * file; { - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned i; int found = 0; @@ -5030,14 +5210,14 @@ process_version_sections (file) case SHT_GNU_versym: { - Elf32_Internal_Shdr * link_section; + Elf_Internal_Shdr * link_section; int total; int cnt; unsigned char * edata; unsigned short * data; char * strtab; Elf_Internal_Sym * symbols; - Elf32_Internal_Shdr * string_sec; + Elf_Internal_Shdr * string_sec; link_section = SECTION_HEADER (section->sh_link); total = section->sh_size / section->sh_entsize; @@ -5326,6 +5506,8 @@ static const char * get_symbol_index_type (type) unsigned int type; { + static char buff [32]; + switch (type) { case SHN_UNDEF: return "UND"; @@ -5333,19 +5515,17 @@ get_symbol_index_type (type) case SHN_COMMON: return "COM"; default: if (type >= SHN_LOPROC && type <= SHN_HIPROC) - return "PRC"; + sprintf (buff, "PRC[0x%04x]", type); else if (type >= SHN_LOOS && type <= SHN_HIOS) - return "OS "; + sprintf (buff, "OS [0x%04x]", type); else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE) - return "RSV"; + sprintf (buff, "RSV[0x%04x]", type); else - { - static char buff [32]; - - sprintf (buff, "%3d", type); - return buff; - } + sprintf (buff, "%3d", type); + break; } + + return buff; } static int * @@ -5392,7 +5572,7 @@ static int process_symbol_table (file) FILE * file; { - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char nb [4]; unsigned char nc [4]; int nbuckets = 0; @@ -5505,7 +5685,7 @@ process_symbol_table (file) strtab = string_table; else { - Elf32_Internal_Shdr * string_sec; + Elf_Internal_Shdr * string_sec; string_sec = SECTION_HEADER (section->sh_link); @@ -5807,7 +5987,7 @@ process_syminfo (file) #ifdef SUPPORT_DISASSEMBLY static void disassemble_section (section, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; FILE * file; { printf (_("\nAssembly dump of section %s\n"), @@ -5821,7 +6001,7 @@ disassemble_section (section, file) static int dump_section (section, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; FILE * file; { bfd_size_type bytes; @@ -6044,7 +6224,7 @@ static int debug_line_pointer_size = 4; static int display_debug_lines (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -6301,7 +6481,7 @@ display_debug_lines (section, start, file) static int display_debug_pubnames (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -6764,7 +6944,7 @@ process_abbrev_section (start, end) static int display_debug_macinfo (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -6838,7 +7018,7 @@ display_debug_macinfo (section, start, file) static int display_debug_abbrev (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -7192,7 +7372,7 @@ decode_location_expression (data, pointer_size, length) printf ("DW_OP_nop"); break; - /* DWARF 2.1 extensions. */ + /* DWARF 3 extensions. */ case DW_OP_push_object_address: printf ("DW_OP_push_object_address"); break; @@ -7204,8 +7384,13 @@ decode_location_expression (data, pointer_size, length) printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4)); data += 4; break; - case DW_OP_calli: - printf ("DW_OP_calli"); + case DW_OP_call_ref: + printf ("DW_OP_call_ref"); + break; + + /* GNU extensions. */ + case DW_OP_GNU_push_tls_address: + printf ("DW_OP_GNU_push_tls_address"); break; default: @@ -7230,8 +7415,8 @@ static void load_debug_loc (file) FILE * file; { - Elf32_Internal_Shdr * sec; - unsigned int i; + Elf_Internal_Shdr * sec; + unsigned int i; /* If it is already loaded, do nothing. */ if (debug_loc_contents != NULL) @@ -7268,7 +7453,7 @@ free_debug_loc () static int display_debug_loc (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -7280,13 +7465,16 @@ display_debug_loc (section, start, file) addr = section->sh_addr; bytes = section->sh_size; section_end = start + bytes; + if (bytes == 0) { printf (_("\nThe .debug_loc section is empty.\n")); return 0; } + printf (_("Contents of the .debug_loc section:\n\n")); printf (_("\n Offset Begin End Expression\n")); + while (start < section_end) { unsigned long begin; @@ -7337,8 +7525,8 @@ static void load_debug_str (file) FILE * file; { - Elf32_Internal_Shdr * sec; - unsigned int i; + Elf_Internal_Shdr * sec; + unsigned int i; /* If it is already loaded, do nothing. */ if (debug_str_contents != NULL) @@ -7385,10 +7573,9 @@ fetch_indirect_string (offset) return debug_str_contents + offset; } - static int display_debug_str (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -7446,7 +7633,6 @@ display_debug_str (section, start, file) return 1; } - static unsigned char * read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size) unsigned long attribute; @@ -7575,8 +7761,8 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size) break; case DW_FORM_strp: - printf (_(" (indirect string, offset: 0x%lx): "), uvalue); - printf (fetch_indirect_string (uvalue)); + printf (_(" (indirect string, offset: 0x%lx): %s"), + uvalue, fetch_indirect_string (uvalue)); break; case DW_FORM_indirect: @@ -7765,7 +7951,7 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size) static int display_debug_info (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file; { @@ -7781,7 +7967,7 @@ display_debug_info (section, start, file) { DWARF2_External_CompUnit * external; DWARF2_Internal_CompUnit compunit; - Elf32_Internal_Shdr * relsec; + Elf_Internal_Shdr * relsec; unsigned char * tags; unsigned int i; int level; @@ -7800,20 +7986,21 @@ display_debug_info (section, start, file) break; } - /* Check for RELA relocations in the abbrev_offset address, and - apply them. */ + /* Check for RELA relocations in the + abbrev_offset address, and apply them. */ for (relsec = section_headers; relsec < section_headers + elf_header.e_shnum; ++relsec) { unsigned long nrelas; Elf_Internal_Rela *rela, *rp; - Elf32_Internal_Shdr *symsec; + Elf_Internal_Shdr *symsec; Elf_Internal_Sym *symtab; Elf_Internal_Sym *sym; if (relsec->sh_type != SHT_RELA - || SECTION_HEADER (relsec->sh_info) != section) + || SECTION_HEADER (relsec->sh_info) != section + || relsec->sh_size == 0) continue; if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, @@ -7834,7 +8021,8 @@ display_debug_info (section, start, file) { sym = symtab + ELF32_R_SYM (rp->r_info); - if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION) + if (ELF32_R_SYM (rp->r_info) != 0 + && ELF32_ST_TYPE (sym->st_info) != STT_SECTION) { warn (_("Skipping unexpected symbol type %u\n"), ELF32_ST_TYPE (sym->st_info)); @@ -7845,7 +8033,8 @@ display_debug_info (section, start, file) { sym = symtab + ELF64_R_SYM (rp->r_info); - if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION) + if (ELF64_R_SYM (rp->r_info) != 0 + && ELF64_ST_TYPE (sym->st_info) != STT_SECTION) { warn (_("Skipping unexpected symbol type %u\n"), ELF64_ST_TYPE (sym->st_info)); @@ -7853,7 +8042,7 @@ display_debug_info (section, start, file) } } - compunit.cu_abbrev_offset += rp->r_addend; + compunit.cu_abbrev_offset = rp->r_addend; break; } @@ -7880,10 +8069,9 @@ display_debug_info (section, start, file) free_abbrevs (); /* Read in the abbrevs used by this compilation unit. */ - { - Elf32_Internal_Shdr * sec; - unsigned char * begin; + Elf_Internal_Shdr * sec; + unsigned char * begin; /* Locate the .debug_abbrev section and process it. */ for (i = 0, sec = section_headers; @@ -7969,7 +8157,7 @@ display_debug_info (section, start, file) static int display_debug_aranges (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -8180,7 +8368,7 @@ size_of_encoded_value (encoding) static int display_debug_frames (section, start, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned char * start; FILE * file ATTRIBUTE_UNUSED; { @@ -8213,7 +8401,11 @@ display_debug_frames (section, start, file) length = byte_get (start, 4); start += 4; if (length == 0) - return 1; + { + printf ("\n%08lx ZERO terminator\n\n", + (unsigned long)(saved_start - section_start)); + return 1; + } if (length == 0xffffffff) { @@ -8367,6 +8559,8 @@ display_debug_frames (section, start, file) encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); fc->pc_begin = byte_get (start, encoded_ptr_size); + if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel) + fc->pc_begin += section->sh_addr + (start - section_start); start += encoded_ptr_size; fc->pc_range = byte_get (start, encoded_ptr_size); start += encoded_ptr_size; @@ -8546,6 +8740,8 @@ display_debug_frames (section, start, file) case DW_CFA_set_loc: vma = byte_get (start, encoded_ptr_size); + if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel) + vma += section->sh_addr + (start - section_start); start += encoded_ptr_size; if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); @@ -8762,9 +8958,9 @@ display_debug_frames (section, start, file) static int display_debug_not_supported (section, start, file) - Elf32_Internal_Shdr * section; - unsigned char * start ATTRIBUTE_UNUSED; - FILE * file ATTRIBUTE_UNUSED; + Elf_Internal_Shdr * section; + unsigned char * start ATTRIBUTE_UNUSED; + FILE * file ATTRIBUTE_UNUSED; { printf (_("Displaying the debug contents of section %s is not yet supported.\n"), SECTION_NAME (section)); @@ -8777,9 +8973,9 @@ display_debug_not_supported (section, start, file) that all compilation units have the same address size. */ static int prescan_debug_info (section, start, file) - Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED; - unsigned char * start; - FILE * file ATTRIBUTE_UNUSED; + Elf_Internal_Shdr * section ATTRIBUTE_UNUSED; + unsigned char * start; + FILE * file ATTRIBUTE_UNUSED; { DWARF2_External_CompUnit * external; @@ -8796,8 +8992,8 @@ prescan_debug_info (section, start, file) struct { const char * const name; - int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); - int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); + int (* display) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); + int (* prescan) PARAMS ((Elf_Internal_Shdr *, unsigned char *, FILE *)); } debug_displays[] = { @@ -8821,7 +9017,7 @@ debug_displays[] = static int display_debug_section (section, file) - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; FILE * file; { char * name = SECTION_NAME (section); @@ -8868,7 +9064,7 @@ static int process_section_contents (file) FILE * file; { - Elf32_Internal_Shdr * section; + Elf_Internal_Shdr * section; unsigned int i; if (! do_dump) @@ -9342,6 +9538,86 @@ process_mips_specific (file) return 1; } +static int +process_gnu_liblist (file) + FILE * file; +{ + Elf_Internal_Shdr * section, * string_sec; + Elf32_External_Lib * elib; + char * strtab; + size_t cnt; + unsigned i; + + if (! do_arch) + return 0; + + for (i = 0, section = section_headers; + i < elf_header.e_shnum; + i++, section ++) + { + switch (section->sh_type) + { + case SHT_GNU_LIBLIST: + elib = ((Elf32_External_Lib *) + get_data (NULL, file, section->sh_offset, section->sh_size, + _("liblist"))); + + if (elib == NULL) + break; + string_sec = SECTION_HEADER (section->sh_link); + + strtab = (char *) get_data (NULL, file, string_sec->sh_offset, + string_sec->sh_size, + _("liblist string table")); + + if (strtab == NULL + || section->sh_entsize != sizeof (Elf32_External_Lib)) + { + free (elib); + break; + } + + printf (_("\nLibrary list section '%s' contains %lu entries:\n"), + SECTION_NAME (section), + (long) (section->sh_size / sizeof (Elf32_External_Lib))); + + puts (" Library Time Stamp Checksum Version Flags"); + + for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib); + ++cnt) + { + Elf32_Lib liblist; + time_t time; + char timebuf[20]; + struct tm * tmp; + + liblist.l_name = BYTE_GET (elib[cnt].l_name); + time = BYTE_GET (elib[cnt].l_time_stamp); + liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum); + liblist.l_version = BYTE_GET (elib[cnt].l_version); + liblist.l_flags = BYTE_GET (elib[cnt].l_flags); + + tmp = gmtime (&time); + sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u", + tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + printf ("%3lu: ", (unsigned long) cnt); + if (do_wide) + printf ("%-20s", strtab + liblist.l_name); + else + printf ("%-20.20s", strtab + liblist.l_name); + printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum, + liblist.l_version, liblist.l_flags); + } + + free (elib); + } + } + + return 1; +} + static const char * get_note_type (e_type) unsigned e_type; @@ -9436,7 +9712,7 @@ get_netbsd_elfcore_note_type (e_type) If the value of namesz is zero, there is no name present. */ static int process_note (pnote) - Elf32_Internal_Note * pnote; + Elf_Internal_Note * pnote; { const char *nt; @@ -9492,7 +9768,7 @@ process_corefile_note_segment (file, offset, length) while (external < (Elf_External_Note *)((char *) pnotes + length)) { Elf_External_Note * next; - Elf32_Internal_Note inote; + Elf_Internal_Note inote; char * temp = NULL; inote.type = BYTE_GET (external->type); @@ -9711,12 +9987,15 @@ get_file_header (file) elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx); } - /* There may be some extensions in the first section header. Don't - bomb if we can't read it. */ - if (is_32bit_elf) - get_32bit_section_headers (file, 1); - else - get_64bit_section_headers (file, 1); + if (elf_header.e_shoff) + { + /* There may be some extensions in the first section header. Don't + bomb if we can't read it. */ + if (is_32bit_elf) + get_32bit_section_headers (file, 1); + else + get_64bit_section_headers (file, 1); + } return 1; } @@ -9766,11 +10045,18 @@ process_file (file_name) return 1; } - process_section_headers (file); + if (! process_section_headers (file)) + { + /* Without loaded section headers we + cannot process lots of things. */ + do_unwind = do_version = do_dump = do_arch = 0; - process_program_headers (file); + if (! do_using_dynamic) + do_syms = do_reloc = 0; + } - process_dynamic_segment (file); + if (process_program_headers (file)) + process_dynamic_segment (file); process_relocs (file); @@ -9786,6 +10072,8 @@ process_file (file_name) process_corefile_contents (file); + process_gnu_liblist (file); + process_arch_specific (file); fclose (file);