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]

[rfa] Update PC without side effect in displaced stepping


During preparation of displaced stepping (in displaced_step_prepare),
regcache_write_pc is called to update PC to the address of copy area,
and gdbarch_write_pc is called subsequently.  However, gdbarch_write_pc
has some side effects besides updating PC values.

As far as I know on updating PC in displaced_step_prepare, what we need
here is to force program to execute one or some instructions in copy
area, and get the *same* effect of single-step one instruction on
original place, so we should update PC without any side effect.

Current approach may have some drawbacks in some cases.  For example, on
ARM, system library is compiled in Thumb mode, and application is
compiled in ARM mode.  The copy area for displaced stepping is in thumb
mode.  During displaced stepping, GDB copies that ARM instruction to
copy area, and using regcache_write_pc to update PC to the new address
of this instruction.  Due to the side effect of arm_write_pc, the T bit
is set in status register, so one 32-bit ARM instruction is interpreted
as two 16-bit thumb instructions by mistake.

This patch is to fix this problem.  Regression tested on x86_64-linux.
OK for mainline?

-- 
Yao (éå)
2010-12-20  Yao Qi  <yao@codesourcery.com>

	* infrun.c (displaced_step_prepare): Replace regcache_write_pc by
	regcache_cooked_write_unsigned to update PC without side effect.

diff --git a/gdb/infrun.c b/gdb/infrun.c
index 1bc00a4..2711e19 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1304,8 +1304,13 @@ displaced_step_prepare (ptid_t ptid)
 
   make_cleanup (displaced_step_clear_cleanup, displaced);
 
-  /* Resume execution at the copy.  */
-  regcache_write_pc (regcache, copy);
+  /* Resume execution at the copy.  Update PC without any side effects.  */
+  if (gdbarch_pc_regnum (gdbarch) >= 0)
+    regcache_cooked_write_unsigned (regcache,
+				    gdbarch_pc_regnum (gdbarch), copy);
+  else
+    internal_error (__FILE__, __LINE__,
+		    _("displaced: Unable to update PC"));
 
   discard_cleanups (ignore_cleanups);
 

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