diff options
author | Kevin Buettner <kevinb@redhat.com> | 2008-01-29 00:15:10 +0000 |
---|---|---|
committer | Kevin Buettner <kevinb@redhat.com> | 2008-01-29 00:15:10 +0000 |
commit | 83845630516f14df94175abe078c133ff4e51685 (patch) | |
tree | cbfdc731cca7282c3b75df7b0789ca7f17e39006 /gdb/mn10300-tdep.c | |
parent | f1e8e64f7075573619bc5e0be5db57f0667dc30a (diff) | |
download | gdb-83845630516f14df94175abe078c133ff4e51685.zip gdb-83845630516f14df94175abe078c133ff4e51685.tar.gz gdb-83845630516f14df94175abe078c133ff4e51685.tar.bz2 |
* mn10300-tdep.c (mn10300_analyze_prologue): Check for an
instruction pattern that appears frequently in position
independent code. Fix bug in code which looks for "fmov" and
backtracks if no "fmov" is found.
Diffstat (limited to 'gdb/mn10300-tdep.c')
-rw-r--r-- | gdb/mn10300-tdep.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index e0fc6a7..8cf9bb3 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -608,6 +608,22 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch, struct frame_info *fi, goto finish_prologue; } + /* Check for "mov pc, a2", an instruction found in optimized, position + independent code. Skip it if found. */ + if (buf[0] == 0xf0 && buf[1] == 0x2e) + { + addr += 2; + + /* Quit now if we're beyond the stop point. */ + if (addr >= stop) + goto finish_prologue; + + /* Get the next two bytes so the prologue scan can continue. */ + status = read_memory_nobpt (addr, buf, 2); + if (status != 0) + goto finish_prologue; + } + if (AM33_MODE (gdbarch) == 2) { /* Determine if any floating point registers are to be saved. @@ -635,6 +651,7 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch, struct frame_info *fi, was actually encountered. As a consequence, ``addr'' would sometimes be advanced even when no fmov instructions were found. */ CORE_ADDR restore_addr = addr; + int fmov_found = 0; /* First, look for add -SIZE,sp (i.e. add imm8,sp (0xf8feXX) or add imm16,sp (0xfafeXXXX) @@ -715,12 +732,9 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch, struct frame_info *fi, 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; + now really commit to the pattern match. */ + + fmov_found = 1; /* Get the floating point register number from the 2nd and 3rd bytes of the "fmov" instruction: @@ -739,29 +753,18 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch, struct frame_info *fi, imm_size = (buf[0] == 0xf9) ? 3 : 4; } } - else - { - /* 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; - } } - /* else the prologue consists entirely of an "add -SIZE,sp" - instruction. Handle this below. */ } - /* else no "add -SIZE,sp" was found indicating no floating point - 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; + /* If no fmov instructions were found by the above sequence, reset + the state and pretend that the above bit of code never happened. */ + if (!fmov_found) + { + addr = restore_addr; + status = read_memory_nobpt (addr, buf, 2); + if (status != 0) + goto finish_prologue; + stack_extra_size = 0; + } } /* Now see if we set up a frame pointer via "mov sp,a3" */ |