[RFA/RFC] Prec multi-thread support [2/4] arch support

Hui Zhu
2009-11-25T08:06:25Z

[-- Attachment #1: Type: text/plain, Size: 9316 bytes --]

1. In record_linux_system_call gdb_sys_clone, I set record_step to 0.
Then the record target will let inferior continue until to a
breakpoint. Most of time, record just let inferior step. But
sys_clone is very special. It cannot work OK with
PTRACE_SINGLESTEP.(It make me hang this patch a log of months.)

2. Add new argument "addr" that point to the next code that need to be
analyzed to linux syscall record function "record_linux_system_call".

2009-11-25 Hui Zhu <teawater@gmail.com>

* amd64-linux-tdep.c (amd64_linux_syscall_record): Add new
argument "addr".
* i386-linux-tdep.c (i386_linux_intx80_sysenter_record): Ditto.
* i386-tdep.c (i386_record_lea_modrm): Add "if (record_debug)"
to segment register warning.
(i386_process_record): Ditto. Add new argument "addr" when
call i386_intx80_record, i386_sysenter_record and
i386_syscall_record.
* i386-tdep.h (gdbarch_tdep): Add new argument "addr" when
call i386_intx80_record, i386_sysenter_record and
i386_syscall_record.
* linux-record.c (inferior.h): New include.
(record_linux_system_call): Add new argument "addr".
Update code for gdb_sys_clone.
* linux-record.h (record_linux_system_call): Add new argument
"addr".

---
amd64-linux-tdep.c | 4 ++--
i386-linux-tdep.c | 4 ++--
i386-tdep.c | 52 +++++++++++++++++++++++++++++-----------------------
i386-tdep.h | 6 +++---
linux-record.c | 13 +++++++++----
linux-record.h | 2 +-
6 files changed, 46 insertions(+), 35 deletions(-)

--- a/amd64-linux-tdep.c
+++ b/amd64-linux-tdep.c
@@ -1155,7 +1155,7 @@ static struct linux_record_tdep amd64_li
#define RECORD_ARCH_GET_GS 0x1004

static int
-amd64_linux_syscall_record (struct regcache *regcache)
+amd64_linux_syscall_record (struct regcache *regcache, CORE_ADDR addr)
{
int ret;
ULONGEST syscall_native;
@@ -1205,7 +1205,7 @@ amd64_linux_syscall_record (struct regca
}
else
{
- ret = record_linux_system_call (syscall_gdb, regcache,
+ ret = record_linux_system_call (syscall_gdb, addr, regcache,
&amd64_linux_record_tdep);
if (ret)
return ret;
--- a/i386-linux-tdep.c
+++ b/i386-linux-tdep.c
@@ -411,7 +411,7 @@ i386_canonicalize_syscall (int syscall)
static struct linux_record_tdep i386_linux_record_tdep;

static int
-i386_linux_intx80_sysenter_record (struct regcache *regcache)
+i386_linux_intx80_sysenter_record (struct regcache *regcache, CORE_ADDR addr)
{
int ret;
LONGEST syscall_native;
@@ -437,7 +437,7 @@ i386_linux_intx80_sysenter_record (struc
return 0;
}

- ret = record_linux_system_call (syscall_gdb, regcache,
+ ret = record_linux_system_call (syscall_gdb, addr, regcache,
&i386_linux_record_tdep);
if (ret)
return ret;
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -3160,10 +3160,11 @@ i386_record_lea_modrm (struct i386_recor

if (irp->override >= 0)
{
- warning (_("Process record ignores the memory change "
- "of instruction at address %s because it "
- "can't get the value of the segment register."),
- paddress (gdbarch, irp->orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory change "
+ "of instruction at address %s because it "
+ "can't get the value of the segment register."),
+ paddress (gdbarch, irp->orig_addr));
return 0;
}

@@ -4042,11 +4043,12 @@ reswitch:
case 0xa3:
if (ir.override >= 0)
{
- warning (_("Process record ignores the memory change "
- "of instruction at address %s because "
- "it can't get the value of the segment "
- "register."),
- paddress (gdbarch, ir.orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory change "
+ "of instruction at address %s because "
+ "it can't get the value of the segment "
+ "register."),
+ paddress (gdbarch, ir.orig_addr));
}
else
{
@@ -4467,11 +4469,12 @@ reswitch:
if (ir.aflag && (es != ds))
{
/* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
- warning (_("Process record ignores the memory "
- "change of instruction at address %s "
- "because it can't get the value of the "
- "ES segment register."),
- paddress (gdbarch, ir.orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory "
+ "change of instruction at address %s "
+ "because it can't get the value of the "
+ "ES segment register."),
+ paddress (gdbarch, ir.orig_addr));
}
else
{
@@ -4872,7 +4875,7 @@ reswitch:
ir.addr -= 2;
goto no_support;
}
- ret = gdbarch_tdep (gdbarch)->i386_intx80_record (ir.regcache);
+ ret = gdbarch_tdep (gdbarch)->i386_intx80_record (ir.regcache, ir.addr);
if (ret)
return ret;
}
@@ -4974,7 +4977,8 @@ reswitch:
ir.addr -= 2;
goto no_support;
}
- ret = gdbarch_tdep (gdbarch)->i386_sysenter_record (ir.regcache);
+ ret = gdbarch_tdep (gdbarch)->i386_sysenter_record (ir.regcache,
+ ir.addr);
if (ret)
return ret;
}
@@ -4999,7 +5003,8 @@ reswitch:
ir.addr -= 2;
goto no_support;
}
- ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache);
+ ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache,
+ ir.addr);
if (ret)
return ret;
}
@@ -5135,12 +5140,13 @@ reswitch:
/* sidt */
if (ir.override >= 0)
{
- warning (_("Process record ignores the memory "
- "change of instruction at "
- "address %s because it can't get "
- "the value of the segment "
- "register."),
- paddress (gdbarch, ir.orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory "
+ "change of instruction at "
+ "address %s because it can't get "
+ "the value of the segment "
+ "register."),
+ paddress (gdbarch, ir.orig_addr));
}
else
{
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -115,11 +115,11 @@ struct gdbarch_tdep
in GDB is not same as I386 instructions. */
const int *record_regmap;
/* Parse intx80 args. */
- int (*i386_intx80_record) (struct regcache *regcache);
+ int (*i386_intx80_record) (struct regcache *regcache, CORE_ADDR addr);
/* Parse sysenter args. */
- int (*i386_sysenter_record) (struct regcache *regcache);
+ int (*i386_sysenter_record) (struct regcache *regcache, CORE_ADDR addr);
/* Parse syscall args. */
- int (*i386_syscall_record) (struct regcache *regcache);
+ int (*i386_syscall_record) (struct regcache *regcache, CORE_ADDR addr);
};

/* Floating-point registers. */
--- a/linux-record.c
+++ b/linux-record.c
@@ -21,6 +21,7 @@
#include "target.h"
#include "gdbtypes.h"
#include "regcache.h"
+#include "inferior.h"
#include "record.h"
#include "linux-record.h"

@@ -222,7 +223,7 @@ record_linux_msghdr (struct regcache *re
Return -1 if something wrong. */

int
-record_linux_system_call (enum gdb_syscall syscall,
+record_linux_system_call (enum gdb_syscall syscall, CORE_ADDR addr,
struct regcache *regcache,
struct linux_record_tdep *tdep)
{
@@ -242,8 +243,9 @@ record_linux_system_call (enum gdb_sysca
int q;
target_terminal_ours ();
q = yquery (_("The next instruction is syscall exit. "
- "It will make the program exit. "
- "Do you want to stop the program?"));
+ "It will make the thread %s exit. "
+ "Do you want to stop the program?"),
+ target_pid_to_str (inferior_ptid));
target_terminal_inferior ();
if (q)
return 1;
@@ -1209,10 +1211,13 @@ record_linux_system_call (enum gdb_sysca

case gdb_sys_fsync:
case gdb_sys_sigreturn:
- case gdb_sys_clone:
case gdb_sys_setdomainname:
break;

+ case gdb_sys_clone:
+ record_step = 0;
+ break;
+
case gdb_sys_newuname:
regcache_raw_read_unsigned (regcache, tdep->arg1, &tmpulongest);
if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest,
--- a/linux-record.h
+++ b/linux-record.h
@@ -534,7 +534,7 @@ enum gdb_syscall {

/* Record a linux syscall. */

-extern int record_linux_system_call (enum gdb_syscall num,
+extern int record_linux_system_call (enum gdb_syscall num, CORE_ADDR addr,
struct regcache *regcache,
struct linux_record_tdep *tdep);
#endif /* _LINUX_RECORD_H_ */

[-- Attachment #2: prec-thread-arch.txt --]
[-- Type: text/plain, Size: 8127 bytes --]

---
amd64-linux-tdep.c | 4 ++--
i386-linux-tdep.c | 4 ++--
i386-tdep.c | 52 +++++++++++++++++++++++++++++-----------------------
i386-tdep.h | 6 +++---
linux-record.c | 13 +++++++++----
linux-record.h | 2 +-
6 files changed, 46 insertions(+), 35 deletions(-)

--- a/amd64-linux-tdep.c
+++ b/amd64-linux-tdep.c
@@ -1155,7 +1155,7 @@ static struct linux_record_tdep amd64_li
#define RECORD_ARCH_GET_GS 0x1004

static int
-amd64_linux_syscall_record (struct regcache *regcache)
+amd64_linux_syscall_record (struct regcache *regcache, CORE_ADDR addr)
{
int ret;
ULONGEST syscall_native;
@@ -1205,7 +1205,7 @@ amd64_linux_syscall_record (struct regca
}
else
{
- ret = record_linux_system_call (syscall_gdb, regcache,
+ ret = record_linux_system_call (syscall_gdb, addr, regcache,
&amd64_linux_record_tdep);
if (ret)
return ret;
--- a/i386-linux-tdep.c
+++ b/i386-linux-tdep.c
@@ -411,7 +411,7 @@ i386_canonicalize_syscall (int syscall)
static struct linux_record_tdep i386_linux_record_tdep;

static int
-i386_linux_intx80_sysenter_record (struct regcache *regcache)
+i386_linux_intx80_sysenter_record (struct regcache *regcache, CORE_ADDR addr)
{
int ret;
LONGEST syscall_native;
@@ -437,7 +437,7 @@ i386_linux_intx80_sysenter_record (struc
return 0;
}

- ret = record_linux_system_call (syscall_gdb, regcache,
+ ret = record_linux_system_call (syscall_gdb, addr, regcache,
&i386_linux_record_tdep);
if (ret)
return ret;
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -3160,10 +3160,11 @@ i386_record_lea_modrm (struct i386_recor

if (irp->override >= 0)
{
- warning (_("Process record ignores the memory change "
- "of instruction at address %s because it "
- "can't get the value of the segment register."),
- paddress (gdbarch, irp->orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory change "
+ "of instruction at address %s because it "
+ "can't get the value of the segment register."),
+ paddress (gdbarch, irp->orig_addr));
return 0;
}

@@ -4042,11 +4043,12 @@ reswitch:
case 0xa3:
if (ir.override >= 0)
{
- warning (_("Process record ignores the memory change "
- "of instruction at address %s because "
- "it can't get the value of the segment "
- "register."),
- paddress (gdbarch, ir.orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory change "
+ "of instruction at address %s because "
+ "it can't get the value of the segment "
+ "register."),
+ paddress (gdbarch, ir.orig_addr));
}
else
{
@@ -4467,11 +4469,12 @@ reswitch:
if (ir.aflag && (es != ds))
{
/* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
- warning (_("Process record ignores the memory "
- "change of instruction at address %s "
- "because it can't get the value of the "
- "ES segment register."),
- paddress (gdbarch, ir.orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory "
+ "change of instruction at address %s "
+ "because it can't get the value of the "
+ "ES segment register."),
+ paddress (gdbarch, ir.orig_addr));
}
else
{
@@ -4872,7 +4875,7 @@ reswitch:
ir.addr -= 2;
goto no_support;
}
- ret = gdbarch_tdep (gdbarch)->i386_intx80_record (ir.regcache);
+ ret = gdbarch_tdep (gdbarch)->i386_intx80_record (ir.regcache, ir.addr);
if (ret)
return ret;
}
@@ -4974,7 +4977,8 @@ reswitch:
ir.addr -= 2;
goto no_support;
}
- ret = gdbarch_tdep (gdbarch)->i386_sysenter_record (ir.regcache);
+ ret = gdbarch_tdep (gdbarch)->i386_sysenter_record (ir.regcache,
+ ir.addr);
if (ret)
return ret;
}
@@ -4999,7 +5003,8 @@ reswitch:
ir.addr -= 2;
goto no_support;
}
- ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache);
+ ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache,
+ ir.addr);
if (ret)
return ret;
}
@@ -5135,12 +5140,13 @@ reswitch:
/* sidt */
if (ir.override >= 0)
{
- warning (_("Process record ignores the memory "
- "change of instruction at "
- "address %s because it can't get "
- "the value of the segment "
- "register."),
- paddress (gdbarch, ir.orig_addr));
+ if (record_debug)
+ warning (_("Process record ignores the memory "
+ "change of instruction at "
+ "address %s because it can't get "
+ "the value of the segment "
+ "register."),
+ paddress (gdbarch, ir.orig_addr));
}
else
{
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -115,11 +115,11 @@ struct gdbarch_tdep
in GDB is not same as I386 instructions. */
const int *record_regmap;
/* Parse intx80 args. */
- int (*i386_intx80_record) (struct regcache *regcache);
+ int (*i386_intx80_record) (struct regcache *regcache, CORE_ADDR addr);
/* Parse sysenter args. */
- int (*i386_sysenter_record) (struct regcache *regcache);
+ int (*i386_sysenter_record) (struct regcache *regcache, CORE_ADDR addr);
/* Parse syscall args. */
- int (*i386_syscall_record) (struct regcache *regcache);
+ int (*i386_syscall_record) (struct regcache *regcache, CORE_ADDR addr);
};

/* Floating-point registers. */
--- a/linux-record.c
+++ b/linux-record.c
@@ -21,6 +21,7 @@
#include "target.h"
#include "gdbtypes.h"
#include "regcache.h"
+#include "inferior.h"
#include "record.h"
#include "linux-record.h"

@@ -222,7 +223,7 @@ record_linux_msghdr (struct regcache *re
Return -1 if something wrong. */

int
-record_linux_system_call (enum gdb_syscall syscall,
+record_linux_system_call (enum gdb_syscall syscall, CORE_ADDR addr,
struct regcache *regcache,
struct linux_record_tdep *tdep)
{
@@ -242,8 +243,9 @@ record_linux_system_call (enum gdb_sysca
int q;
target_terminal_ours ();
q = yquery (_("The next instruction is syscall exit. "
- "It will make the program exit. "
- "Do you want to stop the program?"));
+ "It will make the thread %s exit. "
+ "Do you want to stop the program?"),
+ target_pid_to_str (inferior_ptid));
target_terminal_inferior ();
if (q)
return 1;
@@ -1209,10 +1211,13 @@ record_linux_system_call (enum gdb_sysca

case gdb_sys_fsync:
case gdb_sys_sigreturn:
- case gdb_sys_clone:
case gdb_sys_setdomainname:
break;

+ case gdb_sys_clone:
+ record_step = 0;
+ break;
+
case gdb_sys_newuname:
regcache_raw_read_unsigned (regcache, tdep->arg1, &tmpulongest);
if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest,
--- a/linux-record.h
+++ b/linux-record.h
@@ -534,7 +534,7 @@ enum gdb_syscall {

/* Record a linux syscall. */

-extern int record_linux_system_call (enum gdb_syscall num,
+extern int record_linux_system_call (enum gdb_syscall num, CORE_ADDR addr,
struct regcache *regcache,
struct linux_record_tdep *tdep);
#endif /* _LINUX_RECORD_H_ */