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: Add orig_ax_regnum to i386 gdbarch_tdep


Hi,

This patch adds orig_ax_regnum to i386 gdbarch_tdep so that we can
remove amd64_linux_get_syscall_number, amd64_linux_register_reggroup_p
and amd64_linux_write_pc.  OK to install?

Thanks.


H.J.
--
2010-09-20  H.J. Lu  <hongjiu.lu@intel.com>

	* amd64-linux-tdep.c (amd64_linux_get_syscall_number): Removed.
	(amd64_linux_register_reggroup_p): Likewise.
	(amd64_linux_write_pc): Likewise.
	(amd64_linux_init_abi): Set orig_ax_regnum.  Replace
	amd64_linux_write_pc with i386_linux_write_pc.  Replace
	amd64_linux_register_reggroup_p with
	i386_linux_register_reggroup_p.  Replace
	amd64_linux_get_syscall_number with i386_linux_get_syscall_number.

	* i386-linux-tdep.c (i386_linux_register_reggroup_p): Make it
	global.  Replace I386_LINUX_ORIG_EAX_REGNUM with orig_ax_regnum.
	(i386_linux_write_pc): Make it global.  Replace
	I386_EIP_REGNUM with gdbarch_pc_regnum.  Replace
	I386_LINUX_ORIG_EAX_REGNUM with orig_ax_regnum.
	(i386_linux_get_syscall_number): Make it global.  Replace
	I386_LINUX_ORIG_EAX_REGNUM with orig_ax_regnum.
	(i386_linux_init_abi): Set orig_ax_regnum.

	* i386-linux-tdep.h (i386_linux_register_reggroup_p): New
	prototype.
	(i386_linux_get_syscall_number): Likewise.
	(i386_linux_write_pc): Likewise.

	* i386-tdep.c (i386_gdbarch_init): Initialize orig_ax_regnum
	to -1.

	* i386-tdep.h (gdbarch_tdep): Add orig_ax_regnum.

diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index a1f9db3..a9768bf 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -199,29 +199,6 @@ amd64_linux_sigcontext_addr (struct frame_info *this_frame)
   return sp + AMD64_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
 }
 
-
-static LONGEST
-amd64_linux_get_syscall_number (struct gdbarch *gdbarch,
-                                ptid_t ptid)
-{
-  struct regcache *regcache = get_thread_regcache (ptid);
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  /* The content of a register.  */
-  gdb_byte buf[8];
-  /* The result.  */
-  LONGEST ret;
-
-  /* Getting the system call number from the register.
-     When dealing with x86_64 architecture, this information
-     is stored at %rax register.  */
-  regcache_cooked_read (regcache, AMD64_LINUX_ORIG_RAX_REGNUM, buf);
-
-  ret = extract_signed_integer (buf, 8, byte_order);
-
-  return ret;
-}
-
-
 /* From <asm/sigcontext.h>.  */
 static int amd64_linux_sc_reg_offset[] =
 {
@@ -256,41 +233,6 @@ static int amd64_linux_sc_reg_offset[] =
   -1				/* %gs */
 };
 
-static int
-amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-				 struct reggroup *group)
-{ 
-  if (regnum == AMD64_LINUX_ORIG_RAX_REGNUM)
-    return (group == system_reggroup
-            || group == save_reggroup
-            || group == restore_reggroup);
-  return i386_register_reggroup_p (gdbarch, regnum, group);
-}
-
-/* Set the program counter for process PTID to PC.  */
-
-static void
-amd64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
-{
-  regcache_cooked_write_unsigned (regcache, AMD64_RIP_REGNUM, pc);
-
-  /* We must be careful with modifying the program counter.  If we
-     just interrupted a system call, the kernel might try to restart
-     it when we resume the inferior.  On restarting the system call,
-     the kernel will try backing up the program counter even though it
-     no longer points at the system call.  This typically results in a
-     SIGSEGV or SIGILL.  We can prevent this by writing `-1' in the
-     "orig_rax" pseudo-register.
-
-     Note that "orig_rax" is saved when setting up a dummy call frame.
-     This means that it is properly restored when that frame is
-     popped, and that the interrupted system call will be restarted
-     when we resume the inferior on return from a function call from
-     within GDB.  In all other cases the system call will not be
-     restarted.  */
-  regcache_cooked_write_unsigned (regcache, AMD64_LINUX_ORIG_RAX_REGNUM, -1);
-}
-
 /* Record all registers but IP register for process-record.  */
 
 static int
@@ -1301,6 +1243,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Reserve a number for orig_rax.  */
   set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
+  tdep->orig_ax_regnum = AMD64_LINUX_ORIG_RAX_REGNUM;
 
   if (! tdesc_has_registers (tdesc))
     tdesc = tdesc_amd64_linux;
@@ -1311,8 +1254,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     return;
 
   valid_p = tdesc_numbered_register (feature, tdesc_data,
-				     AMD64_LINUX_ORIG_RAX_REGNUM,
-				     "orig_rax");
+				     tdep->orig_ax_regnum, "orig_rax");
   if (!valid_p)
     return;
 
@@ -1328,14 +1270,14 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     (gdbarch, svr4_lp64_fetch_link_map_offsets);
 
   /* Add the %orig_rax register used for syscall restarting.  */
-  set_gdbarch_write_pc (gdbarch, amd64_linux_write_pc);
+  set_gdbarch_write_pc (gdbarch, i386_linux_write_pc);
 
-  tdep->register_reggroup_p = amd64_linux_register_reggroup_p;
+  tdep->register_reggroup_p = i386_linux_register_reggroup_p;
 
   /* Functions for 'catch syscall'.  */
   set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64);
   set_gdbarch_get_syscall_number (gdbarch,
-                                  amd64_linux_get_syscall_number);
+                                  i386_linux_get_syscall_number);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 7b4a641..ba3a056 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -76,12 +76,13 @@ static struct core_regset_section i386_linux_avx_regset_sections[] =
 };
 
 /* Return non-zero, when the register is in the corresponding register
-   group.  Put the LINUX_ORIG_EAX register in the system group.  */
-static int
+   group.  Put the "orig_eax" register in the system group.  */
+int
 i386_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 				struct reggroup *group)
 {
-  if (regnum == I386_LINUX_ORIG_EAX_REGNUM)
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  if (regnum == tdep->orig_ax_regnum)
     return (group == system_reggroup
 	    || group == save_reggroup
 	    || group == restore_reggroup);
@@ -344,10 +345,14 @@ i386_linux_sigcontext_addr (struct frame_info *this_frame)
 
 /* Set the program counter for process PTID to PC.  */
 
-static void
+void
 i386_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  regcache_cooked_write_unsigned (regcache, I386_EIP_REGNUM, pc);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  regcache_cooked_write_unsigned (regcache, gdbarch_pc_regnum (gdbarch),
+				  pc);
 
   /* We must be careful with modifying the program counter.  If we
      just interrupted a system call, the kernel might try to restart
@@ -363,7 +368,7 @@ i386_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
      when we resume the inferior on return from a function call from
      within GDB.  In all other cases the system call will not be
      restarted.  */
-  regcache_cooked_write_unsigned (regcache, I386_LINUX_ORIG_EAX_REGNUM, -1);
+  regcache_cooked_write_unsigned (regcache, tdep->orig_ax_regnum, -1);
 }
 
 /* Record all registers but IP register for process-record.  */
@@ -492,23 +497,25 @@ i386_linux_record_signal (struct gdbarch *gdbarch,
 }
 
 
-static LONGEST
+LONGEST
 i386_linux_get_syscall_number (struct gdbarch *gdbarch,
                                ptid_t ptid)
 {
   struct regcache *regcache = get_thread_regcache (ptid);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   /* The content of a register.  */
-  gdb_byte buf[4];
+  int ptr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+  gdb_byte *buf = alloca (ptr_size);
   /* The result.  */
   LONGEST ret;
 
   /* Getting the system call number from the register.
      When dealing with x86 architecture, this information
      is stored at %eax register.  */
-  regcache_cooked_read (regcache, I386_LINUX_ORIG_EAX_REGNUM, buf);
+  regcache_cooked_read (regcache, tdep->orig_ax_regnum, buf);
 
-  ret = extract_signed_integer (buf, 4, byte_order);
+  ret = extract_signed_integer (buf, ptr_size, byte_order);
 
   return ret;
 }
@@ -661,6 +668,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Reserve a number for orig_eax.  */
   set_gdbarch_num_regs (gdbarch, I386_LINUX_NUM_REGS);
+  tdep->orig_ax_regnum = I386_LINUX_ORIG_EAX_REGNUM;
 
   if (! tdesc_has_registers (tdesc))
     tdesc = tdesc_i386_linux;
@@ -671,8 +679,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     return;
 
   valid_p = tdesc_numbered_register (feature, tdesc_data,
-				     I386_LINUX_ORIG_EAX_REGNUM,
-				     "orig_eax");
+				     tdep->orig_ax_regnum, "orig_eax");
   if (!valid_p)
     return;
 
diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
index c2291b0..5def22d 100644
--- a/gdb/i386-linux-tdep.h
+++ b/gdb/i386-linux-tdep.h
@@ -66,5 +66,9 @@ extern struct target_desc *tdesc_i386_avx_linux;
 #define I386_LINUX_XSAVE_XCR0_OFFSET 464
 
 extern int i386_linux_gregset_reg_offset[];
+extern int i386_linux_register_reggroup_p (struct gdbarch *, int,
+					   struct reggroup *);
+extern LONGEST i386_linux_get_syscall_number (struct gdbarch *, ptid_t);
+extern void i386_linux_write_pc (struct regcache *, CORE_ADDR);
 
 #endif /* i386-linux-tdep.h */
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 4016a70..7d98759 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -6930,6 +6930,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   tdep->xsave_xcr0_offset = -1;
 
+  /* No orig_eax/orig_rax support.  */
+  tdep->orig_ax_regnum = -1;
+
   tdep->record_regmap = i386_record_regmap;
 
   /* The format used for `long double' on almost all i386 targets is
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 4d0bae7..700a565 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -112,6 +112,10 @@ struct gdbarch_tdep
   /* XSAVE extended state.  */
   struct regset *xstateregset;
 
+  /* Register number for %orig_eax/orig_rax.  Set this to -1 to indicate
+     the absence of orig_eax/orig_rax support.  */
+  int orig_ax_regnum;
+
   /* Register number for %st(0).  The register numbers for the other
      registers follow from this one.  Set this to -1 to indicate the
      absence of an FPU.  */


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