diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-03-13 21:43:34 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-03-13 21:43:34 +0000 |
commit | 5422b5d2fa74279625100e408edc6e31b9e57b03 (patch) | |
tree | e4b579eaebecd246483a3ae141d6939e0e13bdcc | |
parent | 01d8344e9f2cae907cbea8a79e9854ca8e72a36b (diff) | |
download | gdb-offbyone-20030313-branch.zip gdb-offbyone-20030313-branch.tar.gz gdb-offbyone-20030313-branch.tar.bz2 |
2003-03-13 Andrew Cagney <cagney@redhat.com>offbyone-20030313-branch
* frame.c (legacy_saved_regs_this_id): Handle a sentinel frame.
(get_prev_frame): Simplify. Frame ID logic moved to
dummy_frame_this_id and legacy_saved_regs_this_id.
-rw-r--r-- | gdb/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/frame.c | 180 |
2 files changed, 73 insertions, 111 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c634d4c..5565723 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,9 @@ 2003-03-13 Andrew Cagney <cagney@redhat.com> + * frame.c (legacy_saved_regs_this_id): Handle a sentinel frame. + (get_prev_frame): Simplify. Frame ID logic moved to + dummy_frame_this_id and legacy_saved_regs_this_id. + * d10v-tdep.c (d10v_frame_this_id): Replace d10v_frame_id_unwind. (d10v_frame_unwind): Update. (d10v_frame_prev_register): Replace d10v_frame_register_unwind. diff --git a/gdb/frame.c b/gdb/frame.c index 002a306..3050a58 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -745,30 +745,40 @@ legacy_saved_regs_this_id (struct frame_info *next_frame, void **this_prologue_cache, struct frame_id *id) { - int fromleaf; CORE_ADDR base; CORE_ADDR pc; /* Start out by assuming it's NULL. */ (*id) = null_frame_id; - if (frame_relative_level (next_frame) <= 0) - /* FIXME: 2002-11-09: Frameless functions can occure anywhere in - the frame chain, not just the inner most frame! The generic, - per-architecture, frame code should handle this and the below - should simply be removed. */ - fromleaf = FRAMELESS_FUNCTION_INVOCATION (next_frame); - else - fromleaf = 0; - - if (fromleaf) - /* A frameless inner-most frame. The `FP' (which isn't an - architecture frame-pointer register!) of the caller is the same - as the callee. */ - /* FIXME: 2002-11-09: There isn't any reason to special case this - edge condition. Instead the per-architecture code should hande - it locally. */ - base = get_frame_base (next_frame); + if (frame_relative_level (next_frame) < 0) + { + /* We're unwinding a sentinel frame, the PC of which is pointing + at a stack dummy. Fake up the dummy frame's ID using the + same sequence as is found a traditional unwinder. Once all + architectures supply the unwind_dummy_id method, this code + can go away. */ + base = read_fp (); + pc = read_pc (); + } + else if (frame_relative_level (next_frame) == 0 + && FRAMELESS_FUNCTION_INVOCATION (next_frame)) + { + /* FIXME: 2002-11-09: Frameless functions can occure anywhere in + the frame chain, not just the inner most frame! The generic, + per-architecture, frame code should handle this and the below + should simply be removed. */ + /* A frameless inner-most frame. The `FP' (which isn't an + architecture frame-pointer register!) of the caller is the + same as the callee. */ + /* FIXME: 2002-11-09: There isn't any reason to special case + this edge condition. Instead the per-architecture code + should hande it locally. */ + base = get_frame_base (next_frame); + /* FIXME: cagney/2002-06-08: This should probably return the frame's + function and not the PC (a.k.a. resume address). */ + pc = frame_pc_unwind (next_frame); + } else { /* Two macros defined in tm.h specify the machine-dependent @@ -788,16 +798,12 @@ legacy_saved_regs_this_id (struct frame_info *next_frame, main. */ gdb_assert (FRAME_CHAIN_P ()); base = FRAME_CHAIN (next_frame); - if (!frame_chain_valid (base, next_frame)) return; + /* FIXME: cagney/2002-06-08: This should probably return the + frame's function and not the PC (a.k.a. resume address). */ + pc = frame_pc_unwind (next_frame); } - if (base == 0) - return; - - /* FIXME: cagney/2002-06-08: This should probably return the frame's - function and not the PC (a.k.a. resume address). */ - pc = frame_pc_unwind (next_frame); id->pc = pc; id->base = base; } @@ -1385,97 +1391,49 @@ get_prev_frame (struct frame_info *this_frame) prev_frame->pc); /* Find the prev's frame's ID. */ - switch (prev_frame->type) - { - case DUMMY_FRAME: - /* When unwinding a normal frame, the stack structure is - determined by analyzing the frame's function's code (be it - using brute force prologue analysis, or the dwarf2 CFI). In - the case of a dummy frame, that simply isn't possible. The - The PC is either the program entry point, or some random - address on the stack. Trying to use that PC to apply - standard frame ID unwind techniques is just asking for - trouble. */ - if (gdbarch_unwind_dummy_id_p (current_gdbarch)) - { - /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS, - previously saved the dummy frame's ID. Things only work - if the two return the same value. */ - gdb_assert (SAVE_DUMMY_FRAME_TOS_P ()); - /* Use an architecture specific method to extract the prev's - dummy ID from the next frame. Note that this method uses - frame_register_unwind to obtain the register values - needed to determine the dummy frame's ID. */ - prev_frame->id = gdbarch_unwind_dummy_id (current_gdbarch, - this_frame); - } - else if (this_frame->level < 0) - { - /* We're unwinding a sentinel frame, the PC of which is - pointing at a stack dummy. Fake up the dummy frame's ID - using the same sequence as is found a traditional - unwinder. Once all architectures supply the - unwind_dummy_id method, this code can go away. */ - prev_frame->id.base = read_fp (); - prev_frame->id.pc = read_pc (); - } - else - { - /* Outch! We're not on the innermost frame yet we're trying - to unwind to a dummy. The architecture must provide the - unwind_dummy_id() method. Abandon the unwind process but - only after first warning the user. */ - internal_warning (__FILE__, __LINE__, - "Missing unwind_dummy_id architecture method"); - return NULL; - } - break; - case NORMAL_FRAME: - case SIGTRAMP_FRAME: - /* The callee expects to be invoked with: - this->unwind->this_id (this->next, &this->cache, &this->id); + /* The callee expects to be invoked with: - The below is carefully shifted one frame `to the left' so - that both the unwind->this_id and unwind->prev_register - methods are consistently invoked with NEXT_FRAME and - THIS_PROLOGUE_CACHE. + this->unwind->this_id (this->next, &this->cache, &this->id); + + The below is carefully shifted one frame `to the left' so that + both the unwind->this_id and unwind->prev_register methods are + consistently invoked with NEXT_FRAME and THIS_PROLOGUE_CACHE. - Also note that, while the PC for this new previous frame was - unwound first (see above), the below is the first call that - [potentially] requires analysis of the new previous frame's - prologue. Consequently, it is this call, that typically ends - up initializing the previous frame's prologue cache. */ - prev_frame->unwind->this_id (this_frame, - &prev_frame->prologue_cache, - &prev_frame->id); - /* Check that the unwound ID is valid. */ - if (!frame_id_p (prev_frame->id)) - { - if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - unwound frame ID invalid\n"); - return NULL; - } - /* Check that the new frame isn't inner to (younger, below, - next) the old frame. If that happens the frame unwind is - going backwards. */ - /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since - that doesn't have a valid frame ID. Should instead set the - sentinel frame's frame ID to a `sentinel'. Leave it until - after the switch to storing the frame ID, instead of the - frame base, in the frame object. */ - if (this_frame->level >= 0 - && frame_id_inner (prev_frame->id, get_frame_id (this_frame))) - error ("Unwound frame inner-to selected frame (corrupt stack?)"); - /* Note that, due to frameless functions, the stronger test of - the new frame being outer to the old frame can't be used - - frameless functions differ by only their PC value. */ - break; - default: - internal_error (__FILE__, __LINE__, "bad switch"); + Also note that, while the PC for this new previous frame was + unwound first (see above), the below is the first call that + [potentially] requires analysis of the new previous frame's + prologue. Consequently, it is this call, that typically ends up + initializing the previous frame's prologue cache. */ + prev_frame->unwind->this_id (this_frame, + &prev_frame->prologue_cache, + &prev_frame->id); + + /* Check that the unwound ID is valid. */ + if (!frame_id_p (prev_frame->id)) + { + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "Outermost frame - unwound frame ID invalid\n"); + return NULL; } + /* Check that the new frame isn't inner to (younger, below, next) + the old frame. If that happens the frame unwind is going + backwards. */ + /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since that + doesn't have a valid frame ID. Should instead set the sentinel + frame's frame ID to a true `sentinel'. Leave it until after the + switch to storing the frame ID, instead of the frame base, in the + frame object. */ + if (this_frame->level >= 0 + && frame_id_inner (prev_frame->id, get_frame_id (this_frame))) + error ("Unwound frame inner-to selected frame (corrupt stack?)"); + + /* Note that, due to frameless functions, the stronger test of the + new frame being outer to the old frame can't be used - frameless + functions differ by only their PC value. */ + /* FIXME: cagney/2002-12-18: Instead of this hack, should only store the frame ID in PREV_FRAME. Unfortunatly, some architectures (HP/UX) still reply on EXTRA_FRAME_INFO and, hence, still poke at |