From 9e8c70f96b16cf31c016ccdb40c3ea414e0715da Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 21 Sep 2011 20:49:16 +0000 Subject: Annotate sparc objects with cpu hardware capabilities used. bfd/ * elfxx-sparc.c (_bfd_sparc_elf_merge_private_bfd_data): New. * elfxx-sparc.h: Declare it. * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Call it. * elf64-sparc.c (elf64_sparc_merge_private_bfd_data): Likewise. binutils/ * readelf.c (display_sparc_hwcaps): New. (display_sparc_gnu_attribute): New. (process_sparc_specific): New. (process_arch_specific): When EM_SPARC, EM_SPARC32PLUS, or EM_SPARCV9 invoke process_sparc_specific. gas/ * config/tc-sparc.c (hwcap_seen): New bitmask, defined when not TE_SOLARIS. (sparc_ip): When not TE_SOLARIS, accumulate hwcap bits from sparc_opcode->flags of instruction into hwcap_seen. (sparc_md_end): Create Tag_GNU_Sparc_HWCAPS attribute if hwcap_seen is non-zero and not TE_SOLARIS. gas/testsuite/ * gas/sparc/hpcvis3.s: Update for fixed fchksum16 mnemonic. * gas/sparc/hpcvis3.d: Likewise. include/elf/ * sparc.h (Tag_GNU_Sparc_HWCAPS): New object attribute. (ELF_SPARC_HWCAP_*): New HWCAPS bitmask values. include/opcode/ * sparc.h (struct sparc_opcode): Expand 'flags' to unsigned int. (F_MUL32, F_DIV32, F_FSMULD, F_V8PLUS, F_POPC, F_VIS, F_VIS2, F_ASI_BLK_INIT, F_FMAF, F_VIS3, F_HPC, F_RANDOM, F_TRANS, F_FJFMAU, F_IMA, F_ASI_CACHE_SPARING): New flag bits. opcodes/ * sparc-opc.c (sparc_opcodes): Annotate table with HWCAP flag bits. Fix "fchksm16" mnemonic. --- binutils/ChangeLog | 6 ++++ binutils/readelf.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) (limited to 'binutils') diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 3704b70..41aaf62 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -2,6 +2,12 @@ * MAINTAINER: Take over from Jakub Jalinek as SPARC maintainer. + * readelf.c (display_sparc_hwcaps): New. + (display_sparc_gnu_attribute): New. + (process_sparc_specific): New. + (process_arch_specific): When EM_SPARC, EM_SPARC32PLUS, + or EM_SPARCV9 invoke process_sparc_specific. + 2011-09-18 H.J. Lu PR binutils/13196 diff --git a/binutils/readelf.c b/binutils/readelf.c index a9064c5..9e13190 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -11096,6 +11096,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) { @@ -11545,6 +11627,13 @@ process_power_specific (FILE * file) } 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) { return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES, @@ -12898,6 +12987,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; -- cgit v1.1