From: "Maciej W. Rozycki" <macro@imgtec.com>
To: <binutils@sourceware.org>
Subject: [committed] MIPS/opcodes: Correct mixed MIPS16 and microMIPS disassembly
Date: Wed, 18 May 2016 12:09:00 -0000 [thread overview]
Message-ID: <alpine.DEB.2.00.1605181303530.6794@tp.orcam.me.uk> (raw)
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.
---
I have committed this change.
Maciej
binutils-opcodes-mips-compressed.diff
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/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);
reply other threads:[~2016-05-18 12:09 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.DEB.2.00.1605181303530.6794@tp.orcam.me.uk \
--to=macro@imgtec.com \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).