This is the mail archive of the binutils@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]

[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


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