diff options
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/mn10300-tdep.c | 42 |
2 files changed, 41 insertions, 7 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index dfe5cba..de59ea5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2006-02-28 Kevin Buettner <kevinb@redhat.com> + + * mn10300-tdep.c (mn10300_analyze_prologue): Implement backtrack + out of pattern match by saving relevant state. Fix stack size + adjustment bug. + 2006-02-28 Alexandre Oliva <aoliva@redhat.com> * solib-svr4.h (struct link_map_offsets): Add l_ld_offset and diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 81152ad..47844d1 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -620,6 +620,17 @@ mn10300_analyze_prologue (struct frame_info *fi, [mov sp,a3] [mov sp,a3] [add -SIZE2,sp] [add -SIZE2,sp] */ + /* Remember the address at which we started in the event that we + don't ultimately find an fmov instruction. Once we're certain + that we matched one of the above patterns, we'll set + ``restore_addr'' to the appropriate value. Note: At one time + in the past, this code attempted to not adjust ``addr'' until + there was a fair degree of certainty that the pattern would be + matched. However, that code did not wait until an fmov instruction + was actually encountered. As a consequence, ``addr'' would + sometimes be advanced even when no fmov instructions were found. */ + CORE_ADDR restore_addr = addr; + /* First, look for add -SIZE,sp (i.e. add imm8,sp (0xf8feXX) or add imm16,sp (0xfafeXXXX) or add imm32,sp (0xfcfeXXXXXXXX)) */ @@ -651,10 +662,10 @@ mn10300_analyze_prologue (struct frame_info *fi, This is a one byte instruction: mov sp,aN = 0011 11XX where XX is the register number. - Skip this instruction by incrementing addr. (We're - committed now.) The "fmov" instructions will have the - form "fmov fs#,(aN+)" in this case, but that will not - necessitate a change in the "fmov" parsing logic below. */ + Skip this instruction by incrementing addr. The "fmov" + instructions will have the form "fmov fs#,(aN+)" in this + case, but that will not necessitate a change in the + "fmov" parsing logic below. */ addr++; @@ -698,6 +709,14 @@ mn10300_analyze_prologue (struct frame_info *fi, if (buf[0] != 0xf9 && buf[0] != 0xfb) break; + /* An fmov instruction has just been seen. We can + now really commit to the pattern match. Set the + address to restore at the end of this speculative + bit of code to the actually address that we've + been incrementing (or not) throughout the + speculation. */ + restore_addr = addr; + /* Get the floating point register number from the 2nd and 3rd bytes of the "fmov" instruction: Machine Code: 0000 00X0 YYYY 0000 => @@ -719,6 +738,7 @@ mn10300_analyze_prologue (struct frame_info *fi, { /* No "fmov" was found. Reread the two bytes at the original "addr" to reset the state. */ + addr = restore_addr; if (!safe_frame_unwind_memory (fi, addr, buf, 2)) goto finish_prologue; } @@ -727,8 +747,16 @@ mn10300_analyze_prologue (struct frame_info *fi, instruction. Handle this below. */ } /* else no "add -SIZE,sp" was found indicating no floating point - registers are saved in this prologue. Do not increment addr. Pretend - this bit of code never happened. */ + registers are saved in this prologue. */ + + /* In the pattern match code contained within this block, `restore_addr' + is set to the starting address at the very beginning and then + iteratively to the next address to start scanning at once the + pattern match has succeeded. Thus `restore_addr' will contain + the address to rewind to if the pattern match failed. If the + match succeeded, `restore_addr' and `addr' will already have the + same value. */ + addr = restore_addr; } /* Now see if we set up a frame pointer via "mov sp,a3" */ @@ -777,7 +805,7 @@ mn10300_analyze_prologue (struct frame_info *fi, goto finish_prologue; /* Note the size of the stack. */ - stack_extra_size += extract_signed_integer (buf, imm_size); + stack_extra_size -= extract_signed_integer (buf, imm_size); /* We just consumed 2 + imm_size bytes. */ addr += 2 + imm_size; |