summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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