From: Michael Snyder Date: Wed, 24 Apr 2002 21:22:06 +0000 (+0000) Subject: 2002-04-24 Michael Snyder X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f43845b38ec9ab8ef197a9201b2e9be2913df4b3;p=binutils-gdb.git 2002-04-24 Michael Snyder * arm-tdep.c (arm_scan_prologue): Move "mov ip, sp" into the loop. Add handling for "str lr, [sp, #-4]!" and for saves of argument regs ("str r(0123), [r11, #-nn"]). (arm_skip_prologue): Better handling for frameless functions. Treat "mov ip, sp" as optional. Recognize "str lr, [sp, #-4]". (arm_skip_prologue): Recognize str r(0123), [r11, #-nn]. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f8cc9551c54..e7d73252bc1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2002-04-24 Michael Snyder + + * arm-tdep.c (arm_scan_prologue): Move "mov ip, sp" into the + loop. Add handling for "str lr, [sp, #-4]!" and for saves + of argument regs ("str r(0123), [r11, #-nn"]). + (arm_skip_prologue): Better handling for frameless functions. + Treat "mov ip, sp" as optional. Recognize "str lr, [sp, #-4]". + (arm_skip_prologue): Recognize str r(0123), [r11, #-nn]. + Wed Apr 24 14:22:21 2002 Andrew Cagney * arm-tdep.c (arm_gdbarch_init): Add comment that NUM_REGS nor @@ -58,6 +67,7 @@ Wed Apr 24 14:22:21 2002 Andrew Cagney REGISTER_RAW_SIZE of SP_REGNUM not CORE_ADDR. (vx_write_register): Likewise. +>>>>>>> 1.2500 2002-04-23 J. Brobecker * source.c (is_regular_file): New function. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index f05ff6b14eb..a5643a74d79 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -446,22 +446,33 @@ arm_skip_prologue (CORE_ADDR pc) by disassembling the instructions. */ skip_pc = pc; inst = read_memory_integer (skip_pc, 4); - if (inst != 0xe1a0c00d) /* mov ip, sp */ - return pc; - - skip_pc += 4; - inst = read_memory_integer (skip_pc, 4); - if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ + /* "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); } - if ((inst & 0xfffff800) != 0xe92dd800) /* stmfd sp!,{...,fp,ip,lr,pc} */ - return pc; + /* 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); + } 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 @@ -477,7 +488,7 @@ arm_skip_prologue (CORE_ADDR pc) } else { - while ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ + while ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ { skip_pc += 4; inst = read_memory_integer (skip_pc, 4); @@ -490,8 +501,17 @@ arm_skip_prologue (CORE_ADDR pc) inst = read_memory_integer (skip_pc, 4); } - if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ - 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; } @@ -843,23 +863,34 @@ arm_scan_prologue (struct frame_info *fi) traceback. In the APCS, the prologue should start with "mov ip, sp" so - if we don't see this as the first insn, we will stop. [Note: - This doesn't seem to be true any longer, so it's now an optional - part of the prologue. - Kevin Buettner, 2001-11-20] */ + if we don't see this as the first insn, we will stop. - sp_offset = fp_offset = 0; + [Note: This doesn't seem to be true any longer, so it's now an + optional part of the prologue. - Kevin Buettner, 2001-11-20] - if (read_memory_unsigned_integer (prologue_start, 4) - == 0xe1a0c00d) /* mov ip, sp */ - current_pc = prologue_start + 4; - else - current_pc = prologue_start; + [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] */ - for (; current_pc < prologue_end; current_pc += 4) + sp_offset = fp_offset = 0; + + for (current_pc = prologue_start; + current_pc < prologue_end; + current_pc += 4) { unsigned int insn = read_memory_unsigned_integer (current_pc, 4); - if ((insn & 0xffff0000) == 0xe92d0000) + if (insn == 0xe1a0c00d) /* mov ip, sp */ + { + continue; + } + else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */ + { + /* Function is frameless: extra_info defaults OK? */ + continue; + } + else if ((insn & 0xffff0000) == 0xe92d0000) /* stmfd sp!, {..., fp, ip, lr, pc} or stmfd sp!, {a1, a2, a3, a4} */ @@ -874,6 +905,11 @@ arm_scan_prologue (struct frame_info *fi) 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; + } else if ((insn & 0xfffff000) == 0xe24cb000) /* sub fp, ip #n */ { unsigned imm = insn & 0xff; /* immediate value */