diff options
author | Michal Ludvig <mludvig@suse.cz> | 2002-10-24 01:27:43 +0000 |
---|---|---|
committer | Michal Ludvig <mludvig@suse.cz> | 2002-10-24 01:27:43 +0000 |
commit | baed091b2b498c9cd74af81c6891ad13c312ee47 (patch) | |
tree | 8d0c14b78632129a54f17525e54f40fc030ace67 /gdb/x86-64-linux-tdep.c | |
parent | c38da1aff132c1c35324c97cc89efd3629a006e5 (diff) | |
download | gdb-baed091b2b498c9cd74af81c6891ad13c312ee47.zip gdb-baed091b2b498c9cd74af81c6891ad13c312ee47.tar.gz gdb-baed091b2b498c9cd74af81c6891ad13c312ee47.tar.bz2 |
2002-10-24 Michal Ludvig <mludvig@suse.cz>
* dwarf2cfi.c (struct context)
(struct context_reg): Moved to dwarf2cfi.h
(context_alloc, frame_state_alloc, context_cpy):
Made extern instead of static, removed prototypes.
* dwarf2cfi.h (struct context)
(struct context_reg): New, moved from dwarf2cfi.c
(context_alloc, frame_state_alloc, context_cpy):
New prototypes.
* x86-64-linux-tdep.c (x86_64_linux_sigtramp_saved_pc):
Changed from static to extern.
(LINUX_SIGINFO_SIZE, LINUX_SIGCONTEXT_PC_OFFSET)
(LINUX_SIGCONTEXT_FP_OFFSET)
(LINUX_UCONTEXT_SIGCONTEXT_OFFSET): Adjusted.
(x86_64_linux_in_sigtramp, x86_64_linux_frame_chain)
(x86_64_init_frame_pc, x86_64_init_extra_frame_info): New.
* x86-64-tdep.c (x86_64_gdbarch_init): Several
set_gdbarch_*() calls now use x86-64 specific functions
instead of DWARF2 CFI ones.
* x86-64-tdep.h (x86_64_linux_in_sigtramp)
(x86_64_linux_frame_chain, x86_64_init_frame_pc)
(x86_64_init_extra_frame_info): New prototypes.
Diffstat (limited to 'gdb/x86-64-linux-tdep.c')
-rw-r--r-- | gdb/x86-64-linux-tdep.c | 83 |
1 files changed, 73 insertions, 10 deletions
diff --git a/gdb/x86-64-linux-tdep.c b/gdb/x86-64-linux-tdep.c index ac41daa..71e3276 100644 --- a/gdb/x86-64-linux-tdep.c +++ b/gdb/x86-64-linux-tdep.c @@ -35,8 +35,10 @@ #define LINUX_SIGTRAMP_OFFSET1 (7) static const unsigned char linux_sigtramp_code[] = { - LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x89, 0x00, 0x00, 0x00, /* mov $0x89,%rax */ - LINUX_SIGTRAMP_INSN1, 0x05 /* syscall */ + /* mov $__NR_rt_sigreturn,%rax */ + LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00, + /* syscall */ + LINUX_SIGTRAMP_INSN1, 0x05 }; #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code) @@ -68,17 +70,22 @@ x86_64_linux_sigtramp_start (CORE_ADDR pc) return pc; } -#define LINUX_SIGINFO_SIZE 128 +#define LINUX_SIGINFO_SIZE 0 /* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */ -#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36) +#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET 40 + +/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */ +#define LINUX_SIGCONTEXT_PC_OFFSET 128 +#define LINUX_SIGCONTEXT_FP_OFFSET 120 /* Assuming FRAME is for a GNU/Linux sigtramp routine, return the address of the associated sigcontext structure. */ -CORE_ADDR +static CORE_ADDR x86_64_linux_sigcontext_addr (struct frame_info *frame) { CORE_ADDR pc; + ULONGEST rsp; pc = x86_64_linux_sigtramp_start (frame->pc); if (pc) @@ -92,7 +99,8 @@ x86_64_linux_sigcontext_addr (struct frame_info *frame) /* This is the top frame. */ - return read_register (SP_REGNUM) + LINUX_SIGINFO_SIZE + + rsp = read_register (SP_REGNUM); + return rsp + LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET; } @@ -101,13 +109,10 @@ x86_64_linux_sigcontext_addr (struct frame_info *frame) return 0; } -/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */ -#define LINUX_SIGCONTEXT_PC_OFFSET (136) - /* Assuming FRAME is for a GNU/Linux sigtramp routine, return the saved program counter. */ -CORE_ADDR +static CORE_ADDR x86_64_linux_sigtramp_saved_pc (struct frame_info *frame) { CORE_ADDR addr; @@ -135,3 +140,61 @@ x86_64_linux_frame_saved_pc (struct frame_info *frame) return x86_64_linux_sigtramp_saved_pc (frame); return cfi_get_ra (frame); } + +/* Return whether PC is in a GNU/Linux sigtramp routine. */ + +int +x86_64_linux_in_sigtramp (CORE_ADDR pc, char *name) +{ + if (name) + return STREQ ("__restore_rt", name); + + return (x86_64_linux_sigtramp_start (pc) != 0); +} + +CORE_ADDR +x86_64_linux_frame_chain (struct frame_info *fi) +{ + ULONGEST addr; + CORE_ADDR fp, pc; + + if (! fi->signal_handler_caller) + { + fp = cfi_frame_chain (fi); + if(fp) + return fp; + else + addr = fi->frame; + } + else + addr = fi->next->frame; + + addr += LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET; + + fp = read_memory_integer (addr + LINUX_SIGCONTEXT_FP_OFFSET, 8)+8; + + return fp; +} + +void +x86_64_init_frame_pc (int fromleaf, struct frame_info *fi) +{ + CORE_ADDR addr; + + if(fi->next && fi->next->signal_handler_caller) + { + addr = fi->next->next->frame + + LINUX_SIGINFO_SIZE + + LINUX_UCONTEXT_SIGCONTEXT_OFFSET; + fi->pc = read_memory_integer (addr + + LINUX_SIGCONTEXT_PC_OFFSET, 8); + } + else + cfi_init_frame_pc (fromleaf, fi); +} + +void +x86_64_init_extra_frame_info (int fromleaf, struct frame_info *fi) +{ + cfi_init_extra_frame_info (fromleaf, fi); +} |