From: Sandra Loosemore Date: Fri, 8 May 2015 19:34:52 +0000 (-0700) Subject: Fix register save offset for nios2 signal handler trampolines. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=35d54293c3a0fb5e8cd3a82a1e2a6e0481b615af;p=binutils-gdb.git Fix register save offset for nios2 signal handler trampolines. 2015-05-08 Sandra Loosemore gdb/ * nios2-linux-tdep.c (NIOS2_SIGRETURN_TRAMP_ADDR): Define. (NIOS2_SIGRETURN_REGSAVE_OFFSET): Define. (nios2_linux_rt_sigreturn_init): Adjust base address of register save area. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f895f9ccafb..b7a29e6396d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2015-05-08 Sandra Loosemore + + * nios2-linux-tdep.c (NIOS2_SIGRETURN_TRAMP_ADDR): Define. + (NIOS2_SIGRETURN_REGSAVE_OFFSET): Define. + (nios2_linux_rt_sigreturn_init): Adjust base address of + register save area. + 2015-05-08 Sandra Loosemore * nios2-tdep.c (nios2_breakpoint_from_pc): Revert to using diff --git a/gdb/nios2-linux-tdep.c b/gdb/nios2-linux-tdep.c index b829569c9c4..0a837b0a093 100644 --- a/gdb/nios2-linux-tdep.c +++ b/gdb/nios2-linux-tdep.c @@ -114,7 +114,25 @@ nios2_iterate_over_regset_sections (struct gdbarch *gdbarch, } /* Initialize a trad-frame cache corresponding to the tramp-frame. - FUNC is the address of the instruction TRAMP[0] in memory. */ + FUNC is the address of the instruction TRAMP[0] in memory. + + This ABI is not documented. It corresponds to rt_setup_ucontext in + the kernel arch/nios2/kernel/signal.c file. + + The key points are: + - The kernel creates a trampoline at the hard-wired address 0x1044. + - The stack pointer points to an object of type struct rt_sigframe. + The definition of this structure is not exported from the kernel. + The register save area is located at offset 152 bytes (as determined + by inspection of the stack contents in the debugger), and the + registers are saved as r1-r23, ra, fp, gp, ea, sp. + + This interface was implemented with kernel version 3.19 (the first + official mainline kernel). Older unofficial kernel versions used + incompatible conventions; we do not support those here. */ + +#define NIOS2_SIGRETURN_TRAMP_ADDR 0x1044 +#define NIOS2_SIGRETURN_REGSAVE_OFFSET 152 static void nios2_linux_rt_sigreturn_init (const struct tramp_frame *self, @@ -122,7 +140,8 @@ nios2_linux_rt_sigreturn_init (const struct tramp_frame *self, struct trad_frame_cache *this_cache, CORE_ADDR func) { - CORE_ADDR base = func + 41 * 4; + CORE_ADDR sp = get_frame_register_unsigned (next_frame, NIOS2_SP_REGNUM); + CORE_ADDR base = sp + NIOS2_SIGRETURN_REGSAVE_OFFSET; int i; for (i = 0; i < 23; i++)