summaryrefslogtreecommitdiff
path: root/gdb/mn10300-tdep.c
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2006-02-28 22:28:21 +0000
committerKevin Buettner <kevinb@redhat.com>2006-02-28 22:28:21 +0000
commite79a8226c621b42d26c7708dd2f320dca8de987b (patch)
tree5c4bd9082f11138ce8e742182d4868d3a446796e /gdb/mn10300-tdep.c
parent392ad22d9a10985d90871112ae54aa32c91654e5 (diff)
downloadgdb-e79a8226c621b42d26c7708dd2f320dca8de987b.tar.gz
* mn10300-tdep.c (mn10300_analyze_prologue): Implement backtrack
out of pattern match by saving relevant state. Fix stack size adjustment bug.
Diffstat (limited to 'gdb/mn10300-tdep.c')
-rw-r--r--gdb/mn10300-tdep.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 81152ad025b..47844d1a6d2 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;