This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] MIPS/opcodes: Correct mixed MIPS16 and microMIPS disassembly


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1401d2fe675c5b0634a97e84e6b094eea527e63e

commit 1401d2fe675c5b0634a97e84e6b094eea527e63e
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Wed May 18 11:22:30 2016 +0100

    MIPS/opcodes: Correct mixed MIPS16 and microMIPS disassembly
    
    Mixing MIPS16 and microMIPS code in a single binary isn't usually
    supported but GAS happily produces such code if requested.  However it
    is not correctly disassembled even if a symbol table is available and
    function symbols are correctly anotated with the ISA mode.  This is
    because the ELF-header global microMIPS ASE flag takes precedence over
    MIPS16 function annotation, causing them to be treated as regular MIPS
    code.
    
    Correct the problem by respecting function symbol anotation regardless
    of the ELF-header flag.
    
    	binutils/
    	* testsuite/binutils-all/mips/mixed-mips16-micromips.d: New test.
    	* testsuite/binutils-all/mips/mixed-mips16-micromips.s: New test
    	source.
    	* testsuite/binutils-all/mips/mips.exp: Run the new test.
    
    	opcodes/
    	* mips-dis.c (is_compressed_mode_p): Add `micromips_p' operand,
    	replacing references to `micromips_ase' throughout.
    	(_print_insn_mips): Don't use file-level microMIPS annotation to
    	determine the disassembly mode with the symbol table.

Diff:
---
 binutils/ChangeLog                                 |  7 ++++
 binutils/testsuite/binutils-all/mips/mips.exp      |  1 +
 .../binutils-all/mips/mixed-mips16-micromips.d     | 30 +++++++++++++++++
 .../binutils-all/mips/mixed-mips16-micromips.s     | 32 ++++++++++++++++++
 opcodes/ChangeLog                                  |  7 ++++
 opcodes/mips-dis.c                                 | 38 ++++++++++++----------
 6 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 6eb3fa7..c4bb34e 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-18  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* testsuite/binutils-all/mips/mixed-mips16-micromips.d: New test.
+	* testsuite/binutils-all/mips/mixed-mips16-micromips.s: New test
+	source.
+	* testsuite/binutils-all/mips/mips.exp: Run the new test.
+
 2016-05-18  Nick Clifton  <nickc@redhat.com>
 
 	* po/sv.po: Updated Swedish translation.
diff --git a/binutils/testsuite/binutils-all/mips/mips.exp b/binutils/testsuite/binutils-all/mips/mips.exp
index 5c93959..4dab9a6 100644
--- a/binutils/testsuite/binutils-all/mips/mips.exp
+++ b/binutils/testsuite/binutils-all/mips/mips.exp
@@ -22,5 +22,6 @@ if ![istarget mips*-*-*] {
 if [is_elf_format] {
     run_dump_test "mixed-mips16"
     run_dump_test "mixed-micromips"
+    run_dump_test "mixed-mips16-micromips"
     run_dump_test "mips16-undecoded"
 }
diff --git a/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.d b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.d
new file mode 100644
index 0000000..4a53dfb
--- /dev/null
+++ b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.d
@@ -0,0 +1,30 @@
+#PROG: objcopy
+#objdump: -drt
+#name: Mixed MIPS16 and microMIPS disassembly
+
+# Test mixed-mode compressed disassembly.
+
+.*: +file format .*mips.*
+
+SYMBOL TABLE:
+#...
+[0-9a-f]+ g +F +\.text	0+00000c 0xf0 foo
+#...
+[0-9a-f]+ g +F +\.text	0+00000c 0x80 bar
+
+Disassembly of section \.text:
+[0-9a-f]+ <foo>:
+ +[0-9a-f]+:	b202      	lw	v0,8 <\.foo\.data>
+ +[0-9a-f]+:	9a60      	lw	v1,0\(v0\)
+ +[0-9a-f]+:	eb00      	jr	v1
+ +[0-9a-f]+:	653b      	move	t9,v1
+
+[0-9a-f]+ <\.foo\.data>:
+ +[0-9a-f]+:	4040 4040 0000 0000                         @@@@\.\.\.\.
+
+[0-9a-f]+ <bar>:
+ +[0-9a-f]+:	41a3 0000 	lui	v1,0x0
+ +[0-9a-f]+:	ff23 0000 	lw	t9,0\(v1\)
+ +[0-9a-f]+:	45b9      	jrc	t9
+ +[0-9a-f]+:	0c00      	nop
+	\.\.\.
diff --git a/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.s b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.s
new file mode 100644
index 0000000..07dcceb
--- /dev/null
+++ b/binutils/testsuite/binutils-all/mips/mixed-mips16-micromips.s
@@ -0,0 +1,32 @@
+	.align	4, 0
+	.set	mips16
+	.globl	foo
+	.ent	foo
+foo:
+	lw	$v0, .foo.data
+	lw	$v1, 0($v0)
+	move	$t9, $v1
+	jr	$v1
+
+	.type	.foo.data, @object
+.foo.data:
+	.word	0x40404040
+	.size	.foo.data, . - .foo.data
+	.end	foo
+	.set	nomips16
+
+	.align	4, 0
+	.set	micromips
+	.globl	bar
+	.ent	bar
+bar:
+	lui	$v1, 0
+	lw	$t9, 0($v1)
+	jrc	$t9
+	nop
+	.end	bar
+	.set	nomicromips
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align	4, 0
+	.space	16
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index ce23ca1..680d2d8 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-18  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* mips-dis.c (is_compressed_mode_p): Add `micromips_p' operand,
+	replacing references to `micromips_ase' throughout.
+	(_print_insn_mips): Don't use file-level microMIPS annotation to
+	determine the disassembly mode with the symbol table.
+
 2016-05-13  Peter Bergner <bergner@vnet.ibm.com>
 
 	* ppc-opc.c (IMM8): Use PPC_OPERAND_SIGNOPT.
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 535c14a..3f874e7 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -2268,33 +2268,33 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
 }
 
 /* Return 1 if a symbol associated with the location being disassembled
-   indicates a compressed (MIPS16 or microMIPS) mode.  We iterate over
-   all the symbols at the address being considered assuming if at least
-   one of them indicates code compression, then such code has been
-   genuinely produced here (other symbols could have been derived from
-   function symbols defined elsewhere or could define data).  Otherwise,
-   return 0.  */
+   indicates a compressed mode, either MIPS16 or microMIPS, according to
+   MICROMIPS_P.  We iterate over all the symbols at the address being
+   considered assuming if at least one of them indicates code compression,
+   then such code has been genuinely produced here (other symbols could
+   have been derived from function symbols defined elsewhere or could
+   define data).  Otherwise, return 0.  */
 
 static bfd_boolean
-is_compressed_mode_p (struct disassemble_info *info)
+is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
 {
   int i;
   int l;
 
   for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
     if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
-	&& ((!micromips_ase
+	&& ((!micromips_p
 	     && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
-	    || (micromips_ase
+	    || (micromips_p
 		&& ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
       return 1;
     else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
 	      && info->symtab[i]->section == info->section)
       {
 	elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
-	if ((!micromips_ase
+	if ((!micromips_p
 	     && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
-	    || (micromips_ase
+	    || (micromips_p
 		&& ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
 	  return 1;
       }
@@ -2313,7 +2313,6 @@ _print_insn_mips (bfd_vma memaddr,
 		  struct disassemble_info *info,
 		  enum bfd_endian endianness)
 {
-  int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
   bfd_byte buffer[INSNLEN];
   int status;
 
@@ -2325,18 +2324,23 @@ _print_insn_mips (bfd_vma memaddr,
   if (info->mach == bfd_mach_mips_micromips)
     return print_insn_micromips (memaddr, info);
 
-  print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
-
 #if 1
   /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
   /* Only a few tools will work this way.  */
   if (memaddr & 0x01)
-    return print_insn_compr (memaddr, info);
+    {
+      if (micromips_ase)
+	return print_insn_micromips (memaddr, info);
+      else
+	return print_insn_mips16 (memaddr, info);
+    }
 #endif
 
 #if SYMTAB_AVAILABLE
-  if (is_compressed_mode_p (info))
-    return print_insn_compr (memaddr, info);
+  if (is_compressed_mode_p (info, TRUE))
+    return print_insn_micromips (memaddr, info);
+  if (is_compressed_mode_p (info, FALSE))
+    return print_insn_mips16 (memaddr, info);
 #endif
 
   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]