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]

[PATCH] Fix TBB TBH decoding in Thumb-2


I discovered today that the TBB and TBH instructions weren't being
correctly decoded when single-stepping thumb-2 code.  It turned out to
be two problems.  Firstly TBH was being incorrectly tested for (actually
matching a TBB opcode.  Secondly, both TBB and TBH were using the wrong
base address for the jump when the base register was the PC (using the
current PC value rather than PC+4).

Fixed thusly:

2010-03-31  Richard Earnshaw  <rearnsha@arm.com>

	* arm-tdep.c (thumb_get_next_pc_raw): Correctly detect TBH
	instructions.  Use the PC+4 if the base of the TBB or TBH is the 
	PC register.
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.301
diff -p -r1.301 arm-tdep.c
*** arm-tdep.c	24 Mar 2010 20:23:13 -0000	1.301
--- arm-tdep.c	31 Mar 2010 22:07:34 -0000
*************** thumb_get_next_pc_raw (struct frame_info
*** 2959,2977 ****
        else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
  	{
  	  /* TBB.  */
! 	  CORE_ADDR table, offset, length;
  
- 	  table = get_frame_register_unsigned (frame, bits (inst1, 0, 3));
  	  offset = get_frame_register_unsigned (frame, bits (inst2, 0, 3));
  	  length = 2 * get_frame_memory_unsigned (frame, table + offset, 1);
  	  nextpc = pc_val + length;
  	}
!       else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
  	{
  	  /* TBH.  */
! 	  CORE_ADDR table, offset, length;
  
- 	  table = get_frame_register_unsigned (frame, bits (inst1, 0, 3));
  	  offset = 2 * get_frame_register_unsigned (frame, bits (inst2, 0, 3));
  	  length = 2 * get_frame_memory_unsigned (frame, table + offset, 2);
  	  nextpc = pc_val + length;
--- 2959,2987 ----
        else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
  	{
  	  /* TBB.  */
! 	  CORE_ADDR tbl_reg, table, offset, length;
! 
! 	  tbl_reg = bits (inst1, 0, 3);
! 	  if (tbl_reg == 0x0f)
! 	    table = pc + 4;  /* Regcache copy of PC isn't right yet.  */
! 	  else
! 	    table = get_frame_register_unsigned (frame, tbl_reg);
  
  	  offset = get_frame_register_unsigned (frame, bits (inst2, 0, 3));
  	  length = 2 * get_frame_memory_unsigned (frame, table + offset, 1);
  	  nextpc = pc_val + length;
  	}
!       else if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010)
  	{
  	  /* TBH.  */
! 	  CORE_ADDR tbl_reg, table, offset, length;
! 
! 	  tbl_reg = bits (inst1, 0, 3);
! 	  if (tbl_reg == 0x0f)
! 	    table = pc + 4;  /* Regcache copy of PC isn't right yet.  */
! 	  else
! 	    table = get_frame_register_unsigned (frame, tbl_reg);
  
  	  offset = 2 * get_frame_register_unsigned (frame, bits (inst2, 0, 3));
  	  length = 2 * get_frame_memory_unsigned (frame, table + offset, 2);
  	  nextpc = pc_val + length;

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