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.
This commit is contained in:
parent
3ce1502b87
commit
b8d5e71d0b
@ -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>
|
2002-05-09 Mark Kettenis <kettenis@gnu.org>
|
||||||
|
|
||||||
* i386-tdep.h (i386_abi): New enum.
|
* i386-tdep.h (i386_abi): New enum.
|
||||||
|
142
gdb/arm-tdep.c
142
gdb/arm-tdep.c
@ -417,7 +417,7 @@ arm_skip_prologue (CORE_ADDR pc)
|
|||||||
{
|
{
|
||||||
unsigned long inst;
|
unsigned long inst;
|
||||||
CORE_ADDR skip_pc;
|
CORE_ADDR skip_pc;
|
||||||
CORE_ADDR func_addr, func_end;
|
CORE_ADDR func_addr, func_end = 0;
|
||||||
char *func_name;
|
char *func_name;
|
||||||
struct symtab_and_line sal;
|
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
|
/* Can't find the prologue end in the symbol table, try it the hard way
|
||||||
by disassembling the instructions. */
|
by disassembling the instructions. */
|
||||||
skip_pc = pc;
|
|
||||||
inst = read_memory_integer (skip_pc, 4);
|
/* Like arm_scan_prologue, stop no later than pc + 64. */
|
||||||
/* "mov ip, sp" is no longer a required part of the prologue. */
|
if (func_end == 0 || func_end > pc + 64)
|
||||||
if (inst == 0xe1a0c00d) /* mov ip, sp */
|
func_end = pc + 64;
|
||||||
|
|
||||||
|
for (skip_pc = pc; skip_pc < func_end; skip_pc += 4)
|
||||||
{
|
{
|
||||||
skip_pc += 4;
|
|
||||||
inst = read_memory_integer (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, <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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some prologues begin with "str lr, [sp, #-4]!". */
|
return skip_pc; /* End of prologue */
|
||||||
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, <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 & 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* */
|
/* *INDENT-OFF* */
|
||||||
@ -608,7 +597,7 @@ thumb_scan_prologue (struct frame_info *fi)
|
|||||||
whether to save LR (R14). */
|
whether to save LR (R14). */
|
||||||
mask = (insn & 0xff) | ((insn & 0x100) << 6);
|
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--)
|
for (regno = ARM_LR_REGNUM; regno >= 0; regno--)
|
||||||
if (mask & (1 << 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
|
else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR
|
||||||
sub sp, #simm */
|
sub sp, #simm */
|
||||||
{
|
{
|
||||||
if ((findmask & 1) == 0) /* before push? */
|
if ((findmask & 1) == 0) /* before push? */
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
findmask |= 4; /* add/sub sp found */
|
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,
|
Be careful, however, and if it doesn't look like a prologue,
|
||||||
don't try to scan it. If, for instance, a frameless function
|
don't try to scan it. If, for instance, a frameless function
|
||||||
begins with stmfd sp!, then we will tell ourselves there is
|
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
|
and other operations that rely on a knowledge of the stack
|
||||||
traceback.
|
traceback.
|
||||||
|
|
||||||
@ -881,7 +870,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||||||
[Note further: The "mov ip,sp" only seems to be missing in
|
[Note further: The "mov ip,sp" only seems to be missing in
|
||||||
frameless functions at optimization level "-O2" or above,
|
frameless functions at optimization level "-O2" or above,
|
||||||
in which case it is often (but not always) replaced by
|
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;
|
sp_offset = fp_offset = 0;
|
||||||
|
|
||||||
@ -915,7 +904,16 @@ arm_scan_prologue (struct frame_info *fi)
|
|||||||
fi->saved_regs[regno] = sp_offset;
|
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. */
|
/* No need to add this to saved_regs -- it's just an arg reg. */
|
||||||
continue;
|
continue;
|
||||||
@ -971,7 +969,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||||||
}
|
}
|
||||||
else if ((insn & 0xf0000000) != 0xe0000000)
|
else if ((insn & 0xf0000000) != 0xe0000000)
|
||||||
break; /* Condition not true, exit early */
|
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 */
|
break; /* Don't scan past a block load */
|
||||||
else
|
else
|
||||||
/* The optimizer might shove anything into the prologue,
|
/* The optimizer might shove anything into the prologue,
|
||||||
@ -2072,7 +2070,7 @@ arm_get_next_pc (CORE_ADDR pc)
|
|||||||
static void
|
static void
|
||||||
arm_software_single_step (enum target_signal sig, int insert_bpt)
|
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 */
|
static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */
|
||||||
|
|
||||||
if (insert_bpt)
|
if (insert_bpt)
|
||||||
|
Loading…
Reference in New Issue
Block a user