summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-03-27 04:55:43 +0000
committerobrien <obrien@FreeBSD.org>2002-03-27 04:55:43 +0000
commit4865cbe2817be761ce4d854022abdcd318ae6acd (patch)
tree1ca4ea758c9a41cda7ed005e6ec4d703a4d4b3c3
parent2cf6bc353fcf164b912c1d7f2f94f3441f2730b8 (diff)
downloadFreeBSD-src-4865cbe2817be761ce4d854022abdcd318ae6acd.zip
FreeBSD-src-4865cbe2817be761ce4d854022abdcd318ae6acd.tar.gz
Enhance GDB's abillity WRT stack traces where signal handlers are involved.
Correct backtrace was made more complex when the new signal trampoline was introduced to support more than 32 signals, while keeping a modified version of the old signal trampoline. The 'where' command will now show: #2 <signal handler called> where appropiate. Submitted by: Tor.Egge@fast.no
-rw-r--r--gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c45
-rw-r--r--gnu/usr.bin/binutils/gdb/i386/tm.h12
2 files changed, 53 insertions, 4 deletions
diff --git a/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c b/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c
index 1923097..a346f47 100644
--- a/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c
+++ b/gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c
@@ -663,3 +663,48 @@ remove_watchpoint(addr, len, type)
}
#endif /* PT_GETDBREGS */
+
+CORE_ADDR
+fbsd_sigtramp_saved_pc (frame)
+ struct frame_info *frame;
+{
+ CORE_ADDR sigcontext_addr;
+ CORE_ADDR sigcode_addr;
+ char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
+ int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
+ int sigcode_offs = (-1 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
+
+ /* Get sigcontext address, it is the third parameter on the stack. */
+ if (frame->next)
+ sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next)
+ + FRAME_ARGS_SKIP
+ + sigcontext_offs,
+ ptrbytes);
+ else
+ sigcontext_addr = read_memory_integer (read_register (SP_REGNUM)
+ + sigcontext_offs,
+ ptrbytes);
+
+#ifdef OSIGCODE_MAGIC_OFFSET
+ if (frame->next)
+ sigcode_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next)
+ + FRAME_ARGS_SKIP
+ + sigcode_offs,
+ ptrbytes);
+ else
+ sigcode_addr = read_memory_integer (read_register (SP_REGNUM)
+ + sigcode_offs,
+ ptrbytes);
+ target_read_memory (sigcode_addr + OSIGCODE_MAGIC_OFFSET,
+ buf, ptrbytes);
+ if (extract_unsigned_integer(buf, ptrbytes) == 0x01d516) {
+ target_read_memory (sigcontext_addr + OSIGCONTEXT_PC_OFFSET,
+ buf, ptrbytes);
+ } else
+#endif
+ /* Don't cause a memory_error when accessing sigcontext in case the stack
+ layout has changed or the stack is corrupt. */
+ target_read_memory (sigcontext_addr + NSIGCONTEXT_PC_OFFSET, buf, ptrbytes);
+ return extract_unsigned_integer (buf, ptrbytes);
+}
diff --git a/gnu/usr.bin/binutils/gdb/i386/tm.h b/gnu/usr.bin/binutils/gdb/i386/tm.h
index 69dfa44..ac2f86f 100644
--- a/gnu/usr.bin/binutils/gdb/i386/tm.h
+++ b/gnu/usr.bin/binutils/gdb/i386/tm.h
@@ -43,18 +43,22 @@ extern CORE_ADDR fbsd_kern_frame_saved_pc (struct frame_info *);
#define FRAME_SAVED_PC(FRAME) \
(kernel_debugging ? fbsd_kern_frame_saved_pc(FRAME) : \
(((FRAME)->signal_handler_caller \
- ? sigtramp_saved_pc (FRAME) \
+ ? fbsd_sigtramp_saved_pc (FRAME) \
: read_memory_integer ((FRAME)->frame + 4, 4)) \
))
-/* On FreeBSD, sigtramp has size 0x18 and is immediately below the
+/* On FreeBSD, sigtramp has size 0x48 and is immediately below the
ps_strings struct which has size 0x10 and is at the top of the
user stack. */
#undef SIGTRAMP_START
#undef SIGTRAMP_END
-#define SIGTRAMP_START(pc) 0xbfbfdfd8
-#define SIGTRAMP_END(pc) 0xbfbfdff0
+#define SIGTRAMP_START(pc) 0xbfbfffa8
+#define SIGTRAMP_END(pc) 0xbfbffff0
+#undef SIGCONTEXT_PC_OFFSET
+#define OSIGCONTEXT_PC_OFFSET 20
+#define NSIGCONTEXT_PC_OFFSET 76
+#define OSIGCODE_MAGIC_OFFSET 20
struct objfile;
void freebsd_uthread_new_objfile PARAMS ((struct objfile *objfile));
OpenPOWER on IntegriCloud