diff options
author | Andrew Cagney <cagney@redhat.com> | 2004-05-01 15:10:15 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2004-05-01 15:10:15 +0000 |
commit | ebffdeb467c345ce7ca8405eab5276740f1be6a3 (patch) | |
tree | fe12f759a23f4d716e192f3c9f2b68f4574b950b /gdb/m68klinux-tdep.c | |
parent | 804d245a0b540370315706dee35bc84fc9d18f0c (diff) | |
download | gdb-ebffdeb467c345ce7ca8405eab5276740f1be6a3.tar.gz |
2004-05-01 Andrew Cagney <cagney@redhat.com>
* Makefile.in (m68klinux-nat.o): Update dependencies.
* m68klinux-tdep.c: Include "trad-frame.h" and "frame-unwind.h".
(m68k_linux_sigtramp_frame_cache)
(m68k_linux_sigtramp_frame_this_id)
(m68k_linux_sigtramp_frame_prev_register)
(m68k_linux_sigtramp_frame_unwind)
(m68k_linux_sigtramp_frame_sniffer)
(struct m68k_linux_sigtramp_info, m68k_linux_init_abi): Code from
m68k-tdep.h and m68k-tdep.c, add "linux" to function and variable
names, use trad-frame.h.
* m68k-tdep.h (struct gdbarch_tdep): Delete get_sigtramp_info.
(struct m68k_sigtramp_info): Delete.
* m68k-tdep.c (m68k_sigtramp_frame_cache)
(m68k_sigtramp_frame_this_id, m68k_sigtramp_frame_prev_register)
(m68k_sigtramp_frame_unwind, m68k_sigtramp_frame_sniffer)
(m68k_gdbarch_init): Delete all the sigtramp code, moved to
"m68klinux-tdep.c".
Diffstat (limited to 'gdb/m68klinux-tdep.c')
-rw-r--r-- | gdb/m68klinux-tdep.c | 102 |
1 files changed, 98 insertions, 4 deletions
diff --git a/gdb/m68klinux-tdep.c b/gdb/m68klinux-tdep.c index 109195138f4..c174daa85ec 100644 --- a/gdb/m68klinux-tdep.c +++ b/gdb/m68klinux-tdep.c @@ -33,6 +33,8 @@ #include "objfiles.h" #include "symtab.h" #include "m68k-tdep.h" +#include "trad-frame.h" +#include "frame-unwind.h" /* Offsets (in target ints) into jmp_buf. */ @@ -160,12 +162,21 @@ static int m68k_linux_ucontext_reg_offset[M68K_NUM_REGS] = /* Get info about saved registers in sigtramp. */ -static struct m68k_sigtramp_info +struct m68k_linux_sigtramp_info +{ + /* Address of sigcontext. */ + CORE_ADDR sigcontext_addr; + + /* Offset of registers in `struct sigcontext'. */ + int *sc_reg_offset; +}; + +static struct m68k_linux_sigtramp_info m68k_linux_get_sigtramp_info (struct frame_info *next_frame) { CORE_ADDR sp; char buf[4]; - struct m68k_sigtramp_info info; + struct m68k_linux_sigtramp_info info; frame_unwind_register (next_frame, M68K_SP_REGNUM, buf); sp = extract_unsigned_integer (buf, 4); @@ -180,6 +191,90 @@ m68k_linux_get_sigtramp_info (struct frame_info *next_frame) return info; } +/* Signal trampolines. */ + +static struct trad_frame_cache * +m68k_linux_sigtramp_frame_cache (struct frame_info *next_frame, + void **this_cache) +{ + struct frame_id this_id; + struct trad_frame_cache *cache; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct m68k_linux_sigtramp_info info; + char buf[4]; + int i; + + if (*this_cache) + return *this_cache; + + cache = trad_frame_cache_zalloc (next_frame); + + /* FIXME: cagney/2004-05-01: This is is long standing broken code. + The frame ID's code address should be the start-address of the + signal trampoline and not the current PC within that + trampoline. */ + frame_unwind_register (next_frame, M68K_SP_REGNUM, buf); + /* See the end of m68k_push_dummy_call. */ + this_id = frame_id_build (extract_unsigned_integer (buf, 4) - 4 + 8, + frame_pc_unwind (next_frame)); + trad_frame_set_id (cache, this_id); + + info = m68k_linux_get_sigtramp_info (next_frame); + + for (i = 0; i < M68K_NUM_REGS; i++) + if (info.sc_reg_offset[i] != -1) + trad_frame_set_reg_addr (cache, i, + info.sigcontext_addr + info.sc_reg_offset[i]); + + *this_cache = cache; + return cache; +} + +static void +m68k_linux_sigtramp_frame_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct trad_frame_cache *cache = + m68k_linux_sigtramp_frame_cache (next_frame, this_cache); + trad_frame_get_id (cache, this_id); +} + +static void +m68k_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) +{ + /* Make sure we've initialized the cache. */ + struct trad_frame_cache *cache = + m68k_linux_sigtramp_frame_cache (next_frame, this_cache); + trad_frame_get_register (cache, next_frame, regnum, optimizedp, lvalp, + addrp, realnump, valuep); +} + +static const struct frame_unwind m68k_linux_sigtramp_frame_unwind = +{ + SIGTRAMP_FRAME, + m68k_linux_sigtramp_frame_this_id, + m68k_linux_sigtramp_frame_prev_register +}; + +static const struct frame_unwind * +m68k_linux_sigtramp_frame_sniffer (struct frame_info *next_frame) +{ + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + if (m68k_linux_pc_in_sigtramp (pc, name)) + return &m68k_linux_sigtramp_frame_unwind; + + return NULL; +} + /* Extract from an array REGBUF containing the (raw) register state, a function return value of TYPE, and copy that, in virtual format, into VALBUF. */ @@ -289,14 +384,13 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->jb_pc = M68K_LINUX_JB_PC; tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE; - tdep->get_sigtramp_info = m68k_linux_get_sigtramp_info; tdep->struct_return = reg_struct_return; set_gdbarch_extract_return_value (gdbarch, m68k_linux_extract_return_value); set_gdbarch_store_return_value (gdbarch, m68k_linux_store_return_value); set_gdbarch_deprecated_extract_struct_value_address (gdbarch, m68k_linux_extract_struct_value_address); - set_gdbarch_deprecated_pc_in_sigtramp (gdbarch, m68k_linux_pc_in_sigtramp); + frame_unwind_append_sniffer (gdbarch, m68k_linux_sigtramp_frame_sniffer); /* Shared library handling. */ set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); |