This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Decode all ARM unwind instructions in readelf
- From: Zachary T Welch <zwelch at codesourcery dot com>
- To: binutils at sourceware dot org
- Cc: Zachary T Welch <zwelch at codesourcery dot com>
- Date: Fri, 3 Dec 2010 16:42:03 -0800
- Subject: [PATCH] Decode all ARM unwind instructions in readelf
This patch implements decoding of all remaining unwind instructions
specified by the Exception Handling ABI for ARM Architecture (IHI 0038A).
Implements decoding of ARM unwind instructions for ARM VFP/NEON (D0-D31)
and Intel Wireless MMX registers (wR0-wR15, wCGR0-wCGR4). All remaining
encodings are specified by the ARM ABI as spare or reserved instructions.
2010-12-03 Zachary T Welch <zwelch@codesourcery.com>
* readelf.c (decode_arm_unwind): Implement decoding of remaining
ARM unwind instructions (i.e. VFP/NEON and Intel Wireless MMX).
---
binutils/readelf.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index e34d6c4..2fcca13 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -6559,18 +6559,71 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
offset = offset * 4 + 0x204;
printf ("vsp = vsp + %ld", offset);
}
- else
+ else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
{
- if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9)
- {
- GET_OP (op2);
- printf (_("[unsupported two-byte opcode]"));
- }
+ unsigned int first, last;
+ GET_OP (op2);
+ first = op2 >> 4;
+ last = op2 & 0x0f;
+ if (op == 0xc8)
+ first = first + 16;
+ printf ("pop {D%d", first);
+ if (last)
+ printf ("-D%d", first + last);
+ printf ("}");
+ }
+ else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
+ {
+ unsigned int count = op & 0x07;
+ printf ("pop {D8");
+ if (count)
+ printf ("-D%d", 8 + count);
+ printf ("}");
+ }
+ else if (op >= 0xc0 && op <= 0xc5)
+ {
+ unsigned int count = op & 0x07;
+ printf (" pop {wR10");
+ if (count)
+ printf ("-wR%d", 10 + count);
+ printf ("}");
+ }
+ else if (op == 0xc6)
+ {
+ unsigned int first, last;
+ GET_OP (op2);
+ first = op2 >> 4;
+ last = op2 & 0x0f;
+ printf ("pop {wR%d", first);
+ if (last)
+ printf ("-wR%d", first + last);
+ printf ("}");
+ }
+ else if (op == 0xc7)
+ {
+ GET_OP (op2);
+ if (op2 == 0 || (op2 & 0xf0) != 0)
+ printf (_("[Spare]"));
else
{
- printf (_(" [unsupported opcode]"));
+ unsigned int mask = op2 & 0x0f;
+ int first = 1;
+ int i;
+ printf ("pop {");
+ for (i = 0; i < 4; i++)
+ if (mask & (1 << i))
+ {
+ if (first)
+ first = 0;
+ else
+ printf (", ");
+ printf ("wCGR%d", i);
+ }
+ printf ("}");
}
}
+ else
+ printf (_(" [unsupported opcode]"));
printf ("\n");
}
--
1.7.1