From: "Maciej W. Rozycki" <macro@mips.com>
To: gdb-patches@sourceware.org, Daniel Jacobowitz <drow@false.org>
Cc: "Maciej W. Rozycki" <macro@linux-mips.org>
Subject: mips-tdep.c: Fix sw watchpoint-out-of-scope events
Date: Tue, 11 Sep 2007 16:24:00 -0000 [thread overview]
Message-ID: <Pine.LNX.4.61.0709111642220.32532@perivale.mips.com> (raw)
Hello,
This is a fix for software watchpoint-out-of-scope events for MIPS
platforms. It implements a in_function_epilogue_p() hook which is used to
single-step a function's epilogue once a local watchpoint has been
destroyed (because of the restoration of the frame pointer). As a result
the event is only reported once the caller has been reached back.
This change has been tested natively for mips-linux-gnu and remotely for
mipsisa32-sde-elf, with mips-sim-sde32/-EB, mips-sim-sde32/-EB/-mips16,
mips-sim-sde32/-EL and mips-sim-sde32/-EL/-mips16. It fixes sw watchpoint
regressions in gdb.mi/mi*-watch.exp:
FAIL: gdb.mi/mi-watch.exp: wp out of scope (2)
for the remote targets. It does not fix them for Linux, because the o32
calling convention makes the restoration of the GOT pointer in the caller
("lw gp,..." after "jalr") a part of the function call. Therefore
execution stops in the right function, but one instruction too early,
still within the source line of the call. It is still a step forward
though and less of nuisance for the user.
2007-09-11 Maciej W. Rozycki <macro@mips.com>
* mips-tdep.c (mips32_in_function_epilogue_p): New function.
(mips16_in_function_epilogue_p): Likewise.
(mips_in_function_epilogue_p): Likewise.
(mips_gdbarch_init): Register mips_in_function_epilogue_p().
OK to apply?
Maciej
14677.diff
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c 2007-09-11 14:16:22.000000000 +0100
+++ binutils-quilt/src/gdb/mips-tdep.c 2007-09-11 14:17:42.000000000 +0100
@@ -4883,6 +4883,95 @@
return mips32_scan_prologue (pc, limit_pc, NULL, NULL);
}
+/* Check whether the PC is in a function epilogue (32-bit version).
+ This is a helper function for mips_in_function_epilogue_p. */
+static int
+mips32_in_function_epilogue_p (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr = 0, func_end = 0;
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ /* The MIPS epilogue is max. 12 bytes long. */
+ CORE_ADDR addr = func_end - 12;
+
+ if (addr < func_addr + 4)
+ addr = func_addr + 4;
+ if (pc < addr)
+ return 0;
+
+ for (; pc < func_end; pc += MIPS_INSN32_SIZE)
+ {
+ unsigned long high_word;
+ unsigned long inst;
+
+ inst = mips_fetch_instruction (pc);
+ high_word = (inst >> 16) & 0xffff;
+
+ if (high_word != 0x27bd /* addiu $sp,$sp,offset */
+ && high_word != 0x67bd /* daddiu $sp,$sp,offset */
+ && inst != 0x03e00008 /* jr $ra */
+ && inst != 0x00000000) /* nop */
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Check whether the PC is in a function epilogue (16-bit version).
+ This is a helper function for mips_in_function_epilogue_p. */
+static int
+mips16_in_function_epilogue_p (CORE_ADDR pc)
+{
+ CORE_ADDR func_addr = 0, func_end = 0;
+
+ if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ {
+ /* The MIPS epilogue is max. 12 bytes long. */
+ CORE_ADDR addr = func_end - 12;
+
+ if (addr < func_addr + 4)
+ addr = func_addr + 4;
+ if (pc < addr)
+ return 0;
+
+ for (; pc < func_end; pc += MIPS_INSN16_SIZE)
+ {
+ unsigned short inst;
+
+ inst = mips_fetch_instruction (pc);
+
+ if ((inst & 0xf800) == 0xf000) /* extend */
+ continue;
+
+ if (inst != 0x6300 /* addiu $sp,offset */
+ && inst != 0xfb00 /* daddiu $sp,$sp,offset */
+ && inst != 0xe820 /* jr $ra */
+ && inst != 0xe8a0 /* jrc $ra */
+ && inst != 0x6500) /* nop */
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* The epilogue is defined here as the area at the end of a function,
+ after an instruction which destroys the function's stack frame. */
+static int
+mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ if (mips_pc_is_mips16 (pc))
+ return mips16_in_function_epilogue_p (pc);
+ else
+ return mips32_in_function_epilogue_p (pc);
+}
+
/* Root of all "set mips "/"show mips " commands. This will eventually be
used for all MIPS-specific commands. */
@@ -5995,6 +6084,8 @@
set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
+ set_gdbarch_in_function_epilogue_p (gdbarch, mips_in_function_epilogue_p);
+
set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);
next reply other threads:[~2007-09-11 16:24 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-11 16:24 Maciej W. Rozycki [this message]
2007-09-18 15:54 ` Daniel Jacobowitz
2007-09-19 12:31 ` Maciej W. Rozycki
2007-09-19 12:38 ` Daniel Jacobowitz
2007-09-19 13:05 ` Maciej W. Rozycki
2007-09-19 13:16 ` Daniel Jacobowitz
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=Pine.LNX.4.61.0709111642220.32532@perivale.mips.com \
--to=macro@mips.com \
--cc=drow@false.org \
--cc=gdb-patches@sourceware.org \
--cc=macro@linux-mips.org \
/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