This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
PATCH: Add orig_ax_regnum to i386 gdbarch_tdep
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GDB <gdb-patches at sourceware dot org>
- Date: Mon, 20 Sep 2010 06:14:25 -0700
- Subject: PATCH: Add orig_ax_regnum to i386 gdbarch_tdep
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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. */