X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=883c48221e279e6709be22c927ee0a2cf761fd73;hb=ad34eb2f7c3120f83d22cf2d5371673fc95040b4;hp=161270102c71a2812b8e11c709e65779b141509d;hpb=a0f1928042c71027c8f908d10da8d1f7dd17530b;p=binutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index 161270102c7..883c48221e2 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -137,6 +137,7 @@ #include "elf/sh.h" #include "elf/sparc.h" #include "elf/spu.h" +#include "elf/tic6x.h" #include "elf/v850.h" #include "elf/vax.h" #include "elf/x86-64.h" @@ -178,6 +179,7 @@ static Elf_Internal_Shdr * symtab_shndx_hdr; static int show_name; static int do_dynamic; static int do_syms; +static int do_dyn_syms; static int do_reloc; static int do_sections; static int do_section_groups; @@ -261,10 +263,10 @@ static void (* byte_put) (unsigned char *, bfd_vma, int); #define UNKNOWN -1 -#define SECTION_NAME(X) \ - ((X) == NULL ? "" \ - : string_table == NULL ? "" \ - : ((X)->sh_name >= string_table_length ? "" \ +#define SECTION_NAME(X) \ + ((X) == NULL ? _("") \ + : string_table == NULL ? _("") \ + : ((X)->sh_name >= string_table_length ? _("") \ : string_table + (X)->sh_name)) #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ @@ -284,6 +286,11 @@ static void (* byte_put) (unsigned char *, bfd_vma, int); #define streq(a,b) (strcmp ((a), (b)) == 0) #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) #define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0) + +#define REMOVE_ARCH_BITS(ADDR) do { \ + if (elf_header.e_machine == EM_ARM) \ + (ADDR) &= ~1; \ + } while (0) static void * get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb, @@ -543,6 +550,44 @@ find_section (const char * name) return NULL; } +/* Return a pointer to a section containing ADDR, or NULL if no such + section exists. */ + +static Elf_Internal_Shdr * +find_section_by_address (bfd_vma addr) +{ + unsigned int i; + + for (i = 0; i < elf_header.e_shnum; i++) + { + Elf_Internal_Shdr *sec = section_headers + i; + if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size) + return sec; + } + + return NULL; +} + +/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of + bytes read. */ + +static unsigned long +read_uleb128 (unsigned char *data, unsigned int *length_return) +{ + return read_leb128 (data, length_return, 0); +} + +/* Return true if the current file is for IA-64 machine and OpenVMS ABI. + This OS has so many departures from the ELF standard that we test it at + many places. */ + +static inline int +is_ia64_vms (void) +{ + return elf_header.e_machine == EM_IA_64 + && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS; +} + /* Guess the relocation size commonly used by the specific machines. */ static int @@ -615,6 +660,7 @@ guess_is_rela (unsigned int e_machine) case EM_SPARC32PLUS: case EM_SPARCV9: case EM_SPU: + case EM_TI_C6000: case EM_V850: case EM_CYGNUS_V850: case EM_VAX: @@ -1228,6 +1274,10 @@ dump_relocations (FILE * file, case EM_C166: rtype = elf_xc16x_reloc_type (type); break; + + case EM_TI_C6000: + rtype = elf_tic6x_reloc_type (type); + break; } if (rtype == NULL) @@ -1263,7 +1313,7 @@ dump_relocations (FILE * file, else if (symtab_index) { if (symtab == NULL || symtab_index >= nsyms) - printf (" bad symbol index: %08lx", (unsigned long) symtab_index); + printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index); else { Elf_Internal_Sym * psym; @@ -1333,9 +1383,7 @@ dump_relocations (FILE * file, && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX && psym->st_shndx == SHN_IA_64_ANSI_COMMON) sec_name = "ANSI_COM"; - else if (elf_header.e_machine == EM_IA_64 - && (elf_header.e_ident[EI_OSABI] - == ELFOSABI_OPENVMS) + else if (is_ia64_vms () && psym->st_shndx == SHN_IA_64_VMS_SYMVEC) sec_name = "VMS_SYMVEC"; else @@ -1605,6 +1653,21 @@ get_score_dynamic_type (unsigned long type) } } +static const char * +get_tic6x_dynamic_type (unsigned long type) +{ + switch (type) + { + case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET"; + case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET"; + case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE"; + case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE"; + case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP"; + case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX"; + default: + return NULL; + } +} static const char * get_dynamic_type (unsigned long type) @@ -1717,6 +1780,9 @@ get_dynamic_type (unsigned long type) case EM_SCORE: result = get_score_dynamic_type (type); break; + case EM_TI_C6000: + result = get_tic6x_dynamic_type (type); + break; default: result = NULL; break; @@ -2143,7 +2209,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[]) } if (unknown) - strcat (buf,", "); + strcat (buf,_(", ")); } static char * @@ -2269,10 +2335,10 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) strcat (buf, ", emb"); if (e_flags & EF_PPC_RELOCATABLE) - strcat (buf, ", relocatable"); + strcat (buf, _(", relocatable")); if (e_flags & EF_PPC_RELOCATABLE_LIB) - strcat (buf, ", relocatable-lib"); + strcat (buf, _(", relocatable-lib")); break; case EM_V850: @@ -2289,7 +2355,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) strcat (buf, ", v850"); break; default: - strcat (buf, ", unknown v850 architecture variant"); + strcat (buf, _(", unknown v850 architecture variant")); break; } break; @@ -2345,7 +2411,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) MIPS ELF does not specify EF_MIPS_MACH, it is a GNU extension. */ break; - default: strcat (buf, ", unknown CPU"); break; + default: strcat (buf, _(", unknown CPU")); break; } switch ((e_flags & EF_MIPS_ABI)) @@ -2360,7 +2426,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) This means it is likely to be an o32 file, but not for sure. */ break; - default: strcat (buf, ", unknown ABI"); break; + default: strcat (buf, _(", unknown ABI")); break; } if (e_flags & EF_MIPS_ARCH_ASE_MDMX) @@ -2380,9 +2446,14 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break; case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break; case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break; - default: strcat (buf, ", unknown ISA"); break; + default: strcat (buf, _(", unknown ISA")); break; } + if (e_flags & EF_SH_PIC) + strcat (buf, ", pic"); + + if (e_flags & EF_SH_FDPIC) + strcat (buf, ", fdpic"); break; case EM_SH: @@ -2409,7 +2480,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break; case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break; case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break; - default: strcat (buf, ", unknown ISA"); break; + default: strcat (buf, _(", unknown ISA")); break; } break; @@ -2491,6 +2562,27 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) strcat (buf, ", constant gp"); if ((e_flags & EF_IA_64_ABSOLUTE)) strcat (buf, ", absolute"); + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS) + { + if ((e_flags & EF_IA_64_VMS_LINKAGES)) + strcat (buf, ", vms_linkages"); + switch ((e_flags & EF_IA_64_VMS_COMCOD)) + { + case EF_IA_64_VMS_COMCOD_SUCCESS: + break; + case EF_IA_64_VMS_COMCOD_WARNING: + strcat (buf, ", warning"); + break; + case EF_IA_64_VMS_COMCOD_ERROR: + strcat (buf, ", error"); + break; + case EF_IA_64_VMS_COMCOD_ABORT: + strcat (buf, ", abort"); + break; + default: + abort (); + } + } break; case EM_VAX: @@ -2507,6 +2599,14 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) strcat (buf, ", 64-bit doubles"); if (e_flags & E_FLAG_RX_DSP) strcat (buf, ", dsp"); + + case EM_S390: + if (e_flags & EF_S390_HIGH_GPRS) + strcat (buf, ", highgprs"); + + case EM_TI_C6000: + if ((e_flags & EF_C6000_REL)) + strcat (buf, ", relocatable module"); } } @@ -2536,9 +2636,42 @@ get_osabi_name (unsigned int osabi) case ELFOSABI_NSK: return "HP - Non-Stop Kernel"; case ELFOSABI_AROS: return "AROS"; case ELFOSABI_FENIXOS: return "FenixOS"; - case ELFOSABI_STANDALONE: return _("Standalone App"); - case ELFOSABI_ARM: return "ARM"; default: + if (osabi >= 64) + switch (elf_header.e_machine) + { + case EM_ARM: + switch (osabi) + { + case ELFOSABI_ARM: return "ARM"; + default: + break; + } + break; + + case EM_MSP430: + case EM_MSP430_OLD: + switch (osabi) + { + case ELFOSABI_STANDALONE: return _("Standalone App"); + default: + break; + } + break; + + case EM_TI_C6000: + switch (osabi) + { + case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000"); + case ELFOSABI_C6000_LINUX: return "Linux C6000"; + default: + break; + } + break; + + default: + break; + } snprintf (buff, sizeof (buff), _(""), osabi); return buff; } @@ -2625,6 +2758,19 @@ get_ia64_segment_type (unsigned long type) return NULL; } +static const char * +get_tic6x_segment_type (unsigned long type) +{ + switch (type) + { + case PT_C6000_PHATTR: return "C6000_PHATTR"; + default: + break; + } + + return NULL; +} + static const char * get_segment_type (unsigned long p_type) { @@ -2666,6 +2812,9 @@ get_segment_type (unsigned long p_type) case EM_IA_64: result = get_ia64_segment_type (p_type); break; + case EM_TI_C6000: + result = get_tic6x_segment_type (p_type); + break; default: result = NULL; break; @@ -2826,6 +2975,33 @@ get_arm_section_type_name (unsigned int sh_type) return NULL; } +static const char * +get_tic6x_section_type_name (unsigned int sh_type) +{ + switch (sh_type) + { + case SHT_C6000_UNWIND: + return "C6000_UNWIND"; + case SHT_C6000_PREEMPTMAP: + return "C6000_PREEMPTMAP"; + case SHT_C6000_ATTRIBUTES: + return "C6000_ATTRIBUTES"; + case SHT_TI_ICODE: + return "TI_ICODE"; + case SHT_TI_XREF: + return "TI_XREF"; + case SHT_TI_HANDLER: + return "TI_HANDLER"; + case SHT_TI_INITINFO: + return "TI_INITINFO"; + case SHT_TI_PHATTRS: + return "TI_PHATTRS"; + default: + break; + } + return NULL; +} + static const char * get_section_type_name (unsigned int sh_type) { @@ -2884,6 +3060,9 @@ get_section_type_name (unsigned int sh_type) case EM_ARM: result = get_arm_section_type_name (sh_type); break; + case EM_TI_C6000: + result = get_tic6x_section_type_name (sh_type); + break; default: result = NULL; break; @@ -2923,6 +3102,7 @@ get_section_type_name (unsigned int sh_type) } #define OPTION_DEBUG_DUMP 512 +#define OPTION_DYN_SYMS 513 static struct option options[] = { @@ -2939,6 +3119,7 @@ static struct option options[] = {"full-section-name",no_argument, 0, 'N'}, {"symbols", no_argument, 0, 's'}, {"syms", no_argument, 0, 's'}, + {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS}, {"relocs", no_argument, 0, 'r'}, {"notes", no_argument, 0, 'n'}, {"dynamic", no_argument, 0, 'd'}, @@ -2977,7 +3158,8 @@ usage (FILE * stream) -t --section-details Display the section details\n\ -e --headers Equivalent to: -h -l -S\n\ -s --syms Display the symbol table\n\ - --symbols An alias for --syms\n\ + --symbols An alias for --syms\n\ + --dyn-syms Display the dynamic symbol table\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\ @@ -2994,7 +3176,8 @@ usage (FILE * stream) Dump the contents of section as relocated bytes\n\ -w[lLiaprmfFsoRt] or\n\ --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\ - =frames-interp,=str,=loc,=Ranges,=pubtypes]\n\ + =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\ + =trace_info,=trace_abbrev,=trace_aranges]\n\ Display the contents of DWARF2 debug sections\n")); #ifdef SUPPORT_DISASSEMBLY fprintf (stream, _("\ @@ -3202,6 +3385,9 @@ parse_args (int argc, char ** argv) dwarf_select_sections_by_names (optarg); } break; + case OPTION_DYN_SYMS: + do_dyn_syms++; + break; #ifdef SUPPORT_DISASSEMBLY case 'i': request_dump (DISASS_DUMP); @@ -3228,7 +3414,8 @@ parse_args (int argc, char ** argv) if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections && !do_segments && !do_header && !do_dump && !do_version && !do_histogram && !do_debugging && !do_arch && !do_notes - && !do_section_groups && !do_archive_index) + && !do_section_groups && !do_archive_index + && !do_dyn_syms) usage (stderr); else if (argc < 3) { @@ -3304,7 +3491,7 @@ process_file_header (void) (elf_header.e_ident[EI_VERSION] == EV_CURRENT ? "(current)" : (elf_header.e_ident[EI_VERSION] != EV_NONE - ? "" + ? _("") : ""))); printf (_(" OS/ABI: %s\n"), get_osabi_name (elf_header.e_ident[EI_OSABI])); @@ -3332,8 +3519,13 @@ process_file_header (void) (long) elf_header.e_ehsize); printf (_(" Size of program headers: %ld (bytes)\n"), (long) elf_header.e_phentsize); - printf (_(" Number of program headers: %ld\n"), + printf (_(" Number of program headers: %ld"), (long) elf_header.e_phnum); + if (section_headers != NULL + && elf_header.e_phnum == PN_XNUM + && section_headers[0].sh_info != 0) + printf (_(" (%ld)"), (long) section_headers[0].sh_info); + putc ('\n', stdout); printf (_(" Size of section headers: %ld (bytes)\n"), (long) elf_header.e_shentsize); printf (_(" Number of section headers: %ld"), @@ -3348,12 +3540,15 @@ process_file_header (void) printf (" (%u)", section_headers[0].sh_link); else if (elf_header.e_shstrndx != SHN_UNDEF && elf_header.e_shstrndx >= elf_header.e_shnum) - printf (" "); + printf (_(" ")); putc ('\n', stdout); } if (section_headers != NULL) { + if (elf_header.e_phnum == PN_XNUM + && section_headers[0].sh_info != 0) + elf_header.e_phnum = section_headers[0].sh_info; if (elf_header.e_shnum == SHN_UNDEF) elf_header.e_shnum = section_headers[0].sh_size; if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff)) @@ -3624,7 +3819,10 @@ process_program_headers (FILE * file) sec = find_section (".dynamic"); if (sec == NULL || sec->sh_size == 0) { - error (_("no .dynamic section in the dynamic segment\n")); + /* A corresponding .dynamic section is expected, but on + IA-64/OpenVMS it is OK for it to be missing. */ + if (!is_ia64_vms ()) + error (_("no .dynamic section in the dynamic segment\n")); break; } @@ -3691,7 +3889,8 @@ process_program_headers (FILE * file) for (j = 1; j < elf_header.e_shnum; j++, section++) { - if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (section, segment)) + if (ELF_SECTION_SIZE (section, segment) != 0 + && ELF_SECTION_IN_SEGMENT (section, segment)) printf ("%s ", SECTION_NAME (section)); } @@ -3992,8 +4191,9 @@ get_elf_section_flags (bfd_vma sh_flags) /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") }, /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") }, /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") }, - /* SPARC specific. */ + /* Generic. */ /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") }, + /* SPARC specific. */ /* 19 */ { STRING_COMMA_LEN ("ORDERED") } }; @@ -4025,6 +4225,7 @@ get_elf_section_flags (bfd_vma sh_flags) case SHF_OS_NONCONFORMING: sindex = 7; break; case SHF_GROUP: sindex = 8; break; case SHF_TLS: sindex = 9; break; + case SHF_EXCLUDE: sindex = 18; break; default: sindex = -1; @@ -4053,13 +4254,12 @@ get_elf_section_flags (bfd_vma sh_flags) case EM_386: case EM_486: case EM_X86_64: + case EM_L1OM: case EM_OLD_SPARCV9: case EM_SPARC32PLUS: case EM_SPARCV9: case EM_SPARC: - if (flag == SHF_EXCLUDE) - sindex = 18; - else if (flag == SHF_ORDERED) + if (flag == SHF_ORDERED) sindex = 19; break; default: @@ -4102,6 +4302,7 @@ get_elf_section_flags (bfd_vma sh_flags) case SHF_OS_NONCONFORMING: *p = 'O'; break; case SHF_GROUP: *p = 'G'; break; case SHF_TLS: *p = 'T'; break; + case SHF_EXCLUDE: *p = 'E'; break; default: if ((elf_header.e_machine == EM_X86_64 @@ -4169,7 +4370,7 @@ get_elf_section_flags (bfd_vma sh_flags) *p++ = ','; *p++ = ' '; } - sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size, + sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size, (unsigned long) unknown_flags); p += 10 + field_size; } @@ -4377,6 +4578,21 @@ process_section_headers (FILE * file) request_dump_bynumber (i, DEBUG_DUMP); else if (do_debug_frames && streq (name, ".eh_frame")) request_dump_bynumber (i, DEBUG_DUMP); + /* Trace sections for Itanium VMS. */ + else if ((do_debugging || do_trace_info || do_trace_abbrevs + || do_trace_aranges) + && const_strneq (name, ".trace_")) + { + name += sizeof (".trace_") - 1; + + if (do_debugging + || (do_trace_info && streq (name, "info")) + || (do_trace_abbrevs && streq (name, "abbrev")) + || (do_trace_aranges && streq (name, "aranges")) + ) + request_dump_bynumber (i, DEBUG_DUMP); + } + } if (! do_sections) @@ -4473,6 +4689,7 @@ process_section_headers (FILE * file) case EM_386: case EM_486: case EM_X86_64: + case EM_L1OM: case EM_OLD_SPARCV9: case EM_SPARC32PLUS: case EM_SPARCV9: @@ -4601,7 +4818,7 @@ process_section_headers (FILE * file) if (!do_section_details) printf (_("Key to Flags:\n\ W (write), A (alloc), X (execute), M (merge), S (strings)\n\ - I (info), L (link order), G (group), x (unknown)\n\ + I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\ O (extra OS processing required) o (OS specific), p (processor specific)\n")); return 1; @@ -4613,11 +4830,14 @@ get_group_flags (unsigned int flags) static char buff[32]; switch (flags) { + case 0: + return ""; + case GRP_COMDAT: - return "COMDAT"; + return "COMDAT "; default: - snprintf (buff, sizeof (buff), _("[: 0x%x]"), flags); + snprintf (buff, sizeof (buff), _("[: 0x%x] "), flags); break; } return buff; @@ -4763,7 +4983,7 @@ process_section_groups (FILE * file) strtab_size = strtab != NULL ? strtab_sec->sh_size : 0; } group_name = sym->st_name < strtab_size - ? strtab + sym->st_name : ""; + ? strtab + sym->st_name : _(""); } start = (unsigned char *) get_data (NULL, file, section->sh_offset, @@ -4777,7 +4997,7 @@ process_section_groups (FILE * file) if (do_section_groups) { - printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n", + printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"), get_group_flags (entry), i, name, group_name, size); printf (_(" [Index] Name\n")); @@ -4851,6 +5071,187 @@ process_section_groups (FILE * file) return 1; } +/* Data used to display dynamic fixups. */ + +struct ia64_vms_dynfixup +{ + bfd_vma needed_ident; /* Library ident number. */ + bfd_vma needed; /* Index in the dstrtab of the library name. */ + bfd_vma fixup_needed; /* Index of the library. */ + bfd_vma fixup_rela_cnt; /* Number of fixups. */ + bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */ +}; + +/* Data used to display dynamic relocations. */ + +struct ia64_vms_dynimgrela +{ + bfd_vma img_rela_cnt; /* Number of relocations. */ + bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */ +}; + +/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared + library). */ + +static void +dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup, + const char *strtab, unsigned int strtab_sz) +{ + Elf64_External_VMS_IMAGE_FIXUP *imfs; + long i; + const char *lib_name; + + imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off, + 1, fixup->fixup_rela_cnt * sizeof (*imfs), + _("dynamic section image fixups")); + if (!imfs) + return; + + if (fixup->needed < strtab_sz) + lib_name = strtab + fixup->needed; + else + { + warn ("corrupt library name index of 0x%lx found in dynamic entry", + (unsigned long) fixup->needed); + lib_name = "???"; + } + printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"), + (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident); + printf + (_("Seg Offset Type SymVec DataType\n")); + + for (i = 0; i < (long) fixup->fixup_rela_cnt; i++) + { + unsigned int type; + const char *rtype; + + printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg)); + printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset)); + type = BYTE_GET (imfs [i].type); + rtype = elf_ia64_reloc_type (type); + if (rtype == NULL) + printf (" 0x%08x ", type); + else + printf (" %-32s ", rtype); + printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index)); + printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type)); + } + + free (imfs); +} + +/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */ + +static void +dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela) +{ + Elf64_External_VMS_IMAGE_RELA *imrs; + long i; + + imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off, + 1, imgrela->img_rela_cnt * sizeof (*imrs), + _("dynamic section image relas")); + if (!imrs) + return; + + printf (_("\nImage relocs\n")); + printf + (_("Seg Offset Type Addend Seg Sym Off\n")); + + for (i = 0; i < (long) imgrela->img_rela_cnt; i++) + { + unsigned int type; + const char *rtype; + + printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg)); + printf ("%08" BFD_VMA_FMT "x ", + (bfd_vma) BYTE_GET (imrs [i].rela_offset)); + type = BYTE_GET (imrs [i].type); + rtype = elf_ia64_reloc_type (type); + if (rtype == NULL) + printf ("0x%08x ", type); + else + printf ("%-31s ", rtype); + print_vma (BYTE_GET (imrs [i].addend), FULL_HEX); + printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg)); + printf ("%08" BFD_VMA_FMT "x\n", + (bfd_vma) BYTE_GET (imrs [i].sym_offset)); + } + + free (imrs); +} + +/* Display IA-64 OpenVMS dynamic relocations and fixups. */ + +static int +process_ia64_vms_dynamic_relocs (FILE *file) +{ + struct ia64_vms_dynfixup fixup; + struct ia64_vms_dynimgrela imgrela; + Elf_Internal_Dyn *entry; + int res = 0; + bfd_vma strtab_off = 0; + bfd_vma strtab_sz = 0; + char *strtab = NULL; + + memset (&fixup, 0, sizeof (fixup)); + memset (&imgrela, 0, sizeof (imgrela)); + + /* Note: the order of the entries is specified by the OpenVMS specs. */ + for (entry = dynamic_section; + entry < dynamic_section + dynamic_nent; + entry++) + { + switch (entry->d_tag) + { + case DT_IA_64_VMS_STRTAB_OFFSET: + strtab_off = entry->d_un.d_val; + break; + case DT_STRSZ: + strtab_sz = entry->d_un.d_val; + if (strtab == NULL) + strtab = get_data (NULL, file, dynamic_addr + strtab_off, + 1, strtab_sz, _("dynamic string section")); + break; + + case DT_IA_64_VMS_NEEDED_IDENT: + fixup.needed_ident = entry->d_un.d_val; + break; + case DT_NEEDED: + fixup.needed = entry->d_un.d_val; + break; + case DT_IA_64_VMS_FIXUP_NEEDED: + fixup.fixup_needed = entry->d_un.d_val; + break; + case DT_IA_64_VMS_FIXUP_RELA_CNT: + fixup.fixup_rela_cnt = entry->d_un.d_val; + break; + case DT_IA_64_VMS_FIXUP_RELA_OFF: + fixup.fixup_rela_off = entry->d_un.d_val; + res++; + dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz); + break; + + case DT_IA_64_VMS_IMG_RELA_CNT: + imgrela.img_rela_cnt = entry->d_un.d_val; + break; + case DT_IA_64_VMS_IMG_RELA_OFF: + imgrela.img_rela_off = entry->d_un.d_val; + res++; + dump_ia64_vms_dynamic_relocs (file, &imgrela); + break; + + default: + break; + } + } + + if (strtab != NULL) + free (strtab); + + return res; +} + static struct { const char * name; @@ -4922,6 +5323,9 @@ process_relocs (FILE * file) } } + if (is_ia64_vms ()) + has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file); + if (! has_dynamic_reloc) printf (_("\nThere are no dynamic relocations in this file.\n")); } @@ -5066,16 +5470,22 @@ find_symbol_for_address (Elf_Internal_Sym * symtab, Elf_Internal_Sym * best = NULL; unsigned long i; + REMOVE_ARCH_BITS (addr.offset); + for (i = 0, sym = symtab; i < nsyms; ++i, ++sym) { + bfd_vma value = sym->st_value; + + REMOVE_ARCH_BITS (value); + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC && sym->st_name != 0 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx) - && addr.offset >= sym->st_value - && addr.offset - sym->st_value < dist) + && addr.offset >= value + && addr.offset - value < dist) { best = sym; - dist = addr.offset - sym->st_value; + dist = addr.offset - value; if (!dist) break; } @@ -5083,7 +5493,7 @@ find_symbol_for_address (Elf_Internal_Sym * symtab, if (best) { *symname = (best->st_name >= strtab_size - ? "" : strtab + best->st_name); + ? _("") : strtab + best->st_name); *offset = dist; return; } @@ -5137,7 +5547,7 @@ dump_ia64_unwind (struct ia64_unw_aux_info * aux) if (UNW_VER (stamp) != 1) { - printf ("\tUnknown version.\n"); + printf (_("\tUnknown version.\n")); continue; } @@ -5242,15 +5652,15 @@ slurp_ia64_unwind_table (FILE * file, { case 0: aux->table[i].start.section = sym->st_shndx; - aux->table[i].start.offset += rp->r_addend + sym->st_value; + aux->table[i].start.offset = rp->r_addend + sym->st_value; break; case 1: aux->table[i].end.section = sym->st_shndx; - aux->table[i].end.offset += rp->r_addend + sym->st_value; + aux->table[i].end.offset = rp->r_addend + sym->st_value; break; case 2: aux->table[i].info.section = sym->st_shndx; - aux->table[i].info.offset += rp->r_addend + sym->st_value; + aux->table[i].info.offset = rp->r_addend + sym->st_value; break; default: break; @@ -5738,84 +6148,660 @@ hppa_process_unwind (FILE * file) return 1; } -static int -process_unwind (FILE * file) +struct arm_section { - struct unwind_handler - { - int machtype; - int (* handler)(FILE *); - } handlers[] = - { - { EM_IA_64, ia64_process_unwind }, - { EM_PARISC, hppa_process_unwind }, - { 0, 0 } - }; - int i; + unsigned char *data; - if (!do_unwind) - return 1; + Elf_Internal_Shdr *sec; + Elf_Internal_Rela *rela; + unsigned long nrelas; + unsigned int rel_type; - for (i = 0; handlers[i].handler != NULL; i++) - if (elf_header.e_machine == handlers[i].machtype) - return handlers[i].handler (file); + Elf_Internal_Rela *next_rela; +}; - printf (_("\nThere are no unwind sections in this file.\n")); - return 1; +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. */ +}; + +static const char * +arm_print_vma_and_name (struct arm_unw_aux_info *aux, + bfd_vma fn, struct absaddr addr) +{ + const char *procname; + bfd_vma sym_offset; + + if (addr.section == SHN_UNDEF) + addr.offset = fn; + + find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab, + aux->strtab_size, addr, &procname, + &sym_offset); + + print_vma (fn, PREFIX_HEX); + + if (procname) + { + fputs (" <", stdout); + fputs (procname, stdout); + + if (sym_offset) + printf ("+0x%lx", (unsigned long) sym_offset); + fputc ('>', stdout); + } + + return procname; } static void -dynamic_section_mips_val (Elf_Internal_Dyn * entry) +arm_free_section (struct arm_section *arm_sec) { - switch (entry->d_tag) - { - case DT_MIPS_FLAGS: - if (entry->d_un.d_val == 0) - printf ("NONE\n"); - else - { - static const char * opts[] = - { - "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT", - "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS", - "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD", - "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF", - "RLD_ORDER_SAFE" - }; - unsigned int cnt; - int first = 1; - for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt) - if (entry->d_un.d_val & (1 << cnt)) - { - printf ("%s%s", first ? "" : " ", opts[cnt]); - first = 0; - } - puts (""); - } - break; + if (arm_sec->data != NULL) + free (arm_sec->data); - 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)); - else - printf ("\n", (long) entry->d_un.d_ptr); - break; + if (arm_sec->rela != NULL) + free (arm_sec->rela); +} - case DT_MIPS_TIME_STAMP: - { - char timebuf[20]; - struct tm * tmp; +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) +{ + Elf_Internal_Rela *rp; + Elf_Internal_Sym *sym; + const char * relname; + unsigned int word; + bfd_boolean wrapped; - time_t atime = entry->d_un.d_val; - tmp = gmtime (&atime); - 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); - } - break; + addr->section = SHN_UNDEF; + addr->offset = 0; - case DT_MIPS_RLD_VERSION: + if (sec != arm_sec->sec) + { + Elf_Internal_Shdr *relsec; + + arm_free_section (arm_sec); + + arm_sec->sec = sec; + arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1, + sec->sh_size, _("unwind data")); + + arm_sec->rela = NULL; + arm_sec->nrelas = 0; + + for (relsec = section_headers; + relsec < section_headers + elf_header.e_shnum; + ++relsec) + { + if (relsec->sh_info >= elf_header.e_shnum + || section_headers + relsec->sh_info != sec) + continue; + + 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; + break; + } + else if (relsec->sh_type == SHT_RELA) + { + if (!slurp_rela_relocs (aux->file, relsec->sh_offset, + relsec->sh_size, + & arm_sec->rela, & arm_sec->nrelas)) + return 0; + break; + } + } + + arm_sec->next_rela = arm_sec->rela; + } + + if (arm_sec->data == NULL) + return 0; + + word = byte_get (arm_sec->data + word_offset, 4); + + wrapped = FALSE; + for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++) + { + bfd_vma prelval, offset; + + if (rp->r_offset > word_offset && !wrapped) + { + rp = arm_sec->rela; + wrapped = TRUE; + } + if (rp->r_offset > word_offset) + break; + + if (rp->r_offset & 3) + { + warn (_("Skipping unexpected relocation at offset 0x%lx\n"), + (unsigned long) rp->r_offset); + continue; + } + + if (rp->r_offset < word_offset) + continue; + + 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; + } + + sym = aux->symtab + ELF32_R_SYM (rp->r_info); + + if (arm_sec->rel_type == SHT_REL) + { + offset = word & 0x7fffffff; + if (offset & 0x40000000) + offset |= ~ (bfd_vma) 0x7fffffff; + } + else + offset = rp->r_addend; + + offset += sym->st_value; + prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset); + + word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff); + addr->section = sym->st_shndx; + addr->offset = offset; + break; + } + + *wordp = word; + arm_sec->next_rela = rp; + + return 1; +} + +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) +{ + int per_index; + unsigned int more_words; + struct absaddr addr; + +#define ADVANCE \ + if (remaining == 0 && more_words) \ + { \ + data_offset += 4; \ + if (!arm_section_get_word (aux, data_arm_sec, data_sec, \ + data_offset, &word, &addr)) \ + return; \ + remaining = 4; \ + more_words--; \ + } \ + +#define GET_OP(OP) \ + ADVANCE; \ + if (remaining) \ + { \ + remaining--; \ + (OP) = word >> 24; \ + word <<= 8; \ + } \ + else \ + { \ + printf (_("[Truncated opcode]\n")); \ + return; \ + } \ + printf (_("0x%02x "), OP) + + if (remaining == 0) + { + /* Fetch the first word. */ + if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset, + &word, &addr)) + return; + remaining = 4; + } + + if ((word & 0x80000000) == 0) + { + /* Expand prel31 for personality routine. */ + bfd_vma fn; + const char *procname; + + fn = word; + if (fn & 0x40000000) + fn |= ~ (bfd_vma) 0x7fffffff; + fn = fn + data_sec->sh_addr + data_offset; + + printf (_(" Personality routine: ")); + procname = arm_print_vma_and_name (aux, fn, addr); + fputc ('\n', stdout); + + /* The GCC personality routines use the standard compact + encoding, starting with one byte giving the number of + words. */ + if (procname != NULL + && (const_strneq (procname, "__gcc_personality_v0") + || const_strneq (procname, "__gxx_personality_v0") + || const_strneq (procname, "__gcj_personality_v0") + || const_strneq (procname, "__gnu_objc_personality_v0"))) + { + remaining = 0; + more_words = 1; + ADVANCE; + if (!remaining) + { + printf (_(" [Truncated data]\n")); + return; + } + more_words = word >> 24; + word <<= 8; + remaining--; + } + else + return; + } + else + { + + per_index = (word >> 24) & 0x7f; + if (per_index != 0 && per_index != 1 && per_index != 2) + { + printf (_(" [reserved compact index %d]\n"), per_index); + return; + } + + printf (_(" Compact model %d\n"), per_index); + if (per_index == 0) + { + more_words = 0; + word <<= 8; + remaining--; + } + else + { + more_words = (word >> 16) & 0xff; + word <<= 16; + remaining -= 2; + } + } + + /* Decode the unwinding instructions. */ + while (1) + { + unsigned int op, op2; + + ADVANCE; + if (remaining == 0) + break; + remaining--; + op = word >> 24; + word <<= 8; + + printf (_(" 0x%02x "), op); + + if ((op & 0xc0) == 0x00) + { + int offset = ((op & 0x3f) << 2) + 4; + printf (_(" vsp = vsp + %d"), offset); + } + else if ((op & 0xc0) == 0x40) + { + int offset = ((op & 0x3f) << 2) + 4; + printf (_(" vsp = vsp - %d"), offset); + } + else if ((op & 0xf0) == 0x80) + { + GET_OP (op2); + if (op == 0x80 && op2 == 0) + printf (_("Refuse to unwind")); + else + { + unsigned int mask = ((op & 0x0f) << 8) | op2; + int first = 1; + int i; + + printf ("pop {"); + for (i = 0; i < 12; i++) + if (mask & (1 << i)) + { + if (first) + first = 0; + else + printf (", "); + printf ("r%d", 4 + i); + } + printf ("}"); + } + } + else if ((op & 0xf0) == 0x90) + { + if (op == 0x9d || op == 0x9f) + printf (_(" [Reserved]")); + else + printf (_(" vsp = r%d"), op & 0x0f); + } + else if ((op & 0xf0) == 0xa0) + { + int end = 4 + (op & 0x07); + int first = 1; + int i; + printf (" pop {"); + for (i = 4; i <= end; i++) + { + if (first) + first = 0; + else + printf (", "); + printf ("r%d", i); + } + if (op & 0x08) + { + if (first) + printf (", "); + printf ("r14"); + } + printf ("}"); + } + else if (op == 0xb0) + printf (_(" finish")); + else if (op == 0xb1) + { + GET_OP (op2); + if (op2 == 0 || (op2 & 0xf0) != 0) + printf (_("[Spare]")); + else + { + unsigned int mask = op2 & 0x0f; + int first = 1; + int i; + printf ("pop {"); + for (i = 0; i < 12; i++) + if (mask & (1 << i)) + { + if (first) + first = 0; + else + printf (", "); + printf ("r%d", i); + } + printf ("}"); + } + } + else if (op == 0xb2) + { + unsigned char buf[9]; + unsigned int i, len; + unsigned long offset; + for (i = 0; i < sizeof (buf); i++) + { + GET_OP (buf[i]); + if ((buf[i] & 0x80) == 0) + break; + } + assert (i < sizeof (buf)); + offset = read_uleb128 (buf, &len); + assert (len == i + 1); + offset = offset * 4 + 0x204; + printf (_("vsp = vsp + %ld"), offset); + } + else + { + if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9) + { + GET_OP (op2); + printf (_("[unsupported two-byte opcode]")); + } + else + { + printf (_(" [unsupported opcode]")); + } + } + printf ("\n"); + } + + /* Decode the descriptors. Not implemented. */ +} + +static void +dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec) +{ + struct arm_section exidx_arm_sec, extab_arm_sec; + unsigned int i, exidx_len; + + memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec)); + memset (&extab_arm_sec, 0, sizeof (extab_arm_sec)); + exidx_len = exidx_sec->sh_size / 8; + + for (i = 0; i < exidx_len; i++) + { + unsigned int exidx_fn, exidx_entry; + struct absaddr fn_addr, entry_addr; + bfd_vma fn; + + 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)) + { + arm_free_section (&exidx_arm_sec); + arm_free_section (&extab_arm_sec); + return; + } + + fn = exidx_fn & 0x7fffffff; + if (fn & 0x40000000) + fn |= ~ (bfd_vma) 0x7fffffff; + fn = fn + exidx_sec->sh_addr + 8 * i; + + arm_print_vma_and_name (aux, fn, entry_addr); + fputs (": ", stdout); + + if (exidx_entry == 1) + { + print_vma (exidx_entry, PREFIX_HEX); + fputs (" [cantunwind]\n", stdout); + } + else if (exidx_entry & 0x80000000) + { + print_vma (exidx_entry, PREFIX_HEX); + fputc ('\n', stdout); + decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL); + } + else + { + bfd_vma table, table_offset = 0; + Elf_Internal_Shdr *table_sec; + + fputs ("@", stdout); + table = exidx_entry; + if (table & 0x40000000) + table |= ~ (bfd_vma) 0x7fffffff; + table = table + exidx_sec->sh_addr + 8 * i + 4; + print_vma (table, PREFIX_HEX); + printf ("\n"); + + /* Locate the matching .ARM.extab. */ + if (entry_addr.section != SHN_UNDEF + && entry_addr.section < elf_header.e_shnum) + { + table_sec = section_headers + entry_addr.section; + table_offset = entry_addr.offset; + } + else + { + table_sec = find_section_by_address (table); + if (table_sec != NULL) + table_offset = table - table_sec->sh_addr; + } + if (table_sec == NULL) + { + warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"), + (unsigned long) table); + continue; + } + decode_arm_unwind (aux, 0, 0, table_offset, table_sec, + &extab_arm_sec); + } + } + + printf ("\n"); + + arm_free_section (&exidx_arm_sec); + arm_free_section (&extab_arm_sec); +} + +static int +arm_process_unwind (FILE *file) +{ + struct arm_unw_aux_info aux; + Elf_Internal_Shdr *unwsec = NULL; + Elf_Internal_Shdr *strsec; + Elf_Internal_Shdr *sec; + unsigned long i; + + memset (& aux, 0, sizeof (aux)); + aux.file = file; + + if (string_table == NULL) + return 1; + + 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); + + strsec = section_headers + sec->sh_link; + aux.strtab = get_data (NULL, file, strsec->sh_offset, + 1, strsec->sh_size, _("string table")); + aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; + } + else if (sec->sh_type == SHT_ARM_EXIDX) + unwsec = sec; + } + + if (!unwsec) + printf (_("\nThere are no unwind sections in this file.\n")); + + for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) + { + if (sec->sh_type == SHT_ARM_EXIDX) + { + 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); + } + } + + if (aux.symtab) + free (aux.symtab); + if (aux.strtab) + free ((char *) aux.strtab); + + return 1; +} + +static int +process_unwind (FILE * file) +{ + struct unwind_handler + { + int machtype; + int (* handler)(FILE *); + } handlers[] = + { + { EM_ARM, arm_process_unwind }, + { EM_IA_64, ia64_process_unwind }, + { EM_PARISC, hppa_process_unwind }, + { 0, 0 } + }; + int i; + + if (!do_unwind) + return 1; + + 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; +} + +static void +dynamic_section_mips_val (Elf_Internal_Dyn * entry) +{ + switch (entry->d_tag) + { + case DT_MIPS_FLAGS: + if (entry->d_un.d_val == 0) + printf (_("NONE\n")); + else + { + static const char * opts[] = + { + "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT", + "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS", + "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD", + "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF", + "RLD_ORDER_SAFE" + }; + unsigned int cnt; + int first = 1; + + for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt) + if (entry->d_un.d_val & (1 << cnt)) + { + 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)); + else + printf (_("\n"), (long) entry->d_un.d_ptr); + break; + + case DT_MIPS_TIME_STAMP: + { + char timebuf[20]; + struct tm * tmp; + + time_t atime = entry->d_un.d_val; + tmp = gmtime (&atime); + 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); + } + break; + + case DT_MIPS_RLD_VERSION: case DT_MIPS_LOCAL_GOTNO: case DT_MIPS_CONFLICTNO: case DT_MIPS_LIBLISTNO: @@ -5836,7 +6822,6 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry) } } - static void dynamic_section_parisc_val (Elf_Internal_Dyn * entry) { @@ -5899,6 +6884,29 @@ dynamic_section_parisc_val (Elf_Internal_Dyn * entry) putchar ('\n'); } +#ifdef BFD64 + +/* VMS vs Unix time offset and factor. */ + +#define VMS_EPOCH_OFFSET 35067168000000000LL +#define VMS_GRANULARITY_FACTOR 10000000 + +/* Display a VMS time in a human readable format. */ + +static void +print_vms_time (bfd_int64_t vmstime) +{ + struct tm *tm; + time_t unxtime; + + unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR; + tm = gmtime (&unxtime); + printf ("%04u-%02u-%02uT%02u:%02u:%02u", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +} +#endif /* BFD64 */ + static void dynamic_section_ia64_val (Elf_Internal_Dyn * entry) { @@ -5911,6 +6919,46 @@ dynamic_section_ia64_val (Elf_Internal_Dyn * entry) print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX); break; + case DT_IA_64_VMS_LINKTIME: +#ifdef BFD64 + print_vms_time (entry->d_un.d_val); +#endif + break; + + case DT_IA_64_VMS_LNKFLAGS: + print_vma (entry->d_un.d_ptr, PREFIX_HEX); + if (entry->d_un.d_val & VMS_LF_CALL_DEBUG) + printf (" CALL_DEBUG"); + if (entry->d_un.d_val & VMS_LF_NOP0BUFS) + printf (" NOP0BUFS"); + if (entry->d_un.d_val & VMS_LF_P0IMAGE) + printf (" P0IMAGE"); + if (entry->d_un.d_val & VMS_LF_MKTHREADS) + printf (" MKTHREADS"); + if (entry->d_un.d_val & VMS_LF_UPCALLS) + printf (" UPCALLS"); + if (entry->d_un.d_val & VMS_LF_IMGSTA) + printf (" IMGSTA"); + if (entry->d_un.d_val & VMS_LF_INITIALIZE) + printf (" INITIALIZE"); + if (entry->d_un.d_val & VMS_LF_MAIN) + printf (" MAIN"); + if (entry->d_un.d_val & VMS_LF_EXE_INIT) + printf (" EXE_INIT"); + if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG) + printf (" TBK_IN_IMG"); + if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG) + printf (" DBG_IN_IMG"); + if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF) + printf (" TBK_IN_DSF"); + if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF) + printf (" DBG_IN_DSF"); + if (entry->d_un.d_val & VMS_LF_SIGNATURES) + printf (" SIGNATURES"); + if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF) + printf (" REL_SEG_OFF"); + break; + default: print_vma (entry->d_un.d_ptr, PREFIX_HEX); break; @@ -6034,7 +7082,7 @@ print_dynamic_flags (bfd_vma flags) case DF_TEXTREL: fputs ("TEXTREL", stdout); break; case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break; case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break; - default: fputs ("unknown", stdout); break; + default: fputs (_("unknown"), stdout); break; } } puts (""); @@ -6511,7 +7559,7 @@ process_dynamic_section (FILE * file) if (do_dynamic) { print_vma (entry->d_un.d_val, UNSIGNED); - printf (" (bytes)\n"); + printf (_(" (bytes)\n")); } break; @@ -6632,8 +7680,16 @@ get_ver_flags (unsigned int flags) strcat (buff, "WEAK "); } - if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)) - strcat (buff, "| "); + if (flags & VER_FLG_INFO) + { + if (flags & (VER_FLG_BASE|VER_FLG_WEAK)) + strcat (buff, "| "); + + strcat (buff, "INFO "); + } + + if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO)) + strcat (buff, _("| ")); return buff; } @@ -6675,7 +7731,7 @@ process_version_sections (FILE * file) (unsigned long) section->sh_offset, section->sh_link, section->sh_link < elf_header.e_shnum ? SECTION_NAME (section_headers + section->sh_link) - : ""); + : _("")); edefs = (Elf_External_Verdef *) get_data (NULL, file, section->sh_offset, 1,section->sh_size, @@ -6777,7 +7833,7 @@ process_version_sections (FILE * file) (unsigned long) section->sh_offset, section->sh_link, section->sh_link < elf_header.e_shnum ? SECTION_NAME (section_headers + section->sh_link) - : ""); + : _("")); eneed = (Elf_External_Verneed *) get_data (NULL, file, section->sh_offset, 1, @@ -7196,6 +8252,67 @@ get_mips_symbol_other (unsigned int other) } } +static const char * +get_ia64_symbol_other (unsigned int other) +{ + if (is_ia64_vms ()) + { + static char res[32]; + + res[0] = 0; + + /* Function types is for images and .STB files only. */ + switch (elf_header.e_type) + { + case ET_DYN: + case ET_EXEC: + switch (VMS_ST_FUNC_TYPE (other)) + { + case VMS_SFT_CODE_ADDR: + strcat (res, " CA"); + break; + case VMS_SFT_SYMV_IDX: + strcat (res, " VEC"); + break; + case VMS_SFT_FD: + strcat (res, " FD"); + break; + case VMS_SFT_RESERVE: + strcat (res, " RSV"); + break; + default: + abort (); + } + break; + default: + break; + } + switch (VMS_ST_LINKAGE (other)) + { + case VMS_STL_IGNORE: + strcat (res, " IGN"); + break; + case VMS_STL_RESERVE: + strcat (res, " RSV"); + break; + case VMS_STL_STD: + strcat (res, " STD"); + break; + case VMS_STL_LNK: + strcat (res, " LNK"); + break; + default: + abort (); + } + + if (res[0] != 0) + return res + 1; + else + return res; + } + return NULL; +} + static const char * get_symbol_other (unsigned int other) { @@ -7209,6 +8326,10 @@ get_symbol_other (unsigned int other) { case EM_MIPS: result = get_mips_symbol_other (other); + break; + case EM_IA_64: + result = get_ia64_symbol_other (other); + break; default: break; } @@ -7325,7 +8446,7 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn) if (VALID_DYNAMIC_NAME (psym->st_name)) print_symbol (25, GET_DYNAMIC_NAME (psym->st_name)); else - printf (" ", psym->st_name); + printf (_(" "), psym->st_name); putchar ('\n'); } @@ -7343,12 +8464,14 @@ process_symbol_table (FILE * file) bfd_vma * gnuchains = NULL; bfd_vma gnusymidx = 0; - if (! do_syms && !do_histogram) + if (!do_syms && !do_dyn_syms && !do_histogram) return 1; if (dynamic_info[DT_HASH] && (do_histogram - || (do_using_dynamic && dynamic_strings != NULL))) + || (do_using_dynamic + && !do_dyn_syms + && dynamic_strings != NULL))) { unsigned char nb[8]; unsigned char nc[8]; @@ -7404,7 +8527,9 @@ process_symbol_table (FILE * file) if (dynamic_info_DT_GNU_HASH && (do_histogram - || (do_using_dynamic && dynamic_strings != NULL))) + || (do_using_dynamic + && !do_dyn_syms + && dynamic_strings != NULL))) { unsigned char nb[16]; bfd_vma i, maxchain = 0xffffffff, bitmaskwords; @@ -7561,7 +8686,7 @@ process_symbol_table (FILE * file) } } } - else if (do_syms && !do_using_dynamic) + else if (do_dyn_syms || (do_syms && !do_using_dynamic)) { unsigned int i; @@ -7575,8 +8700,10 @@ process_symbol_table (FILE * file) Elf_Internal_Sym * symtab; Elf_Internal_Sym * psym; - if ( section->sh_type != SHT_SYMTAB - && section->sh_type != SHT_DYNSYM) + if ((section->sh_type != SHT_SYMTAB + && section->sh_type != SHT_DYNSYM) + || (!do_syms + && section->sh_type == SHT_SYMTAB)) continue; printf (_("\nSymbol table '%s' contains %lu entries:\n"), @@ -7626,7 +8753,7 @@ process_symbol_table (FILE * file) printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))); printf (" %4s ", get_symbol_index_type (psym->st_shndx)); print_symbol (25, psym->st_name < strtab_size - ? strtab + psym->st_name : ""); + ? strtab + psym->st_name : _("")); if (section->sh_type == SHT_DYNSYM && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0) @@ -7706,7 +8833,7 @@ process_symbol_table (FILE * file) { printf ("@%s (%d)", ivna.vna_name < strtab_size - ? strtab + ivna.vna_name : "", + ? strtab + ivna.vna_name : _(""), ivna.vna_other); check_def = 0; } @@ -7759,7 +8886,7 @@ process_symbol_table (FILE * file) printf ((vers_data & VERSYM_HIDDEN) ? "@%s" : "@@%s", ivda.vda_name < strtab_size - ? strtab + ivda.vda_name : ""); + ? strtab + ivda.vda_name : _("")); } } } @@ -7935,7 +9062,7 @@ process_syminfo (FILE * file ATTRIBUTE_UNUSED) if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name)) print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name)); else - printf ("", dynamic_symbols[i].st_name); + printf (_(""), dynamic_symbols[i].st_name); putchar (' '); switch (dynamic_syminfo[i].si_boundto) @@ -8152,6 +9279,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) || reloc_type == 23; /* R_SPARC_UA32. */ case EM_SPU: return reloc_type == 6; /* R_SPU_ADDR32 */ + case EM_TI_C6000: + return reloc_type == 1; /* R_C6000_ABS32. */ case EM_CYGNUS_V850: case EM_V850: return reloc_type == 6; /* R_V850_ABS32. */ @@ -8335,6 +9464,8 @@ is_16bit_abs_reloc (unsigned int reloc_type) case EM_ALTERA_NIOS2: case EM_NIOS32: return reloc_type == 9; /* R_NIOS_16. */ + case EM_TI_C6000: + return reloc_type == 2; /* R_C6000_ABS16. */ case EM_XC16X: case EM_C166: return reloc_type == 2; /* R_XC16C_ABS_16. */ @@ -8371,6 +9502,7 @@ is_none_reloc (unsigned int reloc_type) case EM_L1OM: /* R_X86_64_NONE. */ case EM_MN10300: /* R_MN10300_NONE. */ case EM_M32R: /* R_M32R_NONE. */ + case EM_TI_C6000:/* R_C6000_NONE. */ case EM_XC16X: case EM_C166: /* R_XC16X_NONE. */ return reloc_type == 0; @@ -8577,7 +9709,6 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file) { Elf_Internal_Shdr * relsec; bfd_size_type num_bytes; - bfd_vma addr; char * data; char * end; char * start; @@ -8611,7 +9742,6 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file) } num_bytes = section->sh_size; - addr = section->sh_addr; data = start; end = start + num_bytes; some_strings_shown = FALSE; @@ -8739,12 +9869,10 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */ static int -uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size) +uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED, + dwarf_size_type *size ATTRIBUTE_UNUSED) { #ifndef HAVE_ZLIB_H - /* These are just to quiet gcc. */ - buffer = 0; - size = 0; return FALSE; #else dwarf_size_type compressed_size = *size; @@ -8832,8 +9960,11 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, return 0; if (section_is_compressed) - if (! uncompress_section_contents (§ion->start, §ion->size)) - return 0; + { + if (! uncompress_section_contents (§ion->start, §ion->size)) + return 0; + sec->sh_size = section->size; + } if (debug_displays [debug].relocate) apply_relocations ((FILE *) file, sec, section->start); @@ -9042,10 +10173,11 @@ static const char * arm_attr_tag_CPU_arch[] = static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"}; static const char * arm_attr_tag_THUMB_ISA_use[] = {"No", "Thumb-1", "Thumb-2"}; -static const char * arm_attr_tag_VFP_arch[] = +static const char * arm_attr_tag_FP_arch[] = {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"}; static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"}; -static const char * arm_attr_tag_Advanced_SIMD_arch[] = {"No", "NEONv1"}; +static const char * arm_attr_tag_Advanced_SIMD_arch[] = + {"No", "NEONv1", "NEONv1 with Fused-MAC"}; static const char * arm_attr_tag_PCS_config[] = {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004", "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"}; @@ -9066,13 +10198,10 @@ static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"}; static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"}; static const char * arm_attr_tag_ABI_FP_number_model[] = {"Unused", "Finite", "RTABI", "IEEE 754"}; -static const char * arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"}; -static const char * arm_attr_tag_ABI_align8_preserved[] = - {"No", "Yes, except leaf SP", "Yes"}; static const char * arm_attr_tag_ABI_enum_size[] = {"Unused", "small", "int", "forced to int"}; static const char * arm_attr_tag_ABI_HardFP_use[] = - {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"}; + {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"}; static const char * arm_attr_tag_ABI_VFP_args[] = {"AAPCS", "VFP registers", "custom"}; static const char * arm_attr_tag_ABI_WMMX_args[] = @@ -9084,14 +10213,21 @@ static const char * arm_attr_tag_ABI_FP_optimization_goals[] = {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size", "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"}; static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"}; -static const char * arm_attr_tag_VFP_HP_extension[] = +static const char * arm_attr_tag_FP_HP_extension[] = {"Not Allowed", "Allowed"}; static const char * arm_attr_tag_ABI_FP_16bit_format[] = {"None", "IEEE 754", "Alternative Format"}; +static const char * arm_attr_tag_MPextension_use[] = + {"Not Allowed", "Allowed"}; +static const char * arm_attr_tag_DIV_use[] = + {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed", + "Allowed in v7-A with integer division extension"}; static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"}; static const char * arm_attr_tag_Virtualization_use[] = + {"Not Allowed", "TrustZone", "Virtualization Extensions", + "TrustZone and Virtualization Extensions"}; +static const char * arm_attr_tag_MPextension_use_legacy[] = {"Not Allowed", "Allowed"}; -static const char * arm_attr_tag_MPextension_use[] = {"Not Allowed", "Allowed"}; #define LOOKUP(id, name) \ {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name} @@ -9103,7 +10239,7 @@ static arm_attr_public_tag arm_attr_public_tags[] = {7, "CPU_arch_profile", 0, NULL}, LOOKUP(8, ARM_ISA_use), LOOKUP(9, THUMB_ISA_use), - LOOKUP(10, VFP_arch), + LOOKUP(10, FP_arch), LOOKUP(11, WMMX_arch), LOOKUP(12, Advanced_SIMD_arch), LOOKUP(13, PCS_config), @@ -9117,8 +10253,8 @@ static arm_attr_public_tag arm_attr_public_tags[] = LOOKUP(21, ABI_FP_exceptions), LOOKUP(22, ABI_FP_user_exceptions), LOOKUP(23, ABI_FP_number_model), - LOOKUP(24, ABI_align8_needed), - LOOKUP(25, ABI_align8_preserved), + {24, "ABI_align_needed", 0, NULL}, + {25, "ABI_align_preserved", 0, NULL}, LOOKUP(26, ABI_enum_size), LOOKUP(27, ABI_HardFP_use), LOOKUP(28, ABI_VFP_args), @@ -9127,44 +10263,19 @@ static arm_attr_public_tag arm_attr_public_tags[] = LOOKUP(31, ABI_FP_optimization_goals), {32, "compatibility", 0, NULL}, LOOKUP(34, CPU_unaligned_access), - LOOKUP(36, VFP_HP_extension), + LOOKUP(36, FP_HP_extension), LOOKUP(38, ABI_FP_16bit_format), + LOOKUP(42, MPextension_use), + LOOKUP(44, DIV_use), {64, "nodefaults", 0, NULL}, {65, "also_compatible_with", 0, NULL}, LOOKUP(66, T2EE_use), {67, "conformance", 1, NULL}, LOOKUP(68, Virtualization_use), - LOOKUP(70, MPextension_use) + LOOKUP(70, MPextension_use_legacy) }; #undef LOOKUP -/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of - bytes read. */ - -static unsigned int -read_uleb128 (unsigned char * p, unsigned int * plen) -{ - unsigned char c; - unsigned int val; - int shift; - int len; - - val = 0; - shift = 0; - len = 0; - do - { - c = *(p++); - len++; - val |= ((unsigned int)c & 0x7f) << shift; - shift += 7; - } - while (c & 0x80); - - *plen = len; - return val; -} - static unsigned char * display_arm_attribute (unsigned char * p) { @@ -9200,24 +10311,63 @@ display_arm_attribute (unsigned char * p) p += len; switch (val) { - case 0: printf ("None\n"); break; - case 'A': printf ("Application\n"); break; - case 'R': printf ("Realtime\n"); break; - case 'M': printf ("Microcontroller\n"); break; + case 0: printf (_("None\n")); break; + case 'A': printf (_("Application\n")); break; + case 'R': printf (_("Realtime\n")); break; + case 'M': printf (_("Microcontroller\n")); break; + case 'S': printf (_("Application or Realtime\n")); break; default: printf ("??? (%d)\n", val); break; } break; + case 24: /* Tag_align_needed. */ + val = read_uleb128 (p, &len); + p += len; + switch (val) + { + case 0: printf (_("None\n")); break; + case 1: printf (_("8-byte\n")); break; + case 2: printf (_("4-byte\n")); break; + case 3: printf ("??? 3\n"); break; + default: + if (val <= 12) + printf (_("8-byte and up to %d-byte extended\n"), + 1 << val); + else + printf ("??? (%d)\n", val); + break; + } + break; + + case 25: /* Tag_align_preserved. */ + val = read_uleb128 (p, &len); + p += len; + switch (val) + { + case 0: printf (_("None\n")); break; + case 1: printf (_("8-byte, except leaf SP\n")); break; + case 2: printf (_("8-byte\n")); break; + case 3: printf ("??? 3\n"); break; + default: + if (val <= 12) + printf (_("8-byte and up to %d-byte extended\n"), + 1 << val); + else + printf ("??? (%d)\n", val); + break; + } + break; + case 32: /* Tag_compatibility. */ val = read_uleb128 (p, &len); p += len; - printf ("flag = %d, vendor = %s\n", val, p); + printf (_("flag = %d, vendor = %s\n"), val, p); p += strlen ((char *) p) + 1; break; case 64: /* Tag_nodefaults. */ p++; - printf ("True\n"); + printf (_("True\n")); break; case 65: /* Tag_also_compatible_with. */ @@ -9301,7 +10451,7 @@ display_gnu_attribute (unsigned char * p, { val = read_uleb128 (p, &len); p += len; - printf ("flag = %d, vendor = %s\n", val, p); + printf (_("flag = %d, vendor = %s\n"), val, p); p += strlen ((char *) p) + 1; return p; } @@ -9346,16 +10496,16 @@ display_power_gnu_attribute (unsigned char * p, int tag) switch (val) { case 0: - printf ("Hard or soft float\n"); + printf (_("Hard or soft float\n")); break; case 1: - printf ("Hard float\n"); + printf (_("Hard float\n")); break; case 2: - printf ("Soft float\n"); + printf (_("Soft float\n")); break; case 3: - printf ("Single-precision hard float\n"); + printf (_("Single-precision hard float\n")); break; default: printf ("??? (%d)\n", val); @@ -9372,10 +10522,10 @@ display_power_gnu_attribute (unsigned char * p, int tag) switch (val) { case 0: - printf ("Any\n"); + printf (_("Any\n")); break; case 1: - printf ("Generic\n"); + printf (_("Generic\n")); break; case 2: printf ("AltiVec\n"); @@ -9398,13 +10548,13 @@ display_power_gnu_attribute (unsigned char * p, int tag) switch (val) { case 0: - printf ("Any\n"); + printf (_("Any\n")); break; case 1: printf ("r3/r4\n"); break; case 2: - printf ("Memory\n"); + printf (_("Memory\n")); break; default: printf ("??? (%d)\n", val); @@ -9450,19 +10600,19 @@ display_mips_gnu_attribute (unsigned char * p, int tag) switch (val) { case 0: - printf ("Hard or soft float\n"); + printf (_("Hard or soft float\n")); break; case 1: - printf ("Hard float (-mdouble-float)\n"); + printf (_("Hard float (double precision)\n")); break; case 2: - printf ("Hard float (-msingle-float)\n"); + printf (_("Hard float (single precision)\n")); break; case 3: - printf ("Soft float\n"); + printf (_("Soft float\n")); break; case 4: - printf ("64-bit float (-mips32r2 -mfp64)\n"); + printf (_("64-bit float (-mips32r2 -mfp64)\n")); break; default: printf ("??? (%d)\n", val); @@ -9492,6 +10642,73 @@ display_mips_gnu_attribute (unsigned char * p, int tag) return p; } +static unsigned char * +display_tic6x_attribute (unsigned char * p) +{ + int tag; + unsigned int len; + int val; + + tag = read_uleb128 (p, &len); + p += len; + + switch (tag) + { + case Tag_C6XABI_Tag_CPU_arch: + val = read_uleb128 (p, &len); + p += len; + printf (" Tag_C6XABI_Tag_CPU_arch: "); + + switch (val) + { + case C6XABI_Tag_CPU_arch_none: + printf (_("None\n")); + break; + case C6XABI_Tag_CPU_arch_C62X: + printf ("C62x\n"); + break; + case C6XABI_Tag_CPU_arch_C67X: + printf ("C67x\n"); + break; + case C6XABI_Tag_CPU_arch_C67XP: + printf ("C67x+\n"); + break; + case C6XABI_Tag_CPU_arch_C64X: + printf ("C64x\n"); + break; + case C6XABI_Tag_CPU_arch_C64XP: + printf ("C64x+\n"); + break; + case C6XABI_Tag_CPU_arch_C674X: + printf ("C674x\n"); + break; + default: + printf ("??? (%d)\n", val); + break; + } + return p; + + case 32: + /* Tag_compatibility - treated as generic by binutils for now + although not currently specified for C6X. */ + val = read_uleb128 (p, &len); + p += len; + printf (_("flag = %d, vendor = %s\n"), val, p); + p += strlen ((char *) p) + 1; + return p; + } + + printf (" Tag_unknown_%d: ", tag); + + /* No general documentation of handling unknown attributes, treat as + ULEB128 for now. */ + val = read_uleb128 (p, &len); + p += len; + printf ("%d (0x%x)\n", val, val); + + return p; +} + static int process_attributes (FILE * file, const char * public_name, @@ -9543,7 +10760,7 @@ process_attributes (FILE * file, } len -= section_len; - printf ("Attribute Section: %s\n", p); + printf (_("Attribute Section: %s\n"), p); if (public_name && streq ((char *) p, public_name)) public_section = TRUE; @@ -9580,13 +10797,13 @@ process_attributes (FILE * file, switch (tag) { case 1: - printf ("File Attributes\n"); + printf (_("File Attributes\n")); break; case 2: - printf ("Section Attributes:"); + printf (_("Section Attributes:")); goto do_numlist; case 3: - printf ("Symbol Attributes:"); + printf (_("Symbol Attributes:")); do_numlist: for (;;) { @@ -9601,7 +10818,7 @@ process_attributes (FILE * file, printf ("\n"); break; default: - printf ("Unknown tag: %d\n", tag); + printf (_("Unknown tag: %d\n"), tag); public_section = FALSE; break; } @@ -9620,7 +10837,7 @@ process_attributes (FILE * file, else { /* ??? Do something sensible, like dump hex. */ - printf (" Unknown section contexts\n"); + printf (_(" Unknown section contexts\n")); p = end; } } @@ -9648,6 +10865,13 @@ process_power_specific (FILE * file) display_power_gnu_attribute); } +static int +process_tic6x_specific (FILE * file) +{ + return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES, + display_tic6x_attribute, NULL); +} + /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT. Print the Address, Access and Initial fields of an entry at VMA ADDR and return the VMA of the next entry. */ @@ -9664,7 +10888,7 @@ print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr) printf ("%10s", ""); printf (" "); if (data == NULL) - printf ("%*s", is_32bit_elf ? 8 : 16, ""); + printf ("%*s", is_32bit_elf ? 8 : 16, _("")); else { bfd_vma entry; @@ -9686,7 +10910,7 @@ print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr) print_vma (addr, LONG_HEX); printf (" "); if (data == NULL) - printf ("%*s", is_32bit_elf ? 8 : 16, ""); + printf ("%*s", is_32bit_elf ? 8 : 16, _("")); else { bfd_vma entry; @@ -9784,9 +11008,9 @@ process_mips_specific (FILE * file) _("liblist")); if (elib) { - printf ("\nSection '.liblist' contains %lu entries:\n", + printf (_("\nSection '.liblist' contains %lu entries:\n"), (unsigned long) liblistno); - fputs (" Library Time Stamp Checksum Version Flags\n", + fputs (_(" Library Time Stamp Checksum Version Flags\n"), stdout); for (cnt = 0; cnt < liblistno; ++cnt) @@ -9812,12 +11036,12 @@ process_mips_specific (FILE * file) if (VALID_DYNAMIC_NAME (liblist.l_name)) print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name)); else - printf ("", liblist.l_name); + printf (_(""), liblist.l_name); printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum, liblist.l_version); if (liblist.l_flags == 0) - puts (" NONE"); + puts (_(" NONE")); else { static const struct @@ -10116,7 +11340,7 @@ process_mips_specific (FILE * file) if (VALID_DYNAMIC_NAME (psym->st_name)) print_symbol (25, GET_DYNAMIC_NAME (psym->st_name)); else - printf ("", psym->st_name); + printf (_(""), psym->st_name); putchar ('\n'); } @@ -10145,16 +11369,16 @@ process_mips_specific (FILE * file) printf (_(" Reserved entries:\n")); printf (_(" %*s %10s %*s Purpose\n"), - addr_size * 2, "Address", "Access", - addr_size * 2, "Initial"); + addr_size * 2, _("Address"), _("Access"), + addr_size * 2, _("Initial")); ent = print_mips_got_entry (data, pltgot, ent); - printf (" Lazy resolver\n"); + printf (_(" Lazy resolver\n")); if (data && (byte_get (data + ent - pltgot, addr_size) >> (addr_size * 8 - 1)) != 0) { ent = print_mips_got_entry (data, pltgot, ent); - printf (" Module pointer (GNU extension)\n"); + printf (_(" Module pointer (GNU extension)\n")); } printf ("\n"); @@ -10162,8 +11386,8 @@ process_mips_specific (FILE * file) { printf (_(" Local entries:\n")); printf (_(" %*s %10s %*s\n"), - addr_size * 2, "Address", "Access", - addr_size * 2, "Initial"); + addr_size * 2, _("Address"), _("Access"), + addr_size * 2, _("Initial")); while (ent < local_end) { ent = print_mips_got_entry (data, pltgot, ent); @@ -10178,9 +11402,9 @@ 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, "Initial", - addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name"); + addr_size * 2, _("Address"), _("Access"), + addr_size * 2, _("Initial"), + addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name")); sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1; for (i = gotsym; i < symtabno; i++) { @@ -10196,7 +11420,7 @@ process_mips_specific (FILE * file) if (VALID_DYNAMIC_NAME (psym->st_name)) print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name)); else - printf ("", psym->st_name); + printf (_(""), psym->st_name); printf ("\n"); } printf ("\n"); @@ -10237,18 +11461,18 @@ process_mips_specific (FILE * file) printf (_("\nPLT GOT:\n\n")); printf (_(" Reserved entries:\n")); printf (_(" %*s %*s Purpose\n"), - addr_size * 2, "Address", addr_size * 2, "Initial"); + addr_size * 2, _("Address"), addr_size * 2, _("Initial")); ent = print_mips_pltgot_entry (data, mips_pltgot, ent); - printf (" PLT lazy resolver\n"); + printf (_(" PLT lazy resolver\n")); ent = print_mips_pltgot_entry (data, mips_pltgot, ent); - printf (" Module pointer\n"); + printf (_(" Module pointer\n")); printf ("\n"); printf (_(" Entries:\n")); printf (_(" %*s %*s %*s %-7s %3s %s\n"), - addr_size * 2, "Address", - addr_size * 2, "Initial", - addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name"); + addr_size * 2, _("Address"), + addr_size * 2, _("Initial"), + addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name")); sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1; for (i = 0; i < count; i++) { @@ -10264,7 +11488,7 @@ process_mips_specific (FILE * file) if (VALID_DYNAMIC_NAME (psym->st_name)) print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name)); else - printf ("", psym->st_name); + printf (_(""), psym->st_name); printf ("\n"); } printf ("\n"); @@ -10325,7 +11549,7 @@ process_gnu_liblist (FILE * file) SECTION_NAME (section), (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib))); - puts (" Library Time Stamp Checksum Version Flags"); + puts (_(" Library Time Stamp Checksum Version Flags")); for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib); ++cnt) @@ -10350,10 +11574,10 @@ process_gnu_liblist (FILE * file) printf ("%3lu: ", (unsigned long) cnt); if (do_wide) printf ("%-20s", liblist.l_name < strtab_size - ? strtab + liblist.l_name : ""); + ? strtab + liblist.l_name : _("")); else printf ("%-20.20s", liblist.l_name < strtab_size - ? strtab + liblist.l_name : ""); + ? strtab + liblist.l_name : _("")); printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum, liblist.l_version, liblist.l_flags); } @@ -10389,8 +11613,20 @@ get_note_type (unsigned e_type) return _("NT_PPC_VMX (ppc Altivec registers)"); case NT_PPC_VSX: return _("NT_PPC_VSX (ppc VSX registers)"); + case NT_X86_XSTATE: + return _("NT_X86_XSTATE (x86 XSAVE extended state)"); case NT_S390_HIGH_GPRS: return _("NT_S390_HIGH_GPRS (s390 upper register halves)"); + case NT_S390_TIMER: + return _("NT_S390_TIMER (s390 timer register)"); + case NT_S390_TODCMP: + return _("NT_S390_TODCMP (s390 TOD comparator register)"); + case NT_S390_TODPREG: + return _("NT_S390_TODPREG (s390 TOD programmable register)"); + case NT_S390_CTRS: + return _("NT_S390_CTRS (s390 control registers)"); + case NT_S390_PREFIX: + return _("NT_S390_PREFIX (s390 prefix register)"); case NT_PSTATUS: return _("NT_PSTATUS (pstatus structure)"); case NT_FPREGS: @@ -10478,9 +11714,9 @@ get_netbsd_elfcore_note_type (unsigned e_type) case EM_SPARCV9: switch (e_type) { - case NT_NETBSDCORE_FIRSTMACH+0: + case NT_NETBSDCORE_FIRSTMACH + 0: return _("PT_GETREGS (reg structure)"); - case NT_NETBSDCORE_FIRSTMACH+2: + case NT_NETBSDCORE_FIRSTMACH + 2: return _("PT_GETFPREGS (fpreg structure)"); default: break; @@ -10492,9 +11728,9 @@ get_netbsd_elfcore_note_type (unsigned e_type) default: switch (e_type) { - case NT_NETBSDCORE_FIRSTMACH+1: + case NT_NETBSDCORE_FIRSTMACH + 1: return _("PT_GETREGS (reg structure)"); - case NT_NETBSDCORE_FIRSTMACH+3: + case NT_NETBSDCORE_FIRSTMACH + 3: return _("PT_GETFPREGS (fpreg structure)"); default: break; @@ -10706,6 +11942,9 @@ process_arch_specific (FILE * file) case EM_PPC: return process_power_specific (file); break; + case EM_TI_C6000: + return process_tic6x_specific (file); + break; default: break; } @@ -10859,7 +12098,7 @@ process_object (char * file_name, FILE * file) do_unwind = do_version = do_dump = do_arch = 0; if (! do_using_dynamic) - do_syms = do_reloc = 0; + do_syms = do_dyn_syms = do_reloc = 0; } if (! process_section_groups (file)) @@ -11376,7 +12615,6 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive) struct archive_info arch; struct archive_info nested_arch; size_t got; - size_t file_name_size; int ret; show_name = 1; @@ -11463,14 +12701,13 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive) if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections && !do_segments && !do_header && !do_dump && !do_version && !do_histogram && !do_debugging && !do_arch && !do_notes - && !do_section_groups) + && !do_section_groups && !do_dyn_syms) { ret = 0; /* Archive index only. */ goto out; } } - file_name_size = strlen (file_name); ret = 0; while (1)