[PATCH]: Fix signal frames on sparc*-*-linux*

David S. Miller
2006-04-04T23:44:28Z

The current code is pulling the register window out of the
trampoline's stack frame, not the signal stack frame.

The other targets were getting this right.

This fixes that.

Any objections?

2006-04-04 David S. Miller <davem@sunset.davemloft.net>

* sparc-linux-tdep.c (sparc32_linux_sigframe_init): Pull register
window out of the correct stack frame.
* sparc64-linux-tdep.c (sparc64_linux_sigframe_init): Likewise.

--- sparc-linux-tdep.c.~1~ 2005-04-22 12:52:21.000000000 -0700
+++ sparc-linux-tdep.c 2006-04-04 15:19:24.000000000 -0700
@@ -91,7 +91,7 @@
struct trad_frame_cache *this_cache,
CORE_ADDR func)
{
- CORE_ADDR base, addr;
+ CORE_ADDR base, addr, sp_addr;
int regnum;

base = frame_unwind_register_unsigned (next_frame, SPARC_O1_REGNUM);
@@ -107,13 +107,16 @@

/* Since %g0 is always zero, keep the identity encoding. */
addr = base + 20;
+ sp_addr = base + 16 + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 4);
for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
{
trad_frame_set_reg_addr (this_cache, regnum, addr);
addr += 4;
}

- base = addr = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
+ base = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
+ addr = get_frame_memory_unsigned (next_frame, sp_addr, 4);
+
for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
{
trad_frame_set_reg_addr (this_cache, regnum, addr);
--- sparc64-linux-tdep.c.~1~ 2005-04-22 16:08:06.000000000 -0700
+++ sparc64-linux-tdep.c 2006-04-04 16:06:41.000000000 -0700
@@ -59,7 +59,7 @@
struct trad_frame_cache *this_cache,
CORE_ADDR func)
{
- CORE_ADDR base, addr;
+ CORE_ADDR base, addr, sp_addr;
int regnum;

base = frame_unwind_register_unsigned (next_frame, SPARC_O1_REGNUM);
@@ -69,6 +69,7 @@

/* Since %g0 is always zero, keep the identity encoding. */
addr = base + 8;
+ sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
{
trad_frame_set_reg_addr (this_cache, regnum, addr);
@@ -81,11 +82,14 @@
trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);

- addr = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
+ base = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
+ if (base & 1)
+ base += BIAS;
+
+ addr = get_frame_memory_unsigned (next_frame, sp_addr, 8);
if (addr & 1)
addr += BIAS;

- base = addr;
for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
{
trad_frame_set_reg_addr (this_cache, regnum, addr);