X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=5423c7fa25f309ba273cebcb8dd8510f5f4ed44e;hb=a06ea96464a2928865beb2ac6f12deb0464bfcd7;hp=c1bc2c5f8f40727dc2edcf091d04b961b0231d33;hpb=a7dbfd1c34af172f068c00d70d5759c797c2db52;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index c1bc2c5f8f..5423c7fa25 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -1,6 +1,6 @@ /* readelf.c -- display contents of an ELF format file Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2011 + 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Originally developed by Eric Youngdale @@ -42,14 +42,13 @@ ELF file than is provided by objdump. In particular it can display DWARF debugging information which (at the moment) objdump cannot. */ -#include "config.h" #include "sysdep.h" #include -#include #include #ifdef HAVE_ZLIB_H #include #endif +#include #if __GNUC__ >= 2 /* Define BFD64 here, even if our default architecture is 32 bit ELF @@ -92,6 +91,7 @@ #define RELOC_MACROS_GEN_FUNC +#include "elf/aarch64.h" #include "elf/alpha.h" #include "elf/arc.h" #include "elf/arm.h" @@ -103,6 +103,7 @@ #include "elf/d10v.h" #include "elf/d30v.h" #include "elf/dlx.h" +#include "elf/epiphany.h" #include "elf/fr30.h" #include "elf/frv.h" #include "elf/h8.h" @@ -133,6 +134,7 @@ #include "elf/pj.h" #include "elf/ppc.h" #include "elf/ppc64.h" +#include "elf/rl78.h" #include "elf/rx.h" #include "elf/s390.h" #include "elf/score.h" @@ -146,6 +148,7 @@ #include "elf/vax.h" #include "elf/x86-64.h" #include "elf/xc16x.h" +#include "elf/xgate.h" #include "elf/xstormy16.h" #include "elf/xtensa.h" @@ -271,9 +274,9 @@ print_mode; #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -#define GET_ELF_SYMBOLS(file, section) \ - (is_32bit_elf ? get_32bit_elf_symbols (file, section) \ - : get_64bit_elf_symbols (file, section)) +#define GET_ELF_SYMBOLS(file, section, sym_count) \ + (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \ + : get_64bit_elf_symbols (file, section, sym_count)) #define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length)) /* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has @@ -382,93 +385,89 @@ print_vma (bfd_vma vma, print_mode mode) return 0; } -/* Display a symbol on stdout. Handles the display of non-printing characters. +/* Display a symbol on stdout. Handles the display of control characters and + multibye characters. - If DO_WIDE is not true then format the symbol to be at most WIDTH characters, - truncating as necessary. If WIDTH is negative then format the string to be - exactly - WIDTH characters, truncating or padding as necessary. + Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true. + + If WIDTH is negative then ensure that the output is at least (- WIDTH) characters, + padding as necessary. Returns the number of emitted characters. */ static unsigned int print_symbol (int width, const char *symbol) { - const char *c; bfd_boolean extra_padding = FALSE; - unsigned int num_printed = 0; + int num_printed = 0; + mbstate_t state; + int width_remaining; - if (do_wide) - { - /* Set the width to a very large value. This simplifies the - code below. */ - width = INT_MAX; - } - else if (width < 0) + if (width < 0) { /* Keep the width positive. This also helps. */ width = - width; extra_padding = TRUE; - } + } - while (width) - { - int len; - - c = symbol; - - /* Look for non-printing symbols inside the symbol's name. - This test is triggered in particular by the names generated - by the assembler for local labels. */ - while (ISPRINT (*c)) - c++; - - len = c - symbol; - - if (len) - { - if (len > width) - len = width; + if (do_wide) + /* Set the remaining width to a very large value. + This simplifies the code below. */ + width_remaining = INT_MAX; + else + width_remaining = width; - printf ("%.*s", len, symbol); + /* Initialise the multibyte conversion state. */ + memset (& state, 0, sizeof (state)); - width -= len; - num_printed += len; - } + while (width_remaining) + { + size_t n; + wchar_t w; + const char c = *symbol++; - if (*c == 0 || width == 0) + if (c == 0) break; - /* Now display the non-printing character, if - there is room left in which to dipslay it. */ - if ((unsigned char) *c < 32) + /* Do not print control characters directly as they can affect terminal + settings. Such characters usually appear in the names generated + by the assembler for local labels. */ + if (ISCNTRL (c)) { - if (width < 2) + if (width_remaining < 2) break; - printf ("^%c", *c + 0x40); - - width -= 2; + printf ("^%c", c + 0x40); + width_remaining -= 2; num_printed += 2; } + else if (ISPRINT (c)) + { + putchar (c); + width_remaining --; + num_printed ++; + } else { - if (width < 6) - break; + /* Let printf do the hard work of displaying multibyte characters. */ + printf ("%.1s", symbol - 1); + width_remaining --; + num_printed ++; - printf ("<0x%.2x>", (unsigned char) *c); - - width -= 6; - num_printed += 6; + /* Try to find out how many bytes made up the character that was + just printed. Advance the symbol pointer past the bytes that + were displayed. */ + n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state); + if (n != (size_t) -1 && n != (size_t) -2 && n > 0) + symbol += (n - 1); } - - symbol = c + 1; } - if (extra_padding && width > 0) + if (extra_padding && num_printed < width) { /* Fill in the remaining spaces. */ - printf ("%-*s", width, " "); - num_printed += 2; + printf ("%-*s", width - num_printed, " "); + num_printed = width; } return num_printed; @@ -547,18 +546,20 @@ guess_is_rela (unsigned int e_machine) case EM_OPENRISC: case EM_OR32: case EM_SCORE: + case EM_XGATE: return FALSE; /* Targets that use RELA relocations. */ case EM_68K: case EM_860: + case EM_AARCH64: + case EM_ADAPTEVA_EPIPHANY: case EM_ALPHA: case EM_ALTERA_NIOS2: case EM_AVR: case EM_AVR_OLD: case EM_BLACKFIN: case EM_CR16: - case EM_CR16_OLD: case EM_CRIS: case EM_CRX: case EM_D30V: @@ -591,6 +592,7 @@ guess_is_rela (unsigned int e_machine) case EM_NIOS32: case EM_PPC64: case EM_PPC: + case EM_RL78: case EM_RX: case EM_S390: case EM_S390_OLD: @@ -607,6 +609,7 @@ guess_is_rela (unsigned int e_machine) case EM_VAX: case EM_X86_64: case EM_L1OM: + case EM_K1OM: case EM_XSTORMY16: case EM_XTENSA: case EM_XTENSA_OLD: @@ -653,7 +656,7 @@ slurp_rela_relocs (FILE * file, Elf32_External_Rela * erelas; erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); + rel_size, _("32-bit relocation data")); if (!erelas) return 0; @@ -683,7 +686,7 @@ slurp_rela_relocs (FILE * file, Elf64_External_Rela * erelas; erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); + rel_size, _("64-bit relocation data")); if (!erelas) return 0; @@ -751,7 +754,7 @@ slurp_rel_relocs (FILE * file, Elf32_External_Rel * erels; erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); + rel_size, _("32-bit relocation data")); if (!erels) return 0; @@ -780,7 +783,7 @@ slurp_rel_relocs (FILE * file, Elf64_External_Rel * erels; erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); + rel_size, _("64-bit relocation data")); if (!erels) return 0; @@ -982,6 +985,10 @@ dump_relocations (FILE * file, rtype = NULL; break; + case EM_AARCH64: + rtype = elf_aarch64_reloc_type (type); + break; + case EM_M32R: case EM_CYGNUS_M32R: rtype = elf_m32r_reloc_type (type); @@ -1138,6 +1145,7 @@ dump_relocations (FILE * file, case EM_X86_64: case EM_L1OM: + case EM_K1OM: rtype = elf_x86_64_reloc_type (type); break; @@ -1166,6 +1174,10 @@ dump_relocations (FILE * file, rtype = elf_vax_reloc_type (type); break; + case EM_ADAPTEVA_EPIPHANY: + rtype = elf_epiphany_reloc_type (type); + break; + case EM_IP2K: case EM_IP2K_OLD: rtype = elf_ip2k_reloc_type (type); @@ -1202,7 +1214,6 @@ dump_relocations (FILE * file, break; case EM_CR16: - case EM_CR16_OLD: rtype = elf_cr16_reloc_type (type); break; @@ -1211,6 +1222,10 @@ dump_relocations (FILE * file, rtype = elf_microblaze_reloc_type (type); break; + case EM_RL78: + rtype = elf_rl78_reloc_type (type); + break; + case EM_RX: rtype = elf_rx_reloc_type (type); break; @@ -1231,6 +1246,10 @@ dump_relocations (FILE * file, case EM_TILEPRO: rtype = elf_tilepro_reloc_type (type); break; + + case EM_XGATE: + rtype = elf_xgate_reloc_type (type); + break; } if (rtype == NULL) @@ -1331,7 +1350,8 @@ dump_relocations (FILE * file, && psym->st_shndx == SHN_MIPS_SUNDEFINED) sec_name = "SUNDEF"; else if ((elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM) + || elf_header.e_machine == EM_L1OM + || elf_header.e_machine == EM_K1OM) && psym->st_shndx == SHN_X86_64_LCOMMON) sec_name = "LARGE_COMMON"; else if (elf_header.e_machine == EM_IA_64 @@ -1370,9 +1390,13 @@ dump_relocations (FILE * file, } else if (is_rela) { - printf ("%*c", is_32bit_elf ? - (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' '); - print_vma (rels[i].r_addend, LONG_HEX); + bfd_signed_vma off = rels[i].r_addend; + + printf ("%*c", is_32bit_elf ? 12 : 20, ' '); + if (off < 0) + printf ("-%" BFD_VMA_FMT "x", - off); + else + printf ("%" BFD_VMA_FMT "x", off); } if (elf_header.e_machine == EM_SPARCV9 @@ -1812,6 +1836,7 @@ get_machine_name (unsigned e_machine) switch (e_machine) { case EM_NONE: return _("None"); + case EM_AARCH64: return "AArch64"; case EM_M32: return "WE32100"; case EM_SPARC: return "Sparc"; case EM_SPU: return "SPU"; @@ -1847,7 +1872,6 @@ get_machine_name (unsigned e_machine) case EM_IA_64: return "Intel IA-64"; case EM_MIPS_X: return "Stanford MIPS-X"; case EM_COLDFIRE: return "Motorola Coldfire"; - case EM_68HC12: return "Motorola M68HC12"; case EM_ALPHA: return "Alpha"; case EM_CYGNUS_D10V: case EM_D10V: return "d10v"; @@ -1856,7 +1880,7 @@ get_machine_name (unsigned e_machine) case EM_CYGNUS_M32R: case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)"; case EM_CYGNUS_V850: - case EM_V850: return "Renesas v850"; + case EM_V850: return "Renesas V850"; case EM_CYGNUS_MN10300: case EM_MN10300: return "mn10300"; case EM_CYGNUS_MN10200: @@ -1882,6 +1906,7 @@ get_machine_name (unsigned e_machine) case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller"; case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller"; case EM_68HC16: return "Motorola MC68HC16 Microcontroller"; + case EM_68HC12: return "Motorola MC68HC12 Microcontroller"; case EM_68HC11: return "Motorola MC68HC11 Microcontroller"; case EM_68HC08: return "Motorola MC68HC08 Microcontroller"; case EM_68HC05: return "Motorola MC68HC05 Microcontroller"; @@ -1899,6 +1924,7 @@ get_machine_name (unsigned e_machine) case EM_PRISM: return "Vitesse Prism"; case EM_X86_64: return "Advanced Micro Devices X86-64"; case EM_L1OM: return "Intel L1OM"; + case EM_K1OM: return "Intel K1OM"; case EM_S390_OLD: case EM_S390: return "IBM S/390"; case EM_SCORE: return "SUNPLUS S+Core"; @@ -1907,6 +1933,7 @@ get_machine_name (unsigned e_machine) case EM_OR32: return "OpenRISC"; case EM_ARC_A5: return "ARC International ARCompact processor"; case EM_CRX: return "National Semiconductor CRX microprocessor"; + case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY"; case EM_DLX: return "OpenDLX"; case EM_IP2K_OLD: case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers"; @@ -1964,9 +1991,9 @@ get_machine_name (unsigned e_machine) case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture"; case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine"; case EM_CR16: - case EM_CR16_OLD: return "National Semiconductor's CR16"; - case EM_MICROBLAZE: return "Xilinx MicroBlaze"; + case EM_MICROBLAZE: case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze"; + case EM_RL78: return "Renesas RL78"; case EM_RX: return "Renesas RX"; case EM_METAG: return "Imagination Technologies META processor architecture"; case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture"; @@ -1979,6 +2006,7 @@ get_machine_name (unsigned e_machine) case EM_TILEPRO: return "Tilera TILEPro multicore architecture family"; case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family"; case EM_CUDA: return "NVIDIA CUDA architecture"; + case EM_XGATE: return "Motorola XGATE embedded processor"; default: snprintf (buff, sizeof (buff), _(": 0x%x"), e_machine); return buff; @@ -2424,6 +2452,9 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) if (e_flags & EF_MIPS_ARCH_ASE_M16) strcat (buf, ", mips16"); + if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) + strcat (buf, ", micromips"); + switch ((e_flags & EF_MIPS_ARCH)) { case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break; @@ -2588,14 +2619,19 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) strcat (buf, ", 64-bit doubles"); if (e_flags & E_FLAG_RX_DSP) strcat (buf, ", dsp"); + if (e_flags & E_FLAG_RX_PID) + strcat (buf, ", pid"); + break; case EM_S390: if (e_flags & EF_S390_HIGH_GPRS) strcat (buf, ", highgprs"); + break; case EM_TI_C6000: if ((e_flags & EF_C6000_REL)) strcat (buf, ", relocatable module"); + break; } } @@ -2612,8 +2648,7 @@ get_osabi_name (unsigned int osabi) case ELFOSABI_NONE: return "UNIX - System V"; case ELFOSABI_HPUX: return "UNIX - HP-UX"; case ELFOSABI_NETBSD: return "UNIX - NetBSD"; - case ELFOSABI_LINUX: return "UNIX - Linux"; - case ELFOSABI_HURD: return "GNU/Hurd"; + case ELFOSABI_GNU: return "UNIX - GNU"; case ELFOSABI_SOLARIS: return "UNIX - Solaris"; case ELFOSABI_AIX: return "UNIX - AIX"; case ELFOSABI_IRIX: return "UNIX - IRIX"; @@ -2666,6 +2701,20 @@ get_osabi_name (unsigned int osabi) } } +static const char * +get_aarch64_segment_type (unsigned long type) +{ + switch (type) + { + case PT_AARCH64_ARCHEXT: + return "AARCH64_ARCHEXT"; + default: + break; + } + + return NULL; +} + static const char * get_arm_segment_type (unsigned long type) { @@ -2788,6 +2837,9 @@ get_segment_type (unsigned long p_type) switch (elf_header.e_machine) { + case EM_AARCH64: + result = get_aarch64_segment_type (p_type); + break; case EM_ARM: result = get_arm_segment_type (p_type); break; @@ -2948,6 +3000,19 @@ get_x86_64_section_type_name (unsigned int sh_type) return NULL; } +static const char * +get_aarch64_section_type_name (unsigned int sh_type) +{ + switch (sh_type) + { + case SHT_AARCH64_ATTRIBUTES: + return "AARCH64_ATTRIBUTES"; + default: + break; + } + return NULL; +} + static const char * get_arm_section_type_name (unsigned int sh_type) { @@ -3044,8 +3109,12 @@ get_section_type_name (unsigned int sh_type) break; case EM_X86_64: case EM_L1OM: + case EM_K1OM: result = get_x86_64_section_type_name (sh_type); break; + case EM_AARCH64: + result = get_aarch64_section_type_name (sh_type); + break; case EM_ARM: result = get_arm_section_type_name (sh_type); break; @@ -3096,6 +3165,7 @@ get_section_type_name (unsigned int sh_type) #define OPTION_DYN_SYMS 513 #define OPTION_DWARF_DEPTH 514 #define OPTION_DWARF_START 515 +#define OPTION_DWARF_CHECK 516 static struct option options[] = { @@ -3131,6 +3201,7 @@ static struct option options[] = {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH}, {"dwarf-start", required_argument, 0, OPTION_DWARF_START}, + {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK}, {"version", no_argument, 0, 'v'}, {"wide", no_argument, 0, 'W'}, @@ -3161,7 +3232,7 @@ usage (FILE * stream) -u --unwind Display the unwind info (if present)\n\ -d --dynamic Display the dynamic section (if present)\n\ -V --version-info Display the version sections (if present)\n\ - -A --arch-specific Display architecture specific information (if any).\n\ + -A --arch-specific Display architecture specific information (if any)\n\ -c --archive-index Display the symbol/file index in an archive\n\ -D --use-dynamic Use the dynamic section info when displaying symbols\n\ -x --hex-dump=\n\ @@ -3399,6 +3470,9 @@ parse_args (int argc, char ** argv) dwarf_start_die = strtoul (optarg, & cp, 0); } break; + case OPTION_DWARF_CHECK: + dwarf_check = 1; + break; case OPTION_DYN_SYMS: do_dyn_syms++; break; @@ -3783,7 +3857,7 @@ process_program_headers (FILE * file) printf ("0x%6.6lx", (unsigned long) segment->p_memsz); else { - print_vma (segment->p_offset, FULL_HEX); + print_vma (segment->p_memsz, FULL_HEX); } printf (" %c%c%c ", @@ -4038,11 +4112,13 @@ get_64bit_section_headers (FILE * file, unsigned int num) } static Elf_Internal_Sym * -get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) +get_32bit_elf_symbols (FILE * file, + Elf_Internal_Shdr * section, + unsigned long * num_syms_return) { - unsigned long number; + unsigned long number = 0; Elf32_External_Sym * esyms = NULL; - Elf_External_Sym_Shndx * shndx; + Elf_External_Sym_Shndx * shndx = NULL; Elf_Internal_Sym * isyms = NULL; Elf_Internal_Sym * psym; unsigned int j; @@ -4051,7 +4127,7 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) if (section->sh_entsize == 0) { error (_("sh_entsize is zero\n")); - return NULL; + goto exit_point; } number = section->sh_size / section->sh_entsize; @@ -4059,13 +4135,13 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1) { error (_("Invalid sh_entsize\n")); - return NULL; + goto exit_point; } esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1, section->sh_size, _("symbols")); if (esyms == NULL) - return NULL; + goto exit_point; shndx = NULL; if (symtab_shndx_hdr != NULL @@ -4075,7 +4151,7 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file, symtab_shndx_hdr->sh_offset, 1, symtab_shndx_hdr->sh_size, - _("symtab shndx")); + _("symbol table section indicies")); if (shndx == NULL) goto exit_point; } @@ -4104,21 +4180,26 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) } exit_point: - if (shndx) + if (shndx != NULL) free (shndx); - if (esyms) + if (esyms != NULL) free (esyms); + if (num_syms_return != NULL) + * num_syms_return = isyms == NULL ? 0 : number; + return isyms; } static Elf_Internal_Sym * -get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) +get_64bit_elf_symbols (FILE * file, + Elf_Internal_Shdr * section, + unsigned long * num_syms_return) { - unsigned long number; - Elf64_External_Sym * esyms; - Elf_External_Sym_Shndx * shndx; - Elf_Internal_Sym * isyms; + unsigned long number = 0; + Elf64_External_Sym * esyms = NULL; + Elf_External_Sym_Shndx * shndx = NULL; + Elf_Internal_Sym * isyms = NULL; Elf_Internal_Sym * psym; unsigned int j; @@ -4126,7 +4207,7 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) if (section->sh_entsize == 0) { error (_("sh_entsize is zero\n")); - return NULL; + goto exit_point; } number = section->sh_size / section->sh_entsize; @@ -4134,15 +4215,14 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1) { error (_("Invalid sh_entsize\n")); - return NULL; + goto exit_point; } esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1, section->sh_size, _("symbols")); if (!esyms) - return NULL; + goto exit_point; - shndx = NULL; if (symtab_shndx_hdr != NULL && (symtab_shndx_hdr->sh_link == (unsigned long) (section - section_headers))) @@ -4150,12 +4230,9 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file, symtab_shndx_hdr->sh_offset, 1, symtab_shndx_hdr->sh_size, - _("symtab shndx")); - if (!shndx) - { - free (esyms); - return NULL; - } + _("symbol table section indicies")); + if (shndx == NULL) + goto exit_point; } isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym)); @@ -4163,32 +4240,34 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) if (isyms == NULL) { error (_("Out of memory\n")); - if (shndx) - free (shndx); - free (esyms); - return NULL; + goto exit_point; } - for (j = 0, psym = isyms; - j < number; - j++, psym++) + for (j = 0, psym = isyms; j < number; j++, psym++) { psym->st_name = BYTE_GET (esyms[j].st_name); psym->st_info = BYTE_GET (esyms[j].st_info); psym->st_other = BYTE_GET (esyms[j].st_other); psym->st_shndx = BYTE_GET (esyms[j].st_shndx); + if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL) psym->st_shndx = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j])); else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff)) psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); + psym->st_value = BYTE_GET (esyms[j].st_value); psym->st_size = BYTE_GET (esyms[j].st_size); } - if (shndx) + exit_point: + if (shndx != NULL) free (shndx); - free (esyms); + if (esyms != NULL) + free (esyms); + + if (num_syms_return != NULL) + * num_syms_return = isyms == NULL ? 0 : number; return isyms; } @@ -4295,6 +4374,7 @@ get_elf_section_flags (bfd_vma sh_flags) case EM_486: case EM_X86_64: case EM_L1OM: + case EM_K1OM: case EM_OLD_SPARCV9: case EM_SPARC32PLUS: case EM_SPARCV9: @@ -4346,7 +4426,8 @@ get_elf_section_flags (bfd_vma sh_flags) default: if ((elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM) + || elf_header.e_machine == EM_L1OM + || elf_header.e_machine == EM_K1OM) && flag == SHF_X86_64_LARGE) *p = 'l'; else if (flag & SHF_MASKOS) @@ -4554,8 +4635,7 @@ process_section_headers (FILE * file) } CHECK_ENTSIZE (section, i, Sym); - num_dynamic_syms = section->sh_size / section->sh_entsize; - dynamic_symbols = GET_ELF_SYMBOLS (file, section); + dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms); } else if (section->sh_type == SHT_STRTAB && streq (name, ".dynstr")) @@ -4601,18 +4681,19 @@ process_section_headers (FILE * file) name += sizeof (".debug_") - 1; if (do_debugging - || (do_debug_info && streq (name, "info")) - || (do_debug_info && streq (name, "types")) - || (do_debug_abbrevs && streq (name, "abbrev")) - || (do_debug_lines && streq (name, "line")) - || (do_debug_pubnames && streq (name, "pubnames")) - || (do_debug_pubtypes && streq (name, "pubtypes")) - || (do_debug_aranges && streq (name, "aranges")) - || (do_debug_ranges && streq (name, "ranges")) - || (do_debug_frames && streq (name, "frame")) - || (do_debug_macinfo && streq (name, "macinfo")) - || (do_debug_str && streq (name, "str")) - || (do_debug_loc && streq (name, "loc")) + || (do_debug_info && const_strneq (name, "info")) + || (do_debug_info && const_strneq (name, "types")) + || (do_debug_abbrevs && const_strneq (name, "abbrev")) + || (do_debug_lines && const_strneq (name, "line")) + || (do_debug_pubnames && const_strneq (name, "pubnames")) + || (do_debug_pubtypes && const_strneq (name, "pubtypes")) + || (do_debug_aranges && const_strneq (name, "aranges")) + || (do_debug_ranges && const_strneq (name, "ranges")) + || (do_debug_frames && const_strneq (name, "frame")) + || (do_debug_macinfo && const_strneq (name, "macinfo")) + || (do_debug_macinfo && const_strneq (name, "macro")) + || (do_debug_str && const_strneq (name, "str")) + || (do_debug_loc && const_strneq (name, "loc")) ) request_dump_bynumber (i, DEBUG_DUMP); } @@ -4693,22 +4774,20 @@ process_section_headers (FILE * file) i < elf_header.e_shnum; i++, section++) { + printf (" [%2u] ", i); if (do_section_details) { - printf (" [%2u] %s\n", - i, - SECTION_NAME (section)); - if (is_32bit_elf || do_wide) - printf (" %-15.15s ", - get_section_type_name (section->sh_type)); + print_symbol (INT_MAX, SECTION_NAME (section)); + printf ("\n "); } else - printf ((do_wide ? " [%2u] %-17s %-15s " - : " [%2u] %-17.17s %-15.15s "), - i, - SECTION_NAME (section), - get_section_type_name (section->sh_type)); - + { + print_symbol (-17, SECTION_NAME (section)); + } + + printf (do_wide ? " %-15s " : " %-15.15s ", + get_section_type_name (section->sh_type)); + if (is_32bit_elf) { const char * link_too_big = NULL; @@ -4736,6 +4815,7 @@ process_section_headers (FILE * file) case EM_486: case EM_X86_64: case EM_L1OM: + case EM_K1OM: case EM_OLD_SPARCV9: case EM_SPARC32PLUS: case EM_SPARCV9: @@ -4864,7 +4944,8 @@ process_section_headers (FILE * file) if (!do_section_details) { if (elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM) + || elf_header.e_machine == EM_L1OM + || elf_header.e_machine == EM_K1OM) printf (_("Key to Flags:\n\ W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\ I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\ @@ -4907,6 +4988,7 @@ process_section_groups (FILE * file) Elf_Internal_Shdr * symtab_sec; Elf_Internal_Shdr * strtab_sec; Elf_Internal_Sym * symtab; + unsigned long num_syms; char * strtab; size_t strtab_size; @@ -4925,7 +5007,8 @@ process_section_groups (FILE * file) if (section_headers == NULL) { error (_("Section headers are not available!\n")); - abort (); + /* PR 13622: This can happen with a corrupt ELF header. */ + return 0; } section_headers_groups = (struct group **) calloc (elf_header.e_shnum, @@ -4964,6 +5047,7 @@ process_section_groups (FILE * file) symtab_sec = NULL; strtab_sec = NULL; symtab = NULL; + num_syms = 0; strtab = NULL; strtab_size = 0; for (i = 0, section = section_headers, group = section_groups; @@ -4994,7 +5078,7 @@ process_section_groups (FILE * file) symtab_sec = sec; if (symtab) free (symtab); - symtab = GET_ELF_SYMBOLS (file, symtab_sec); + symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms); } if (symtab == NULL) @@ -5003,6 +5087,12 @@ process_section_groups (FILE * file) continue; } + if (section->sh_info >= num_syms) + { + error (_("Bad sh_info in group section `%s'\n"), name); + continue; + } + sym = symtab + section->sh_info; if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) @@ -5213,7 +5303,7 @@ dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela) imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off, 1, imgrela->img_rela_cnt * sizeof (*imrs), - _("dynamic section image relas")); + _("dynamic section image relocations")); if (!imrs) return; @@ -5419,7 +5509,7 @@ process_relocs (FILE * 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)); @@ -5440,8 +5530,7 @@ process_relocs (FILE * file) && symsec->sh_type != SHT_DYNSYM) continue; - nsyms = symsec->sh_size / symsec->sh_entsize; - symtab = GET_ELF_SYMBOLS (file, symsec); + symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms); if (symtab == NULL) continue; @@ -5553,6 +5642,7 @@ find_symbol_for_address (Elf_Internal_Sym * symtab, break; } } + if (best) { *symname = (best->st_name >= strtab_size @@ -5560,6 +5650,7 @@ find_symbol_for_address (Elf_Internal_Sym * symtab, *offset = dist; return; } + *symname = NULL; *offset = addr.offset; } @@ -5737,7 +5828,7 @@ slurp_ia64_unwind_table (FILE * file, return 1; } -static int +static void ia64_process_unwind (FILE * file) { Elf_Internal_Shdr * sec; @@ -5753,8 +5844,7 @@ ia64_process_unwind (FILE * file) if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum) { - aux.nsyms = sec->sh_size / sec->sh_entsize; - aux.symtab = GET_ELF_SYMBOLS (file, sec); + aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms); strsec = section_headers + sec->sh_link; assert (aux.strtab == NULL); @@ -5875,8 +5965,6 @@ ia64_process_unwind (FILE * file) free (aux.symtab); if (aux.strtab) free ((char *) aux.strtab); - - return 1; } struct hppa_unw_table_entry @@ -6148,7 +6236,7 @@ slurp_hppa_unwind_table (FILE * file, return 1; } -static int +static void hppa_process_unwind (FILE * file) { struct hppa_unw_aux_info aux; @@ -6157,18 +6245,17 @@ hppa_process_unwind (FILE * file) Elf_Internal_Shdr * sec; unsigned long i; - memset (& aux, 0, sizeof (aux)); - if (string_table == NULL) - return 1; + return; + + memset (& aux, 0, sizeof (aux)); for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) { if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum) { - aux.nsyms = sec->sh_size / sec->sh_entsize; - aux.symtab = GET_ELF_SYMBOLS (file, sec); + aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms); strsec = section_headers + sec->sh_link; assert (aux.strtab == NULL); @@ -6209,30 +6296,25 @@ hppa_process_unwind (FILE * file) free (aux.symtab); if (aux.strtab) free ((char *) aux.strtab); - - return 1; } struct arm_section { - unsigned char *data; - - Elf_Internal_Shdr *sec; - Elf_Internal_Rela *rela; - unsigned long nrelas; - unsigned int rel_type; - - Elf_Internal_Rela *next_rela; + unsigned char * data; /* The unwind data. */ + Elf_Internal_Shdr * sec; /* The cached unwind section header. */ + Elf_Internal_Rela * rela; /* The cached relocations for this section. */ + unsigned long nrelas; /* The number of relocations. */ + unsigned int rel_type; /* REL or RELA ? */ + Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */ }; struct arm_unw_aux_info { - FILE *file; - - Elf_Internal_Sym *symtab; /* The symbol table. */ - unsigned long nsyms; /* Number of symbols. */ - char *strtab; /* The string table. */ - unsigned long strtab_size; /* Size of string table. */ + FILE * file; /* The file containing the unwind sections. */ + Elf_Internal_Sym * symtab; /* The file's symbol table. */ + unsigned long nsyms; /* Number of symbols. */ + char * strtab; /* The file's string table. */ + unsigned long strtab_size; /* Size of string table. */ }; static const char * @@ -6274,11 +6356,25 @@ arm_free_section (struct arm_section *arm_sec) free (arm_sec->rela); } -static int -arm_section_get_word (struct arm_unw_aux_info *aux, - struct arm_section *arm_sec, - Elf_Internal_Shdr *sec, bfd_vma word_offset, - unsigned int *wordp, struct absaddr *addr) +/* 1) If SEC does not match the one cached in ARM_SEC, then free the current + cached section and install SEC instead. + 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC + and return its valued in * WORDP, relocating if necessary. + 3) Update the NEXT_RELA field in ARM_SEC and store the section index and + relocation's offset in ADDR. + 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset + into the string table of the symbol associated with the reloc. If no + reloc was applied store -1 there. + 5) Return TRUE upon success, FALSE otherwise. */ + +static bfd_boolean +get_unwind_section_word (struct arm_unw_aux_info * aux, + struct arm_section * arm_sec, + Elf_Internal_Shdr * sec, + bfd_vma word_offset, + unsigned int * wordp, + struct absaddr * addr, + bfd_vma * sym_name) { Elf_Internal_Rela *rp; Elf_Internal_Sym *sym; @@ -6289,6 +6385,10 @@ arm_section_get_word (struct arm_unw_aux_info *aux, addr->section = SHN_UNDEF; addr->offset = 0; + if (sym_name != NULL) + *sym_name = (bfd_vma) -1; + + /* If necessary, update the section cache. */ if (sec != arm_sec->sec) { Elf_Internal_Shdr *relsec; @@ -6309,12 +6409,13 @@ arm_section_get_word (struct arm_unw_aux_info *aux, || section_headers + relsec->sh_info != sec) continue; + arm_sec->rel_type = relsec->sh_type; if (relsec->sh_type == SHT_REL) { if (!slurp_rel_relocs (aux->file, relsec->sh_offset, relsec->sh_size, & arm_sec->rela, & arm_sec->nrelas)) - return 0; + return FALSE; break; } else if (relsec->sh_type == SHT_RELA) @@ -6322,19 +6423,25 @@ arm_section_get_word (struct arm_unw_aux_info *aux, if (!slurp_rela_relocs (aux->file, relsec->sh_offset, relsec->sh_size, & arm_sec->rela, & arm_sec->nrelas)) - return 0; + return FALSE; break; } + else + warn (_("unexpected relocation type (%d) for section %d"), + relsec->sh_type, relsec->sh_info); } arm_sec->next_rela = arm_sec->rela; } + /* If there is no unwind data we can do nothing. */ if (arm_sec->data == NULL) - return 0; + return FALSE; + /* Get the word at the required offset. */ word = byte_get (arm_sec->data + word_offset, 4); + /* Look through the relocs to find the one that applies to the provided offset. */ wrapped = FALSE; for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++) { @@ -6358,31 +6465,6 @@ arm_section_get_word (struct arm_unw_aux_info *aux, if (rp->r_offset < word_offset) continue; - switch (elf_header.e_machine) - { - case EM_ARM: - relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info)); - break; - - case EM_TI_C6000: - relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info)); - break; - - default: - abort(); - } - - if (streq (relname, "R_ARM_NONE") - || streq (relname, "R_C6000_NONE")) - continue; - - if (!(streq (relname, "R_ARM_PREL31") - || streq (relname, "R_C6000_PREL31"))) - { - warn (_("Skipping unexpected relocation type %s\n"), relname); - continue; - } - sym = aux->symtab + ELF32_R_SYM (rp->r_info); if (arm_sec->rel_type == SHT_REL) @@ -6391,31 +6473,67 @@ arm_section_get_word (struct arm_unw_aux_info *aux, if (offset & 0x40000000) offset |= ~ (bfd_vma) 0x7fffffff; } - else + else if (arm_sec->rel_type == SHT_RELA) offset = rp->r_addend; + else + abort (); offset += sym->st_value; prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset); - if (streq (relname, "R_C6000_PREL31")) - prelval >>= 1; + /* Check that we are processing the expected reloc type. */ + if (elf_header.e_machine == EM_ARM) + { + relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info)); + + if (streq (relname, "R_ARM_NONE")) + continue; + + if (! streq (relname, "R_ARM_PREL31")) + { + warn (_("Skipping unexpected relocation type %s\n"), relname); + continue; + } + } + else if (elf_header.e_machine == EM_TI_C6000) + { + relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info)); + + if (streq (relname, "R_C6000_NONE")) + continue; + + if (! streq (relname, "R_C6000_PREL31")) + { + warn (_("Skipping unexpected relocation type %s\n"), relname); + continue; + } + + prelval >>= 1; + } + else + /* This function currently only supports ARM and TI unwinders. */ + abort (); word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff); addr->section = sym->st_shndx; addr->offset = offset; + if (sym_name) + * sym_name = sym->st_name; break; } *wordp = word; arm_sec->next_rela = rp; - return 1; + return TRUE; } -static const char *tic6x_unwind_regnames[16] = { - "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3", - "A14", "A13", "A12", "A11", "A10", - "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"}; +static const char *tic6x_unwind_regnames[16] = +{ + "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3", + "A14", "A13", "A12", "A11", "A10", + "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]" +}; static void decode_tic6x_unwind_regmask (unsigned int mask) @@ -6437,8 +6555,8 @@ decode_tic6x_unwind_regmask (unsigned int mask) if (remaining == 0 && more_words) \ { \ data_offset += 4; \ - if (!arm_section_get_word (aux, data_arm_sec, data_sec, \ - data_offset, &word, &addr)) \ + if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \ + data_offset, & word, & addr, NULL)) \ return; \ remaining = 4; \ more_words--; \ @@ -6542,7 +6660,7 @@ decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux, } if (op & 0x08) { - if (first) + if (!first) printf (", "); printf ("r14"); } @@ -6687,12 +6805,12 @@ decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux, op = word >> 24; word <<= 8; - printf (_(" 0x%02x "), op); + printf (" 0x%02x ", op); if ((op & 0xc0) == 0x00) { int offset = ((op & 0x3f) << 3) + 8; - printf (_(" sp = sp + %d"), offset); + printf (" sp = sp + %d", offset); } else if ((op & 0xc0) == 0x80) { @@ -6717,7 +6835,8 @@ decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux, unsigned int nregs; unsigned int i; const char *name; - struct { + struct + { unsigned int offset; unsigned int reg; } regpos[16]; @@ -6774,6 +6893,7 @@ decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux, unsigned char buf[9]; unsigned int i, len; unsigned long offset; + for (i = 0; i < sizeof (buf); i++) { GET_OP (buf[i]); @@ -6802,7 +6922,7 @@ decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux, } static bfd_vma -expand_prel31 (bfd_vma word, bfd_vma where) +arm_expand_prel31 (bfd_vma word, bfd_vma where) { bfd_vma offset; @@ -6817,21 +6937,29 @@ expand_prel31 (bfd_vma word, bfd_vma where) } static void -decode_arm_unwind (struct arm_unw_aux_info *aux, - unsigned int word, unsigned int remaining, - bfd_vma data_offset, Elf_Internal_Shdr *data_sec, - struct arm_section *data_arm_sec) +decode_arm_unwind (struct arm_unw_aux_info * aux, + unsigned int word, + unsigned int remaining, + bfd_vma data_offset, + Elf_Internal_Shdr * data_sec, + struct arm_section * data_arm_sec) { int per_index; unsigned int more_words = 0; struct absaddr addr; + bfd_vma sym_name = (bfd_vma) -1; if (remaining == 0) { - /* Fetch the first word. */ - if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset, - &word, &addr)) + /* Fetch the first word. + Note - when decoding an object file the address extracted + here will always be 0. So we also pass in the sym_name + parameter so that we can find the symbol associated with + the personality routine. */ + if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset, + & word, & addr, & sym_name)) return; + remaining = 4; } @@ -6841,9 +6969,23 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, bfd_vma fn; const char *procname; - fn = expand_prel31 (word, data_sec->sh_addr + data_offset); + fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset); printf (_(" Personality routine: ")); - procname = arm_print_vma_and_name (aux, fn, addr); + if (fn == 0 + && addr.section == SHN_UNDEF && addr.offset == 0 + && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size) + { + procname = aux->strtab + sym_name; + print_vma (fn, PREFIX_HEX); + if (procname) + { + fputs (" <", stdout); + fputs (procname, stdout); + fputc ('>', stdout); + } + } + else + procname = arm_print_vma_and_name (aux, fn, addr); fputc ('\n', stdout); /* The GCC personality routines use the standard compact @@ -6873,9 +7015,20 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, } else { - + /* ARM EHABI Section 6.3: + + An exception-handling table entry for the compact model looks like: + + 31 30-28 27-24 23-0 + -- ----- ----- ---- + 1 0 index Data for personalityRoutine[index] */ + + if (elf_header.e_machine == EM_ARM + && (word & 0x70000000)) + warn (_("Corrupt ARM compact model table entry: %x \n"), word); + per_index = (word >> 24) & 0x7f; - printf (_(" Compact model %d\n"), per_index); + printf (_(" Compact model index: %d\n"), per_index); if (per_index == 0) { more_words = 0; @@ -6899,14 +7052,17 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, data_offset, data_sec, data_arm_sec); } else - printf (" [reserved]\n"); + { + warn (_("Unknown ARM compact model index encountered\n")); + printf (_(" [reserved]\n")); + } break; case EM_TI_C6000: if (per_index < 3) { decode_tic6x_unwind_bytecode (aux, word, remaining, more_words, - data_offset, data_sec, data_arm_sec); + data_offset, data_sec, data_arm_sec); } else if (per_index < 5) { @@ -6923,11 +7079,12 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, tic6x_unwind_regnames[word & 0xf]); } else - printf (" [reserved]\n"); + printf (_(" [reserved (%d)]\n"), per_index); break; default: - abort (); + error (_("Unsupported architecture type %d encountered when decoding unwind table"), + elf_header.e_machine); } /* Decode the descriptors. Not implemented. */ @@ -6951,19 +7108,25 @@ dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec) fputc ('\n', stdout); - if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec, - 8 * i, &exidx_fn, &fn_addr) - || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec, - 8 * i + 4, &exidx_entry, &entry_addr)) + if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec, + 8 * i, & exidx_fn, & fn_addr, NULL) + || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec, + 8 * i + 4, & exidx_entry, & entry_addr, NULL)) { - arm_free_section (&exidx_arm_sec); - arm_free_section (&extab_arm_sec); + arm_free_section (& exidx_arm_sec); + arm_free_section (& extab_arm_sec); return; } - fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i); + /* ARM EHABI, Section 5: + An index table entry consists of 2 words. + The first word contains a prel31 offset to the start of a function, with bit 31 clear. */ + if (exidx_fn & 0x80000000) + warn (_("corrupt index table entry: %x\n"), exidx_fn); - arm_print_vma_and_name (aux, fn, entry_addr); + fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i); + + arm_print_vma_and_name (aux, fn, fn_addr); fputs (": ", stdout); if (exidx_entry == 1) @@ -6983,7 +7146,7 @@ dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec) Elf_Internal_Shdr *table_sec; fputs ("@", stdout); - table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4); + table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4); print_vma (table, PREFIX_HEX); printf ("\n"); @@ -7018,7 +7181,8 @@ dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec) } /* Used for both ARM and C6X unwinding tables. */ -static int + +static void arm_process_unwind (FILE *file) { struct arm_unw_aux_info aux; @@ -7028,9 +7192,6 @@ arm_process_unwind (FILE *file) unsigned long i; unsigned int sec_type; - memset (& aux, 0, sizeof (aux)); - aux.file = file; - switch (elf_header.e_machine) { case EM_ARM: @@ -7041,19 +7202,23 @@ arm_process_unwind (FILE *file) sec_type = SHT_C6000_UNWIND; break; - default: - abort(); + default: + error (_("Unsupported architecture type %d encountered when processing unwind table"), + elf_header.e_machine); + return; } if (string_table == NULL) - return 1; + return; + + memset (& aux, 0, sizeof (aux)); + aux.file = file; for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) { if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum) { - aux.nsyms = sec->sh_size / sec->sh_entsize; - aux.symtab = GET_ELF_SYMBOLS (file, sec); + aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms); strsec = section_headers + sec->sh_link; assert (aux.strtab == NULL); @@ -7065,37 +7230,35 @@ arm_process_unwind (FILE *file) unwsec = sec; } - if (!unwsec) + if (unwsec == NULL) printf (_("\nThere are no unwind sections in this file.\n")); + else + for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) + { + if (sec->sh_type == sec_type) + { + printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"), + SECTION_NAME (sec), + (unsigned long) sec->sh_offset, + (unsigned long) (sec->sh_size / (2 * eh_addr_size))); - for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) - { - if (sec->sh_type == sec_type) - { - printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"), - SECTION_NAME (sec), - (unsigned long) sec->sh_offset, - (unsigned long) (sec->sh_size / (2 * eh_addr_size))); - - dump_arm_unwind (&aux, sec); - } - } + dump_arm_unwind (&aux, sec); + } + } if (aux.symtab) free (aux.symtab); if (aux.strtab) free ((char *) aux.strtab); - - return 1; } -static int +static void process_unwind (FILE * file) { struct unwind_handler { int machtype; - int (* handler)(FILE *); + void (* handler)(FILE *); } handlers[] = { { EM_ARM, arm_process_unwind }, @@ -7107,14 +7270,14 @@ process_unwind (FILE * file) int i; if (!do_unwind) - return 1; + return; for (i = 0; handlers[i].handler != NULL; i++) if (elf_header.e_machine == handlers[i].machtype) return handlers[i].handler (file); - printf (_("\nThere are no unwind sections in this file.\n")); - return 1; + printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"), + get_machine_name (elf_header.e_machine)); } static void @@ -7124,7 +7287,7 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry) { case DT_MIPS_FLAGS: if (entry->d_un.d_val == 0) - printf (_("NONE\n")); + printf (_("NONE")); else { static const char * opts[] = @@ -7144,15 +7307,14 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry) printf ("%s%s", first ? "" : " ", opts[cnt]); first = 0; } - puts (""); } break; case DT_MIPS_IVERSION: if (VALID_DYNAMIC_NAME (entry->d_un.d_val)) - printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val)); + printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val)); else - printf (_("\n"), (long) entry->d_un.d_ptr); + printf (_(""), entry->d_un.d_ptr); break; case DT_MIPS_TIME_STAMP: @@ -7165,7 +7327,7 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry) snprintf (timebuf, sizeof (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 (_("Time Stamp: %s\n"), timebuf); + printf (_("Time Stamp: %s"), timebuf); } break; @@ -7182,12 +7344,13 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry) case DT_MIPS_DELTA_SYM_NO: case DT_MIPS_DELTA_CLASSSYM_NO: case DT_MIPS_COMPACT_SIZE: - printf ("%ld\n", (long) entry->d_un.d_ptr); + print_vma (entry->d_un.d_ptr, DEC); break; default: - printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr); + print_vma (entry->d_un.d_ptr, PREFIX_HEX); } + putchar ('\n'); } static void @@ -7514,14 +7677,12 @@ process_dynamic_section (FILE * file) else section.sh_entsize = sizeof (Elf64_External_Sym); - num_dynamic_syms = section.sh_size / section.sh_entsize; + dynamic_symbols = GET_ELF_SYMBOLS (file, §ion, & num_dynamic_syms); if (num_dynamic_syms < 1) { error (_("Unable to determine the number of symbols to load\n")); continue; } - - dynamic_symbols = GET_ELF_SYMBOLS (file, §ion); } } @@ -8222,7 +8383,7 @@ process_version_sections (FILE * file) eneed = (Elf_External_Verneed *) get_data (NULL, file, section->sh_offset, 1, section->sh_size, - _("version need section")); + _("Version Needs section")); if (!eneed) break; endbuf = (char *) eneed + section->sh_size; @@ -8299,13 +8460,15 @@ process_version_sections (FILE * file) isum += aux.vna_next; vstart += aux.vna_next; } + if (j < ent.vn_cnt) - printf (_(" Version need aux past end of section\n")); + warn (_("Missing Version Needs auxillary information\n")); idx += ent.vn_next; } + if (cnt < section->sh_info) - printf (_(" Version need past end of section\n")); + warn (_("Missing Version Needs information\n")); free (eneed); } @@ -8321,6 +8484,7 @@ process_version_sections (FILE * file) char * strtab; Elf_Internal_Sym * symbols; Elf_Internal_Shdr * string_sec; + unsigned long num_syms; long off; if (section->sh_link >= elf_header.e_shnum) @@ -8334,7 +8498,7 @@ process_version_sections (FILE * file) found = 1; - symbols = GET_ELF_SYMBOLS (file, link_section); + symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms); if (symbols == NULL) break; @@ -8403,10 +8567,8 @@ process_version_sections (FILE * file) data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' '); /* If this index value is greater than the size of the symbols - array, break to avoid an out-of-bounds read, */ - if ((unsigned long)(cnt + j) >= - ((unsigned long)link_section->sh_size / - (unsigned long)link_section->sh_entsize)) + array, break to avoid an out-of-bounds read. */ + if ((unsigned long)(cnt + j) >= num_syms) { warn (_("invalid index into symbol array\n")); break; @@ -8587,8 +8749,8 @@ get_symbol_binding (unsigned int binding) else if (binding >= STB_LOOS && binding <= STB_HIOS) { if (binding == STB_GNU_UNIQUE - && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX - /* GNU/Linux is still using the default value 0. */ + && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU + /* GNU is still using the default value 0. */ || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE)) return "UNIQUE"; snprintf (buff, sizeof (buff), _(": %d"), binding); @@ -8640,8 +8802,9 @@ get_symbol_type (unsigned int type) } if (type == STT_GNU_IFUNC - && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX - /* GNU/Linux is still using the default value 0. */ + && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU + || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD + /* GNU is still using the default value 0. */ || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE)) return "IFUNC"; @@ -8671,11 +8834,20 @@ get_mips_symbol_other (unsigned int other) { switch (other) { - case STO_OPTIONAL: return "OPTIONAL"; - case STO_MIPS16: return "MIPS16"; - case STO_MIPS_PLT: return "MIPS PLT"; - case STO_MIPS_PIC: return "MIPS PIC"; - default: return NULL; + case STO_OPTIONAL: + return "OPTIONAL"; + case STO_MIPS_PLT: + return "MIPS PLT"; + case STO_MIPS_PIC: + return "MIPS PIC"; + case STO_MICROMIPS: + return "MICROMIPS"; + case STO_MICROMIPS | STO_MIPS_PIC: + return "MICROMIPS, MIPS PIC"; + case STO_MIPS16: + return "MIPS16"; + default: + return NULL; } } @@ -8784,7 +8956,8 @@ get_symbol_index_type (unsigned int type) && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX) return "ANSI_COM"; else if ((elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM) + || elf_header.e_machine == EM_L1OM + || elf_header.e_machine == EM_K1OM) && type == SHN_X86_64_LCOMMON) return "LARGE_COM"; else if ((type == SHN_MIPS_SCOMMON @@ -9128,6 +9301,7 @@ process_symbol_table (FILE * file) unsigned long int strtab_size = 0; Elf_Internal_Sym * symtab; Elf_Internal_Sym * psym; + unsigned long num_syms; if ((section->sh_type != SHT_SYMTAB && section->sh_type != SHT_DYNSYM) @@ -9151,7 +9325,7 @@ process_symbol_table (FILE * file) else printf (_(" Num: Value Size Type Bind Vis Ndx Name\n")); - symtab = GET_ELF_SYMBOLS (file, section); + symtab = GET_ELF_SYMBOLS (file, section, & num_syms); if (symtab == NULL) continue; @@ -9172,9 +9346,7 @@ process_symbol_table (FILE * file) strtab_size = strtab != NULL ? string_sec->sh_size : 0; } - for (si = 0, psym = symtab; - si < section->sh_size / section->sh_entsize; - si++, psym++) + for (si = 0, psym = symtab; si < num_syms; si++, psym++) { printf ("%6d: ", si); print_vma (psym->st_value, LONG_HEX); @@ -9638,6 +9810,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) return reloc_type == 1; /* R_860_32. */ case EM_960: return reloc_type == 2; /* R_960_32. */ + case EM_AARCH64: + return reloc_type == 258; /* R_AARCH64_ABS32 */ case EM_ALPHA: return reloc_type == 1; /* R_ALPHA_REFLONG. */ case EM_ARC: @@ -9647,12 +9821,13 @@ is_32bit_abs_reloc (unsigned int reloc_type) case EM_AVR_OLD: case EM_AVR: return reloc_type == 1; + case EM_ADAPTEVA_EPIPHANY: + return reloc_type == 3; case EM_BLACKFIN: return reloc_type == 0x12; /* R_byte4_data. */ case EM_CRIS: return reloc_type == 3; /* R_CRIS_32. */ case EM_CR16: - case EM_CR16_OLD: return reloc_type == 3; /* R_CR16_NUM32. */ case EM_CRX: return reloc_type == 15; /* R_CRX_NUM32. */ @@ -9726,6 +9901,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) return reloc_type == 1; /* R_PPC64_ADDR32. */ case EM_PPC: return reloc_type == 1; /* R_PPC_ADDR32. */ + case EM_RL78: + return reloc_type == 1; /* R_RL78_DIR32. */ case EM_RX: return reloc_type == 1; /* R_RX_DIR32. */ case EM_S370: @@ -9757,10 +9934,13 @@ is_32bit_abs_reloc (unsigned int reloc_type) return reloc_type == 1; /* R_VAX_32. */ case EM_X86_64: case EM_L1OM: + case EM_K1OM: return reloc_type == 10; /* R_X86_64_32. */ case EM_XC16X: case EM_C166: return reloc_type == 3; /* R_XC16C_ABS_32. */ + case EM_XGATE: + return reloc_type == 4; /* R_XGATE_32. */ case EM_XSTORMY16: return reloc_type == 1; /* R_XSTROMY16_32. */ case EM_XTENSA_OLD: @@ -9786,6 +9966,10 @@ is_32bit_pcrel_reloc (unsigned int reloc_type) return reloc_type == 2; /* R_386_PC32. */ case EM_68K: return reloc_type == 4; /* R_68K_PC32. */ + case EM_AARCH64: + return reloc_type == 261; /* R_AARCH64_PREL32 */ + case EM_ADAPTEVA_EPIPHANY: + return reloc_type == 6; case EM_ALPHA: return reloc_type == 10; /* R_ALPHA_SREL32. */ case EM_ARM: @@ -9815,6 +9999,7 @@ is_32bit_pcrel_reloc (unsigned int reloc_type) return reloc_type == 4; /* R_TILEPRO_32_PCREL. */ case EM_X86_64: case EM_L1OM: + case EM_K1OM: return reloc_type == 2; /* R_X86_64_PC32. */ case EM_XTENSA_OLD: case EM_XTENSA: @@ -9837,6 +10022,8 @@ is_64bit_abs_reloc (unsigned int reloc_type) { switch (elf_header.e_machine) { + case EM_AARCH64: + return reloc_type == 257; /* R_AARCH64_ABS64. */ case EM_ALPHA: return reloc_type == 2; /* R_ALPHA_REFQUAD. */ case EM_IA_64: @@ -9851,6 +10038,7 @@ is_64bit_abs_reloc (unsigned int reloc_type) return reloc_type == 54; /* R_SPARC_UA64. */ case EM_X86_64: case EM_L1OM: + case EM_K1OM: return reloc_type == 1; /* R_X86_64_64. */ case EM_S390_OLD: case EM_S390: @@ -9872,6 +10060,8 @@ is_64bit_pcrel_reloc (unsigned int reloc_type) { switch (elf_header.e_machine) { + case EM_AARCH64: + return reloc_type == 260; /* R_AARCH64_PREL64. */ case EM_ALPHA: return reloc_type == 11; /* R_ALPHA_SREL64. */ case EM_IA_64: @@ -9886,6 +10076,7 @@ is_64bit_pcrel_reloc (unsigned int reloc_type) return reloc_type == 46; /* R_SPARC_DISP64. */ case EM_X86_64: case EM_L1OM: + case EM_K1OM: return reloc_type == 24; /* R_X86_64_PC64. */ case EM_S390_OLD: case EM_S390: @@ -9924,6 +10115,8 @@ is_16bit_abs_reloc (unsigned int reloc_type) case EM_AVR_OLD: case EM_AVR: return reloc_type == 4; /* R_AVR_16. */ + case EM_ADAPTEVA_EPIPHANY: + return reloc_type == 5; case EM_CYGNUS_D10V: case EM_D10V: return reloc_type == 3; /* R_D10V_16. */ @@ -9948,6 +10141,14 @@ is_16bit_abs_reloc (unsigned int reloc_type) case EM_XC16X: case EM_C166: return reloc_type == 2; /* R_XC16C_ABS_16. */ + case EM_CYGNUS_MN10200: + case EM_MN10200: + return reloc_type == 2; /* R_MN10200_16. */ + case EM_CYGNUS_MN10300: + case EM_MN10300: + return reloc_type == 2; /* R_MN10300_16. */ + case EM_XGATE: + return reloc_type == 3; /* R_XGATE_16. */ default: return FALSE; } @@ -9969,6 +10170,7 @@ is_none_reloc (unsigned int reloc_type) case EM_MIPS: /* R_MIPS_NONE. */ case EM_PARISC: /* R_PARISC_NONE. */ case EM_ALPHA: /* R_ALPHA_NONE. */ + case EM_ADAPTEVA_EPIPHANY: case EM_PPC: /* R_PPC_NONE. */ case EM_PPC64: /* R_PPC64_NONE. */ case EM_ARM: /* R_ARM_NONE. */ @@ -9979,6 +10181,7 @@ is_none_reloc (unsigned int reloc_type) case EM_CRIS: /* R_CRIS_NONE. */ case EM_X86_64: /* R_X86_64_NONE. */ case EM_L1OM: /* R_X86_64_NONE. */ + case EM_K1OM: /* R_X86_64_NONE. */ case EM_MN10300: /* R_MN10300_NONE. */ case EM_MOXIE: /* R_MOXIE_NONE. */ case EM_M32R: /* R_M32R_NONE. */ @@ -9988,6 +10191,8 @@ is_none_reloc (unsigned int reloc_type) case EM_XC16X: case EM_C166: /* R_XC16X_NONE. */ return reloc_type == 0; + case EM_AARCH64: + return reloc_type == 0 || reloc_type == 256; case EM_XTENSA_OLD: case EM_XTENSA: return (reloc_type == 0 /* R_XTENSA_NONE. */ @@ -10025,6 +10230,7 @@ apply_relocations (void * file, Elf_Internal_Rela * rp; Elf_Internal_Shdr * symsec; Elf_Internal_Sym * symtab; + unsigned long num_syms; Elf_Internal_Sym * sym; if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) @@ -10054,7 +10260,7 @@ apply_relocations (void * file, is_rela = FALSE; symsec = section_headers + relsec->sh_link; - symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec); + symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms); for (rp = relocs; rp < relocs + num_relocs; ++rp) { @@ -10062,6 +10268,7 @@ apply_relocations (void * file, unsigned int reloc_type; unsigned int reloc_size; unsigned char * rloc; + unsigned long sym_index; reloc_type = get_reloc_type (rp->r_info); @@ -10095,7 +10302,14 @@ apply_relocations (void * file, continue; } - sym = symtab + get_reloc_symindex (rp->r_info); + sym_index = (unsigned long) get_reloc_symindex (rp->r_info); + if (sym_index >= num_syms) + { + warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"), + sym_index, SECTION_NAME (section)); + continue; + } + sym = symtab + sym_index; /* If the reloc has a symbol associated with it, make sure that it is of an appropriate type. @@ -11069,6 +11283,88 @@ display_power_gnu_attribute (unsigned char * p, int tag) return p; } +static void +display_sparc_hwcaps (int mask) +{ + if (mask) + { + int first = 1; + if (mask & ELF_SPARC_HWCAP_MUL32) + fputs ("mul32", stdout), first = 0; + if (mask & ELF_SPARC_HWCAP_DIV32) + printf ("%sdiv32", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_FSMULD) + printf ("%sfsmuld", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_V8PLUS) + printf ("%sv8plus", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_POPC) + printf ("%spopc", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_VIS) + printf ("%svis", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_VIS2) + printf ("%svis2", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT) + printf ("%sASIBlkInit", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_FMAF) + printf ("%sfmaf", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_VIS3) + printf ("%svis3", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_HPC) + printf ("%shpc", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_RANDOM) + printf ("%srandom", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_TRANS) + printf ("%strans", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_FJFMAU) + printf ("%sfjfmau", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_IMA) + printf ("%sima", first ? "" : "|"), first = 0; + if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING) + printf ("%scspare", first ? "" : "|"), first = 0; + } + else + fputc('0', stdout); + fputc('\n', stdout); +} + +static unsigned char * +display_sparc_gnu_attribute (unsigned char * p, int tag) +{ + int type; + unsigned int len; + int val; + + if (tag == Tag_GNU_Sparc_HWCAPS) + { + val = read_uleb128 (p, &len); + p += len; + printf (" Tag_GNU_Sparc_HWCAPS: "); + + display_sparc_hwcaps (val); + return p; + } + + if (tag & 1) + type = 1; /* String. */ + else + type = 2; /* uleb128. */ + printf (" Tag_unknown_%d: ", tag); + + if (type == 1) + { + printf ("\"%s\"\n", p); + p += strlen ((char *) p) + 1; + } + else + { + val = read_uleb128 (p, &len); + p += len; + printf ("%d (0x%x)\n", val, val); + } + + return p; +} + static unsigned char * display_mips_gnu_attribute (unsigned char * p, int tag) { @@ -11517,6 +11813,13 @@ process_power_specific (FILE * file) display_power_gnu_attribute); } +static int +process_sparc_specific (FILE * file) +{ + return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL, + display_sparc_gnu_attribute); +} + static int process_tic6x_specific (FILE * file) { @@ -11657,7 +11960,7 @@ process_mips_specific (FILE * file) elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset, liblistno, sizeof (Elf32_External_Lib), - _("liblist")); + _("liblist section data")); if (elib) { printf (_("\nSection '.liblist' contains %lu entries:\n"), @@ -12013,7 +12316,8 @@ process_mips_specific (FILE * file) offset = offset_from_vma (file, pltgot, global_end - pltgot); data = (unsigned char *) get_data (NULL, file, offset, - global_end - pltgot, 1, _("GOT")); + global_end - pltgot, 1, + _("Global Offset Table data")); if (data == NULL) return 0; @@ -12057,9 +12361,14 @@ process_mips_specific (FILE * file) printf (_(" Global entries:\n")); printf (" %*s %10s %*s %*s %-7s %3s %s\n", - addr_size * 2, _("Address"), _("Access"), + addr_size * 2, _("Address"), + _("Access"), addr_size * 2, _("Initial"), - addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name")); + addr_size * 2, _("Sym.Val."), + _("Type"), + /* Note for translators: "Ndx" = abbreviated form of "Index". */ + _("Ndx"), _("Name")); + sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1; for (i = gotsym; i < symtabno; i++) { @@ -12112,11 +12421,11 @@ process_mips_specific (FILE * file) offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot); data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot, - 1, _("PLT GOT")); + 1, _("Procedure Linkage Table data")); if (data == NULL) return 0; - printf (_("\nPLT GOT:\n\n")); + printf ("\nPLT GOT:\n\n"); printf (_(" Reserved entries:\n")); printf (_(" %*s %*s Purpose\n"), addr_size * 2, _("Address"), addr_size * 2, _("Initial")); @@ -12185,7 +12494,7 @@ process_gnu_liblist (FILE * file) elib = (Elf32_External_Lib *) get_data (NULL, file, section->sh_offset, 1, section->sh_size, - _("liblist")); + _("liblist section data")); if (elib == NULL) break; @@ -12353,7 +12662,7 @@ print_gnu_note (Elf_Internal_Note *pnote) printf (_(" Build ID: ")); for (i = 0; i < pnote->descsz; ++i) printf ("%02x", pnote->descdata[i] & 0xff); - printf (_("\n")); + printf ("\n"); } break; @@ -12455,7 +12764,7 @@ get_netbsd_elfcore_note_type (unsigned e_type) } } - snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"), + snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d", e_type - NT_NETBSDCORE_FIRSTMACH); return buff; } @@ -12509,7 +12818,7 @@ print_stapsdt_note (Elf_Internal_Note *pnote) print_vma (base_addr, FULL_HEX); printf (_(", Semaphore: ")); print_vma (semaphore, FULL_HEX); - printf (_("\n")); + printf ("\n"); printf (_(" Arguments: %s\n"), arg_fmt); return data == data_end; @@ -12529,13 +12838,13 @@ get_ia64_vms_note_type (unsigned e_type) case NT_VMS_SRC: return _("NT_VMS_SRC (source files)"); case NT_VMS_TITLE: - return _("NT_VMS_TITLE"); + return "NT_VMS_TITLE"; case NT_VMS_EIDC: return _("NT_VMS_EIDC (consistency check)"); case NT_VMS_FPMODE: return _("NT_VMS_FPMODE (FP mode)"); case NT_VMS_LINKTIME: - return _("NT_VMS_LINKTIME"); + return "NT_VMS_LINKTIME"; case NT_VMS_IMGNAM: return _("NT_VMS_IMGNAM (image name)"); case NT_VMS_IMGID: @@ -12547,9 +12856,9 @@ get_ia64_vms_note_type (unsigned e_type) case NT_VMS_GSTNAM: return _("NT_VMS_GSTNAM (sym table name)"); case NT_VMS_ORIG_DYN: - return _("NT_VMS_ORIG_DYN"); + return "NT_VMS_ORIG_DYN"; case NT_VMS_PATCHTIME: - return _("NT_VMS_PATCHTIME"); + return "NT_VMS_PATCHTIME"; default: snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); return buff; @@ -12578,7 +12887,8 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) break; #ifdef BFD64 case NT_VMS_FPMODE: - printf (_(" FP mode: 0x%016" BFD_VMA_FMT "x\n"), + printf (_(" Floating Point mode: ")); + printf ("0x%016" BFD_VMA_FMT "x\n", (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8)); break; case NT_VMS_LINKTIME: @@ -12597,11 +12907,11 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) printf (_(" Major id: %u, minor id: %u\n"), (unsigned) byte_get ((unsigned char *)pnote->descdata, 4), (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4)); - printf (_(" Manip date : ")); + printf (_(" Last modified : ")); print_vms_time ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8)); - printf (_("\n" - " Link flags : 0x%016" BFD_VMA_FMT "x\n"), + printf (_("\n Link flags : ")); + printf ("0x%016" BFD_VMA_FMT "x\n", (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8)); printf (_(" Header flags: 0x%08x\n"), (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4)); @@ -12749,7 +13059,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) external = next; /* Prevent out-of-bounds indexing. */ - if (inote.namedata + inote.namesz >= (char *) pnotes + length + if (inote.namedata + inote.namesz > (char *) pnotes + length || inote.namedata + inote.namesz < inote.namedata) { warn (_("corrupt note found at offset %lx into core notes\n"), @@ -12763,7 +13073,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) one version of Linux (RedHat 6.0) generates corefiles that don't comply with the ELF spec by failing to include the null byte in namesz. */ - if (inote.namedata[inote.namesz] != '\0') + if (inote.namedata[inote.namesz - 1] != '\0') { temp = (char *) malloc (inote.namesz + 1); @@ -12826,7 +13136,7 @@ process_note_sections (FILE * file) int res = 1; for (i = 0, section = section_headers; - i < elf_header.e_shnum; + i < elf_header.e_shnum && section != NULL; i++, section++) if (section->sh_type == SHT_NOTE) res &= process_corefile_note_segment (file, @@ -12871,6 +13181,11 @@ process_arch_specific (FILE * file) case EM_PPC: return process_power_specific (file); break; + case EM_SPARC: + case EM_SPARC32PLUS: + case EM_SPARCV9: + return process_sparc_specific (file); + break; case EM_TI_C6000: return process_tic6x_specific (file); break; @@ -13177,7 +13492,7 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive) unsigned long current_pos; printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"), - file_name, arch.index_num, arch.sym_size); + file_name, (long) arch.index_num, arch.sym_size); current_pos = ftell (file); for (i = l = 0; i < arch.index_num; i++) @@ -13194,7 +13509,9 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive) if (qualified_name != NULL) { - printf (_("Binary %s contains:\n"), qualified_name); + printf (_("Contents of binary %s at offset "), qualified_name); + (void) print_vma (arch.index_array[i], PREFIX_HEX); + putchar ('\n'); free (qualified_name); } } @@ -13210,11 +13527,14 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive) l += strlen (arch.sym_table + l) + 1; } - if (l & 01) - ++l; + if (arch.uses_64bit_indicies) + l = (l + 7) & ~ 7; + else + l += l & 1; + if (l < arch.sym_size) - error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"), - file_name); + error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"), + file_name, arch.sym_size - l); if (fseek (file, current_pos, SEEK_SET) != 0) {