MIPS/opcodes: Also set disassembler's ASE flags from ELF structures
authorMaciej W. Rozycki <macro@imgtec.com>
Wed, 14 Dec 2016 21:49:56 +0000 (21:49 +0000)
committerMaciej W. Rozycki <macro@imgtec.com>
Wed, 14 Dec 2016 22:12:21 +0000 (22:12 +0000)
Respect any ASE flags recorded in ELF file structures for the purpose of
selecting instructions to be disassembled, preventing code from being
hex-dumped even though having been clearly indicated as valid at the
assembly time.  Use date from the MIPS ABI flags structure if present,
and otherwise there may be an MDMX ASE flag set in the ELF file header.
For backwards compatibility only set extra flags and do not clear any,
preserving all previously set by the architecture selected to be
disassembled for.

include/
* elf/mips.h (Elf_Internal_ABIFlags_v0): Also declare struct
typedef as `elf_internal_abiflags_v0'.

bfd/
* bfd-in.h (elf_internal_abiflags_v0): New struct declaration.
(bfd_mips_elf_get_abiflags): New prototype.
* elfxx-mips.c (bfd_mips_elf_get_abiflags): New function.
* bfd-in2.h: Regenerate.

opcodes/
* mips-dis.c (mips_convert_abiflags_ases): New function.
(set_default_mips_dis_options): Also infer ASE flags from ELF
file structures.

binutils/
* testsuite/binutils-all/mips/mips-ase-1.d: New test.
* testsuite/binutils-all/mips/mips-ase-2.d: New test.
* testsuite/binutils-all/mips/mips-ase-3.d: New test.
* testsuite/binutils-all/mips/mips-ase-1.s: New test source.
* testsuite/binutils-all/mips/mips-ase-2.s: New test source.
* testsuite/binutils-all/mips/mips.exp: Run the new tests.

15 files changed:
bfd/ChangeLog
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/elfxx-mips.c
binutils/ChangeLog
binutils/testsuite/binutils-all/mips/mips-ase-1.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/mips-ase-1.s [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/mips-ase-2.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/mips-ase-2.s [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/mips-ase-3.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/mips.exp
include/ChangeLog
include/elf/mips.h
opcodes/ChangeLog
opcodes/mips-dis.c

index 21cbcac95e5051b897ded2886a89390502081647..ded152e47ddfa2f5f6f0f727930cdafc796e4a66 100644 (file)
@@ -1,3 +1,10 @@
+2016-12-14  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * bfd-in.h (elf_internal_abiflags_v0): New struct declaration.
+       (bfd_mips_elf_get_abiflags): New prototype.
+       * elfxx-mips.c (bfd_mips_elf_get_abiflags): New function.
+       * bfd-in2.h: Regenerate.
+
 2016-12-14  Yury Norov <ynorov@caviumnetworks.com>
 
          * bfd/elfnn-aarch64.c: fix TLS relaxations for ilp32 where
index 4b3bcfd02aa364ea7278695a1910f792b292e032..14f55ab9d2366c20d7347075d8b17fe9f01a58eb 100644 (file)
@@ -1045,3 +1045,7 @@ extern bfd_boolean v850_elf_create_sections
 
 extern bfd_boolean v850_elf_set_note
   (bfd *, unsigned int, unsigned int);
+
+/* MIPS ABI flags data access.  For the disassembler.  */
+struct elf_internal_abiflags_v0;
+extern struct elf_internal_abiflags_v0 *bfd_mips_elf_get_abiflags (bfd *);
index fdb787882846bde11eda3d825981ead22dd645ba..1c6b70fc56c109ee37301f252a7c1370fcfe4d56 100644 (file)
@@ -1052,6 +1052,10 @@ extern bfd_boolean v850_elf_create_sections
 
 extern bfd_boolean v850_elf_set_note
   (bfd *, unsigned int, unsigned int);
+
+/* MIPS ABI flags data access.  For the disassembler.  */
+struct elf_internal_abiflags_v0;
+extern struct elf_internal_abiflags_v0 *bfd_mips_elf_get_abiflags (bfd *);
 /* Extracted from init.c.  */
 void bfd_init (void);
 
index 96317aaadac00964ad2370020be1aedd05dcdde3..d649676e2254f59df12cb292e26af0d269de5afd 100644 (file)
@@ -16327,6 +16327,16 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
   return n;
 }
 
+/* Return the ABI flags associated with ABFD if available.  */
+
+Elf_Internal_ABIFlags_v0 *
+bfd_mips_elf_get_abiflags (bfd *abfd)
+{
+  struct mips_elf_obj_tdata *tdata = mips_elf_tdata (abfd);
+
+  return tdata->abiflags_valid ? &tdata->abiflags : NULL;
+}
+
 void
 _bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
 {
index 45ec4537b92fd345f75963c8d6495ca34538b0bd..057e309dd973fe47cfc5d8931a13061e5bcc71cf 100644 (file)
@@ -1,3 +1,12 @@
+2016-12-14  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * testsuite/binutils-all/mips/mips-ase-1.d: New test.
+       * testsuite/binutils-all/mips/mips-ase-2.d: New test.
+       * testsuite/binutils-all/mips/mips-ase-3.d: New test.
+       * testsuite/binutils-all/mips/mips-ase-1.s: New test source.
+       * testsuite/binutils-all/mips/mips-ase-2.s: New test source.
+       * testsuite/binutils-all/mips/mips.exp: Run the new tests.
+
 2016-12-13  Jiong Wang  <jiong.wang@arm.com>
 
        * readelf.c (is_32bit_abs_reloc): Recognize R_AARCH64_P32_ABS32.
diff --git a/binutils/testsuite/binutils-all/mips/mips-ase-1.d b/binutils/testsuite/binutils-all/mips/mips-ase-1.d
new file mode 100644 (file)
index 0000000..d9d5839
--- /dev/null
@@ -0,0 +1,29 @@
+#PROG: objcopy
+#objdump: -dp --prefix-addresses --show-raw-insn
+#name: MIPS ELF file ASE information interpretation for disassembly 1
+#as: -32
+
+# Verify that in the absence of its ASE flag MDMX code is not disassembled
+# with MIPS64r2, where MDMX presence is not implied.
+
+.*: +file format .*mips.*
+!private flags = .*mdmx.*
+
+MIPS ABI Flags Version: 0
+
+ISA: MIPS64r2
+GPR size: 32
+CPR1 size: 64
+CPR2 size: 0
+FP ABI: Hard float \(32-bit CPU, 64-bit FPU\)
+ISA Extension: None
+ASEs:
+       None
+FLAGS 1: .*
+FLAGS 2: .*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7aa2080b     0x7aa2080b
+[0-9a-f]+ <[^>]*> 46c520c0     add\.ps \$f3,\$f4,\$f5
+[0-9a-f]+ <[^>]*> 46c83998     addr\.ps        \$f6,\$f7,\$f8
+       \.\.\.
diff --git a/binutils/testsuite/binutils-all/mips/mips-ase-1.s b/binutils/testsuite/binutils-all/mips/mips-ase-1.s
new file mode 100644 (file)
index 0000000..c1d7671
--- /dev/null
@@ -0,0 +1,12 @@
+       .module mips64r2
+       .module fp=64
+       .set    mdmx
+       .set    mips3d
+foo:
+       add.qh  $v0, $v1, $v2
+       add.ps  $f3, $f4, $f5
+       addr.ps $f6, $f7, $f8
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
diff --git a/binutils/testsuite/binutils-all/mips/mips-ase-2.d b/binutils/testsuite/binutils-all/mips/mips-ase-2.d
new file mode 100644 (file)
index 0000000..baf80dd
--- /dev/null
@@ -0,0 +1,29 @@
+#PROG: objcopy
+#objdump: -dp --prefix-addresses --show-raw-insn
+#name: MIPS ELF file ASE information interpretation for disassembly 2
+#as: -32
+
+# Verify that in the presence of its ASE flag MDMX code is disassembled
+# with MIPS64r2, where MDMX presence is not implied.
+
+.*: +file format .*mips.*
+private flags = .[8-f]......: .*mdmx.*
+
+MIPS ABI Flags Version: 0
+
+ISA: MIPS64r2
+GPR size: 32
+CPR1 size: 64
+CPR2 size: 0
+FP ABI: Hard float \(32-bit CPU, 64-bit FPU\)
+ISA Extension: None
+ASEs:
+       MDMX ASE
+FLAGS 1: .*
+FLAGS 2: .*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7aa2080b     add\.qh \$v0,\$v1,\$v2
+[0-9a-f]+ <[^>]*> 46c520c0     add\.ps \$f3,\$f4,\$f5
+[0-9a-f]+ <[^>]*> 46c83998     addr\.ps        \$f6,\$f7,\$f8
+       \.\.\.
diff --git a/binutils/testsuite/binutils-all/mips/mips-ase-2.s b/binutils/testsuite/binutils-all/mips/mips-ase-2.s
new file mode 100644 (file)
index 0000000..54adac2
--- /dev/null
@@ -0,0 +1,12 @@
+       .module mips64r2
+       .module fp=64
+       .module mdmx
+       .set    mips3d
+foo:
+       add.qh  $v0, $v1, $v2
+       add.ps  $f3, $f4, $f5
+       addr.ps $f6, $f7, $f8
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
diff --git a/binutils/testsuite/binutils-all/mips/mips-ase-3.d b/binutils/testsuite/binutils-all/mips/mips-ase-3.d
new file mode 100644 (file)
index 0000000..a52a647
--- /dev/null
@@ -0,0 +1,18 @@
+#PROG: objcopy
+#objdump: -dp --prefix-addresses --show-raw-insn
+#name: MIPS ELF file ASE information interpretation for disassembly 3
+#as: -32
+#objcopy: -R .MIPS.abiflags
+#source: mips-ase-2.s
+
+# Verify that in the presence of its ASE flag MDMX code is disassembled
+# with MIPS64r2, where MDMX presence is not implied.
+
+.*: +file format .*mips.*
+private flags = .[8-f]......: .*mdmx.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7aa2080b     add\.qh \$v0,\$v1,\$v2
+[0-9a-f]+ <[^>]*> 46c520c0     add\.ps \$f3,\$f4,\$f5
+[0-9a-f]+ <[^>]*> 46c83998     addr\.ps        \$f6,\$f7,\$f8
+       \.\.\.
index f3d956f4b255a0de4bf3ba8bf795016a649ce989..143fbc4d7993a34866f9935aba67075985fcbff9 100644 (file)
@@ -20,6 +20,9 @@ if ![istarget mips*-*-*] {
 }
 
 if [is_elf_format] {
+    run_dump_test "mips-ase-1"
+    run_dump_test "mips-ase-2"
+    run_dump_test "mips-ase-3"
     run_dump_test "mixed-mips16"
     run_dump_test "mixed-micromips"
     run_dump_test "mixed-mips16-micromips"
index f65fabb21ac2f0d4a81a79f6b7063c8029249ba1..57ea85ec4c6c709ff241d528d03287b3aea45faa 100644 (file)
@@ -1,3 +1,8 @@
+2016-12-14  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * elf/mips.h (Elf_Internal_ABIFlags_v0): Also declare struct
+       typedef as `elf_internal_abiflags_v0'.
+
 2016-12-13 Renlin Li <renlin.li@arm.com>
 
        * opcode/aarch64.h (aarch64_operand_class): Remove
index 7e813de82801b92e04bf9912671840bc7c1abbb6..b70f5d17cbc0730666ab76bb3905a31a5ba2dd6c 100644 (file)
@@ -1101,7 +1101,7 @@ typedef struct
   unsigned char flags2[4];
 } Elf_External_ABIFlags_v0;
 
-typedef struct
+typedef struct elf_internal_abiflags_v0
 {
   /* Version of flags structure.  */
   unsigned short version;
index 3f74c26931c6aef4d35f28c014b14183252cc770..c8a1b7eab9d18e81f9cf21963da855332ff24dde 100644 (file)
@@ -1,3 +1,9 @@
+2016-12-14  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * mips-dis.c (mips_convert_abiflags_ases): New function.
+       (set_default_mips_dis_options): Also infer ASE flags from ELF
+       file structures.
+
 2016-12-14  Maciej W. Rozycki  <macro@imgtec.com>
 
        * mips-dis.c (set_default_mips_dis_options): Reorder ELF file
index 380a675b9dcccbd1bdac6255d468ff883727087c..c30bbd0207667e0a67c99f79bb3c4034ef045ebc 100644 (file)
@@ -764,6 +764,40 @@ is_micromips (Elf_Internal_Ehdr *header)
   return 0;
 }
 
+/* Convert ASE flags from .MIPS.abiflags to internal values.  */
+
+static unsigned long
+mips_convert_abiflags_ases (unsigned long afl_ases)
+{
+  unsigned long opcode_ases = 0;
+
+  if (afl_ases & AFL_ASE_DSP)
+    opcode_ases |= ASE_DSP;
+  if (afl_ases & AFL_ASE_DSPR2)
+    opcode_ases |= ASE_DSPR2;
+  if (afl_ases & AFL_ASE_EVA)
+    opcode_ases |= ASE_EVA;
+  if (afl_ases & AFL_ASE_MCU)
+    opcode_ases |= ASE_MCU;
+  if (afl_ases & AFL_ASE_MDMX)
+    opcode_ases |= ASE_MDMX;
+  if (afl_ases & AFL_ASE_MIPS3D)
+    opcode_ases |= ASE_MIPS3D;
+  if (afl_ases & AFL_ASE_MT)
+    opcode_ases |= ASE_MT;
+  if (afl_ases & AFL_ASE_SMARTMIPS)
+    opcode_ases |= ASE_SMARTMIPS;
+  if (afl_ases & AFL_ASE_VIRT)
+    opcode_ases |= ASE_VIRT;
+  if (afl_ases & AFL_ASE_MSA)
+    opcode_ases |= ASE_MSA;
+  if (afl_ases & AFL_ASE_XPA)
+    opcode_ases |= ASE_XPA;
+  if (afl_ases & AFL_ASE_DSPR3)
+    opcode_ases |= ASE_DSPR3;
+  return opcode_ases;
+}
+
 static void
 set_default_mips_dis_options (struct disassemble_info *info)
 {
@@ -810,14 +844,20 @@ set_default_mips_dis_options (struct disassemble_info *info)
   /* Update settings according to the ELF file header flags.  */
   if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
     {
-      Elf_Internal_Ehdr *header;
+      struct bfd *abfd = info->section->owner;
+      Elf_Internal_Ehdr *header = elf_elfheader (abfd);
+      Elf_Internal_ABIFlags_v0 *abiflags = bfd_mips_elf_get_abiflags (abfd);
 
-      header = elf_elfheader (info->section->owner);
       /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
       if (is_newabi (header))
        mips_gpr_names = mips_gpr_names_newabi;
       /* If a microMIPS binary, then don't use MIPS16 bindings.  */
       micromips_ase = is_micromips (header);
+      /* OR in any extra ASE flags set in ELF file structures.  */
+      if (abiflags)
+       mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
+      else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
+       mips_ase |= ASE_MDMX;
     }
 }