This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch] Arm prologe skipping broken on 64-bit hosts
- From: Paul Brook <paul at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 15 Feb 2006 03:02:13 +0000
- Subject: Re: [patch] Arm prologe skipping broken on 64-bit hosts
- References: <200602150137.21894.paul@codesourcery.com>
This time with the patch.
On Wednesday 15 February 2006 01:37, Paul Brook wrote:
> The Arm prologue skipping code is broken on 64-bit hosts. The problem is
> that the opcode is loaded as a signed integer, then stored in an "unsigned
> long". This is then compared against unsigned 32-bit constants.
>
> The attached patch fixes this by reading the instruction as an unsigned
> value. For consistency I made the same change in other similar routines.
>
> Tested with cross to arm-none-eabi.
> Ok?
>
> Paul
>
> 2006-02-15 Paul Brook <paul@codesourcery.com>
>
> * arm-tdep.c (arm_skip_prologue, thumb_get_next_pc, arm_get_next_pc):
> Load insn opcodes as unsigned values.
? p
? patches
? bfd/doc/bfd.info
Index: gdb/arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.204
diff -u -p -r1.204 arm-tdep.c
--- gdb/arm-tdep.c 15 Jan 2006 14:51:28 -0000 1.204
+++ gdb/arm-tdep.c 15 Feb 2006 00:49:19 -0000
@@ -360,7 +360,7 @@ arm_skip_prologue (CORE_ADDR pc)
for (skip_pc = pc; skip_pc < func_end; skip_pc += 4)
{
- inst = read_memory_integer (skip_pc, 4);
+ inst = read_memory_unsigned_integer (skip_pc, 4);
/* "mov ip, sp" is no longer a required part of the prologue. */
if (inst == 0xe1a0c00d) /* mov ip, sp */
@@ -1540,7 +1540,7 @@ CORE_ADDR
thumb_get_next_pc (CORE_ADDR pc)
{
unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */
- unsigned short inst1 = read_memory_integer (pc, 2);
+ unsigned short inst1 = read_memory_unsigned_integer (pc, 2);
CORE_ADDR nextpc = pc + 2; /* default is next instruction */
unsigned long offset;
@@ -1552,7 +1552,7 @@ thumb_get_next_pc (CORE_ADDR pc)
all of the other registers. */
offset = bitcount (bits (inst1, 0, 7)) * DEPRECATED_REGISTER_SIZE;
sp = read_register (ARM_SP_REGNUM);
- nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4);
+ nextpc = (CORE_ADDR) read_memory_unsigned_integer (sp + offset, 4);
nextpc = ADDR_BITS_REMOVE (nextpc);
if (nextpc == pc)
error (_("Infinite loop detected"));
@@ -1570,7 +1570,7 @@ thumb_get_next_pc (CORE_ADDR pc)
}
else if ((inst1 & 0xf800) == 0xf000) /* long branch with link, and blx */
{
- unsigned short inst2 = read_memory_integer (pc + 2, 2);
+ unsigned short inst2 = read_memory_unsigned_integer (pc + 2, 2);
offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
nextpc = pc_val + offset;
/* For BLX make sure to clear the low bits. */
@@ -1604,7 +1604,7 @@ arm_get_next_pc (CORE_ADDR pc)
return thumb_get_next_pc (pc);
pc_val = (unsigned long) pc;
- this_instr = read_memory_integer (pc, 4);
+ this_instr = read_memory_unsigned_integer (pc, 4);
status = read_register (ARM_PS_REGNUM);
nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */