From 81f726abf0aa11a89163ad39b7a0a5575d96b023 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 21 Apr 2005 22:04:04 +0000 Subject: [PATCH] * sparc-linux-tdep.c (sparc32_linux_sigframe_init): New function. (sparc32_linux_sigframe, sparc32_linux_rt_sigframe): New tramp_frames. (sparc_linux_sigtramp_start, sparc32_linux_sigtramp_start, sparc32_linux_rt_sigtramp_start, sparc32_linux_sigtramp_p, sparc32_linux_sigtramp_frame_cache, sparc32_linux_sigtramp_frame_this_id, sparc32_linux_sigtramp_frame_prev_register, sparc32_linux_sigtramp_frame_unwind, sparc32_linux_sigtramp_frame_sniffer): Delete. (sparc32_linux_init_abi): Register new tramp unwinders. Kill register of old sigtramp sniffer. * sparc64-linux-tdep.c (sparc64_linux_sigframe_init): New function. (sparc64_linux_rt_sigframe): New tramp frame. (sparc64_linux_sigtramp_start, sparc64_linux_sigtramp_p, sparc64_linux_sigtramp_frame_cache, sparc64_linux_sigtramp_frame_this_id, sparc64_linux_sigtramp_frame_prev_register, sparc64_linux_sigtramp_frame_unwind, sparc64_linux_sigtramp_frame_sniffer): Delete. (sparc64_linux_init_abi): Register new tramp unwinders. Kill register of old sigtramp sniffer. Makefile.in (sparc64-linux-tdep.o): Update dependencies. (sparc-linux-tdep.o): Likewise. --- gdb/ChangeLog | 27 +++++ gdb/Makefile.in | 6 +- gdb/sparc-linux-tdep.c | 231 ++++++++++----------------------------- gdb/sparc64-linux-tdep.c | 196 ++++++++------------------------- 4 files changed, 136 insertions(+), 324 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0dcb93230f..e8845b6bcc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2005-04-21 David S. Miller + + * sparc-linux-tdep.c (sparc32_linux_sigframe_init): New function. + (sparc32_linux_sigframe, sparc32_linux_rt_sigframe): New tramp_frames. + (sparc_linux_sigtramp_start, sparc32_linux_sigtramp_start, + sparc32_linux_rt_sigtramp_start, sparc32_linux_sigtramp_p, + sparc32_linux_sigtramp_frame_cache, + sparc32_linux_sigtramp_frame_this_id, + sparc32_linux_sigtramp_frame_prev_register, + sparc32_linux_sigtramp_frame_unwind, + sparc32_linux_sigtramp_frame_sniffer): Delete. + (sparc32_linux_init_abi): Register new tramp unwinders. Kill + register of old sigtramp sniffer. + * sparc64-linux-tdep.c (sparc64_linux_sigframe_init): New + function. + (sparc64_linux_rt_sigframe): New tramp frame. + (sparc64_linux_sigtramp_start, sparc64_linux_sigtramp_p, + sparc64_linux_sigtramp_frame_cache, + sparc64_linux_sigtramp_frame_this_id, + sparc64_linux_sigtramp_frame_prev_register, + sparc64_linux_sigtramp_frame_unwind, + sparc64_linux_sigtramp_frame_sniffer): Delete. + (sparc64_linux_init_abi): Register new tramp unwinders. Kill + register of old sigtramp sniffer. + Makefile.in (sparc64-linux-tdep.o): Update dependencies. + (sparc-linux-tdep.o): Likewise. + 2005-04-21 Mark Kettenis * ser-base.c: Include "gdb_string.h". diff --git a/gdb/Makefile.in b/gdb/Makefile.in index abfec49184..f075d3c476 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2567,7 +2567,7 @@ sparc64-linux-nat.o: sparc64-linux-nat.c $(defs_h) $(sparc64_tdep_h) \ $(sparc_nat_h) sparc64-linux-tdep.o: sparc64-linux-tdep.c $(defs_h) $(frame_h) \ $(frame_unwind_h) $(gdbarch_h) $(osabi_h) $(solib_svr4_h) \ - $(symtab_h) $(trad_frame_h) $(gdb_assert_h) $(gdb_string_h) \ + $(symtab_h) $(trad_frame_h) \ $(sparc64_tdep_h) sparc64-nat.o: sparc64-nat.c $(defs_h) $(gdbarch_h) $(sparc64_tdep_h) \ $(sparc_nat_h) @@ -2590,8 +2590,8 @@ sparc64-tdep.o: sparc64-tdep.c $(defs_h) $(arch_utils_h) $(floatformat_h) \ $(sparc64_tdep_h) sparc-linux-tdep.o: sparc-linux-tdep.c $(defs_h) $(floatformat_h) $(frame_h) \ $(frame_unwind_h) $(gdbarch_h) $(gdbcore_h) $(osabi_h) $(regcache_h) \ - $(solib_svr4_h) $(symtab_h) $(trad_frame_h) $(gdb_assert_h) \ - $(gdb_string_h) $(sparc_tdep_h) + $(solib_svr4_h) $(symtab_h) $(trad_frame_h) \ + $(sparc_tdep_h) sparc-nat.o: sparc-nat.c $(defs_h) $(inferior_h) $(regcache_h) $(target_h) \ $(gdb_assert_h) $(gdb_string_h) $(gdb_wait_h) $(sparc_tdep_h) \ $(sparc_nat_h) $(inf_ptrace_h) diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c index db40365524..6b8ad311b4 100644 --- a/gdb/sparc-linux-tdep.c +++ b/gdb/sparc-linux-tdep.c @@ -23,6 +23,7 @@ #include "floatformat.h" #include "frame.h" #include "frame-unwind.h" +#include "tramp-frame.h" #include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" @@ -31,12 +32,9 @@ #include "symtab.h" #include "trad-frame.h" -#include "gdb_assert.h" -#include "gdb_string.h" - #include "sparc-tdep.h" -/* Recognizing signal handler frames. */ +/* Signal trampoline support. */ /* GNU/Linux has two flavors of signals. Normal signal handlers, and "realtime" (RT) signals. The RT signals can provide additional @@ -69,195 +67,86 @@ /* The instruction sequence for RT signals is mov __NR_rt_sigreturn, %g1 ! hex: 0x82102065 - ta {0x10,0x6d} ! hex: 0x91d02010 or 0x91d0206d + ta {0x10,0x6d} ! hex: 0x91d02010 - The effect is to call the system call rt_sigreturn. The trap number - is variable based upon whether this is a 32-bit or 64-bit sparc binary. + The effect is to call the system call rt_sigreturn. Note that 64-bit binaries only use this RT signal return method. */ #define LINUX32_RT_SIGTRAMP_INSN0 0x82102065 #define LINUX32_RT_SIGTRAMP_INSN1 0x91d02010 -/* If PC is in a sigtramp routine consisting of the instructions INSN0 - and INSN1, return the address of the start of the routine. - Otherwise, return 0. */ +static void sparc32_linux_sigframe_init (const struct tramp_frame *self, + struct frame_info *next_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func); -CORE_ADDR -sparc_linux_sigtramp_start (struct frame_info *next_frame, - ULONGEST insn0, ULONGEST insn1) +static const struct tramp_frame sparc32_linux_sigframe = { + SIGTRAMP_FRAME, + 4, + { + { LINUX32_SIGTRAMP_INSN0, -1 }, + { LINUX32_SIGTRAMP_INSN1, -1 }, + { TRAMP_SENTINEL_INSN, -1 } + }, + sparc32_linux_sigframe_init +}; + +static const struct tramp_frame sparc32_linux_rt_sigframe = { + SIGTRAMP_FRAME, + 4, + { + { LINUX32_RT_SIGTRAMP_INSN0, -1 }, + { LINUX32_RT_SIGTRAMP_INSN1, -1 }, + { TRAMP_SENTINEL_INSN, -1 } + }, + sparc32_linux_sigframe_init +}; + +static void +sparc32_linux_sigframe_init (const struct tramp_frame *self, + struct frame_info *next_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) { - CORE_ADDR pc = frame_pc_unwind (next_frame); - ULONGEST word0, word1; - unsigned char buf[8]; /* Two instructions. */ - - /* We only recognize a signal trampoline if PC is at the start of - one of the instructions. We optimize for finding the PC at the - start of the instruction sequence, as will be the case when the - trampoline is not the first frame on the stack. We assume that - in the case where the PC is not at the start of the instruction - sequence, there will be a few trailing readable bytes on the - stack. */ - - if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf)) - return 0; - - word0 = extract_unsigned_integer (buf, 4); - if (word0 != insn0) - { - if (word0 != insn1) - return 0; - - pc -= 4; - if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf)) - return 0; - - word0 = extract_unsigned_integer (buf, 4); - } - - word1 = extract_unsigned_integer (buf + 4, 4); - if (word0 != insn0 || word1 != insn1) - return 0; - - return pc; -} - -static CORE_ADDR -sparc32_linux_sigtramp_start (struct frame_info *next_frame) -{ - return sparc_linux_sigtramp_start (next_frame, LINUX32_SIGTRAMP_INSN0, - LINUX32_SIGTRAMP_INSN1); -} - -static CORE_ADDR -sparc32_linux_rt_sigtramp_start (struct frame_info *next_frame) -{ - return sparc_linux_sigtramp_start (next_frame, LINUX32_RT_SIGTRAMP_INSN0, - LINUX32_RT_SIGTRAMP_INSN1); -} - -static int -sparc32_linux_sigtramp_p (struct frame_info *next_frame) -{ - CORE_ADDR pc = frame_pc_unwind (next_frame); - char *name; - - find_pc_partial_function (pc, &name, NULL, NULL); - - /* If we have NAME, we can optimize the search. The trampolines are - named __sigreturn_stub and __rt_sigreturn_stub. 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 (sparc32_linux_sigtramp_start (next_frame) != 0 - || sparc32_linux_rt_sigtramp_start (next_frame) != 0); - - return (strcmp ("__sigreturn_stub", name) == 0 - || strcmp ("__rt_sigreturn_stub", name) == 0); -} - -static struct sparc_frame_cache * -sparc32_linux_sigtramp_frame_cache (struct frame_info *next_frame, - void **this_cache) -{ - struct sparc_frame_cache *cache; - CORE_ADDR sigcontext_addr, addr; + CORE_ADDR base, addr; int regnum; - if (*this_cache) - return *this_cache; - - cache = sparc32_frame_cache (next_frame, this_cache); - gdb_assert (cache == *this_cache); - - /* ??? What about signal trampolines that aren't frameless? */ - regnum = SPARC_SP_REGNUM; - cache->base = frame_unwind_register_unsigned (next_frame, regnum); - - regnum = SPARC_O1_REGNUM; - sigcontext_addr = frame_unwind_register_unsigned (next_frame, regnum); - - addr = sparc32_linux_sigtramp_start (next_frame); - if (addr == 0) - { - /* If this is a RT signal trampoline, adjust SIGCONTEXT_ADDR - accordingly. */ - addr = sparc32_linux_rt_sigtramp_start (next_frame); - if (addr) - sigcontext_addr += 128; - else - addr = frame_func_unwind (next_frame); - } - cache->pc = addr; - - cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + base = frame_unwind_register_unsigned (next_frame, SPARC_O1_REGNUM); + if (self == &sparc32_linux_rt_sigframe) + base += 128; /* Offsets from */ - cache->saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 0; - cache->saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 4; - cache->saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 8; - cache->saved_regs[SPARC32_Y_REGNUM].addr = sigcontext_addr + 12; + trad_frame_set_reg_addr (this_cache, SPARC32_PSR_REGNUM, base + 0x00); + trad_frame_set_reg_addr (this_cache, SPARC32_PC_REGNUM, base + 0x04); + trad_frame_set_reg_addr (this_cache, SPARC32_NPC_REGNUM, base + 0x08); + trad_frame_set_reg_addr (this_cache, SPARC32_Y_REGNUM, base + 0x0c); /* Since %g0 is always zero, keep the identity encoding. */ - for (regnum = SPARC_G1_REGNUM, addr = sigcontext_addr + 20; - regnum <= SPARC_O7_REGNUM; regnum++, addr += 4) - cache->saved_regs[regnum].addr = addr; + addr = base + 0x14; + for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++) + { + trad_frame_set_reg_addr (this_cache, regnum, addr); + addr += 4; + } - for (regnum = SPARC_L0_REGNUM, addr = cache->base; - regnum <= SPARC_I7_REGNUM; regnum++, addr += 4) - cache->saved_regs[regnum].addr = addr; - - return cache; + base = addr = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM); + for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) + { + trad_frame_set_reg_addr (this_cache, regnum, addr); + addr += 4; + } + trad_frame_set_id (this_cache, frame_id_build (base, func)); } -static void -sparc32_linux_sigtramp_frame_this_id (struct frame_info *next_frame, - void **this_cache, - struct frame_id *this_id) -{ - struct sparc_frame_cache *cache = - sparc32_linux_sigtramp_frame_cache (next_frame, this_cache); - - (*this_id) = frame_id_build (cache->base, cache->pc); -} - -static void -sparc32_linux_sigtramp_frame_prev_register (struct frame_info *next_frame, - void **this_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, - CORE_ADDR *addrp, - int *realnump, void *valuep) -{ - struct sparc_frame_cache *cache = - sparc32_linux_sigtramp_frame_cache (next_frame, this_cache); - - trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum, - optimizedp, lvalp, addrp, realnump, valuep); -} - -static const struct frame_unwind sparc32_linux_sigtramp_frame_unwind = -{ - SIGTRAMP_FRAME, - sparc32_linux_sigtramp_frame_this_id, - sparc32_linux_sigtramp_frame_prev_register -}; - -static const struct frame_unwind * -sparc32_linux_sigtramp_frame_sniffer (struct frame_info *next_frame) -{ - if (sparc32_linux_sigtramp_p (next_frame)) - return &sparc32_linux_sigtramp_frame_unwind; - - return NULL; -} static void sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { + tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_sigframe); + tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_rt_sigframe); + /* GNU/Linux is very similar to Solaris ... */ sparc32_sol2_init_abi (info, gdbarch); @@ -268,8 +157,6 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_long_double_bit (gdbarch, 64); set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); - frame_unwind_append_sniffer (gdbarch, sparc32_linux_sigtramp_frame_sniffer); - /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c index 0047625b1c..3401d2b4fc 100644 --- a/gdb/sparc64-linux-tdep.c +++ b/gdb/sparc64-linux-tdep.c @@ -22,15 +22,13 @@ #include "defs.h" #include "frame.h" #include "frame-unwind.h" +#include "tramp-frame.h" #include "gdbarch.h" #include "osabi.h" #include "solib-svr4.h" #include "symtab.h" #include "trad-frame.h" -#include "gdb_assert.h" -#include "gdb_string.h" - #include "sparc64-tdep.h" /* The instruction sequence for RT signals is @@ -43,162 +41,62 @@ #define LINUX64_RT_SIGTRAMP_INSN0 0x82102065 #define LINUX64_RT_SIGTRAMP_INSN1 0x91d0206d -/* If PC is in a sigtramp routine consisting of the instructions - LINUX64_RT_SIGTRAMP_INSN0 and LINUX64_RT_SIGTRAMP_INSN1, return - the address of the start of the routine. Otherwise, return 0. */ -static CORE_ADDR -sparc64_linux_sigtramp_start (struct frame_info *next_frame) +static void sparc64_linux_sigframe_init (const struct tramp_frame *self, + struct frame_info *next_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func); + +static const struct tramp_frame sparc64_linux_rt_sigframe = { + SIGTRAMP_FRAME, + 4, + { + { LINUX64_RT_SIGTRAMP_INSN0, -1 }, + { LINUX64_RT_SIGTRAMP_INSN1, -1 }, + { TRAMP_SENTINEL_INSN, -1 } + }, + sparc64_linux_sigframe_init +}; + +static void +sparc64_linux_sigframe_init (const struct tramp_frame *self, + struct frame_info *next_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) { - CORE_ADDR pc = frame_pc_unwind (next_frame); - ULONGEST word0, word1; - unsigned char buf[8]; /* Two instructions. */ - - /* We only recognize a signal trampoline if PC is at the start of - one of the instructions. We optimize for finding the PC at the - start of the instruction sequence, as will be the case when the - trampoline is not the first frame on the stack. We assume that - in the case where the PC is not at the start of the instruction - sequence, there will be a few trailing readable bytes on the - stack. */ - - if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf)) - return 0; - - word0 = extract_unsigned_integer (buf, 4); - if (word0 != LINUX64_RT_SIGTRAMP_INSN0) - { - if (word0 != LINUX64_RT_SIGTRAMP_INSN1) - return 0; - - pc -= 4; - if (!safe_frame_unwind_memory (next_frame, pc, buf, sizeof buf)) - return 0; - - word0 = extract_unsigned_integer (buf, 4); - } - - word1 = extract_unsigned_integer (buf + 4, 4); - if (word0 != LINUX64_RT_SIGTRAMP_INSN0 - || word1 != LINUX64_RT_SIGTRAMP_INSN1) - return 0; - - return pc; -} - -static int -sparc64_linux_sigtramp_p (struct frame_info *next_frame) -{ - CORE_ADDR pc = frame_pc_unwind (next_frame); - char *name; - - find_pc_partial_function (pc, &name, NULL, NULL); - - /* If we have NAME, we can optimize the search. The trampolines is - named __rt_sigreturn_stub. However, is isn'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 (sparc64_linux_sigtramp_start (next_frame) != 0); - - return (strcmp ("__rt_sigreturn_stub", name) == 0); -} - -static struct sparc_frame_cache * -sparc64_linux_sigtramp_frame_cache (struct frame_info *next_frame, - void **this_cache) -{ - struct sparc_frame_cache *cache; - CORE_ADDR sigcontext_addr, addr; + CORE_ADDR base, addr; int regnum; - if (*this_cache) - return *this_cache; - - cache = sparc_frame_cache (next_frame, this_cache); - gdb_assert (cache == *this_cache); - - regnum = SPARC_SP_REGNUM; - cache->base = frame_unwind_register_unsigned (next_frame, regnum); - if (cache->base & 1) - cache->base += BIAS; - - regnum = SPARC_O1_REGNUM; - sigcontext_addr = frame_unwind_register_unsigned (next_frame, regnum); - - /* If this is a RT signal trampoline, adjust SIGCONTEXT_ADDR - accordingly. */ - addr = sparc64_linux_sigtramp_start (next_frame); - if (addr) - sigcontext_addr += 128; - else - addr = frame_func_unwind (next_frame); - - cache->pc = addr; - - cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + base = frame_unwind_register_unsigned (next_frame, SPARC_O1_REGNUM); + base += 128; /* Offsets from */ /* Since %g0 is always zero, keep the identity encoding. */ - for (addr = sigcontext_addr + 8, regnum = SPARC_G1_REGNUM; - regnum <= SPARC_O7_REGNUM; regnum++, addr += 8) - cache->saved_regs[regnum].addr = addr; + addr = base + 0x08; + for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++) + { + trad_frame_set_reg_addr (this_cache, regnum, addr); + addr += 8; + } - cache->saved_regs[SPARC64_STATE_REGNUM].addr = addr + 0; - cache->saved_regs[SPARC64_PC_REGNUM].addr = addr + 8; - cache->saved_regs[SPARC64_NPC_REGNUM].addr = addr + 16; - cache->saved_regs[SPARC64_Y_REGNUM].addr = addr + 24; - cache->saved_regs[SPARC64_FPRS_REGNUM].addr = addr + 28; + trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0x00); + trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 0x08); + trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 0x10); + trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 0x18); + trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 0x1c); - for (regnum = SPARC_L0_REGNUM, addr = cache->base; - regnum <= SPARC_I7_REGNUM; regnum++, addr += 8) - cache->saved_regs[regnum].addr = addr; + addr = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM); + if (addr & 1) + addr += BIAS; - return cache; -} - -static void -sparc64_linux_sigtramp_frame_this_id (struct frame_info *next_frame, - void **this_cache, - struct frame_id *this_id) -{ - struct sparc_frame_cache *cache = - sparc64_linux_sigtramp_frame_cache (next_frame, this_cache); - - (*this_id) = frame_id_build (cache->base, cache->pc); -} - -static void -sparc64_linux_sigtramp_frame_prev_register (struct frame_info *next_frame, - void **this_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, - CORE_ADDR *addrp, - int *realnump, void *valuep) -{ - struct sparc_frame_cache *cache = - sparc64_linux_sigtramp_frame_cache (next_frame, this_cache); - - trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum, - optimizedp, lvalp, addrp, realnump, valuep); -} - -static const struct frame_unwind sparc64_linux_sigtramp_frame_unwind = -{ - SIGTRAMP_FRAME, - sparc64_linux_sigtramp_frame_this_id, - sparc64_linux_sigtramp_frame_prev_register -}; - -static const struct frame_unwind * -sparc64_linux_sigtramp_frame_sniffer (struct frame_info *next_frame) -{ - if (sparc64_linux_sigtramp_p (next_frame)) - return &sparc64_linux_sigtramp_frame_unwind; - - return NULL; + base = addr; + for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) + { + trad_frame_set_reg_addr (this_cache, regnum, addr); + addr += 8; + } + trad_frame_set_id (this_cache, frame_id_build (base, func)); } static void @@ -206,7 +104,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - frame_unwind_append_sniffer (gdbarch, sparc64_linux_sigtramp_frame_sniffer); + tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe); /* GNU/Linux is very similar to Solaris ... */ sparc64_sol2_init_abi (info, gdbarch);