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
next 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