X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=ea0aa023701ef018ccf1d3e992207a7eea5bb8a2;hb=fd31a1711cf8813860353e9196cdfdfbbdd749d4;hp=da706c24a0334953536eff5964bacda84014a9ab;hpb=285d1771e796256eb31ae133bdcb13df1f60c3e9;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index da706c24a0..ea0aa02370 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -49,34 +49,41 @@ #define RELOC_MACROS_GEN_FUNC -#include "elf/i386.h" -#include "elf/v850.h" -#include "elf/ppc.h" -#include "elf/mips.h" #include "elf/alpha.h" +#include "elf/arc.h" #include "elf/arm.h" -#include "elf/m68k.h" -#include "elf/sparc.h" -#include "elf/m32r.h" +#include "elf/avr.h" +#include "elf/cris.h" #include "elf/d10v.h" #include "elf/d30v.h" -#include "elf/sh.h" -#include "elf/mn10200.h" -#include "elf/mn10300.h" -#include "elf/hppa.h" -#include "elf/h8.h" -#include "elf/arc.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" -#include "elf/i960.h" +#include "elf/mn10200.h" +#include "elf/mn10300.h" +#include "elf/or32.h" #include "elf/pj.h" -#include "elf/avr.h" -#include "elf/ia64.h" -#include "elf/cris.h" -#include "elf/i860.h" -#include "elf/x86-64.h" +#include "elf/ppc.h" #include "elf/s390.h" +#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" #include "bucomm.h" @@ -126,6 +133,7 @@ int do_debug_frames; int do_debug_frames_interp; int do_debug_macinfo; int do_debug_str; +int do_debug_loc; int do_arch; int do_notes; int is_32bit_elf; @@ -226,10 +234,13 @@ static int display_debug_aranges PARAMS ((Elf32_Internal_Sh 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 unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *)); static void load_debug_str PARAMS ((FILE *)); static void free_debug_str PARAMS ((void)); static const char * fetch_indirect_string PARAMS ((unsigned long)); +static void load_debug_loc PARAMS ((FILE *)); +static void free_debug_loc PARAMS ((void)); static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int)); static int process_extended_line_op PARAMS ((unsigned char *, int, int)); static void reset_state_machine PARAMS ((int)); @@ -255,6 +266,7 @@ 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; @@ -516,7 +528,7 @@ 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. */ @@ -529,7 +541,7 @@ print_symbol (width, symbol) printf (symbol); else if (width < 0) printf ("%-*.*s", width, width, symbol); - else + else printf ("%-.*s", width, symbol); } @@ -596,6 +608,9 @@ guess_is_rela (e_machine) case EM_386: case EM_486: case EM_960: + case EM_DLX: + case EM_OPENRISC: + case EM_OR32: case EM_M32R: case EM_CYGNUS_M32R: case EM_D10V: @@ -624,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: @@ -637,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: @@ -656,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; @@ -842,29 +860,49 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) if (is_32bit_elf) { if (is_rela) - printf - (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n")); + { + if (do_wide) + printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n")); + else + printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n")); + } else - printf - (_(" Offset Info Type Symbol's Value Symbol's Name\n")); + { + if (do_wide) + printf (_(" Offset Info Type Sym. Value Symbol's Name\n")); + else + printf (_(" Offset Info Type Sym.Value Sym. Name\n")); + } } else { if (is_rela) - printf - (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n")); + { + if (do_wide) + printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n")); + else + printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n")); + } else - printf - (_(" Offset Info Type Symbol's Value Symbol's Name\n")); + { + if (do_wide) + printf (_(" Offset Info Type Symbol's Value Symbol's Name\n")); + else + printf (_(" Offset Info Type Sym. Value Sym. Name\n")); + } } for (i = 0; i < rel_size; i++) { const char * rtype; + const char * rtype2 = NULL; + const char * rtype3 = NULL; bfd_vma offset; bfd_vma info; bfd_vma symtab_index; bfd_vma type; + bfd_vma type2 = (bfd_vma) NULL; + bfd_vma type3 = (bfd_vma) NULL; if (is_rela) { @@ -884,10 +922,16 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) } else { - if (elf_header.e_machine == EM_SPARCV9) - type = ELF64_R_TYPE_ID (info); + if (elf_header.e_machine == EM_MIPS) + { + type = ELF64_MIPS_R_TYPE (info); + type2 = ELF64_MIPS_R_TYPE2 (info); + type3 = ELF64_MIPS_R_TYPE3 (info); + } + else if (elf_header.e_machine == EM_SPARCV9) + type = ELF64_R_TYPE_ID (info); else - type = ELF64_R_TYPE (info); + type = ELF64_R_TYPE (info); /* The #ifdef BFD64 below is to prevent a compile time warning. We know that if we do not have a 64 bit data type that we will never execute this code anyway. */ @@ -907,13 +951,18 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) else { #ifdef _bfd_int64_low - printf ("%8.8lx%8.8lx %8.8lx%8.8lx ", + printf (do_wide + ? "%8.8lx%8.8lx %8.8lx%8.8lx " + : "%4.4lx%8.8lx %4.4lx%8.8lx ", _bfd_int64_high (offset), _bfd_int64_low (offset), _bfd_int64_high (info), _bfd_int64_low (info)); #else - printf ("%16.16lx %16.16lx ", offset, info); + printf (do_wide + ? "%16.16lx %16.16lx " + : "%12.12lx %12.12lx ", + offset, info); #endif } @@ -933,6 +982,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; @@ -968,6 +1022,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) rtype = elf_d30v_reloc_type (type); break; + case EM_DLX: + rtype = elf_dlx_reloc_type (type); + break; + case EM_SH: rtype = elf_sh_reloc_type (type); break; @@ -987,6 +1045,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; @@ -1003,6 +1065,11 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) case EM_MIPS: case EM_MIPS_RS3_LE: rtype = elf_mips_reloc_type (type); + if (!is_32bit_elf) + { + rtype2 = elf_mips_reloc_type (type2); + rtype3 = elf_mips_reloc_type (type3); + } break; case EM_ALPHA: @@ -1027,6 +1094,11 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) rtype = elf_h8_reloc_type (type); break; + case EM_OPENRISC: + case EM_OR32: + rtype = elf_or32_reloc_type (type); + break; + case EM_PJ: case EM_PJ_OLD: rtype = elf_pj_reloc_type (type); @@ -1047,24 +1119,37 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) rtype = elf_x86_64_reloc_type (type); break; - case EM_S390_OLD: - case EM_S390: - rtype = elf_s390_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); + break; 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) #ifdef _bfd_int64_low - printf (_("unrecognised: %-7lx"), _bfd_int64_low (type)); + printf (_("unrecognized: %-7lx"), _bfd_int64_low (type)); #else - printf (_("unrecognised: %-7lx"), type); + printf (_("unrecognized: %-7lx"), type); #endif else - printf ("%-21.21s", rtype); + printf (do_wide ? "%-21.21s" : "%-17.17s", rtype); if (symtab_index) { @@ -1078,14 +1163,14 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) printf (" "); print_vma (psym->st_value, LONG_HEX); - printf (" "); + printf (is_32bit_elf ? " " : " "); if (psym->st_name == 0) - print_symbol (-25, SECTION_NAME (section_headers + psym->st_shndx)); + print_symbol (22, SECTION_NAME (section_headers + psym->st_shndx)); else if (strtab == NULL) printf (_(""), psym->st_name); else - print_symbol (-25, strtab + psym->st_name); + print_symbol (22, strtab + psym->st_name); if (is_rela) printf (" + %lx", (unsigned long) relas [i].r_addend); @@ -1093,7 +1178,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) } else if (is_rela) { - printf ("%*c", is_32bit_elf ? 34 : 26, ' '); + printf ("%*c", is_32bit_elf ? (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' '); print_vma (relas[i].r_addend, LONG_HEX); } @@ -1102,6 +1187,33 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info)); putchar ('\n'); + + if (! is_32bit_elf && elf_header.e_machine == EM_MIPS) + { + printf (" Type2: "); + + if (rtype2 == NULL) +#ifdef _bfd_int64_low + printf (_("unrecognized: %-7lx"), _bfd_int64_low (type2)); +#else + printf (_("unrecognized: %-7lx"), type2); +#endif + else + printf ("%-17.17s", rtype2); + + printf("\n Type3: "); + + if (rtype3 == NULL) +#ifdef _bfd_int64_low + printf (_("unrecognized: %-7lx"), _bfd_int64_low (type3)); +#else + printf (_("unrecognized: %-7lx"), type3); +#endif + else + printf ("%-17.17s", rtype3); + + putchar ('\n'); + } } if (is_rela) @@ -1185,6 +1297,8 @@ get_ppc64_dynamic_type (type) switch (type) { case DT_PPC64_GLINK: return "PPC64_GLINK"; + case DT_PPC64_OPD: return "PPC64_OPD"; + case DT_PPC64_OPDSZ: return "PPC64_OPDSZ"; default: return NULL; } @@ -1288,6 +1402,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)) { @@ -1425,6 +1545,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"; @@ -1458,6 +1579,11 @@ get_machine_name (e_machine) case EM_S390_OLD: case EM_S390: return "IBM S/390"; case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core"; + 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; @@ -1492,7 +1618,7 @@ decode_ARM_machine_flags (e_flags, buf) switch (eabi) { default: - strcat (buf, ", "); + strcat (buf, ", "); if (e_flags) unknown = 1; break; @@ -1626,10 +1752,12 @@ get_machine_flags (e_flags, e_machine) decode_ARM_machine_flags (e_flags, buf); break; - case EM_68K: - if (e_flags & EF_CPU32) - strcat (buf, ", cpu32"); - break; + case EM_68K: + if (e_flags & EF_CPU32) + strcat (buf, ", cpu32"); + if (e_flags & EF_M68000) + strcat (buf, ", m68000"); + break; case EM_PPC: if (e_flags & EF_PPC_EMB) @@ -1820,6 +1948,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; } } @@ -1906,6 +2043,7 @@ get_segment_type (p_type) case PT_NOTE: return "NOTE"; case PT_SHLIB: return "SHLIB"; case PT_PHDR: return "PHDR"; + case PT_TLS: return "TLS"; case PT_GNU_EH_FRAME: return "GNU_EH_FRAME"; @@ -2078,6 +2216,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)) @@ -2117,6 +2256,8 @@ get_section_type_name (sh_type) } } +#define OPTION_DEBUG_DUMP 512 + struct option options [] = { {"all", no_argument, 0, 'a'}, @@ -2136,7 +2277,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'}, @@ -2151,35 +2292,39 @@ struct option options [] = static void usage () { - fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n")); - fprintf (stdout, _(" Options are:\n")); - fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V -A -I\n")); - fprintf (stdout, _(" -h or --file-header Display the ELF file header\n")); - fprintf (stdout, _(" -l or --program-headers or --segments\n")); - fprintf (stdout, _(" Display the program headers\n")); - fprintf (stdout, _(" -S or --section-headers or --sections\n")); - fprintf (stdout, _(" Display the sections' header\n")); - fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n")); - fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n")); - fprintf (stdout, _(" -n or --notes Display the core notes (if present)\n")); - fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n")); - fprintf (stdout, _(" -u or --unwind Display the unwind info (if present)\n")); - fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n")); - fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n")); - fprintf (stdout, _(" -A or --arch-specific Display architecture specific information (if any).\n")); - fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n")); - fprintf (stdout, _(" -x or --hex-dump=\n")); - fprintf (stdout, _(" Dump the contents of section \n")); - fprintf (stdout, _(" -w[liaprmfs] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]\n")); - fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n")); + fprintf (stdout, _("Usage: readelf elf-file(s)\n")); + fprintf (stdout, _(" Display information about the contents of ELF format files\n")); + fprintf (stdout, _(" Options are:\n\ + -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\ + -h --file-header Display the ELF file header\n\ + -l --program-headers Display the program headers\n\ + --segments An alias for --program-headers\n\ + -S --section-headers Display the sections' header\n\ + --sections An alias for --section-headers\n\ + -e --headers Equivalent to: -h -l -S\n\ + -s --syms Display the symbol table\n\ + --symbols An alias for --syms\n\ + -n --notes Display the core notes (if present)\n\ + -r --relocs Display the relocations (if present)\n\ + -u --unwind Display the unwind info (if present)\n\ + -d --dynamic Display the dynamic segment (if present)\n\ + -V --version-info Display the version sections (if present)\n\ + -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[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, _(" -i or --instruction-dump=\n")); - fprintf (stdout, _(" Disassemble the contents of section \n")); + fprintf (stdout, _("\ + -i --instruction-dump=\n\ + Disassemble the contents of section \n")); #endif - fprintf (stdout, _(" -I or --histogram Display histogram of bucket list lengths\n")); - fprintf (stdout, _(" -v or --version Display the version number of readelf\n")); - fprintf (stdout, _(" -W or --wide Don't split lines or truncate symbols to fit into 80 columns\n")); - fprintf (stdout, _(" -H or --help Display this information\n")); + fprintf (stdout, _("\ + -I --histogram Display histogram of bucket list lengths\n\ + -W --wide Allow output width to exceed 80 characters\n\ + -H --help Display this information\n\ + -v --version Display the version number of readelf\n")); fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (0); @@ -2308,7 +2453,7 @@ parse_args (argc, argv) else { unsigned int index = 0; - + do_debugging = 0; while (optarg[index]) @@ -2355,12 +2500,99 @@ parse_args (argc, argv) do_debug_str = 1; break; + case 'o': + case 'O': + do_debug_loc = 1; + break; + default: - warn (_("Unrecognised debug option '%s'\n"), optarg); + warn (_("Unrecognized debug option '%s'\n"), optarg); break; } } 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 ++; @@ -2674,8 +2906,10 @@ process_program_headers (file) if (do_segments) { - printf - (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : ""); + if (elf_header.e_phnum > 1) + printf (_("\nProgram Headers:\n")); + else + printf (_("\nProgram Headers:\n")); if (is_32bit_elf) printf @@ -3113,6 +3347,7 @@ get_elf_section_flags (sh_flags) case SHF_LINK_ORDER: strcat (buff, "L"); break; case SHF_OS_NONCONFORMING: strcat (buff, "O"); break; case SHF_GROUP: strcat (buff, "G"); break; + case SHF_TLS: strcat (buff, "T"); break; default: if (flag & SHF_MASKOS) @@ -3221,7 +3456,8 @@ process_section_headers (file) } else if ((do_debugging || do_debug_info || do_debug_abbrevs || do_debug_lines || do_debug_pubnames || do_debug_aranges - || do_debug_frames || do_debug_macinfo || do_debug_str) + || do_debug_frames || do_debug_macinfo || do_debug_str + || do_debug_loc) && strncmp (name, ".debug_", 7) == 0) { name += 7; @@ -3235,6 +3471,7 @@ process_section_headers (file) || (do_debug_frames && (strcmp (name, "frame") == 0)) || (do_debug_macinfo && (strcmp (name, "macinfo") == 0)) || (do_debug_str && (strcmp (name, "str") == 0)) + || (do_debug_loc && (strcmp (name, "loc") == 0)) ) request_dump (i, DEBUG_DUMP); } @@ -3249,7 +3486,10 @@ process_section_headers (file) if (! do_sections) return 1; - printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : ""); + if (elf_header.e_shnum > 1) + printf (_("\nSection Headers:\n")); + else + printf (_("\nSection Header:\n")); if (is_32bit_elf) printf @@ -3334,13 +3574,13 @@ process_section_headers (file) { putchar (' '); print_vma (section->sh_addr, LONG_HEX); - if ((long) section->sh_offset == section->sh_offset) - printf (" %8.8lx", (unsigned long) section->sh_offset); - else - { - printf (" "); - print_vma (section->sh_offset, LONG_HEX); - } + if ((long) section->sh_offset == section->sh_offset) + printf (" %8.8lx", (unsigned long) section->sh_offset); + else + { + printf (" "); + print_vma (section->sh_offset, LONG_HEX); + } printf ("\n "); print_vma (section->sh_size, LONG_HEX); printf (" "); @@ -3455,7 +3695,7 @@ process_relocs (file) if (string_table == NULL) printf ("%d", section->sh_name); else - printf ("'%s'", SECTION_NAME (section)); + printf (_("'%s'"), SECTION_NAME (section)); printf (_(" at offset 0x%lx contains %lu entries:\n"), rel_offset, (unsigned long) (rel_size / section->sh_entsize)); @@ -3610,13 +3850,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" : "", @@ -3888,7 +4128,7 @@ process_unwind (file) if (string_table == NULL) printf ("%d", unwsec->sh_name); else - printf ("'%s'", SECTION_NAME (unwsec)); + printf (_("'%s'"), SECTION_NAME (unwsec)); } else { @@ -3902,7 +4142,7 @@ process_unwind (file) if (string_table == NULL) printf ("%d", unwsec->sh_name); else - printf ("'%s'", SECTION_NAME (unwsec)); + printf (_("'%s'"), SECTION_NAME (unwsec)); printf (_(" at offset 0x%lx contains %lu entries:\n"), (unsigned long) unwsec->sh_offset, @@ -4059,6 +4299,7 @@ dynamic_segment_parisc_val (entry) print_vma (entry->d_un.d_ptr, PREFIX_HEX); break; } + putchar ('\n'); } static int @@ -4151,7 +4392,10 @@ static const char * get_dynamic_flags (flags) bfd_vma flags; { - static char buff [64]; + static char buff [128]; + char *p = buff; + + *p = '\0'; while (flags) { bfd_vma flag; @@ -4159,14 +4403,20 @@ get_dynamic_flags (flags) flag = flags & - flags; flags &= ~ flag; + if (p != buff) + *p++ = ' '; + switch (flag) { - case DF_ORIGIN: strcat (buff, "ORIGIN "); break; - case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break; - case DF_TEXTREL: strcat (buff, "TEXTREL "); break; - case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break; - default: strcat (buff, "unknown "); break; + case DF_ORIGIN: strcpy (p, "ORIGIN"); break; + case DF_SYMBOLIC: strcpy (p, "SYMBOLIC"); break; + case DF_TEXTREL: strcpy (p, "TEXTREL"); break; + case DF_BIND_NOW: strcpy (p, "BIND_NOW"); break; + case DF_STATIC_TLS: strcpy (p, "STATIC_TLS"); break; + default: strcpy (p, "unknown"); break; } + + p = strchr (p, '\0'); } return buff; } @@ -4352,7 +4602,7 @@ process_dynamic_segment (file) { case DT_FLAGS: if (do_dynamic) - printf ("%s", get_dynamic_flags (entry->d_un.d_val)); + puts (get_dynamic_flags (entry->d_un.d_val)); break; case DT_AUXILIARY: @@ -4400,11 +4650,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"); @@ -4426,11 +4678,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"); @@ -4457,6 +4711,7 @@ process_dynamic_segment (file) else { unsigned long int val = entry->d_un.d_val; + if (val & DF_1_NOW) { printf (" NOW"); @@ -4614,6 +4869,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); @@ -4660,6 +4917,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: @@ -5161,6 +5434,7 @@ get_symbol_type (type) case STT_SECTION: return "SECTION"; case STT_FILE: return "FILE"; case STT_COMMON: return "COMMON"; + case STT_TLS: return "TLS"; default: if (type >= STT_LOPROC && type <= STT_HIPROC) { @@ -6078,12 +6352,12 @@ display_debug_lines (section, start, file) state_machine_regs.line += adv; printf (_(" and Line by %d to %d\n"), adv, state_machine_regs.line); - } - else switch (op_code) + } + else switch (op_code) { case DW_LNS_extended_op: data += process_extended_line_op (data, info.li_default_is_stmt, - debug_line_pointer_size); + debug_line_pointer_size); break; case DW_LNS_copy: @@ -6152,17 +6426,17 @@ display_debug_lines (section, start, file) case DW_LNS_set_prologue_end: printf (_(" Set prologue_end to true\n")); break; - + case DW_LNS_set_epilogue_begin: printf (_(" Set epilogue_begin to true\n")); break; - + case DW_LNS_set_isa: adv = read_leb128 (data, & bytes_read, 0); data += bytes_read; printf (_(" Set ISA to %d\n"), adv); break; - + default: printf (_(" Unknown opcode %d with operands: "), op_code); { @@ -6438,6 +6712,7 @@ get_AT_name (attribute) case DW_AT_src_coords: return "DW_AT_src_coords"; case DW_AT_body_begin: return "DW_AT_body_begin"; case DW_AT_body_end: return "DW_AT_body_end"; + case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; default: { static char buffer [100]; @@ -7107,6 +7382,112 @@ decode_location_expression (data, pointer_size, length) } } +static const char * debug_loc_contents; +static bfd_vma debug_loc_size; + +static void +load_debug_loc (file) + FILE * file; +{ + Elf32_Internal_Shdr * sec; + unsigned int i; + + /* If it is already loaded, do nothing. */ + if (debug_loc_contents != NULL) + return; + + /* Locate the .debug_loc section. */ + for (i = 0, sec = section_headers; + i < elf_header.e_shnum; + i ++, sec ++) + if (strcmp (SECTION_NAME (sec), ".debug_loc") == 0) + break; + + if (i == elf_header.e_shnum || sec->sh_size == 0) + return; + + debug_loc_size = sec->sh_size; + + debug_loc_contents = ((char *) + get_data (NULL, file, sec->sh_offset, sec->sh_size, + _("debug_loc section data"))); +} + +static void +free_debug_loc () +{ + if (debug_loc_contents == NULL) + return; + + free ((char *) debug_loc_contents); + debug_loc_contents = NULL; + debug_loc_size = 0; +} + + +static int +display_debug_loc (section, start, file) + Elf32_Internal_Shdr * section; + unsigned char * start; + FILE * file ATTRIBUTE_UNUSED; +{ + unsigned char *section_end; + unsigned long bytes; + unsigned char *section_begin = start; + bfd_vma addr; + + 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; + unsigned long end; + unsigned short length; + unsigned long offset; + + offset = start - section_begin; + + while (1) + { + /* Normally, the lists in the debug_loc section are related to a + given compilation unit, and thus, we would use the + pointer size of that compilation unit. However, since we are + displaying it seperately here, we either have to store + pointer sizes of all compilation units, or assume they don't + change. We assume, like the debug_line display, that + it doesn't change. */ + begin = byte_get (start, debug_line_pointer_size); + start += debug_line_pointer_size; + end = byte_get (start, debug_line_pointer_size); + start += debug_line_pointer_size; + + if (begin == 0 && end == 0) + break; + + begin += addr; + end += addr; + + length = byte_get (start, 2); + start += 2; + + printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end); + decode_location_expression (start, debug_line_pointer_size, length); + printf (")\n"); + + start += length; + } + printf ("\n"); + } + return 1; +} static const char * debug_str_contents; static bfd_vma debug_str_size; @@ -7287,7 +7668,7 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size) data += bytes_read; printf (" %s", get_FORM_name (form)); return read_and_display_attr_value (attribute, form, data, cu_offset, - pointer_size); + pointer_size); } switch (form) @@ -7362,7 +7743,7 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size) break; default: - warn (_("Unrecognised form: %d\n"), form); + warn (_("Unrecognized form: %d\n"), form); break; } @@ -7511,6 +7892,12 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size) decode_location_expression (block_start, pointer_size, uvalue); printf (")"); } + else if (form == DW_FORM_data4) + { + printf ("("); + printf ("location list"); + printf (")"); + } break; default: @@ -7530,7 +7917,7 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size) { printf (" %-18s:", get_AT_name (attribute)); data = read_and_display_attr_value (attribute, form, data, cu_offset, - pointer_size); + pointer_size); printf ("\n"); return data; } @@ -7547,6 +7934,7 @@ display_debug_info (section, start, file) printf (_("The section %s contains:\n\n"), SECTION_NAME (section)); load_debug_str (file); + load_debug_loc (file); while (start < end) { @@ -7731,6 +8119,7 @@ display_debug_info (section, start, file) } free_debug_str (); + free_debug_loc (); printf ("\n"); @@ -8167,102 +8556,107 @@ display_debug_frames (section, start, file) about to interpret instructions for the chunk. */ if (do_debug_frames_interp) - { - /* Start by making a pass over the chunk, allocating storage - and taking note of what registers are used. */ - unsigned char * tmp = start; + { + /* Start by making a pass over the chunk, allocating storage + and taking note of what registers are used. */ + unsigned char * tmp = start; - while (start < block_end) - { - unsigned op, opa; - unsigned long reg; + while (start < block_end) + { + unsigned op, opa; + unsigned long reg; - op = * start ++; - opa = op & 0x3f; - if (op & 0xc0) - op &= 0xc0; + op = * start ++; + opa = op & 0x3f; + if (op & 0xc0) + op &= 0xc0; - /* Warning: if you add any more cases to this switch, be - sure to add them to the corresponding switch below. */ - switch (op) - { - case DW_CFA_advance_loc: - break; - case DW_CFA_offset: - LEB (); - frame_need_space (fc, opa); - fc->col_type[opa] = DW_CFA_undefined; - break; - case DW_CFA_restore: - frame_need_space (fc, opa); - fc->col_type[opa] = DW_CFA_undefined; - break; - case DW_CFA_set_loc: - start += encoded_ptr_size; - break; - case DW_CFA_advance_loc1: - start += 1; - break; - case DW_CFA_advance_loc2: - start += 2; - break; - case DW_CFA_advance_loc4: - start += 4; - break; - case DW_CFA_offset_extended: - reg = LEB (); LEB (); - frame_need_space (fc, reg); - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_restore_extended: - reg = LEB (); - frame_need_space (fc, reg); - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_undefined: - reg = LEB (); - frame_need_space (fc, reg); - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_same_value: - reg = LEB (); - frame_need_space (fc, reg); - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_register: - reg = LEB (); LEB (); - frame_need_space (fc, reg); - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_def_cfa: - LEB (); LEB (); - break; - case DW_CFA_def_cfa_register: - LEB (); - break; - case DW_CFA_def_cfa_offset: - LEB (); - break; -#ifndef DW_CFA_GNU_args_size -#define DW_CFA_GNU_args_size 0x2e -#endif - case DW_CFA_GNU_args_size: - LEB (); - break; -#ifndef DW_CFA_GNU_negative_offset_extended -#define DW_CFA_GNU_negative_offset_extended 0x2f -#endif - case DW_CFA_GNU_negative_offset_extended: - reg = LEB (); LEB (); - frame_need_space (fc, reg); - fc->col_type[reg] = DW_CFA_undefined; + /* Warning: if you add any more cases to this switch, be + sure to add them to the corresponding switch below. */ + switch (op) + { + case DW_CFA_advance_loc: + break; + case DW_CFA_offset: + LEB (); + frame_need_space (fc, opa); + fc->col_type[opa] = DW_CFA_undefined; + break; + case DW_CFA_restore: + frame_need_space (fc, opa); + fc->col_type[opa] = DW_CFA_undefined; + break; + case DW_CFA_set_loc: + start += encoded_ptr_size; + break; + case DW_CFA_advance_loc1: + start += 1; + break; + case DW_CFA_advance_loc2: + start += 2; + break; + case DW_CFA_advance_loc4: + start += 4; + break; + case DW_CFA_offset_extended: + reg = LEB (); LEB (); + frame_need_space (fc, reg); + fc->col_type[reg] = DW_CFA_undefined; + break; + case DW_CFA_restore_extended: + reg = LEB (); + frame_need_space (fc, reg); + fc->col_type[reg] = DW_CFA_undefined; + break; + case DW_CFA_undefined: + reg = LEB (); + frame_need_space (fc, reg); + fc->col_type[reg] = DW_CFA_undefined; + break; + case DW_CFA_same_value: + reg = LEB (); + frame_need_space (fc, reg); + fc->col_type[reg] = DW_CFA_undefined; + break; + case DW_CFA_register: + reg = LEB (); LEB (); + frame_need_space (fc, reg); + fc->col_type[reg] = DW_CFA_undefined; + break; + case DW_CFA_def_cfa: + LEB (); LEB (); + break; + case DW_CFA_def_cfa_register: + LEB (); + break; + case DW_CFA_def_cfa_offset: + LEB (); + break; + case DW_CFA_offset_extended_sf: + reg = LEB (); SLEB (); + frame_need_space (fc, reg); + fc->col_type[reg] = DW_CFA_undefined; + break; + case DW_CFA_def_cfa_sf: + LEB (); SLEB (); + break; + case DW_CFA_def_cfa_offset_sf: + SLEB (); + break; + case DW_CFA_GNU_args_size: + LEB (); + break; + case DW_CFA_GNU_negative_offset_extended: + reg = LEB (); LEB (); + frame_need_space (fc, reg); + fc->col_type[reg] = DW_CFA_undefined; - default: - break; - } - } - start = tmp; - } + default: + break; + } + } + start = tmp; + } /* Now we know what registers are used, make a second pass over the chunk, this time actually printing out the info. */ @@ -8279,16 +8673,16 @@ display_debug_frames (section, start, file) if (op & 0xc0) op &= 0xc0; - /* Warning: if you add any more cases to this switch, be - sure to add them to the corresponding switch above. */ + /* Warning: if you add any more cases to this switch, be + sure to add them to the corresponding switch above. */ switch (op) { case DW_CFA_advance_loc: if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); + frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc: %d to %08lx\n", - opa * fc->code_factor, + printf (" DW_CFA_advance_loc: %d to %08lx\n", + opa * fc->code_factor, fc->pc_begin + opa * fc->code_factor); fc->pc_begin += opa * fc->code_factor; break; @@ -8296,7 +8690,7 @@ display_debug_frames (section, start, file) case DW_CFA_offset: roffs = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_offset: r%d at cfa%+ld\n", + printf (" DW_CFA_offset: r%d at cfa%+ld\n", opa, roffs * fc->data_factor); fc->col_type[opa] = DW_CFA_offset; fc->col_offset[opa] = roffs * fc->data_factor; @@ -8304,7 +8698,7 @@ display_debug_frames (section, start, file) case DW_CFA_restore: if (! do_debug_frames_interp) - printf (" DW_CFA_restore: r%d\n", opa); + printf (" DW_CFA_restore: r%d\n", opa); fc->col_type[opa] = cie->col_type[opa]; fc->col_offset[opa] = cie->col_offset[opa]; break; @@ -8313,19 +8707,19 @@ display_debug_frames (section, start, file) vma = byte_get (start, encoded_ptr_size); start += encoded_ptr_size; if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); + frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma); + printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma); fc->pc_begin = vma; break; case DW_CFA_advance_loc1: ofs = byte_get (start, 1); start += 1; if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); + frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc1: %ld to %08lx\n", - ofs * fc->code_factor, + printf (" DW_CFA_advance_loc1: %ld to %08lx\n", + ofs * fc->code_factor, fc->pc_begin + ofs * fc->code_factor); fc->pc_begin += ofs * fc->code_factor; break; @@ -8333,10 +8727,10 @@ display_debug_frames (section, start, file) case DW_CFA_advance_loc2: ofs = byte_get (start, 2); start += 2; if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); + frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc2: %ld to %08lx\n", - ofs * fc->code_factor, + printf (" DW_CFA_advance_loc2: %ld to %08lx\n", + ofs * fc->code_factor, fc->pc_begin + ofs * fc->code_factor); fc->pc_begin += ofs * fc->code_factor; break; @@ -8344,10 +8738,10 @@ display_debug_frames (section, start, file) case DW_CFA_advance_loc4: ofs = byte_get (start, 4); start += 4; if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); + frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc4: %ld to %08lx\n", - ofs * fc->code_factor, + printf (" DW_CFA_advance_loc4: %ld to %08lx\n", + ofs * fc->code_factor, fc->pc_begin + ofs * fc->code_factor); fc->pc_begin += ofs * fc->code_factor; break; @@ -8365,7 +8759,7 @@ display_debug_frames (section, start, file) case DW_CFA_restore_extended: reg = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_restore_extended: r%ld\n", reg); + printf (" DW_CFA_restore_extended: r%ld\n", reg); fc->col_type[reg] = cie->col_type[reg]; fc->col_offset[reg] = cie->col_offset[reg]; break; @@ -8373,7 +8767,7 @@ display_debug_frames (section, start, file) case DW_CFA_undefined: reg = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_undefined: r%ld\n", reg); + printf (" DW_CFA_undefined: r%ld\n", reg); fc->col_type[reg] = DW_CFA_undefined; fc->col_offset[reg] = 0; break; @@ -8381,7 +8775,7 @@ display_debug_frames (section, start, file) case DW_CFA_same_value: reg = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_same_value: r%ld\n", reg); + printf (" DW_CFA_same_value: r%ld\n", reg); fc->col_type[reg] = DW_CFA_same_value; fc->col_offset[reg] = 0; break; @@ -8390,14 +8784,14 @@ display_debug_frames (section, start, file) reg = LEB (); roffs = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_register: r%ld\n", reg); + printf (" DW_CFA_register: r%ld\n", reg); fc->col_type[reg] = DW_CFA_register; fc->col_offset[reg] = roffs; break; case DW_CFA_remember_state: if (! do_debug_frames_interp) - printf (" DW_CFA_remember_state\n"); + printf (" DW_CFA_remember_state\n"); rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk)); rs->ncols = fc->ncols; rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int)); @@ -8410,7 +8804,7 @@ display_debug_frames (section, start, file) case DW_CFA_restore_state: if (! do_debug_frames_interp) - printf (" DW_CFA_restore_state\n"); + printf (" DW_CFA_restore_state\n"); rs = remembered_state; remembered_state = rs->next; frame_need_space (fc, rs->ncols-1); @@ -8425,39 +8819,61 @@ display_debug_frames (section, start, file) fc->cfa_reg = LEB (); fc->cfa_offset = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa: r%d ofs %d\n", + printf (" DW_CFA_def_cfa: r%d ofs %d\n", fc->cfa_reg, fc->cfa_offset); break; case DW_CFA_def_cfa_register: fc->cfa_reg = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg); + printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg); break; case DW_CFA_def_cfa_offset: fc->cfa_offset = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset); + printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset); break; case DW_CFA_nop: if (! do_debug_frames_interp) - printf (" DW_CFA_nop\n"); + printf (" DW_CFA_nop\n"); + break; + + case DW_CFA_offset_extended_sf: + reg = LEB (); + l = SLEB (); + frame_need_space (fc, reg); + if (! do_debug_frames_interp) + printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n", + reg, l * fc->data_factor); + fc->col_type[reg] = DW_CFA_offset; + fc->col_offset[reg] = l * fc->data_factor; + break; + + case DW_CFA_def_cfa_sf: + fc->cfa_reg = LEB (); + fc->cfa_offset = SLEB (); + if (! do_debug_frames_interp) + printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n", + fc->cfa_reg, fc->cfa_offset); + break; + + case DW_CFA_def_cfa_offset_sf: + fc->cfa_offset = SLEB (); + if (! do_debug_frames_interp) + printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset); break; -#ifndef DW_CFA_GNU_window_save -#define DW_CFA_GNU_window_save 0x2d -#endif case DW_CFA_GNU_window_save: if (! do_debug_frames_interp) - printf (" DW_CFA_GNU_window_save\n"); + printf (" DW_CFA_GNU_window_save\n"); break; case DW_CFA_GNU_args_size: ul = LEB (); if (! do_debug_frames_interp) - printf (" DW_CFA_GNU_args_size: %ld\n", ul); + printf (" DW_CFA_GNU_args_size: %ld\n", ul); break; case DW_CFA_GNU_negative_offset_extended: @@ -8465,12 +8881,23 @@ display_debug_frames (section, start, file) l = - LEB (); frame_need_space (fc, reg); if (! do_debug_frames_interp) - printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n", + printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n", reg, l * fc->data_factor); fc->col_type[reg] = DW_CFA_offset; fc->col_offset[reg] = l * fc->data_factor; break; + /* FIXME: How do we handle these? */ + case DW_CFA_def_cfa_expression: + fprintf (stderr, "unsupported DW_CFA_def_cfa_expression\n"); + start = block_end; + break; + + case DW_CFA_expression: + fprintf (stderr, "unsupported DW_CFA_expression\n"); + start = block_end; + break; + default: fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op); start = block_end; @@ -8478,7 +8905,7 @@ display_debug_frames (section, start, file) } if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); + frame_display_row (fc, &need_col_headers, &max_regs); start = block_end; } @@ -8542,7 +8969,7 @@ debug_displays[] = { ".eh_frame", display_debug_frames, NULL }, { ".debug_macinfo", display_debug_macinfo, NULL }, { ".debug_str", display_debug_str, NULL }, - + { ".debug_loc", display_debug_loc, NULL }, { ".debug_pubtypes", display_debug_not_supported, NULL }, { ".debug_ranges", display_debug_not_supported, NULL }, { ".debug_static_func", display_debug_not_supported, NULL }, @@ -8585,7 +9012,7 @@ display_debug_section (section, file) } if (i == -1) - printf (_("Unrecognised debug section: %s\n"), name); + printf (_("Unrecognized debug section: %s\n"), name); free (start); @@ -8617,11 +9044,11 @@ process_section_contents (file) int j; if (section->sh_size == 0) - continue; + continue; /* See if there is some pre-scan operation for this section. */ for (j = NUM_ELEM (debug_displays); j--;) - if (strcmp (debug_displays[j].name, name) == 0) + if (strcmp (debug_displays[j].name, name) == 0) { if (debug_displays[j].prescan != NULL) { @@ -8639,8 +9066,8 @@ process_section_contents (file) free (start); } - break; - } + break; + } } for (i = 0, section = section_headers; @@ -9009,7 +9436,7 @@ process_mips_specific (file) if (dynamic_symbols == NULL) { - error (_("conflict list with without table")); + error (_("conflict list found without a dynamic symbol table")); return 0; } @@ -9074,6 +9501,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; @@ -9092,7 +9599,7 @@ get_note_type (e_type) case NT_PSINFO: return _("NT_PSINFO (psinfo structure)"); case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)"); case NT_LWPSINFO: return _("NT_LWPSINFO (lwpsinfo_t structure)"); - case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)"); + case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus structure)"); default: sprintf (buff, _("Unknown note type: (0x%08x)"), e_type); return buff; @@ -9168,7 +9675,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; + Elf32_Internal_Note * pnote; { const char *nt; @@ -9223,6 +9730,7 @@ process_corefile_note_segment (file, offset, length) while (external < (Elf_External_Note *)((char *) pnotes + length)) { + Elf_External_Note * next; Elf32_Internal_Note inote; char * temp = NULL; @@ -9233,7 +9741,18 @@ process_corefile_note_segment (file, offset, length) inote.descdata = inote.namedata + align_power (inote.namesz, 2); inote.descpos = offset + (inote.descdata - (char *) pnotes); - external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2)); + next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2)); + + if (((char *) next) > (((char *) pnotes) + length)) + { + warn (_("corrupt note found at offset %x into core notes\n"), + ((char *) external) - ((char *) pnotes)); + warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"), + inote.type, inote.namesz, inote.descsz); + break; + } + + external = next; /* Verify that name is null terminated. It appears that at least one version of Linux (RedHat 6.0) generates corefiles that don't @@ -9431,12 +9950,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; } @@ -9506,6 +10028,8 @@ process_file (file_name) process_corefile_contents (file); + process_gnu_liblist (file); + process_arch_specific (file); fclose (file);