From 06c967f12639f598f410512a0d0e6791c1ee4154 Mon Sep 17 00:00:00 2001 From: skrll Date: Thu, 13 Mar 2008 18:18:15 +0000 Subject: [PATCH] Modernise NetBSD/alpha gdb - taken from gdb-current. Add support for siginfo trampolines as well as sigcontext. --- gnu/dist/gdb6/gdb/alpha-tdep.c | 43 ++-- gnu/dist/gdb6/gdb/alpha-tdep.h | 15 +- gnu/dist/gdb6/gdb/alphabsd-nat.c | 16 +- gnu/dist/gdb6/gdb/alphabsd-tdep.c | 17 +- gnu/dist/gdb6/gdb/alphabsd-tdep.h | 21 +- gnu/dist/gdb6/gdb/alphanbsd-tdep.c | 347 ++++++++++++++++++----------- 6 files changed, 279 insertions(+), 180 deletions(-) diff --git a/gnu/dist/gdb6/gdb/alpha-tdep.c b/gnu/dist/gdb6/gdb/alpha-tdep.c index 4480b21164e3..e3f52ca8fe85 100644 --- a/gnu/dist/gdb6/gdb/alpha-tdep.c +++ b/gnu/dist/gdb6/gdb/alpha-tdep.c @@ -1271,67 +1271,74 @@ alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) targets don't supply this value in their core files. */ void -alpha_supply_int_regs (int regno, const void *r0_r30, - const void *pc, const void *unique) +alpha_supply_int_regs (struct regcache *regcache, int regno, + const void *r0_r30, const void *pc, const void *unique) { + const gdb_byte *regs = r0_r30; int i; for (i = 0; i < 31; ++i) if (regno == i || regno == -1) - regcache_raw_supply (current_regcache, i, (const char *)r0_r30 + i*8); + regcache_raw_supply (regcache, i, regs + i * 8); if (regno == ALPHA_ZERO_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_ZERO_REGNUM, NULL); + regcache_raw_supply (regcache, ALPHA_ZERO_REGNUM, NULL); if (regno == ALPHA_PC_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_PC_REGNUM, pc); + regcache_raw_supply (regcache, ALPHA_PC_REGNUM, pc); if (regno == ALPHA_UNIQUE_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_UNIQUE_REGNUM, unique); + regcache_raw_supply (regcache, ALPHA_UNIQUE_REGNUM, unique); } void -alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique) +alpha_fill_int_regs (const struct regcache *regcache, + int regno, void *r0_r30, void *pc, void *unique) { + gdb_byte *regs = r0_r30; int i; for (i = 0; i < 31; ++i) if (regno == i || regno == -1) - regcache_raw_collect (current_regcache, i, (char *)r0_r30 + i*8); + regcache_raw_collect (regcache, i, regs + i * 8); if (regno == ALPHA_PC_REGNUM || regno == -1) - regcache_raw_collect (current_regcache, ALPHA_PC_REGNUM, pc); + regcache_raw_collect (regcache, ALPHA_PC_REGNUM, pc); if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1)) - regcache_raw_collect (current_regcache, ALPHA_UNIQUE_REGNUM, unique); + regcache_raw_collect (regcache, ALPHA_UNIQUE_REGNUM, unique); } void -alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr) +alpha_supply_fp_regs (struct regcache *regcache, int regno, + const void *f0_f30, const void *fpcr) { + const gdb_byte *regs = f0_f30; int i; for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) if (regno == i || regno == -1) - regcache_raw_supply (current_regcache, i, - (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + regcache_raw_supply (regcache, i, + regs + (i - ALPHA_FP0_REGNUM) * 8); if (regno == ALPHA_FPCR_REGNUM || regno == -1) - regcache_raw_supply (current_regcache, ALPHA_FPCR_REGNUM, fpcr); + regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, fpcr); } void -alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr) +alpha_fill_fp_regs (const struct regcache *regcache, + int regno, void *f0_f30, void *fpcr) { + gdb_byte *regs = f0_f30; int i; for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i) if (regno == i || regno == -1) - regcache_raw_collect (current_regcache, i, - (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8); + regcache_raw_collect (regcache, i, + regs + (i - ALPHA_FP0_REGNUM) * 8); if (regno == ALPHA_FPCR_REGNUM || regno == -1) - regcache_raw_collect (current_regcache, ALPHA_FPCR_REGNUM, fpcr); + regcache_raw_collect (regcache, ALPHA_FPCR_REGNUM, fpcr); } diff --git a/gnu/dist/gdb6/gdb/alpha-tdep.h b/gnu/dist/gdb6/gdb/alpha-tdep.h index ab6be39125b2..74dc8d80c31e 100644 --- a/gnu/dist/gdb6/gdb/alpha-tdep.h +++ b/gnu/dist/gdb6/gdb/alpha-tdep.h @@ -22,6 +22,8 @@ #ifndef ALPHA_TDEP_H #define ALPHA_TDEP_H +struct regcache; + /* Say how long (ordinary) registers are. This is a piece of bogosity used in push_word and a few other places; register_size() is the real way to know how big a register is. */ @@ -106,10 +108,13 @@ extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc); extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); extern void alpha_dwarf2_init_abi (struct gdbarch_info, struct gdbarch *); -extern void alpha_supply_int_regs (int, const void *, const void *, - const void *); -extern void alpha_fill_int_regs (int, void *, void *, void *); -extern void alpha_supply_fp_regs (int, const void *, const void *); -extern void alpha_fill_fp_regs (int, void *, void *); +extern void alpha_supply_int_regs (struct regcache *, int, const void *, + const void *, const void *); +extern void alpha_fill_int_regs (const struct regcache *, int, + void *, void *, void *); +extern void alpha_supply_fp_regs (struct regcache *, int, + const void *, const void *); +extern void alpha_fill_fp_regs (const struct regcache *, + int, void *, void *); #endif /* ALPHA_TDEP_H */ diff --git a/gnu/dist/gdb6/gdb/alphabsd-nat.c b/gnu/dist/gdb6/gdb/alphabsd-nat.c index b144957a61c3..2da0b92c1a00 100644 --- a/gnu/dist/gdb6/gdb/alphabsd-nat.c +++ b/gnu/dist/gdb6/gdb/alphabsd-nat.c @@ -51,25 +51,25 @@ typedef struct fpreg fpregset_t; void supply_gregset (gregset_t *gregsetp) { - alphabsd_supply_reg ((char *) gregsetp, -1); + alphabsd_supply_reg (current_regcache, (char *) gregsetp, -1); } void fill_gregset (gregset_t *gregsetp, int regno) { - alphabsd_fill_reg ((char *) gregsetp, regno); + alphabsd_fill_reg (current_regcache, (char *) gregsetp, regno); } void supply_fpregset (fpregset_t *fpregsetp) { - alphabsd_supply_fpreg ((char *) fpregsetp, -1); + alphabsd_supply_fpreg (current_regcache, (char *) fpregsetp, -1); } void fill_fpregset (fpregset_t *fpregsetp, int regno) { - alphabsd_fill_fpreg ((char *) fpregsetp, regno); + alphabsd_fill_fpreg (current_regcache, (char *) fpregsetp, regno); } /* Determine if PT_GETREGS fetches this register. */ @@ -95,7 +95,7 @@ alphabsd_fetch_inferior_registers (int regno) (PTRACE_TYPE_ARG3) &gregs, TIDGET (inferior_ptid)) == -1) perror_with_name (_("Couldn't get registers")); - alphabsd_supply_reg ((char *) &gregs, regno); + alphabsd_supply_reg (current_regcache, (char *) &gregs, regno); if (regno != -1) return; } @@ -108,7 +108,7 @@ alphabsd_fetch_inferior_registers (int regno) (PTRACE_TYPE_ARG3) &fpregs, TIDGET (inferior_ptid)) == -1) perror_with_name (_("Couldn't get floating point status")); - alphabsd_supply_fpreg ((char *) &fpregs, regno); + alphabsd_supply_fpreg (current_regcache, (char *) &fpregs, regno); } } @@ -125,7 +125,7 @@ alphabsd_store_inferior_registers (int regno) (PTRACE_TYPE_ARG3) &gregs, TIDGET (inferior_ptid)) == -1) perror_with_name (_("Couldn't get registers")); - alphabsd_fill_reg ((char *) &gregs, regno); + alphabsd_fill_reg (current_regcache, (char *) &gregs, regno); if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &gregs, TIDGET (inferior_ptid)) == -1) @@ -143,7 +143,7 @@ alphabsd_store_inferior_registers (int regno) (PTRACE_TYPE_ARG3) &fpregs, TIDGET (inferior_ptid)) == -1) perror_with_name (_("Couldn't get floating point status")); - alphabsd_fill_fpreg ((char *) &fpregs, regno); + alphabsd_fill_fpreg (current_regcache, (char *) &fpregs, regno); if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &fpregs, TIDGET (inferior_ptid)) == -1) diff --git a/gnu/dist/gdb6/gdb/alphabsd-tdep.c b/gnu/dist/gdb6/gdb/alphabsd-tdep.c index 978444a8f229..c98cd95af1cd 100644 --- a/gnu/dist/gdb6/gdb/alphabsd-tdep.c +++ b/gnu/dist/gdb6/gdb/alphabsd-tdep.c @@ -19,6 +19,7 @@ Boston, MA 02110-1301, USA. */ #include "defs.h" +#include "regcache.h" #include "alpha-tdep.h" #include "alphabsd-tdep.h" @@ -27,29 +28,29 @@ ptrace register structure used by BSD on Alpha. */ void -alphabsd_supply_reg (char *regs, int regno) +alphabsd_supply_reg (struct regcache *regcache, const char *regs, int regno) { /* PC is at slot 32; UNIQUE not present. */ - alpha_supply_int_regs (regno, regs, regs + 31*8, NULL); + alpha_supply_int_regs (regcache, regno, regs, regs + 31 * 8, NULL); } void -alphabsd_fill_reg (char *regs, int regno) +alphabsd_fill_reg (const struct regcache *regcache, char *regs, int regno) { /* PC is at slot 32; UNIQUE not present. */ - alpha_fill_int_regs (regno, regs, regs + 31*8, NULL); + alpha_fill_int_regs (regcache, regno, regs, regs + 31 * 8, NULL); } void -alphabsd_supply_fpreg (char *fpregs, int regno) +alphabsd_supply_fpreg (struct regcache *regcache, const char *fpregs, int regno) { /* FPCR is at slot 33; slot 32 unused. */ - alpha_supply_fp_regs (regno, fpregs, fpregs + 32*8); + alpha_supply_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8); } void -alphabsd_fill_fpreg (char *fpregs, int regno) +alphabsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno) { /* FPCR is at slot 33; slot 32 unused. */ - alpha_fill_fp_regs (regno, fpregs, fpregs + 32*8); + alpha_fill_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8); } diff --git a/gnu/dist/gdb6/gdb/alphabsd-tdep.h b/gnu/dist/gdb6/gdb/alphabsd-tdep.h index 4c2543829568..39ae8c29540c 100644 --- a/gnu/dist/gdb6/gdb/alphabsd-tdep.h +++ b/gnu/dist/gdb6/gdb/alphabsd-tdep.h @@ -21,13 +21,20 @@ #ifndef ALPHABSD_TDEP_H #define ALPHABSD_TDEP_H -void alphabsd_supply_reg (char *, int); -void alphabsd_fill_reg (char *, int); +struct regcache; -void alphabsd_supply_fpreg (char *, int); -void alphabsd_fill_fpreg (char *, int); +void alphabsd_supply_reg (struct regcache *, const char *, int); +void alphabsd_fill_reg (const struct regcache *, char *, int); -#define SIZEOF_STRUCT_REG (32 * 8) -#define SIZEOF_STRUCT_FPREG (33 * 8) +void alphabsd_supply_fpreg (struct regcache *, const char *, int); +void alphabsd_fill_fpreg (const struct regcache *, char *, int); -#endif /* ALPHABSD_TDEP_H */ +/* Functions exported from alphanbsd-tdep.c. */ + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ +extern const struct regset * + alphanbsd_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t len); + +#endif /* alphabsd-tdep.h */ diff --git a/gnu/dist/gdb6/gdb/alphanbsd-tdep.c b/gnu/dist/gdb6/gdb/alphanbsd-tdep.c index 1f814121d9ec..b983327ce884 100644 --- a/gnu/dist/gdb6/gdb/alphanbsd-tdep.c +++ b/gnu/dist/gdb6/gdb/alphanbsd-tdep.c @@ -21,12 +21,17 @@ Boston, MA 02110-1301, USA. */ #include "defs.h" -#include "gdbcore.h" #include "frame.h" +#include "gdbcore.h" +#include "osabi.h" #include "regcache.h" +#include "regset.h" #include "value.h" #include "osabi.h" +#include "trad-frame.h" +#include "tramp-frame.h" +#include "gdb_assert.h" #include "gdb_string.h" #include "alpha-tdep.h" @@ -34,14 +39,78 @@ #include "nbsd-tdep.h" #include "solib-svr4.h" -static void -fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR ignore) -{ - char *regs, *fpregs; - int regno; +/* Core file support. */ - /* Table to map a gdb register number to a trapframe register index. */ +/* Even though NetBSD/alpha used ELF since day one, it used the + traditional a.out-style core dump format before NetBSD 1.6. */ + +/* Sizeof `struct reg' in . */ +#define ALPHANBSD_SIZEOF_GREGS (32 * 8) + +/* Sizeof `struct fpreg' in = ALPHANBSD_SIZEOF_FPREGS); + + for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + (i - ALPHA_FP0_REGNUM) * 8); + } + + if (regnum == ALPHA_FPCR_REGNUM || regnum == -1) + regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, regs + 32 * 8); +} + +/* Supply register REGNUM from the buffer specified by GREGS and LEN + in the general-purpose register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ + +static void +alphanbsd_supply_gregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + const gdb_byte *regs = gregs; + int i; + + gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS); + + for (i = 0; i < ALPHA_ZERO_REGNUM; i++) + { + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + i * 8); + } + + if (regnum == ALPHA_PC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8); +} + +/* Supply register REGNUM from the buffer specified by GREGS and LEN + in the general-purpose register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ + +static void +alphanbsd_aout_supply_gregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + const gdb_byte *regs = gregs; + int i; + + /* Table to map a GDB register number to a trapframe register index. */ static const int regmap[] = { 0, 1, 2, 3, @@ -53,145 +122,154 @@ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, 21, 22, 23, 24, 25, 29, 26 }; -#define SIZEOF_TRAPFRAME (33 * 8) - /* We get everything from one section. */ - if (which != 0) - return; + gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS); - regs = core_reg_sect; - fpregs = core_reg_sect + SIZEOF_TRAPFRAME; - - if (core_reg_size < (SIZEOF_TRAPFRAME + SIZEOF_STRUCT_FPREG)) + for (i = 0; i < ARRAY_SIZE(regmap); i++) { - warning (_("Wrong size register set in core file.")); - return; + if (regnum == i || regnum == -1) + regcache_raw_supply (regcache, i, regs + regmap[i] * 8); } - /* Integer registers. */ - for (regno = 0; regno < ALPHA_ZERO_REGNUM; regno++) - regcache_raw_supply (current_regcache, regno, regs + (regmap[regno] * 8)); - regcache_raw_supply (current_regcache, ALPHA_ZERO_REGNUM, NULL); - regcache_raw_supply (current_regcache, PC_REGNUM, regs + (28 * 8)); + if (regnum == ALPHA_PC_REGNUM || regnum == -1) + regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8); - /* Floating point registers. */ - alphabsd_supply_fpreg (fpregs, -1); + if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS) + { + regs += ALPHANBSD_SIZEOF_GREGS; + len -= ALPHANBSD_SIZEOF_GREGS; + alphanbsd_supply_fpregset (regset, regcache, regnum, regs, len); + } } +/* NetBSD/alpha register sets. */ + +static struct regset alphanbsd_gregset = +{ + NULL, + alphanbsd_supply_gregset +}; + +static struct regset alphanbsd_fpregset = +{ + NULL, + alphanbsd_supply_fpregset +}; + +static struct regset alphanbsd_aout_gregset = +{ + NULL, + alphanbsd_aout_supply_gregset +}; + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ + +const struct regset * +alphanbsd_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + if (strcmp (sect_name, ".reg") == 0 && sect_size >= ALPHANBSD_SIZEOF_GREGS) + { + if (sect_size >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS) + return &alphanbsd_aout_gregset; + else + return &alphanbsd_gregset; + } + + if (strcmp (sect_name, ".reg2") == 0 && sect_size >= ALPHANBSD_SIZEOF_FPREGS) + return &alphanbsd_fpregset; + + return NULL; +} + static void -fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which, - CORE_ADDR ignore) -{ - switch (which) - { - case 0: /* Integer registers. */ - if (core_reg_size != SIZEOF_STRUCT_REG) - warning (_("Wrong size register set in core file.")); - else - alphabsd_supply_reg (core_reg_sect, -1); - break; +alphanbsd_sigtramp_cache_init (const struct tramp_frame *, + struct frame_info *, + struct trad_frame_cache *, + CORE_ADDR); - case 2: /* Floating point registers. */ - if (core_reg_size != SIZEOF_STRUCT_FPREG) - warning (_("Wrong size FP register set in core file.")); - else - alphabsd_supply_fpreg (core_reg_sect, -1); - break; - - default: - /* Don't know what kind of register request this is; just ignore it. */ - break; - } -} - -static struct core_fns alphanbsd_core_fns = -{ - bfd_target_unknown_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; - -static struct core_fns alphanbsd_elfcore_fns = -{ - bfd_target_elf_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_elfcore_registers, /* core_read_registers */ - NULL /* next */ -}; - -/* Under NetBSD/alpha, signal handler invocations can be identified by the +/* Under NetBSD/alpha signal handler invocations can be identified by the designated code sequence that is used to return from a signal handler. In particular, the return address of a signal handler points to the - following code sequence: - - ldq a0, 0(sp) - lda sp, 16(sp) - lda v0, 295(zero) # __sigreturn14 - call_pal callsys - - Each instruction has a unique encoding, so we simply attempt to match - the instruction the PC is pointing to with any of the above instructions. - If there is a hit, we know the offset to the start of the designated - sequence and can then check whether we really are executing in the - signal trampoline. If not, -1 is returned, otherwise the offset from the - start of the return sequence is returned. */ -static const unsigned char sigtramp_retcode[] = + following code sequences. */ +static const struct tramp_frame alphanbsd_sigtramp_sc1 = { - 0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */ - 0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */ - 0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */ - 0x83, 0x00, 0x00, 0x00, /* call_pal callsys */ + SIGTRAMP_FRAME, + 4, + { + { 0xa61e0000, 0xffffffff }, /* ldq a0, 0(sp) */ + { 0x23de0010, 0xffffffff }, /* lda sp, 16(sp) */ + { 0x201f0127, 0xffffffff }, /* lda v0, 295 */ + { 0x00000083, 0xffffffff }, /* call_pal callsys */ + { TRAMP_SENTINEL_INSN, -1 } + }, + alphanbsd_sigtramp_cache_init }; -#define RETCODE_NWORDS 4 -#define RETCODE_SIZE (RETCODE_NWORDS * 4) -LONGEST -alphanbsd_sigtramp_offset (CORE_ADDR pc) +/* The siginfo signal trampoline for NetBSD/alpha introduced in 2.0 */ +static const struct tramp_frame alphanbsd_sigtramp_si2 = { - unsigned char ret[RETCODE_SIZE], w[4]; - LONGEST off; + SIGTRAMP_FRAME, + 4, + { + { 0x221e0080, -1 }, /* lda a0,128(sp) */ + { 0x201f0134, -1 }, /* lda v0,308 */ + { 0x00000083, -1 }, /* callsys */ + { 0x47e00410, -1 }, /* mov v0,a0 */ + { 0x201f0001, -1 }, /* lda v0,1 */ + { 0x00000083, -1 }, /* callsys */ + { TRAMP_SENTINEL_INSN, -1 } + }, + alphanbsd_sigtramp_cache_init +}; + +/* The siginfo signal trampoline for NetBSD/alpha introduced in 4.0 */ +static const struct tramp_frame alphanbsd_sigtramp_si4 = +{ + SIGTRAMP_FRAME, + 4, + { + { 0x27ba0000, 0xffff0000 }, + { 0x23bd0000, 0xffff0000 }, /* ldgp gp,0(ra) */ + { 0x221e0080, -1 }, /* lda a0,128(sp) */ + { 0x201f0134, -1 }, /* lda v0,308 */ + { 0x00000083, -1 }, /* callsys */ + { 0x221fffff, -1 }, /* lda a0,-1 */ + { 0x201f0001, -1 }, /* lda v0,1 */ + { 0x00000083, -1 }, /* callsys */ + { TRAMP_SENTINEL_INSN, -1 } + }, + alphanbsd_sigtramp_cache_init +}; + +static void +alphanbsd_sigtramp_cache_init (const struct tramp_frame *self, + struct frame_info *next_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + CORE_ADDR addr, sp; int i; - if (deprecated_read_memory_nobpt (pc, (char *) w, 4) != 0) - return -1; + sp = frame_unwind_register_unsigned (next_frame, SP_REGNUM); - for (i = 0; i < RETCODE_NWORDS; i++) + if (self == &alphanbsd_sigtramp_sc1) { + addr = sp; + } else { + addr = sp + 128 + 56; + } + + for (i = 0; i < 32; i++, addr += ALPHA_REGISTER_SIZE) { - if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0) - break; + trad_frame_set_reg_addr (this_cache, i, addr); } - if (i == RETCODE_NWORDS) - return (-1); + trad_frame_set_reg_addr (this_cache, ALPHA_PC_REGNUM, addr); - off = i * 4; - pc -= off; - - if (deprecated_read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0) - return -1; - - if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0) - return off; - - return -1; -} - -static int -alphanbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name) -{ - return (nbsd_pc_in_sigtramp (pc, func_name) - || alphanbsd_sigtramp_offset (pc) >= 0); -} - -static CORE_ADDR -alphanbsd_sigcontext_addr (struct frame_info *frame) -{ - /* FIXME: This is not correct for all versions of NetBSD/alpha. - We will probably need to disassemble the trampoline to figure - out which trampoline frame type we have. */ - return get_frame_base (frame); + /* Construct the frame ID using the function start. */ + trad_frame_set_id (this_cache, frame_id_build (sp, func)); } static void @@ -210,15 +288,19 @@ alphanbsd_init_abi (struct gdbarch_info info, must use software single-stepping. */ set_gdbarch_software_single_step (gdbarch, alpha_software_single_step); - set_solib_svr4_fetch_link_map_offsets (gdbarch, - nbsd_lp64_solib_svr4_fetch_link_map_offsets); - - tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset; - tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp; - tdep->sigcontext_addr = alphanbsd_sigcontext_addr; + /* NetBSD/alpha has SVR4-style shared libraries. */ + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_lp64_fetch_link_map_offsets); tdep->jb_pc = 2; tdep->jb_elt_size = 8; + + set_gdbarch_regset_from_core_section + (gdbarch, alphanbsd_regset_from_core_section); + + tramp_frame_prepend_unwinder (gdbarch, &alphanbsd_sigtramp_sc1); + tramp_frame_prepend_unwinder (gdbarch, &alphanbsd_sigtramp_si2); + tramp_frame_prepend_unwinder (gdbarch, &alphanbsd_sigtramp_si4); } void @@ -228,7 +310,4 @@ _initialize_alphanbsd_tdep (void) alphanbsd_init_abi); gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD_ELF, alphanbsd_init_abi); - - deprecated_add_core_fns (&alphanbsd_core_fns); - deprecated_add_core_fns (&alphanbsd_elfcore_fns); }