diff options
author | Daniel Jacobowitz <drow@false.org> | 2005-03-03 15:14:09 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2005-03-03 15:14:09 +0000 |
commit | 909cf6ea0e10b779675091b118b93d3015afa8ed (patch) | |
tree | c5687e41781ecff17c6970d35ec763c3da5aa898 /gdb/arm-tdep.c | |
parent | 5e1e0414856014d69870c730984fcb9a768399ed (diff) | |
download | gdb-909cf6ea0e10b779675091b118b93d3015afa8ed.zip gdb-909cf6ea0e10b779675091b118b93d3015afa8ed.tar.gz gdb-909cf6ea0e10b779675091b118b93d3015afa8ed.tar.bz2 |
* arm-tdep.c (arm_make_stub_cache, arm_stub_this_id)
(arm_stub_unwind, arm_stub_unwind_sniffer): New.
(arm_gdbarch_init): Add arm_stub_unwind_sniffer.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r-- | gdb/arm-tdep.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 6afe0d5..18b13fe 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -1013,6 +1013,56 @@ arm_prologue_unwind_sniffer (struct frame_info *next_frame) return &arm_prologue_unwind; } +static struct arm_prologue_cache * +arm_make_stub_cache (struct frame_info *next_frame) +{ + int reg; + struct arm_prologue_cache *cache; + CORE_ADDR unwound_fp; + + cache = frame_obstack_zalloc (sizeof (struct arm_prologue_cache)); + cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + + cache->prev_sp = frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM); + + return cache; +} + +/* Our frame ID for a stub frame is the current SP and LR. */ + +static void +arm_stub_this_id (struct frame_info *next_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct arm_prologue_cache *cache; + + if (*this_cache == NULL) + *this_cache = arm_make_stub_cache (next_frame); + cache = *this_cache; + + *this_id = frame_id_build (cache->prev_sp, + frame_pc_unwind (next_frame)); +} + +struct frame_unwind arm_stub_unwind = { + NORMAL_FRAME, + arm_stub_this_id, + arm_prologue_prev_register +}; + +static const struct frame_unwind * +arm_stub_unwind_sniffer (struct frame_info *next_frame) +{ + char dummy[4]; + + if (in_plt_section (frame_unwind_address_in_block (next_frame), NULL) + || target_read_memory (frame_pc_unwind (next_frame), dummy, 4) != 0) + return &arm_stub_unwind; + + return NULL; +} + static CORE_ADDR arm_normal_frame_base (struct frame_info *next_frame, void **this_cache) { @@ -2737,6 +2787,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) gdbarch_init_osabi (info, gdbarch); /* Add some default predicates. */ + frame_unwind_append_sniffer (gdbarch, arm_stub_unwind_sniffer); frame_unwind_append_sniffer (gdbarch, arm_sigtramp_unwind_sniffer); frame_unwind_append_sniffer (gdbarch, arm_prologue_unwind_sniffer); |