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  <lgustavo@codesourcery.com>

	* 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) <stop_reason> : Set to
	arm_prologue_unwind_stop_reason.
This commit is contained in:
Luis Machado 2015-02-10 09:46:11 -02:00
parent f7de9aab90
commit c1ee941477
2 changed files with 35 additions and 10 deletions

View File

@ -1,3 +1,11 @@
2015-02-10 Luis Machado <lgustavo@codesourcery.com>
* 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) <stop_reason> : Set to
arm_prologue_unwind_stop_reason.
2015-02-09 Mark Wielaard <mjw@redhat.com>
* dwarf2read.c (set_cu_language): Recognize DW_LANG_Fortran03 and

View File

@ -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,