From c1ee941477569693777617d2f5defbba21085216 Mon Sep 17 00:00:00 2001 From: Luis Machado Date: Tue, 10 Feb 2015 09:46:11 -0200 Subject: [PATCH] Relax ARM prologue unwinder assumption Modify the ARM prologue unwinder to use the stop_reason hook instead of returning imprecise frame id's through the arm prologue this_id hook. gdb/ 2015-02-10 Luis Machado * arm-tdep.c (arm_prologue_unwind_stop_reason): New function. (arm_prologue_this_id): Move PC and SP limit checks to arm_prologue_unwind_stop_reason. (arm_prologue_unwind) : Set to arm_prologue_unwind_stop_reason. --- gdb/ChangeLog | 8 ++++++++ gdb/arm-tdep.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 305b4b2..9941dba 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2015-02-10 Luis Machado + + * arm-tdep.c (arm_prologue_unwind_stop_reason): New function. + (arm_prologue_this_id): Move PC and SP limit checks to + arm_prologue_unwind_stop_reason. + (arm_prologue_unwind) : Set to + arm_prologue_unwind_stop_reason. + 2015-02-09 Mark Wielaard * dwarf2read.c (set_cu_language): Recognize DW_LANG_Fortran03 and diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 8e9552a..f3a6325 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -2021,6 +2021,31 @@ arm_make_prologue_cache (struct frame_info *this_frame) return cache; } +/* Implementation of the stop_reason hook for arm_prologue frames. */ + +static enum unwind_stop_reason +arm_prologue_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct arm_prologue_cache *cache; + CORE_ADDR pc; + + if (*this_cache == NULL) + *this_cache = arm_make_prologue_cache (this_frame); + cache = *this_cache; + + /* This is meant to halt the backtrace at "_start". */ + pc = get_frame_pc (this_frame); + if (pc <= gdbarch_tdep (get_frame_arch (this_frame))->lowest_pc) + return UNWIND_OUTERMOST; + + /* If we've hit a wall, stop. */ + if (cache->prev_sp == 0) + return UNWIND_OUTERMOST; + + return UNWIND_NO_REASON; +} + /* Our frame ID for a normal frame is the current function's starting PC and the caller's SP when we were called. */ @@ -2037,18 +2062,10 @@ arm_prologue_this_id (struct frame_info *this_frame, *this_cache = arm_make_prologue_cache (this_frame); cache = *this_cache; - /* This is meant to halt the backtrace at "_start". */ - pc = get_frame_pc (this_frame); - if (pc <= gdbarch_tdep (get_frame_arch (this_frame))->lowest_pc) - return; - - /* If we've hit a wall, stop. */ - if (cache->prev_sp == 0) - return; - /* Use function start address as part of the frame ID. If we cannot identify the start address (due to missing symbol information), fall back to just using the current PC. */ + pc = get_frame_pc (this_frame); func = get_frame_func (this_frame); if (!func) func = pc; @@ -2117,7 +2134,7 @@ arm_prologue_prev_register (struct frame_info *this_frame, struct frame_unwind arm_prologue_unwind = { NORMAL_FRAME, - default_frame_unwind_stop_reason, + arm_prologue_unwind_stop_reason, arm_prologue_this_id, arm_prologue_prev_register, NULL, -- 2.7.4