This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Arm prologe skipping broken on 64-bit hosts


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 */
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]