* [PATCH v2] Fix interrupt.exp fails with m32 in x86_64
@ 2014-05-06 8:21 Hui Zhu
2014-06-12 8:40 ` Hui Zhu
0 siblings, 1 reply; 2+ messages in thread
From: Hui Zhu @ 2014-05-06 8:21 UTC (permalink / raw)
To: Mark Kettenis, Pedro Alves; +Cc: Hui Zhu, H.Peter Anvin, gdb-patches ml
According to your comments in the discussion thread about Linux kernel
patch. I make a new patch for GDB that let %eax sign-extend if %orig_eax >= 0.
Thanks,
Hui
2014-05-06 Hui Zhu <hui@codesourcery.com>
* amd64-linux-nat.c (fill_gregset): Make %eax
sign-extended if need.
(amd64_linux_store_inferior_registers): Change
amd64_collect_native_gregset to fill_gregset.
* amd64-nat.c (amd64_native_gregset_reg_offset): Remove static.
* amd64-nat.h (amd64_native_gregset_reg_offset): Add extern.
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -128,7 +128,52 @@ void
fill_gregset (const struct regcache *regcache,
elf_gregset_t *gregsetp, int regnum)
{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
amd64_collect_native_gregset (regcache, gregsetp, regnum);
+
+ /* If target arch is 32 bits and GDB interrupt a system call of
+ inferior (%orig_rax >= 0), %rax is the errno of this system call.
+ amd64_collect_native_gregset let %eax zero-extend put %rax from
+ negative to positive.
+ If Linux cannot convert value of %rax back, the system call of
+ inferior will got errno -ERESTARTNOHAND, -ERESTARTSYS, -ERESTARTNOINTR
+ or -ERESTART_RESTARTBLOCK.
+ So if this is a 32 bits system call and fill value to %orig_eax
+ (not %eax to make sure REGCACHE has the right value of %orig_rax)
+ or all registers, let %eax sign-extend. */
+ if (regcache_register_status (regcache, I386_LINUX_ORIG_EAX_REGNUM)
+ == REG_VALID
+ && regcache_register_status (regcache, I386_EAX_REGNUM) == REG_VALID
+ && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32
+ && (regnum == I386_LINUX_ORIG_EAX_REGNUM || regnum == -1))
+ {
+ LONGEST val;
+ gdb_byte buf[MAX_REGISTER_SIZE];
+ int orig_eax_size;
+
+ /* Get value of orig_eax and put it to val. */
+ regcache_raw_collect (regcache, I386_LINUX_ORIG_EAX_REGNUM,
+ buf);
+ orig_eax_size = register_size (gdbarch,
+ I386_LINUX_ORIG_EAX_REGNUM);
+ val = extract_signed_integer (buf, orig_eax_size,
+ gdbarch_byte_order (gdbarch));
+ if (val >= 0)
+ {
+ /* Make %eax get sign-extended to 64 bits. */
+ char *regs = (char *) gregsetp;
+ int offset = amd64_native_gregset_reg_offset (gdbarch,
+ I386_EAX_REGNUM);
+
+ regcache_raw_collect (regcache, I386_EAX_REGNUM,
+ regs + offset);
+ val = extract_signed_integer ((gdb_byte *)(regs + offset), 4,
+ gdbarch_byte_order (gdbarch));
+ store_signed_integer ((gdb_byte *)(regs + offset), 8,
+ gdbarch_byte_order (gdbarch), val);
+ }
+ }
}
/* Transfering floating-point registers between GDB, inferiors and cores. */
@@ -234,7 +279,7 @@ amd64_linux_store_inferior_registers (st
if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0)
perror_with_name (_("Couldn't get registers"));
- amd64_collect_native_gregset (regcache, ®s, regnum);
+ fill_gregset (regcache, ®s, regnum);
if (ptrace (PTRACE_SETREGS, tid, 0, (long) ®s) < 0)
perror_with_name (_("Couldn't write registers"));
--- a/gdb/amd64-nat.c
+++ b/gdb/amd64-nat.c
@@ -51,7 +51,7 @@ int amd64_native_gregset64_num_regs = AM
/* Return the offset of REGNUM within the appropriate native
general-purpose register set. */
-static int
+int
amd64_native_gregset_reg_offset (struct gdbarch *gdbarch, int regnum)
{
int *reg_offset = amd64_native_gregset64_reg_offset;
--- a/gdb/amd64-nat.h
+++ b/gdb/amd64-nat.h
@@ -30,6 +30,12 @@ extern int amd64_native_gregset32_num_re
extern int *amd64_native_gregset64_reg_offset;
extern int amd64_native_gregset64_num_regs;
+/* Return the offset of REGNUM within the appropriate native
+ general-purpose register set. */
+
+extern int amd64_native_gregset_reg_offset (struct gdbarch *gdbarch,
+ int regnum);
+
/* Return whether the native general-purpose register set supplies
register REGNUM. */
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v2] Fix interrupt.exp fails with m32 in x86_64
2014-05-06 8:21 [PATCH v2] Fix interrupt.exp fails with m32 in x86_64 Hui Zhu
@ 2014-06-12 8:40 ` Hui Zhu
0 siblings, 0 replies; 2+ messages in thread
From: Hui Zhu @ 2014-06-12 8:40 UTC (permalink / raw)
To: Hui Zhu; +Cc: Mark Kettenis, Pedro Alves, H.Peter Anvin, gdb-patches ml
Ping.
Thanks,
Hui
On Tue, May 6, 2014 at 4:21 PM, Hui Zhu <hui@codesourcery.com> wrote:
> According to your comments in the discussion thread about Linux kernel
> patch. I make a new patch for GDB that let %eax sign-extend if %orig_eax >= 0.
>
> Thanks,
> Hui
>
> 2014-05-06 Hui Zhu <hui@codesourcery.com>
>
> * amd64-linux-nat.c (fill_gregset): Make %eax
> sign-extended if need.
> (amd64_linux_store_inferior_registers): Change
> amd64_collect_native_gregset to fill_gregset.
> * amd64-nat.c (amd64_native_gregset_reg_offset): Remove static.
> * amd64-nat.h (amd64_native_gregset_reg_offset): Add extern.
>
> --- a/gdb/amd64-linux-nat.c
> +++ b/gdb/amd64-linux-nat.c
> @@ -128,7 +128,52 @@ void
> fill_gregset (const struct regcache *regcache,
> elf_gregset_t *gregsetp, int regnum)
> {
> + struct gdbarch *gdbarch = get_regcache_arch (regcache);
> +
> amd64_collect_native_gregset (regcache, gregsetp, regnum);
> +
> + /* If target arch is 32 bits and GDB interrupt a system call of
> + inferior (%orig_rax >= 0), %rax is the errno of this system call.
> + amd64_collect_native_gregset let %eax zero-extend put %rax from
> + negative to positive.
> + If Linux cannot convert value of %rax back, the system call of
> + inferior will got errno -ERESTARTNOHAND, -ERESTARTSYS, -ERESTARTNOINTR
> + or -ERESTART_RESTARTBLOCK.
> + So if this is a 32 bits system call and fill value to %orig_eax
> + (not %eax to make sure REGCACHE has the right value of %orig_rax)
> + or all registers, let %eax sign-extend. */
> + if (regcache_register_status (regcache, I386_LINUX_ORIG_EAX_REGNUM)
> + == REG_VALID
> + && regcache_register_status (regcache, I386_EAX_REGNUM) == REG_VALID
> + && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32
> + && (regnum == I386_LINUX_ORIG_EAX_REGNUM || regnum == -1))
> + {
> + LONGEST val;
> + gdb_byte buf[MAX_REGISTER_SIZE];
> + int orig_eax_size;
> +
> + /* Get value of orig_eax and put it to val. */
> + regcache_raw_collect (regcache, I386_LINUX_ORIG_EAX_REGNUM,
> + buf);
> + orig_eax_size = register_size (gdbarch,
> + I386_LINUX_ORIG_EAX_REGNUM);
> + val = extract_signed_integer (buf, orig_eax_size,
> + gdbarch_byte_order (gdbarch));
> + if (val >= 0)
> + {
> + /* Make %eax get sign-extended to 64 bits. */
> + char *regs = (char *) gregsetp;
> + int offset = amd64_native_gregset_reg_offset (gdbarch,
> + I386_EAX_REGNUM);
> +
> + regcache_raw_collect (regcache, I386_EAX_REGNUM,
> + regs + offset);
> + val = extract_signed_integer ((gdb_byte *)(regs + offset), 4,
> + gdbarch_byte_order (gdbarch));
> + store_signed_integer ((gdb_byte *)(regs + offset), 8,
> + gdbarch_byte_order (gdbarch), val);
> + }
> + }
> }
>
> /* Transfering floating-point registers between GDB, inferiors and cores. */
> @@ -234,7 +279,7 @@ amd64_linux_store_inferior_registers (st
> if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0)
> perror_with_name (_("Couldn't get registers"));
>
> - amd64_collect_native_gregset (regcache, ®s, regnum);
> + fill_gregset (regcache, ®s, regnum);
>
> if (ptrace (PTRACE_SETREGS, tid, 0, (long) ®s) < 0)
> perror_with_name (_("Couldn't write registers"));
> --- a/gdb/amd64-nat.c
> +++ b/gdb/amd64-nat.c
> @@ -51,7 +51,7 @@ int amd64_native_gregset64_num_regs = AM
> /* Return the offset of REGNUM within the appropriate native
> general-purpose register set. */
>
> -static int
> +int
> amd64_native_gregset_reg_offset (struct gdbarch *gdbarch, int regnum)
> {
> int *reg_offset = amd64_native_gregset64_reg_offset;
> --- a/gdb/amd64-nat.h
> +++ b/gdb/amd64-nat.h
> @@ -30,6 +30,12 @@ extern int amd64_native_gregset32_num_re
> extern int *amd64_native_gregset64_reg_offset;
> extern int amd64_native_gregset64_num_regs;
>
> +/* Return the offset of REGNUM within the appropriate native
> + general-purpose register set. */
> +
> +extern int amd64_native_gregset_reg_offset (struct gdbarch *gdbarch,
> + int regnum);
> +
> /* Return whether the native general-purpose register set supplies
> register REGNUM. */
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-06-12 8:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-06 8:21 [PATCH v2] Fix interrupt.exp fails with m32 in x86_64 Hui Zhu
2014-06-12 8:40 ` Hui Zhu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).