[commit,arm] Fix minor ARM prologue parsing bug

Message ID 201103211729.p2LHTYe9024479@d06av02.portsmouth.uk.ibm.com
State Accepted
Headers show

Commit Message

Ulrich Weigand March 21, 2011, 5:29 p.m.
Hello,

this patch fixes a minor problem in ARM prologue parsing: we're usually
careful to skip over all non-prologue instructions; however, there is
one weird case where prologue parsing is completely aborted instead,
namely when encountering a load or load multiple instruction via some
register other than the stack pointer.

This doesn't really make sense, and causes backtrace failures with
certain glibc build.  The patch below fixes this by treating such
load instruction just like any other non-prologue instruction.

Tested on armv7l-linux-gnueabi with no regressions.
Committed to mainline.

Bye,
Ulrich


ChangeLog:

	* arm-tdep.c (arm_analyze_prologue): Do not abort parsing when
	encountering a load via a non-SP register.

Patch

Index: gdb/arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.335
diff -u -p -r1.335 arm-tdep.c
--- gdb/arm-tdep.c	11 Mar 2011 14:48:55 -0000	1.335
+++ gdb/arm-tdep.c	18 Mar 2011 22:05:25 -0000
@@ -1856,23 +1856,15 @@  arm_analyze_prologue (struct gdbarch *gd
       else if (arm_instruction_changes_pc (insn))
 	/* Don't scan past anything that might change control flow.  */
 	break;
-      else if ((insn & 0xfe500000) == 0xe8100000)	/* ldm */
-	{
-	  /* Ignore block loads from the stack, potentially copying
-	     parameters from memory.  */
-	  if (pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
-	    continue;
-	  else
-	    break;
-	}
-      else if ((insn & 0xfc500000) == 0xe4100000)
-	{
-	  /* Similarly ignore single loads from the stack.  */
-	  if (pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
-	    continue;
-	  else
-	    break;
-	}
+      else if ((insn & 0xfe500000) == 0xe8100000	/* ldm */
+	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
+	/* Ignore block loads from the stack, potentially copying
+	   parameters from memory.  */
+	continue;
+      else if ((insn & 0xfc500000) == 0xe4100000
+	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
+	/* Similarly ignore single loads from the stack.  */
+	continue;
       else if ((insn & 0xffff0ff0) == 0xe1a00000)
 	/* MOV Rd, Rm.  Skip register copies, i.e. saves to another
 	   register instead of the stack.  */