static int i386_linux_pc_in_sigtramp (CORE_ADDR pc, char *name) { if (name) return STREQ ("__restore", name) || STREQ ("__restore_rt", name); return (i386_linux_sigtramp_start (pc) != 0 || i386_linux_rt_sigtramp_start (pc) != 0); }
static CORE_ADDR i386_linux_sigcontext_addr (struct frame_info *frame) { CORE_ADDR pc; pc = i386_linux_sigtramp_start (frame->pc); if (pc) { CORE_ADDR sp; if (frame->next) /* If this isn't the top frame, the next frame must be for the signal handler itself. The sigcontext structure lives on the stack, right after the signum argument. */ return frame->next->frame + 12; /* This is the top frame. We'll have to find the address of the sigcontext structure by looking at the stack pointer. Keep in mind that the first instruction of the sigtramp code is "pop %eax". If the PC is at this instruction, adjust the returned value accordingly. */ sp = read_register (SP_REGNUM); if (pc == frame->pc) return sp + 4; return sp; } pc = i386_linux_rt_sigtramp_start (frame->pc); if (pc) { if (frame->next) /* If this isn't the top frame, the next frame must be for the signal handler itself. The sigcontext structure is part of the user context. A pointer to the user context is passed as the third argument to the signal handler. */ return read_memory_integer (frame->next->frame + 16, 4) + 20; /* This is the top frame. Again, use the stack pointer to find the address of the sigcontext structure. */ return read_memory_integer (read_register (SP_REGNUM) + 8, 4) + 20; } error ("Couldn't recognize signal trampoline."); return 0; }
static CORE_ADDR i386_linux_sigcontext_addr (struct frame_info *this_frame) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR pc; CORE_ADDR sp; gdb_byte buf[4]; get_frame_register (this_frame, I386_ESP_REGNUM, buf); sp = extract_unsigned_integer (buf, 4, byte_order); pc = i386_linux_sigtramp_start (this_frame); if (pc) { /* The sigcontext structure lives on the stack, right after the signum argument. We determine the address of the sigcontext structure by looking at the frame's stack pointer. Keep in mind that the first instruction of the sigtramp code is "pop %eax". If the PC is after this instruction, adjust the returned value accordingly. */ if (pc == get_frame_pc (this_frame)) return sp + 4; return sp; } pc = i386_linux_rt_sigtramp_start (this_frame); if (pc) { CORE_ADDR ucontext_addr; /* The sigcontext structure is part of the user context. A pointer to the user context is passed as the third argument to the signal handler. */ read_memory (sp + 8, buf, 4); ucontext_addr = extract_unsigned_integer (buf, 4, byte_order); return ucontext_addr + I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET; } error (_("Couldn't recognize signal trampoline.")); return 0; }
static int i386_linux_sigtramp_p (struct frame_info *this_frame) { CORE_ADDR pc = get_frame_pc (this_frame); const char *name; find_pc_partial_function (pc, &name, NULL, NULL); /* If we have NAME, we can optimize the search. The trampolines are named __restore and __restore_rt. However, they aren't dynamically exported from the shared C library, so the trampoline may appear to be part of the preceding function. This should always be sigaction, __sigaction, or __libc_sigaction (all aliases to the same function). */ if (name == NULL || strstr (name, "sigaction") != NULL) return (i386_linux_sigtramp_start (this_frame) != 0 || i386_linux_rt_sigtramp_start (this_frame) != 0); return (strcmp ("__restore", name) == 0 || strcmp ("__restore_rt", name) == 0); }