diff options
-rw-r--r-- | gnu/usr.bin/binutils/gdb/i386/freebsd-nat.c | 45 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/i386/tm.h | 12 |
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)); |