2002-04-25 Michael Snyder * 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. Index: arm-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/arm-tdep.c,v retrieving revision 1.57 diff -p -r1.57 arm-tdep.c *** arm-tdep.c 1 May 2002 00:57:51 -0000 1.57 --- arm-tdep.c 8 May 2002 22:31:53 -0000 *************** arm_skip_prologue (CORE_ADDR pc) *** 417,423 **** { unsigned long inst; CORE_ADDR skip_pc; ! CORE_ADDR func_addr, func_end; char *func_name; struct symtab_and_line sal; --- 417,423 ---- { unsigned long inst; CORE_ADDR skip_pc; ! CORE_ADDR func_addr, func_end = 0; char *func_name; struct symtab_and_line sal; *************** arm_skip_prologue (CORE_ADDR pc) *** 444,517 **** /* 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); ! } ! if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ { - 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); ! } ! /* 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. */ ! ! /* 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, , [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 & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ ! { ! skip_pc += 4; ! inst = read_memory_integer (skip_pc, 4); ! } ! if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ ! { ! skip_pc += 4; ! inst = read_memory_integer (skip_pc, 4); ! } ! while ((inst & 0xffffcfc0) == 0xe50b0000) /* str r(0123), [r11, #-nn] */ ! { ! skip_pc += 4; ! inst = read_memory_integer (skip_pc, 4); } ! return skip_pc; } /* *INDENT-OFF* */ --- 444,506 ---- /* Can't find the prologue end in the symbol table, try it the hard way by disassembling the instructions. */ ! /* Like arm_scan_prologue, stop no later than pc + 64. */ ! if (func_end == 0 || func_end > pc + 64) ! func_end = pc + 64; ! for (skip_pc = pc; skip_pc < func_end; 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; ! /* Some prologues begin with "str lr, [sp, #-4]!". */ ! if (inst == 0xe52de004) /* str lr, [sp, #-4]! */ ! continue; ! if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ ! continue; ! if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */ ! 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. */ ! ! /* 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, , [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; /* End of prologue */ } /* *INDENT-OFF* */ *************** thumb_scan_prologue (struct frame_info * *** 597,603 **** whether to save LR (R14). */ mask = (insn & 0xff) | ((insn & 0x100) << 6); ! /* Calculate offsets of saved R0-R7 and LR. */ for (regno = ARM_LR_REGNUM; regno >= 0; regno--) if (mask & (1 << regno)) { --- 586,592 ---- whether to save LR (R14). */ mask = (insn & 0xff) | ((insn & 0x100) << 6); ! /* Calculate offsets of saved R0-R7 and LR. */ for (regno = ARM_LR_REGNUM; regno >= 0; regno--) if (mask & (1 << regno)) { *************** thumb_scan_prologue (struct frame_info * *** 611,617 **** else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR sub sp, #simm */ { ! if ((findmask & 1) == 0) /* before push? */ continue; else findmask |= 4; /* add/sub sp found */ --- 600,606 ---- else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR sub sp, #simm */ { ! if ((findmask & 1) == 0) /* before push? */ continue; else findmask |= 4; /* add/sub sp found */ *************** arm_scan_prologue (struct frame_info *fi *** 857,863 **** 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" and other operations that rely on a knowledge of the stack traceback. --- 846,852 ---- 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 as "finish" and other operations that rely on a knowledge of the stack traceback. *************** arm_scan_prologue (struct frame_info *fi *** 870,876 **** [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] */ sp_offset = fp_offset = 0; --- 859,865 ---- [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] */ sp_offset = fp_offset = 0; *************** arm_scan_prologue (struct frame_info *fi *** 904,910 **** fi->saved_regs[regno] = sp_offset; } } ! else if ((insn & 0xffffcfc0) == 0xe50b0000) /* str rx, [r11, -n] */ { /* No need to add this to saved_regs -- it's just an arg reg. */ continue; --- 893,908 ---- fi->saved_regs[regno] = sp_offset; } } ! 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; *************** arm_scan_prologue (struct frame_info *fi *** 960,966 **** } else if ((insn & 0xf0000000) != 0xe0000000) break; /* Condition not true, exit early */ ! else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ break; /* Don't scan past a block load */ else /* The optimizer might shove anything into the prologue, --- 958,964 ---- } else if ((insn & 0xf0000000) != 0xe0000000) break; /* Condition not true, exit early */ ! else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ break; /* Don't scan past a block load */ else /* The optimizer might shove anything into the prologue, *************** arm_get_next_pc (CORE_ADDR pc) *** 2050,2056 **** static void arm_software_single_step (enum target_signal sig, int insert_bpt) { ! static int next_pc; /* State between setting and unsetting. */ static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ if (insert_bpt) --- 2048,2054 ---- static void arm_software_single_step (enum target_signal sig, int insert_bpt) { ! static int next_pc; /* State between setting and unsetting. */ static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ if (insert_bpt)