diff options
author | Michael Snyder <msnyder@vmware.com> | 2002-05-09 18:07:00 +0000 |
---|---|---|
committer | Michael Snyder <msnyder@vmware.com> | 2002-05-09 18:07:00 +0000 |
commit | b8d5e71d0bc6657abed6e85cf53b0efa3ec51b08 (patch) | |
tree | 3f5e2f58fad12eacc54ef11c896d6ec48c5b4e81 /gdb | |
parent | 3ce1502b874a327cac9143b69c6912856deaaa28 (diff) | |
download | fsf-binutils-gdb-b8d5e71d0bc6657abed6e85cf53b0efa3ec51b08.zip fsf-binutils-gdb-b8d5e71d0bc6657abed6e85cf53b0efa3ec51b08.tar.gz fsf-binutils-gdb-b8d5e71d0bc6657abed6e85cf53b0efa3ec51b08.tar.bz2 |
2002-05-09 Michael Snyder <msnyder@redhat.com>
* arm-tdep.c (arm_scan_prologue): Accept strb r(0123),[r11,#-nn],
strh r(0123),[r11,#-nn], str r(0123),[r11,#-nn], as well as
strb r(0123),[sp,#nn], strh r(0123),[sp,#nn] and
str r(0123),[sp,#nn].
(arm_skip_prologue): Ditto. Also make disassembly
order-independent by placing it in a loop.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/arm-tdep.c | 126 |
2 files changed, 71 insertions, 64 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a307bce..79991b3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2002-05-09 Michael Snyder <msnyder@redhat.com> + + * arm-tdep.c (arm_scan_prologue): Accept strb r(0123),[r11,#-nn], + strh r(0123),[r11,#-nn], str r(0123),[r11,#-nn], as well as + strb r(0123),[sp,#nn], strh r(0123),[sp,#nn] and + str r(0123),[sp,#nn]. + (arm_skip_prologue): Ditto. Also make disassembly + order-independent by placing it in a loop. + 2002-05-09 Mark Kettenis <kettenis@gnu.org> * i386-tdep.h (i386_abi): New enum. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index bc928e12..646d5c6 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -417,7 +417,7 @@ arm_skip_prologue (CORE_ADDR pc) { unsigned long inst; CORE_ADDR skip_pc; - CORE_ADDR func_addr, func_end; + CORE_ADDR func_addr, func_end = 0; char *func_name; struct symtab_and_line sal; @@ -449,74 +449,63 @@ arm_skip_prologue (CORE_ADDR pc) /* Can't find the prologue end in the symbol table, try it the hard way by disassembling the instructions. */ - skip_pc = pc; - inst = read_memory_integer (skip_pc, 4); - /* "mov ip, sp" is no longer a required part of the prologue. */ - if (inst == 0xe1a0c00d) /* mov ip, sp */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } - /* Some prologues begin with "str lr, [sp, #-4]!". */ - if (inst == 0xe52de004) /* str lr, [sp, #-4]! */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } + /* Like arm_scan_prologue, stop no later than pc + 64. */ + if (func_end == 0 || func_end > pc + 64) + func_end = pc + 64; - if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ + for (skip_pc = pc; skip_pc < func_end; skip_pc += 4) { - skip_pc += 4; inst = read_memory_integer (skip_pc, 4); - } - if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } + /* "mov ip, sp" is no longer a required part of the prologue. */ + if (inst == 0xe1a0c00d) /* mov ip, sp */ + continue; - /* Any insns after this point may float into the code, if it makes - for better instruction scheduling, so we skip them only if we - find them, but still consider the function to be frame-ful. */ + /* Some prologues begin with "str lr, [sp, #-4]!". */ + if (inst == 0xe52de004) /* str lr, [sp, #-4]! */ + continue; - /* We may have either one sfmfd instruction here, or several stfe - insns, depending on the version of floating point code we - support. */ - if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, <cnt>, [sp]! */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } - else - { - while ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } - } + if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ + continue; - if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } + if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */ + continue; - if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - } + /* Any insns after this point may float into the code, if it makes + for better instruction scheduling, so we skip them only if we + find them, but still consider the function to be frame-ful. */ - while ((inst & 0xffffcfc0) == 0xe50b0000) /* str r(0123), [r11, #-nn] */ - { - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); + /* We may have either one sfmfd instruction here, or several stfe + insns, depending on the version of floating point code we + support. */ + if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, <cnt>, [sp]! */ + continue; + + if ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ + continue; + + if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ + continue; + + if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ + continue; + + if ((inst & 0xffffc000) == 0xe54b0000 || /* strb r(0123),[r11,#-nn] */ + (inst & 0xffffc0f0) == 0xe14b00b0 || /* strh r(0123),[r11,#-nn] */ + (inst & 0xffffc000) == 0xe50b0000) /* str r(0123),[r11,#-nn] */ + continue; + + if ((inst & 0xffffc000) == 0xe5cd0000 || /* strb r(0123),[sp,#nn] */ + (inst & 0xffffc0f0) == 0xe1cd00b0 || /* strh r(0123),[sp,#nn] */ + (inst & 0xffffc000) == 0xe58d0000) /* str r(0123),[sp,#nn] */ + continue; + + /* Un-recognized instruction; stop scanning. */ + break; } - return skip_pc; + return skip_pc; /* End of prologue */ } /* *INDENT-OFF* */ @@ -608,7 +597,7 @@ thumb_scan_prologue (struct frame_info *fi) whether to save LR (R14). */ mask = (insn & 0xff) | ((insn & 0x100) << 6); - /* Calculate offsets of saved R0-R7 and LR. */ + /* Calculate offsets of saved R0-R7 and LR. */ for (regno = ARM_LR_REGNUM; regno >= 0; regno--) if (mask & (1 << regno)) { @@ -622,7 +611,7 @@ thumb_scan_prologue (struct frame_info *fi) else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR sub sp, #simm */ { - if ((findmask & 1) == 0) /* before push? */ + if ((findmask & 1) == 0) /* before push? */ continue; else findmask |= 4; /* add/sub sp found */ @@ -868,7 +857,7 @@ arm_scan_prologue (struct frame_info *fi) Be careful, however, and if it doesn't look like a prologue, don't try to scan it. If, for instance, a frameless function begins with stmfd sp!, then we will tell ourselves there is - a frame, which will confuse stack traceback, as well ad"finish" + a frame, which will confuse stack traceback, as well as "finish" and other operations that rely on a knowledge of the stack traceback. @@ -881,7 +870,7 @@ arm_scan_prologue (struct frame_info *fi) [Note further: The "mov ip,sp" only seems to be missing in frameless functions at optimization level "-O2" or above, in which case it is often (but not always) replaced by - "str lr, [sp, #-4]!". - Michael Snyder, 2002-04-23] */ + "str lr, [sp, #-4]!". - Michael Snyder, 2002-04-23] */ sp_offset = fp_offset = 0; @@ -915,7 +904,16 @@ arm_scan_prologue (struct frame_info *fi) fi->saved_regs[regno] = sp_offset; } } - else if ((insn & 0xffffcfc0) == 0xe50b0000) /* str rx, [r11, -n] */ + else if ((insn & 0xffffc000) == 0xe54b0000 || /* strb rx,[r11,#-n] */ + (insn & 0xffffc0f0) == 0xe14b00b0 || /* strh rx,[r11,#-n] */ + (insn & 0xffffc000) == 0xe50b0000) /* str rx,[r11,#-n] */ + { + /* No need to add this to saved_regs -- it's just an arg reg. */ + continue; + } + else if ((insn & 0xffffc000) == 0xe5cd0000 || /* strb rx,[sp,#n] */ + (insn & 0xffffc0f0) == 0xe1cd00b0 || /* strh rx,[sp,#n] */ + (insn & 0xffffc000) == 0xe58d0000) /* str rx,[sp,#n] */ { /* No need to add this to saved_regs -- it's just an arg reg. */ continue; @@ -971,7 +969,7 @@ arm_scan_prologue (struct frame_info *fi) } else if ((insn & 0xf0000000) != 0xe0000000) break; /* Condition not true, exit early */ - else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ + else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ break; /* Don't scan past a block load */ else /* The optimizer might shove anything into the prologue, @@ -2072,7 +2070,7 @@ arm_get_next_pc (CORE_ADDR pc) static void arm_software_single_step (enum target_signal sig, int insert_bpt) { - static int next_pc; /* State between setting and unsetting. */ + static int next_pc; /* State between setting and unsetting. */ static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ if (insert_bpt) |