Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Ulrich Weigand" <uweigand@de.ibm.com>
To: gdb-patches@sourceware.org, rearnsha@arm.com
Subject: [rfa] Fix software-watchpoint failures by adding epilogue detection
Date: Wed, 22 Sep 2010 19:20:00 -0000	[thread overview]
Message-ID: <201009221846.o8MIklfl003240@d12av02.megacenter.de.ibm.com> (raw)

Hello,

I've been seeing failures in software watchpoint tests on ARM (Thumb-2),
due to missing modeling of precise unwind states during function
epilogues.  This problem is well known from other architectures,
and is usually fixed by skipping epilogue during sofware watchpoint
single-stepping via the gdbarch_in_function_epilogue_p callback.

However, ARM currently does not define this routine.  The following
patch adds an implementation that detects common Thumb epilogue
sequences (ARM is missing, but could be added in an analogous way).

This fixes the following test case failures:
FAIL: gdb.base/recurse.exp: continue to second instance watchpoint, second time
FAIL: gdb.base/recurse.exp: second instance watchpoint deleted when leaving scope (the program exited)
FAIL: gdb.base/recurse.exp: continue to first instance watchpoint, second time (the program is no longer running)
FAIL: gdb.base/recurse.exp: first instance watchpoint deleted when leaving scope (the program is no longer running)
FAIL: gdb.base/watch-cond.exp: watchpoint with local expression, local condition evaluates in correct frame

and adds:
XPASS: gdb.mi/mi-watch.exp: sw: watchpoint trigger
XPASS: gdb.mi/mi2-watch.exp: sw: watchpoint trigger

Tested on armv7l-linux-gnueabi with no regressions.

OK for mainline?

Bye,
Ulrich


ChangeLog:

	* arm-tdep.c (arm_in_function_epilogue_p): New function.
	(arm_gdbarch_init): Install it.


=== modified file 'gdb/arm-tdep.c'
--- gdb/arm-tdep.c	2010-08-30 15:33:03 +0000
+++ gdb/arm-tdep.c	2010-09-22 17:07:18 +0000
@@ -1686,6 +1686,87 @@
     }
 }
 
+/* Return true if we are in the function's epilogue, i.e. after the
+   instruction that destroyed the function's stack frame.
+
+   We consider this to be the case if, starting from the current
+   instruction, we have a sequence of:
+
+   - [optional] setting SP from the frame pointer
+   - restoring registers from SP [may include PC]
+   - a return-type instruction [if PC wasn't already restored]
+
+  If we find anything else, we assume we're not in the epilogue.  */
+
+static int
+arm_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
+
+  if (arm_pc_is_thumb (pc))
+    {
+      for (;;)
+	{
+	  unsigned int insn;
+	  gdb_byte buf[2];
+
+	  if (target_read_memory (pc, buf, 2))
+	    return 0;
+
+	  pc += 2;
+	  insn = extract_unsigned_integer (buf, 2, byte_order_for_code);
+
+	  if (insn == 0x4770)  /* bx lr */
+	    return 1;
+	  else if (insn == 0x46f7)  /* mov pc, lr */
+	    return 1;
+	  else if (insn == 0x46bd)  /* mov sp, r7 */
+	    ;
+	  else if ((insn & 0xfe00) == 0xbc00)  /* pop <registers> */
+	    {
+	      if (insn & 0x0100)  /* <registers> include PC.  */
+		return 1;
+	    }
+	  else if ((insn & 0xe000) == 0xe000)  /* 32-bit Thumb-2 instruction */
+	    {
+	      unsigned int insn2;
+
+	      if (target_read_memory (pc, buf, 2))
+		return 0;
+
+	      pc += 2;
+	      insn2 = extract_unsigned_integer (buf, 2, byte_order_for_code);
+
+	      if ((insn & 0xffdf) == 0xe89d)  /* ldm.w sp{!}, <registers> */
+		{
+		  if (insn2 & 0x8000)  /* <registers> include PC.  */
+		    return 1;
+		}
+	      else if (insn == 0xf85d  /* ldr.w <Rt>, [sp], #4 */
+		       && (insn2 & 0x0fff) == 0x0d04)
+		{
+		  if ((insn2 & 0xf000) == 0xf000) /* <Rt> is PC.  */
+		    return 1;
+		}
+	      else if ((insn & 0xffbf) == 0xecbd  /* vldm sp!, <list> */
+		       && (insn2 & 0x0e00) == 0x0a00)
+		;
+	      else
+		return 0;
+	    }
+	  else
+	    return 0;
+	}
+    }
+  else
+    {
+      /* FIXME: We don't handle ARM for now.  */
+    }
+
+  return 0;
+}
+
+
 /* When arguments must be pushed onto the stack, they go on in reverse
    order.  The code below implements a FILO (stack) to do this.  */
 
@@ -6818,6 +6899,9 @@
   /* Advance PC across function entry code.  */
   set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue);
 
+  /* Detect whether PC is in function epilogue.  */
+  set_gdbarch_in_function_epilogue_p (gdbarch, arm_in_function_epilogue_p);
+
   /* Skip trampolines.  */
   set_gdbarch_skip_trampoline_code (gdbarch, arm_skip_stub);
 

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


             reply	other threads:[~2010-09-22 18:47 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-22 19:20 Ulrich Weigand [this message]
2010-09-22 20:01 ` Daniel Jacobowitz
2010-09-23 16:13   ` Ulrich Weigand
2010-09-24 16:11     ` Ulrich Weigand
2010-09-28 20:23       ` Daniel Jacobowitz
2010-09-28 21:47         ` Ulrich Weigand
2010-09-28 21:49           ` Daniel Jacobowitz
2010-09-29 15:24             ` Richard Earnshaw
2010-10-07 16:12             ` [rfa, v3] Fix software-watchpoint failures on ARM " Ulrich Weigand
2010-10-08 13:01               ` Richard Earnshaw
2010-10-08 13:27                 ` Ulrich Weigand
2010-09-29 14:43           ` [rfa] Fix software-watchpoint failures " Yao Qi

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=201009221846.o8MIklfl003240@d12av02.megacenter.de.ibm.com \
    --to=uweigand@de.ibm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=rearnsha@arm.com \
    /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