diff options
author | Andrew Cagney <cagney@redhat.com> | 2002-10-01 01:24:01 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2002-10-01 01:24:01 +0000 |
commit | 68315eb83ae243c85c26e24223f6573a3bacb18e (patch) | |
tree | 6d1f94e56d4c364bcd42e2f4702dedf3ab999a61 | |
parent | 28e0c55ddcf855a87f58ef62aab5cf66033138df (diff) | |
download | gdb-68315eb83ae243c85c26e24223f6573a3bacb18e.zip gdb-68315eb83ae243c85c26e24223f6573a3bacb18e.tar.gz gdb-68315eb83ae243c85c26e24223f6573a3bacb18e.tar.bz2 |
2002-09-30 Andrew Cagney <ac131313@redhat.com>
* blockframe.c (generic_find_dummy_frame): Rewrite. Only test
against TOP when TOP was explictly set.
(generic_push_dummy_frame): Set TOP to zero.
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/blockframe.c | 41 |
2 files changed, 39 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 821b175..845cfbf 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2002-09-30 Andrew Cagney <ac131313@redhat.com> + + * blockframe.c (generic_find_dummy_frame): Rewrite. Only test + against TOP when TOP was explictly set. + (generic_push_dummy_frame): Set TOP to zero. + 2002-09-30 Elena Zannoni <ezannoni@redhat.com> * event-loop.c (start_event_loop): Rename variable 'result' to diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 674285d..eba45a3 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -1151,8 +1151,8 @@ static struct dummy_frame *dummy_frame_stack = NULL; /* Function: find_dummy_frame(pc, fp, sp) - Search the stack of dummy frames for one matching the given PC, FP - and SP. Unlike PC_IN_CALL_DUMMY, this function doesn't need to + Search the stack of dummy frames for one matching the given PC and + FP/SP. Unlike PC_IN_CALL_DUMMY, this function doesn't need to adjust for DECR_PC_AFTER_BREAK. This is because it is only legal to call this function after the PC has been adjusted. */ @@ -1163,12 +1163,37 @@ generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp) for (dummyframe = dummy_frame_stack; dummyframe != NULL; dummyframe = dummyframe->next) - if ((pc >= dummyframe->call_lo && pc < dummyframe->call_hi) - && (fp == dummyframe->fp - || fp == dummyframe->sp - || fp == dummyframe->top)) - /* The frame in question lies between the saved fp and sp, inclusive */ + { + /* Does the PC fall within the dummy frame's breakpoint + instruction. If not, discard this one. */ + if (!(pc >= dummyframe->call_lo && pc < dummyframe->call_hi)) + continue; + /* Does the FP match? */ + if (dummyframe->top != 0) + { + /* If the target architecture explicitly saved the + top-of-stack before the inferior function call, assume + that that same architecture will always pass in an FP + (frame base) value that eactly matches that saved TOS. + Don't check the saved SP and SP as they can lead to false + hits. */ + if (fp != dummyframe->top) + continue; + } + else + { + /* An older target that hasn't explicitly or implicitly + saved the dummy frame's top-of-stack. Try matching the + FP against the saved SP and FP. NOTE: If you're trying + to fix a problem with GDB not correctly finding a dummy + frame, check the comments that go with FRAME_ALIGN() and + SAVE_DUMMY_FRAME_TOS(). */ + if (fp != dummyframe->fp && fp != dummyframe->sp) + continue; + } + /* The FP matches this dummy frame. */ return dummyframe->regcache; + } return 0; } @@ -1265,7 +1290,7 @@ generic_push_dummy_frame (void) dummy_frame->pc = read_pc (); dummy_frame->sp = read_sp (); - dummy_frame->top = dummy_frame->sp; + dummy_frame->top = 0; dummy_frame->fp = fp; regcache_cpy (dummy_frame->regcache, current_regcache); dummy_frame->next = dummy_frame_stack; |