* arm-tdep.c (arm_minimal_frame_chain): Renamed from
arm_frame_chain. Take NEXT_FRAME and CACHE arguments. Use the cache instead of DEPRECATED_FRAME_SAVED_PC. (arm_minimal_frame_info): Renamed from arm_init_extra_frame_info. Take NEXT_FRAME and CACHE arguments. Call FRAMELESS_FUNCTION_INVOCATION instead of checking FROMLEAF argument. Set unwound_pc in CACHE instead of modifying the frame argument. Don't bother checking the frame type when looking for sigtramp frames. (arm_make_prologue_cache, arm_frame_chain) (arm_init_extra_frame_info): New functions.
This commit is contained in:
parent
9b8d791a57
commit
24de872b6f
|
@ -1,3 +1,17 @@
|
|||
2003-09-03 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* arm-tdep.c (arm_minimal_frame_chain): Renamed from
|
||||
arm_frame_chain. Take NEXT_FRAME and CACHE arguments.
|
||||
Use the cache instead of DEPRECATED_FRAME_SAVED_PC.
|
||||
(arm_minimal_frame_info): Renamed from arm_init_extra_frame_info.
|
||||
Take NEXT_FRAME and CACHE arguments. Call
|
||||
FRAMELESS_FUNCTION_INVOCATION instead of checking FROMLEAF argument.
|
||||
Set unwound_pc in CACHE instead of modifying the frame argument.
|
||||
Don't bother checking the frame type when looking for sigtramp
|
||||
frames.
|
||||
(arm_make_prologue_cache, arm_frame_chain)
|
||||
(arm_init_extra_frame_info): New functions.
|
||||
|
||||
2003-09-03 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* arm-tdep.c (arm_get_cache): Define.
|
||||
|
|
167
gdb/arm-tdep.c
167
gdb/arm-tdep.c
|
@ -955,21 +955,19 @@ arm_find_callers_reg (struct frame_info *fi, int regnum)
|
|||
DEPRECATED_INIT_FRAME_PC will be called for the new frame. For
|
||||
ARM, we save the frame size when we initialize the frame_info. */
|
||||
|
||||
static CORE_ADDR
|
||||
arm_frame_chain (struct frame_info *fi)
|
||||
CORE_ADDR
|
||||
arm_minimal_frame_chain (struct frame_info *next_frame, struct arm_prologue_cache *cache)
|
||||
{
|
||||
CORE_ADDR caller_pc;
|
||||
int framereg = arm_get_cache (fi)->framereg;
|
||||
int framereg = arm_get_cache (next_frame)->framereg;
|
||||
|
||||
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0))
|
||||
/* A generic call dummy's frame is the same as caller's. */
|
||||
return get_frame_base (fi);
|
||||
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (next_frame), 0, 0))
|
||||
return get_frame_base (next_frame);
|
||||
|
||||
if (get_frame_pc (fi) < LOWEST_PC)
|
||||
if (get_frame_pc (next_frame) < LOWEST_PC)
|
||||
return 0;
|
||||
|
||||
/* If the caller is the startup code, we're at the end of the chain. */
|
||||
caller_pc = DEPRECATED_FRAME_SAVED_PC (fi);
|
||||
caller_pc = cache->unwound_pc;
|
||||
|
||||
/* If the caller is Thumb and the caller is ARM, or vice versa,
|
||||
the frame register of the caller is different from ours.
|
||||
|
@ -977,7 +975,12 @@ arm_frame_chain (struct frame_info *fi)
|
|||
frame register number. */
|
||||
/* XXX Fixme, we should try to do this without creating a temporary
|
||||
cache! */
|
||||
if (arm_pc_is_thumb (caller_pc) != arm_pc_is_thumb (get_frame_pc (fi)))
|
||||
/* NOTE drow/2003-06-26: I'm quite suspicious of this code... what is it
|
||||
really doing? I have the feeling that it's trying to handle the case
|
||||
where my framereg is ARM_FP_REGNUM, and my (Thumb) caller's framereg is
|
||||
THUMB_FP_REGNUM, and switching between the two. But the unwinder should
|
||||
be taking care of that. */
|
||||
if (arm_pc_is_thumb (caller_pc) != arm_pc_is_thumb (get_frame_pc (next_frame)))
|
||||
{
|
||||
struct arm_prologue_cache *cache
|
||||
= xcalloc (1, sizeof (struct arm_prologue_cache)
|
||||
|
@ -997,52 +1000,45 @@ arm_frame_chain (struct frame_info *fi)
|
|||
/* If the caller used a frame register, return its value.
|
||||
Otherwise, return the caller's stack pointer. */
|
||||
if (framereg == ARM_FP_REGNUM || framereg == THUMB_FP_REGNUM)
|
||||
return arm_find_callers_reg (fi, framereg);
|
||||
return arm_find_callers_reg (next_frame, framereg);
|
||||
else
|
||||
return get_frame_base (fi) + arm_get_cache (fi)->framesize;
|
||||
/* FIXME drow/2003-06-26: The next frame is an opaque thing at this point,
|
||||
we should only be using frame methods on it. What if it's a dummy
|
||||
frame, calling a frameless function (framereg == ARM_SP_REGNUM)? Test
|
||||
it. */
|
||||
return get_frame_base (next_frame) + arm_get_cache (next_frame)->framesize;
|
||||
}
|
||||
|
||||
/* This function actually figures out the frame address for a given pc
|
||||
and sp. This is tricky because we sometimes don't use an explicit
|
||||
frame pointer, and the previous stack pointer isn't necessarily
|
||||
recorded on the stack. The only reliable way to get this info is
|
||||
to examine the prologue. FROMLEAF is a little confusing, it means
|
||||
this is the next frame up the chain AFTER a frameless function. If
|
||||
this is true, then the frame value for this frame is still in the
|
||||
fp register. */
|
||||
to examine the prologue. */
|
||||
|
||||
static void
|
||||
arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
||||
arm_minimal_frame_info (struct frame_info *next_frame,
|
||||
struct arm_prologue_cache *cache)
|
||||
{
|
||||
int reg;
|
||||
CORE_ADDR sp;
|
||||
|
||||
if (get_frame_saved_regs (fi) == NULL)
|
||||
frame_saved_regs_zalloc (fi);
|
||||
|
||||
frame_extra_info_zalloc (fi, (sizeof (struct arm_prologue_cache)
|
||||
+ ((NUM_REGS + NUM_PSEUDO_REGS - 1)
|
||||
* sizeof (CORE_ADDR))));
|
||||
|
||||
if (get_next_frame (fi))
|
||||
deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
|
||||
|
||||
memset (get_frame_saved_regs (fi), '\000', sizeof get_frame_saved_regs (fi));
|
||||
memset (cache->saved_regs, '\000', sizeof (CORE_ADDR) * (NUM_REGS + NUM_PSEUDO_REGS));
|
||||
|
||||
/* Compute stack pointer for this frame. We use this value for both
|
||||
the sigtramp and call dummy cases. */
|
||||
if (!get_next_frame (fi))
|
||||
sp = read_sp();
|
||||
else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (get_next_frame (fi)), 0, 0))
|
||||
|
||||
if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (next_frame), 0, 0))
|
||||
/* For generic dummy frames, pull the value direct from the frame.
|
||||
Having an unwind function to do this would be nice. */
|
||||
sp = deprecated_read_register_dummy (get_frame_pc (get_next_frame (fi)),
|
||||
get_frame_base (get_next_frame (fi)),
|
||||
sp = deprecated_read_register_dummy (get_frame_pc (next_frame),
|
||||
get_frame_base (next_frame),
|
||||
ARM_SP_REGNUM);
|
||||
else if (arm_get_cache (next_frame))
|
||||
sp = (get_frame_base (next_frame)
|
||||
- arm_get_cache (next_frame)->frameoffset
|
||||
+ arm_get_cache (next_frame)->framesize);
|
||||
else
|
||||
sp = (get_frame_base (get_next_frame (fi))
|
||||
- arm_get_cache (get_next_frame (fi))->frameoffset
|
||||
+ arm_get_cache (get_next_frame (fi))->framesize);
|
||||
sp = read_sp (); /* FIXME remove case */
|
||||
|
||||
/* Determine whether or not we're in a sigtramp frame.
|
||||
Unfortunately, it isn't sufficient to test (get_frame_type (fi)
|
||||
|
@ -1061,57 +1057,106 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
|||
frame.c:get_prev_frame() is modified to set the frame's type
|
||||
before calling functions like this. */
|
||||
|
||||
/* NOTE drow/2003-06-26: This will move to a predicate for a different unwinder shortly. */
|
||||
|
||||
if (SIGCONTEXT_REGISTER_ADDRESS_P ()
|
||||
&& ((get_frame_type (fi) == SIGTRAMP_FRAME) || PC_IN_SIGTRAMP (get_frame_pc (fi), (char *)0)))
|
||||
&& PC_IN_SIGTRAMP (cache->unwound_pc, (char *)0))
|
||||
{
|
||||
for (reg = 0; reg < NUM_REGS; reg++)
|
||||
get_frame_saved_regs (fi)[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, get_frame_pc (fi), reg);
|
||||
cache->saved_regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, cache->unwound_pc, reg);
|
||||
|
||||
/* FIXME: What about thumb mode? */
|
||||
arm_get_cache (fi)->framereg = ARM_SP_REGNUM;
|
||||
deprecated_update_frame_base_hack (fi, read_memory_integer (get_frame_saved_regs (fi)[arm_get_cache (fi)->framereg], REGISTER_RAW_SIZE (arm_get_cache (fi)->framereg)));
|
||||
arm_get_cache (fi)->framesize = 0;
|
||||
arm_get_cache (fi)->frameoffset = 0;
|
||||
|
||||
cache->framereg = ARM_SP_REGNUM;
|
||||
cache->unwound_sp = read_memory_integer (cache->saved_regs[cache->framereg], REGISTER_RAW_SIZE (cache->framereg));
|
||||
cache->framesize = 0;
|
||||
cache->frameoffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
arm_get_cache (fi)->unwound_pc = get_frame_pc (fi);
|
||||
arm_get_cache (fi)->unwound_sp = get_frame_base (fi);
|
||||
/* At this point, the unwound sp is just the result of frame_chain.
|
||||
Then it gets changed below. */
|
||||
|
||||
arm_scan_prologue (arm_get_cache (fi));
|
||||
arm_scan_prologue (cache);
|
||||
|
||||
if (!get_next_frame (fi))
|
||||
if (!next_frame)
|
||||
/* This is the innermost frame? */
|
||||
deprecated_update_frame_base_hack (fi, read_register (arm_get_cache (fi)->framereg));
|
||||
else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (get_next_frame (fi)), 0, 0))
|
||||
cache->unwound_sp = read_register (cache->framereg);
|
||||
else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (next_frame), 0, 0))
|
||||
/* Next inner most frame is a dummy, just grab its frame.
|
||||
Dummy frames always have the same FP as their caller. */
|
||||
deprecated_update_frame_base_hack (fi, get_frame_base (get_next_frame (fi)));
|
||||
else if (arm_get_cache (fi)->framereg == ARM_FP_REGNUM
|
||||
|| arm_get_cache (fi)->framereg == THUMB_FP_REGNUM)
|
||||
cache->unwound_sp = get_frame_base (next_frame);
|
||||
else if (cache->framereg == ARM_FP_REGNUM
|
||||
|| cache->framereg == THUMB_FP_REGNUM)
|
||||
{
|
||||
/* not the innermost frame */
|
||||
/* If we have an FP, the callee saved it. */
|
||||
if (get_frame_saved_regs (get_next_frame (fi))[arm_get_cache (fi)->framereg] != 0)
|
||||
deprecated_update_frame_base_hack (fi, read_memory_integer (get_frame_saved_regs (get_next_frame (fi))[arm_get_cache (fi)->framereg], 4));
|
||||
else if (fromleaf)
|
||||
if (get_frame_saved_regs (next_frame) /**/ && get_frame_saved_regs (next_frame)[cache->framereg] != 0)
|
||||
cache->unwound_sp = read_memory_integer (get_frame_saved_regs (next_frame)[cache->framereg], 4);
|
||||
else if (frame_relative_level (next_frame) == 0
|
||||
&& FRAMELESS_FUNCTION_INVOCATION (next_frame))
|
||||
/* If we were called by a frameless fn. then our frame is
|
||||
still in the frame pointer register on the board... */
|
||||
deprecated_update_frame_base_hack (fi, deprecated_read_fp ());
|
||||
cache->unwound_sp = deprecated_read_fp ();
|
||||
}
|
||||
|
||||
/* Calculate actual addresses of saved registers using offsets
|
||||
determined by arm_scan_prologue. */
|
||||
for (reg = 0; reg < NUM_REGS; reg++)
|
||||
if (arm_get_cache (fi)->saved_regs[reg] != 0)
|
||||
get_frame_saved_regs (fi)[reg] = (arm_get_cache (fi)->saved_regs[reg]
|
||||
+ get_frame_base (fi)
|
||||
+ arm_get_cache (fi)->framesize
|
||||
- arm_get_cache (fi)->frameoffset);
|
||||
if (cache->saved_regs[reg] != 0)
|
||||
cache->saved_regs[reg] = (cache->saved_regs[reg]
|
||||
+ cache->unwound_sp
|
||||
+ cache->framesize
|
||||
- cache->frameoffset);
|
||||
}
|
||||
}
|
||||
|
||||
static struct arm_prologue_cache *
|
||||
arm_make_prologue_cache (struct frame_info *next_frame)
|
||||
{
|
||||
struct arm_prologue_cache *cache;
|
||||
|
||||
cache = frame_obstack_zalloc (sizeof (struct arm_prologue_cache)
|
||||
+ sizeof (CORE_ADDR) * (NUM_REGS + NUM_PSEUDO_REGS - 1));
|
||||
|
||||
cache->unwound_pc = frame_pc_unwind (next_frame);
|
||||
if (frame_relative_level (next_frame) < 0)
|
||||
cache->unwound_sp = deprecated_read_fp ();
|
||||
else
|
||||
cache->unwound_sp = arm_minimal_frame_chain (next_frame, cache);
|
||||
arm_minimal_frame_info (next_frame, cache);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
arm_frame_chain (struct frame_info *next_frame)
|
||||
{
|
||||
struct arm_prologue_cache *cache;
|
||||
|
||||
cache = arm_make_prologue_cache (next_frame);
|
||||
return cache->unwound_sp;
|
||||
}
|
||||
|
||||
static void
|
||||
arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
||||
{
|
||||
struct arm_prologue_cache *cache;
|
||||
|
||||
cache = arm_make_prologue_cache (deprecated_get_next_frame_hack (fi));
|
||||
|
||||
if (get_frame_saved_regs (fi) == NULL)
|
||||
frame_saved_regs_zalloc (fi);
|
||||
|
||||
frame_extra_info_zalloc (fi, (sizeof (struct arm_prologue_cache)
|
||||
+ ((NUM_REGS + NUM_PSEUDO_REGS - 1)
|
||||
* sizeof (CORE_ADDR))));
|
||||
|
||||
memcpy (get_frame_extra_info (fi), cache, (sizeof (struct arm_prologue_cache)
|
||||
+ ((NUM_REGS + NUM_PSEUDO_REGS - 1)
|
||||
* sizeof (CORE_ADDR))));
|
||||
memcpy (get_frame_saved_regs (fi), cache->saved_regs,
|
||||
(NUM_REGS + NUM_PSEUDO_REGS - 1) * sizeof (CORE_ADDR));
|
||||
}
|
||||
|
||||
/* Find the caller of this frame. We do this by seeing if ARM_LR_REGNUM
|
||||
is saved in the stack anywhere, otherwise we get it from the
|
||||
|
|
Loading…
Reference in New Issue