* [RFA][PATCH v4 0/5] Add TDB regset support
@ 2013-07-03 16:57 Andreas Arnez
2013-07-03 17:00 ` [RFA][PATCH v4 1/5] S/390 regmap rework Andreas Arnez
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: Andreas Arnez @ 2013-07-03 16:57 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
This is another iteration of GDB support for the "transaction diagnostic
block", TDB, which is provided by the transactional-execution facility
in newer z/Architecture systems.
There was some discussion on previous versions of this patch,
specifically about the part that introduces dynamic core file register
notes support. Thus this version continues supporting the old "static"
interface. Also, the architecture-specific patches are now separated
out for easier review.
NEWS | 4
corelow.c | 42 +--
doc/gdb.texinfo | 38 ++
features/Makefile | 3
gdbarch.c | 35 ++
gdbarch.h | 19 +
gdbarch.sh | 36 +-
gdbserver/Makefile.in | 7
gdbserver/configure.srv | 5
gdbserver/linux-s390-low.c | 25 +
linux-tdep.c | 103 ++++---
ppc-linux-tdep.c | 93 +------
regset.c | 22 +
regset.h | 7
s390-nat.c | 256 +++++++++----------
s390-tdep.c | 590 +++++++++++++++++++++------------------------
s390-tdep.h | 60 ++++
17 files changed, 739 insertions(+), 606 deletions(-)
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFA][PATCH v4 1/5] S/390 regmap rework
2013-07-03 16:57 [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
@ 2013-07-03 17:00 ` Andreas Arnez
2013-07-15 14:46 ` Luis Machado
2013-07-03 17:02 ` [RFA][PATCH v4 2/5] S/390: Add TDB regset Andreas Arnez
` (4 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Andreas Arnez @ 2013-07-03 17:00 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
S/390 regmap rework: Represent register maps in a less redundant and
more readable way. Also remove some code repetition.
2013-07-03 Andreas Arnez <arnez@linux.vnet.ibm.com>
* s390-tdep.h (S390_IS_GREGSET_REGNUM): New macro.
(S390_IS_FPREGSET_REGNUM): New macro.
* s390-tdep.c (s390_dwarf_regmap): Make const.
(regnum_is_gpr_full): New function for replacing repeated code.
(s390_pseudo_register_name): Use it.
(s390_pseudo_register_type): Likewise.
(s390_pseudo_register_read): Likewise.
(s390_pseudo_register_write): Likewise.
(s390_unwind_pseudo_register): Likewise.
(s390_regmap_gregset): New format for regmap.
(s390x_regmap_gregset): Likewise.
(s390_regmap_fpregset): Likewise.
(s390_regmap_upper): Likewise.
(s390_regmap_last_break): Likewise.
(s390_regmap_system_call): Likewise.
(s390_supply_regset): Adjust to new regmap format.
(s390_collect_regset): Likewise.
* s390-nat.c (s390_native_supply): Adjust to new regmap format.
(s390_native_collect): Likewise.
(supply_gregset): Likewise.
(fill_gregset): Likewise.
(supply_fpregset): Likewise.
(fill_fpregset): Likewise.
(fetch_regset): Likewise.
(store_regset): Likewise.
(s390_linux_fetch_inferior_registers): Likewise.
(s390_linux_fetch_inferior_registers): Likewise.
Index: gdb/gdb/s390-tdep.h
===================================================================
--- gdb.orig/gdb/s390-tdep.h
+++ gdb/gdb/s390-tdep.h
@@ -106,16 +106,24 @@
#define S390_RETADDR_REGNUM S390_R14_REGNUM
#define S390_FRAME_REGNUM S390_R11_REGNUM
+#define S390_IS_GREGSET_REGNUM(i) \
+ (((i) >= S390_PSWM_REGNUM && (i) <= S390_A15_REGNUM) \
+ || ((i) >= S390_R0_UPPER_REGNUM && (i) <= S390_R15_UPPER_REGNUM) \
+ || (i) == S390_ORIG_R2_REGNUM)
+
+#define S390_IS_FPREGSET_REGNUM(i) \
+ ((i) >= S390_FPC_REGNUM && (i) <= S390_F15_REGNUM)
+
/* Core file register sets, defined in s390-tdep.c. */
#define s390_sizeof_gregset 0x90
-extern int s390_regmap_gregset[S390_NUM_REGS];
+extern const short s390_regmap_gregset[];
#define s390x_sizeof_gregset 0xd8
-extern int s390x_regmap_gregset[S390_NUM_REGS];
+extern const short s390x_regmap_gregset[];
#define s390_sizeof_fpregset 0x88
-extern int s390_regmap_fpregset[S390_NUM_REGS];
-extern int s390_regmap_last_break[S390_NUM_REGS];
-extern int s390x_regmap_last_break[S390_NUM_REGS];
-extern int s390_regmap_system_call[S390_NUM_REGS];
+extern const short s390_regmap_fpregset[];
+extern const short s390_regmap_last_break[];
+extern const short s390x_regmap_last_break[];
+extern const short s390_regmap_system_call[];
/* GNU/Linux target descriptions. */
extern struct target_desc *tdesc_s390_linux32;
Index: gdb/gdb/s390-nat.c
===================================================================
--- gdb.orig/gdb/s390-nat.c
+++ gdb/gdb/s390-nat.c
@@ -63,139 +63,129 @@ static int have_regset_system_call = 0;
#define regmap_fpregset s390_regmap_fpregset
-/* When debugging a 32-bit executable running under a 64-bit kernel,
- we have to fix up the 64-bit registers we get from the kernel
- to make them look like 32-bit registers. */
+static void
+s390_native_supply (struct regcache *regcache, const short *map,
+ const gdb_byte *regp)
+{
+ for (; map[0] >= 0; map += 2)
+ regcache_raw_supply (regcache, map[1], regp + map[0]);
+}
static void
-s390_native_supply (struct regcache *regcache, int regno,
- const gdb_byte *regp, int *regmap)
+s390_native_collect (const struct regcache *regcache, const short *map,
+ int regno, gdb_byte *regp)
{
- int offset = regmap[regno];
+ for (; map[0] >= 0; map += 2)
+ if (regno == -1 || regno == map[1])
+ regcache_raw_collect (regcache, map[1], regp + map[0]);
+}
+
+/* Fill GDB's register array with the general-purpose register values
+ in *REGP.
+ When debugging a 32-bit executable running under a 64-bit kernel,
+ we have to fix up the 64-bit registers we get from the kernel to
+ make them look like 32-bit registers. */
+void
+supply_gregset (struct regcache *regcache, const gregset_t *regp)
+{
#ifdef __s390x__
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
+ if (gdbarch_ptr_bit (gdbarch) == 32)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ ULONGEST pswm = 0, pswa = 0;
+ gdb_byte buf[4];
+ const short *map;
- if (regno == S390_PSWM_REGNUM)
- {
- ULONGEST pswm;
- gdb_byte buf[4];
-
- pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
- 8, byte_order);
-
- store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
- regcache_raw_supply (regcache, regno, buf);
- return;
- }
-
- if (regno == S390_PSWA_REGNUM)
+ for (map = regmap_gregset; map[0] >= 0; map += 2)
{
- ULONGEST pswm, pswa;
- gdb_byte buf[4];
+ const gdb_byte *p = (const gdb_byte *) regp + map[0];
+ int regno = map[1];
- pswa = extract_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
- 8, byte_order);
- pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
- 8, byte_order);
-
- store_unsigned_integer (buf, 4, byte_order,
- (pswa & 0x7fffffff) | (pswm & 0x80000000));
- regcache_raw_supply (regcache, regno, buf);
- return;
+ if (regno == S390_PSWM_REGNUM)
+ pswm = extract_unsigned_integer (p, 8, byte_order);
+ else if (regno == S390_PSWA_REGNUM)
+ pswa = extract_unsigned_integer (p, 8, byte_order);
+ else
+ {
+ if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
+ || regno == S390_ORIG_R2_REGNUM)
+ p += 4;
+ regcache_raw_supply (regcache, regno, p);
+ }
}
- if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
- || regno == S390_ORIG_R2_REGNUM)
- offset += 4;
+ store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
+ regcache_raw_supply (regcache, S390_PSWM_REGNUM, buf);
+ store_unsigned_integer (buf, 4, byte_order,
+ (pswa & 0x7fffffff) | (pswm & 0x80000000));
+ regcache_raw_supply (regcache, S390_PSWA_REGNUM, buf);
+ return;
}
#endif
- if (offset != -1)
- regcache_raw_supply (regcache, regno, regp + offset);
+ s390_native_supply (regcache, regmap_gregset, (const gdb_byte *) regp);
}
-static void
-s390_native_collect (const struct regcache *regcache, int regno,
- gdb_byte *regp, int *regmap)
+/* Fill register REGNO (if it is a general-purpose register) in
+ *REGP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+void
+fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
{
- int offset = regmap[regno];
-
#ifdef __s390x__
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
+ if (gdbarch_ptr_bit (gdbarch) == 32)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ gdb_byte *psw_p[2];
+ const short *map;
- if (regno == S390_PSWM_REGNUM)
+ for (map = regmap_gregset; map[0] >= 0; map += 2)
{
- ULONGEST pswm;
- gdb_byte buf[4];
+ gdb_byte *p = (gdb_byte *) regp + map[0];
+ int reg = map[1];
- regcache_raw_collect (regcache, regno, buf);
- pswm = extract_unsigned_integer (buf, 4, byte_order);
+ if (reg >= S390_PSWM_REGNUM && reg <= S390_PSWA_REGNUM)
+ psw_p[reg - S390_PSWM_REGNUM] = p;
- /* We don't know the final addressing mode until the PSW address
- is known, so leave it as-is. When the PSW address is collected
- (below), the addressing mode will be updated. */
- store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
- 4, byte_order, pswm & 0xfff7ffff);
- return;
+ else if (regno == -1 || regno == reg)
+ {
+ if ((reg >= S390_R0_REGNUM && reg <= S390_R15_REGNUM)
+ || reg == S390_ORIG_R2_REGNUM)
+ {
+ memset (p, 0, 4);
+ p += 4;
+ }
+ regcache_raw_collect (regcache, reg, p + 4);
+ }
}
- if (regno == S390_PSWA_REGNUM)
+ if (regno == -1
+ || regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM)
{
- ULONGEST pswa;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ ULONGEST pswa, pswm;
gdb_byte buf[4];
- regcache_raw_collect (regcache, regno, buf);
+ regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
+ pswm = extract_unsigned_integer (buf, 4, byte_order);
+ regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
pswa = extract_unsigned_integer (buf, 4, byte_order);
- store_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
- 8, byte_order, pswa & 0x7fffffff);
-
- /* Update basic addressing mode bit in PSW mask, see above. */
- store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM] + 4,
- 4, byte_order, pswa & 0x80000000);
- return;
- }
-
- if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
- || regno == S390_ORIG_R2_REGNUM)
- {
- memset (regp + offset, 0, 4);
- offset += 4;
+ if (regno == -1 || regno == S390_PSWM_REGNUM)
+ store_unsigned_integer (psw_p[0], 8, byte_order,
+ ((pswm & 0xfff7ffff) << 32) |
+ (pswa & 0x80000000));
+ if (regno == -1 || regno == S390_PSWA_REGNUM)
+ store_unsigned_integer (psw_p[1], 8, byte_order,
+ pswa & 0x7fffffff);
}
+ return;
}
#endif
- if (offset != -1)
- regcache_raw_collect (regcache, regno, regp + offset);
-}
-
-/* Fill GDB's register array with the general-purpose register values
- in *REGP. */
-void
-supply_gregset (struct regcache *regcache, const gregset_t *regp)
-{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_gregset);
-}
-
-/* Fill register REGNO (if it is a general-purpose register) in
- *REGP with the value in GDB's register array. If REGNO is -1,
- do this for all registers. */
-void
-fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
-{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- if (regno == -1 || regno == i)
- s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_gregset);
+ s390_native_collect (regcache, regmap_gregset, regno, (gdb_byte *) regp);
}
/* Fill GDB's register array with the floating-point register values
@@ -203,9 +193,7 @@ fill_gregset (const struct regcache *reg
void
supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_fpregset);
+ s390_native_supply (regcache, regmap_fpregset, (const gdb_byte *) regp);
}
/* Fill register REGNO (if it is a general-purpose register) in
@@ -214,10 +202,7 @@ supply_fpregset (struct regcache *regcac
void
fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- if (regno == -1 || regno == i)
- s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_fpregset);
+ s390_native_collect (regcache, regmap_fpregset, regno, (gdb_byte *) regp);
}
/* Find the TID for the current inferior thread to use with ptrace. */
@@ -311,12 +296,10 @@ store_fpregs (const struct regcache *reg
process/thread TID and store their values in GDB's register cache. */
static void
fetch_regset (struct regcache *regcache, int tid,
- int regset, int regsize, int *regmap)
+ int regset, int regsize, const short *regmap)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
gdb_byte *buf = alloca (regsize);
struct iovec iov;
- int i;
iov.iov_base = buf;
iov.iov_len = regsize;
@@ -324,8 +307,7 @@ fetch_regset (struct regcache *regcache,
if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
perror_with_name (_("Couldn't get register set"));
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_supply (regcache, i, buf, regmap);
+ s390_native_supply (regcache, regmap, buf);
}
/* Store all registers in the kernel's register set whose number is REGSET,
@@ -333,12 +315,10 @@ fetch_regset (struct regcache *regcache,
GDB's register cache back to process/thread TID. */
static void
store_regset (struct regcache *regcache, int tid,
- int regset, int regsize, int *regmap)
+ int regset, int regsize, const short *regmap)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
gdb_byte *buf = alloca (regsize);
struct iovec iov;
- int i;
iov.iov_base = buf;
iov.iov_len = regsize;
@@ -346,8 +326,7 @@ store_regset (struct regcache *regcache,
if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
perror_with_name (_("Couldn't get register set"));
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_collect (regcache, i, buf, regmap);
+ s390_native_collect (regcache, regmap, -1, buf);
if (ptrace (PTRACE_SETREGSET, tid, (long) regset, (long) &iov) < 0)
perror_with_name (_("Couldn't set register set"));
@@ -378,12 +357,10 @@ s390_linux_fetch_inferior_registers (str
{
int tid = s390_inferior_tid ();
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
fetch_regs (regcache, tid);
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
fetch_fpregs (regcache, tid);
if (have_regset_last_break)
@@ -406,12 +383,10 @@ s390_linux_store_inferior_registers (str
{
int tid = s390_inferior_tid ();
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
store_regs (regcache, tid, regnum);
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
store_fpregs (regcache, tid, regnum);
/* S390_LAST_BREAK_REGNUM is read-only. */
Index: gdb/gdb/s390-tdep.c
===================================================================
--- gdb.orig/gdb/s390-tdep.c
+++ gdb/gdb/s390-tdep.c
@@ -141,7 +141,7 @@ s390_write_pc (struct regcache *regcache
/* DWARF Register Mapping. */
-static int s390_dwarf_regmap[] =
+static const short s390_dwarf_regmap[] =
{
/* General Purpose Registers. */
S390_R0_REGNUM, S390_R1_REGNUM, S390_R2_REGNUM, S390_R3_REGNUM,
@@ -212,6 +212,14 @@ s390_adjust_frame_regnum (struct gdbarch
/* Pseudo registers. */
+static int
+regnum_is_gpr_full (struct gdbarch_tdep *tdep, int regnum)
+{
+ return (tdep->gpr_full_regnum != -1
+ && regnum >= tdep->gpr_full_regnum
+ && regnum <= tdep->gpr_full_regnum + 15);
+}
+
static const char *
s390_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
{
@@ -223,9 +231,7 @@ s390_pseudo_register_name (struct gdbarc
if (regnum == tdep->cc_regnum)
return "cc";
- if (tdep->gpr_full_regnum != -1
- && regnum >= tdep->gpr_full_regnum
- && regnum < tdep->gpr_full_regnum + 16)
+ if (regnum_is_gpr_full (tdep, regnum))
{
static const char *full_name[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -248,9 +254,7 @@ s390_pseudo_register_type (struct gdbarc
if (regnum == tdep->cc_regnum)
return builtin_type (gdbarch)->builtin_int;
- if (tdep->gpr_full_regnum != -1
- && regnum >= tdep->gpr_full_regnum
- && regnum < tdep->gpr_full_regnum + 16)
+ if (regnum_is_gpr_full (tdep, regnum))
return builtin_type (gdbarch)->builtin_uint64;
internal_error (__FILE__, __LINE__, _("invalid regnum"));
@@ -295,9 +299,7 @@ s390_pseudo_register_read (struct gdbarc
return status;
}
- if (tdep->gpr_full_regnum != -1
- && regnum >= tdep->gpr_full_regnum
- && regnum < tdep->gpr_full_regnum + 16)
+ if (regnum_is_gpr_full (tdep, regnum))
{
enum register_status status;
ULONGEST val_upper;
@@ -352,9 +354,7 @@ s390_pseudo_register_write (struct gdbar
return;
}
- if (tdep->gpr_full_regnum != -1
- && regnum >= tdep->gpr_full_regnum
- && regnum < tdep->gpr_full_regnum + 16)
+ if (regnum_is_gpr_full (tdep, regnum))
{
regnum -= tdep->gpr_full_regnum;
val = extract_unsigned_integer (buf, regsize, byte_order);
@@ -409,175 +409,166 @@ s390_pseudo_register_reggroup_p (struct
}
-/* Core file register sets. */
+/* Maps for register sets. */
-int s390_regmap_gregset[S390_NUM_REGS] =
-{
- /* Program Status Word. */
- 0x00, 0x04,
- /* General Purpose Registers. */
- 0x08, 0x0c, 0x10, 0x14,
- 0x18, 0x1c, 0x20, 0x24,
- 0x28, 0x2c, 0x30, 0x34,
- 0x38, 0x3c, 0x40, 0x44,
- /* Access Registers. */
- 0x48, 0x4c, 0x50, 0x54,
- 0x58, 0x5c, 0x60, 0x64,
- 0x68, 0x6c, 0x70, 0x74,
- 0x78, 0x7c, 0x80, 0x84,
- /* Floating Point Control Word. */
- -1,
- /* Floating Point Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GPR Uppper Halves. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GNU/Linux-specific optional "registers". */
- 0x88, -1, -1,
-};
+const short s390_regmap_gregset[] =
+ {
+ 0x00, S390_PSWM_REGNUM,
+ 0x04, S390_PSWA_REGNUM,
+ 0x08, S390_R0_REGNUM,
+ 0x0c, S390_R1_REGNUM,
+ 0x10, S390_R2_REGNUM,
+ 0x14, S390_R3_REGNUM,
+ 0x18, S390_R4_REGNUM,
+ 0x1c, S390_R5_REGNUM,
+ 0x20, S390_R6_REGNUM,
+ 0x24, S390_R7_REGNUM,
+ 0x28, S390_R8_REGNUM,
+ 0x2c, S390_R9_REGNUM,
+ 0x30, S390_R10_REGNUM,
+ 0x34, S390_R11_REGNUM,
+ 0x38, S390_R12_REGNUM,
+ 0x3c, S390_R13_REGNUM,
+ 0x40, S390_R14_REGNUM,
+ 0x44, S390_R15_REGNUM,
+ 0x48, S390_A0_REGNUM,
+ 0x4c, S390_A1_REGNUM,
+ 0x50, S390_A2_REGNUM,
+ 0x54, S390_A3_REGNUM,
+ 0x58, S390_A4_REGNUM,
+ 0x5c, S390_A5_REGNUM,
+ 0x60, S390_A6_REGNUM,
+ 0x64, S390_A7_REGNUM,
+ 0x68, S390_A8_REGNUM,
+ 0x6c, S390_A9_REGNUM,
+ 0x70, S390_A10_REGNUM,
+ 0x74, S390_A11_REGNUM,
+ 0x78, S390_A12_REGNUM,
+ 0x7c, S390_A13_REGNUM,
+ 0x80, S390_A14_REGNUM,
+ 0x84, S390_A15_REGNUM,
+ 0x88, S390_ORIG_R2_REGNUM,
+ -1, -1
+ };
-int s390x_regmap_gregset[S390_NUM_REGS] =
-{
- /* Program Status Word. */
- 0x00, 0x08,
- /* General Purpose Registers. */
- 0x10, 0x18, 0x20, 0x28,
- 0x30, 0x38, 0x40, 0x48,
- 0x50, 0x58, 0x60, 0x68,
- 0x70, 0x78, 0x80, 0x88,
- /* Access Registers. */
- 0x90, 0x94, 0x98, 0x9c,
- 0xa0, 0xa4, 0xa8, 0xac,
- 0xb0, 0xb4, 0xb8, 0xbc,
- 0xc0, 0xc4, 0xc8, 0xcc,
- /* Floating Point Control Word. */
- -1,
- /* Floating Point Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GPR Uppper Halves. */
- 0x10, 0x18, 0x20, 0x28,
- 0x30, 0x38, 0x40, 0x48,
- 0x50, 0x58, 0x60, 0x68,
- 0x70, 0x78, 0x80, 0x88,
- /* GNU/Linux-specific optional "registers". */
- 0xd0, -1, -1,
-};
+const short s390x_regmap_gregset[] =
+ {
+ 0x00, S390_PSWM_REGNUM,
+ 0x08, S390_PSWA_REGNUM,
+ 0x10, S390_R0_REGNUM,
+ 0x18, S390_R1_REGNUM,
+ 0x20, S390_R2_REGNUM,
+ 0x28, S390_R3_REGNUM,
+ 0x30, S390_R4_REGNUM,
+ 0x38, S390_R5_REGNUM,
+ 0x40, S390_R6_REGNUM,
+ 0x48, S390_R7_REGNUM,
+ 0x50, S390_R8_REGNUM,
+ 0x58, S390_R9_REGNUM,
+ 0x60, S390_R10_REGNUM,
+ 0x68, S390_R11_REGNUM,
+ 0x70, S390_R12_REGNUM,
+ 0x78, S390_R13_REGNUM,
+ 0x80, S390_R14_REGNUM,
+ 0x88, S390_R15_REGNUM,
+ 0x90, S390_A0_REGNUM,
+ 0x94, S390_A1_REGNUM,
+ 0x98, S390_A2_REGNUM,
+ 0x9c, S390_A3_REGNUM,
+ 0xa0, S390_A4_REGNUM,
+ 0xa4, S390_A5_REGNUM,
+ 0xa8, S390_A6_REGNUM,
+ 0xac, S390_A7_REGNUM,
+ 0xb0, S390_A8_REGNUM,
+ 0xb4, S390_A9_REGNUM,
+ 0xb8, S390_A10_REGNUM,
+ 0xbc, S390_A11_REGNUM,
+ 0xc0, S390_A12_REGNUM,
+ 0xc4, S390_A13_REGNUM,
+ 0xc8, S390_A14_REGNUM,
+ 0xcc, S390_A15_REGNUM,
+ 0x10, S390_R0_UPPER_REGNUM,
+ 0x18, S390_R1_UPPER_REGNUM,
+ 0x20, S390_R2_UPPER_REGNUM,
+ 0x28, S390_R3_UPPER_REGNUM,
+ 0x30, S390_R4_UPPER_REGNUM,
+ 0x38, S390_R5_UPPER_REGNUM,
+ 0x40, S390_R6_UPPER_REGNUM,
+ 0x48, S390_R7_UPPER_REGNUM,
+ 0x50, S390_R8_UPPER_REGNUM,
+ 0x58, S390_R9_UPPER_REGNUM,
+ 0x60, S390_R10_UPPER_REGNUM,
+ 0x68, S390_R11_UPPER_REGNUM,
+ 0x70, S390_R12_UPPER_REGNUM,
+ 0x78, S390_R13_UPPER_REGNUM,
+ 0x80, S390_R14_UPPER_REGNUM,
+ 0x88, S390_R15_UPPER_REGNUM,
+ 0xd0, S390_ORIG_R2_REGNUM,
+ -1, -1
+ };
-int s390_regmap_fpregset[S390_NUM_REGS] =
-{
- /* Program Status Word. */
- -1, -1,
- /* General Purpose Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Access Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Floating Point Control Word. */
- 0x00,
- /* Floating Point Registers. */
- 0x08, 0x10, 0x18, 0x20,
- 0x28, 0x30, 0x38, 0x40,
- 0x48, 0x50, 0x58, 0x60,
- 0x68, 0x70, 0x78, 0x80,
- /* GPR Uppper Halves. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GNU/Linux-specific optional "registers". */
- -1, -1, -1,
-};
+const short s390_regmap_fpregset[] =
+ {
+ 0x00, S390_FPC_REGNUM,
+ 0x08, S390_F0_REGNUM,
+ 0x10, S390_F1_REGNUM,
+ 0x18, S390_F2_REGNUM,
+ 0x20, S390_F3_REGNUM,
+ 0x28, S390_F4_REGNUM,
+ 0x30, S390_F5_REGNUM,
+ 0x38, S390_F6_REGNUM,
+ 0x40, S390_F7_REGNUM,
+ 0x48, S390_F8_REGNUM,
+ 0x50, S390_F9_REGNUM,
+ 0x58, S390_F10_REGNUM,
+ 0x60, S390_F11_REGNUM,
+ 0x68, S390_F12_REGNUM,
+ 0x70, S390_F13_REGNUM,
+ 0x78, S390_F14_REGNUM,
+ 0x80, S390_F15_REGNUM,
+ -1, -1
+ };
-int s390_regmap_upper[S390_NUM_REGS] =
-{
- /* Program Status Word. */
- -1, -1,
- /* General Purpose Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Access Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Floating Point Control Word. */
- -1,
- /* Floating Point Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GPR Uppper Halves. */
- 0x00, 0x04, 0x08, 0x0c,
- 0x10, 0x14, 0x18, 0x1c,
- 0x20, 0x24, 0x28, 0x2c,
- 0x30, 0x34, 0x38, 0x3c,
- /* GNU/Linux-specific optional "registers". */
- -1, -1, -1,
-};
+const short s390_regmap_upper[] =
+ {
+ 0x00, S390_R0_UPPER_REGNUM,
+ 0x04, S390_R1_UPPER_REGNUM,
+ 0x08, S390_R2_UPPER_REGNUM,
+ 0x0c, S390_R3_UPPER_REGNUM,
+ 0x10, S390_R4_UPPER_REGNUM,
+ 0x14, S390_R5_UPPER_REGNUM,
+ 0x18, S390_R6_UPPER_REGNUM,
+ 0x1c, S390_R7_UPPER_REGNUM,
+ 0x20, S390_R8_UPPER_REGNUM,
+ 0x24, S390_R9_UPPER_REGNUM,
+ 0x28, S390_R10_UPPER_REGNUM,
+ 0x2c, S390_R11_UPPER_REGNUM,
+ 0x30, S390_R12_UPPER_REGNUM,
+ 0x34, S390_R13_UPPER_REGNUM,
+ 0x38, S390_R14_UPPER_REGNUM,
+ 0x3c, S390_R15_UPPER_REGNUM,
+ -1, -1
+ };
-int s390_regmap_last_break[S390_NUM_REGS] =
-{
- /* Program Status Word. */
- -1, -1,
- /* General Purpose Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Access Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Floating Point Control Word. */
- -1,
- /* Floating Point Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GPR Uppper Halves. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GNU/Linux-specific optional "registers". */
- -1, 4, -1,
-};
+const short s390_regmap_last_break[] =
+ {
+ 0x04, S390_LAST_BREAK_REGNUM,
+ -1, -1
+ };
+
+const short s390x_regmap_last_break[] =
+ {
+ 0x00, S390_LAST_BREAK_REGNUM,
+ -1, -1
+ };
+
+const short s390_regmap_system_call[] =
+ {
+ 0x00, S390_SYSTEM_CALL_REGNUM,
+ -1, -1
+ };
-int s390x_regmap_last_break[S390_NUM_REGS] =
-{
- /* Program Status Word. */
- -1, -1,
- /* General Purpose Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Access Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Floating Point Control Word. */
- -1,
- /* Floating Point Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GPR Uppper Halves. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GNU/Linux-specific optional "registers". */
- -1, 0, -1,
-};
-int s390_regmap_system_call[S390_NUM_REGS] =
-{
- /* Program Status Word. */
- -1, -1,
- /* General Purpose Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Access Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* Floating Point Control Word. */
- -1,
- /* Floating Point Registers. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GPR Uppper Halves. */
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- /* GNU/Linux-specific optional "registers". */
- -1, -1, 0,
-};
/* Supply register REGNUM from the register set REGSET to register cache
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
@@ -585,14 +576,10 @@ static void
s390_supply_regset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *regs, size_t len)
{
- const int *offset = regset->descr;
- int i;
-
- for (i = 0; i < S390_NUM_REGS; i++)
- {
- if ((regnum == i || regnum == -1) && offset[i] != -1)
- regcache_raw_supply (regcache, i, (const char *)regs + offset[i]);
- }
+ const short *map;
+ for (map = regset->descr; map[0] >= 0; map += 2)
+ if (regnum == -1 || regnum == map[1])
+ regcache_raw_supply (regcache, map[1], (const char *)regs + map[0]);
}
/* Collect register REGNUM from the register cache REGCACHE and store
@@ -604,14 +591,10 @@ s390_collect_regset (const struct regset
const struct regcache *regcache,
int regnum, void *regs, size_t len)
{
- const int *offset = regset->descr;
- int i;
-
- for (i = 0; i < S390_NUM_REGS; i++)
- {
- if ((regnum == i || regnum == -1) && offset[i] != -1)
- regcache_raw_collect (regcache, i, (char *)regs + offset[i]);
- }
+ const short *map;
+ for (map = regset->descr; map[0] >= 0; map += 2)
+ if (regnum == -1 || regnum == map[1])
+ regcache_raw_collect (regcache, map[1], (char *)regs + map[0]);
}
static const struct regset s390_gregset = {
@@ -1718,9 +1701,7 @@ s390_unwind_pseudo_register (struct fram
/* Unwind full GPRs to show at least the lower halves (as the
upper halves are undefined). */
- if (tdep->gpr_full_regnum != -1
- && regnum >= tdep->gpr_full_regnum
- && regnum < tdep->gpr_full_regnum + 16)
+ if (regnum_is_gpr_full (tdep, regnum))
{
int reg = regnum - tdep->gpr_full_regnum;
struct value *val;
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFA][PATCH v4 2/5] S/390: Add TDB regset
2013-07-03 16:57 [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
2013-07-03 17:00 ` [RFA][PATCH v4 1/5] S/390 regmap rework Andreas Arnez
@ 2013-07-03 17:02 ` Andreas Arnez
2013-07-03 19:25 ` Eli Zaretskii
2013-07-03 17:04 ` [RFA][PATCH v4 3/5] Dynamic core regset sections support Andreas Arnez
` (3 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Andreas Arnez @ 2013-07-03 17:02 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
The z/Architecture transactional-execution facility includes support
for a "transaction diagnostic block" (TDB) that is written by the
hardware upon interrupted transactions. From a running inferior the
TDB can be retrieved via PTRACE_GETREGSET, but ENODATA is returned if
the inferior was interrupted outside transactions. Analogously, a
core file conditionally contains the TDB, depending on whether the
process died within a transaction or not.
This patch represents the TDB as a new regset in GDB. A new feature
"org.gnu.gdb.s390.tdb" is defined and new target descriptions are
provided.
gdb/ChangeLog:
2013-07-03 Andreas Arnez <arnez@linux.vnet.ibm.com>
* features/s390-tdb.xml: New file.
* features/s390-te-linux64.xml: New file.
* features/s390x-te-linux64.xml: New file.
* features/Makefile (WHICH): Add new tdescs above.
(s390-te-linux64-expedite): Set.
(s390x-te-linux64-expedite): Set.
* s390-tdep.h (HWCAP_S390_HIGH_GPRS): Define.
(HWCAP_S390_TE): Likewise.
(S390_TDB_DWORD0_REGNUM): Likewise.
(S390_TDB_DWORD0_REGNUM): Likewise.
(S390_TDB_ABORT_CODE_REGNUM): Likewise.
(S390_TDB_CONFLICT_TOKEN_REGNUM): Likewise.
(S390_TDB_ATIA_REGNUM): Likewise.
(S390_TDB_R0_REGNUM): Likewise.
(S390_TDB_R1_REGNUM): Likewise.
(S390_TDB_R2_REGNUM): Likewise.
(S390_TDB_R3_REGNUM): Likewise.
(S390_TDB_R4_REGNUM): Likewise.
(S390_TDB_R5_REGNUM): Likewise.
(S390_TDB_R6_REGNUM): Likewise.
(S390_TDB_R7_REGNUM): Likewise.
(S390_TDB_R8_REGNUM): Likewise.
(S390_TDB_R9_REGNUM): Likewise.
(S390_TDB_R10_REGNUM): Likewise.
(S390_TDB_R11_REGNUM): Likewise.
(S390_TDB_R12_REGNUM): Likewise.
(S390_TDB_R13_REGNUM): Likewise.
(S390_TDB_R14_REGNUM): Likewise.
(S390_TDB_R15_REGNUM): Likewise.
(S390_NUM_REGS): Increase.
(S390_IS_TDBREGSET_REGNUM): New macro.
(s390_regmap_tdb): Declare.
(s390_sizeof_tdbregset): Define.
(tdesc_s390_te_linux64): Declare.
(tdesc_s390x_te_linux64): Likewise.
* s390-tdep.c: Add includes for "auxv.h", <elf.h>,
"features/s390-te-linux64.c", and "features/s390x-te-linux64.c".
(s390_regmap_tdb): New regmap.
(s390_tdb_regset): New regset.
(s390_linux64v2_regset_sections): Add TDB regset to list.
(s390x_linux64v2_regset_sections): Likewise.
(s390_regset_from_core_section): Recognize TDB core note section.
(s390_core_read_description): If HWCAP indicates TE support,
select tdesc_s390_te_linux64 or tdesc_s390_s390x_te_linux64.
(s390_gdbarch_init): Handle TDB regset.
(_initialize_s390_tdep): Initialize new tdescs.
* s390-nat.c (HWCAP_S390_HIGH_GPRS): Remove define.
(have_regset_tdb): New variable.
(s390_native_supply): Support register invalidation.
(fetch_regset): Invalidate registers if ptrace yields ENODATA.
(check_regset): Treat ENODATA as "regset exists".
(s390_linux_fetch_inferior_registers): Add TDB.
(s390_read_description): Check for TDB existence and select
appropriate tdesc.
* gdbserver/configure.srv (srv_regobj): Append new objects
s390-te-linux64.o and s390x-te-linux64.o.
(srv_xmlfiles): Append new files s390-te-linux64.xml,
s390x-te-linux64.xml, and s390-tdb.xml.
* gdbserver/Makefile.in (clean): Add removal of new makefile
targets.
(s390-te-linux64.c): New makefile target.
(s390x-te-linux64.c): Likewise.
* gdbserver/linux-s390-low.c (init_registers_s390_te_linux64): New
declaration.
(tdesc_s390_te_linux64): Likewise.
(init_registers_s390x_te_linux64): Likewise.
(tdesc_s390x_te_linux64): Likewise.
(s390_check_regset): Treat ENODATA as "regset exists".
(s390_arch_setup): Add TDB regset support.
(initialize_low_arch): Initialize registers for new tdescs.
* NEWS: Mention TDB support.
* features/s390-te-linux64.c: New file (generated).
* features/s390x-te-linux64.c: New file (generated).
* regformats/s390-te-linux64.dat: New file (generated).
* regformats/s390x-te-linux64.dat: New file (generated).
gdb/doc/ChangeLog:
2013-06-12 Andreas Arnez <arnez@linux.vnet.ibm.com>
* gdb.texinfo (Decimal Floating Point format): Mention S/390.
(Standard Target Features): Add new node to menu.
(S/390 and System z Features): New node.
gdb/testsuite/ChangeLog:
2013-06-12 Andreas Arnez <arnez@linux.vnet.ibm.com>
* gdb.arch/s390-tdbregs.c: New file.
* gdb.arch/s390-tdbregs.exp: New file.
Index: gdb/gdb/features/s390-tdb.xml
===================================================================
--- /dev/null
+++ gdb/gdb/features/s390-tdb.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.s390.tdb">
+ <reg name="tdb0" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tac" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tct" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="atia" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr0" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr1" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr2" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr3" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr4" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr5" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr6" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr7" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr8" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr9" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr10" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr11" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr12" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr13" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr14" bitsize="64" type="uint64" group="tdb"/>
+ <reg name="tr15" bitsize="64" type="uint64" group="tdb"/>
+</feature>
Index: gdb/gdb/s390-tdep.c
===================================================================
--- gdb.orig/gdb/s390-tdep.c
+++ gdb/gdb/s390-tdep.c
@@ -44,6 +44,7 @@
#include "prologue-value.h"
#include "linux-tdep.h"
#include "s390-tdep.h"
+#include "auxv.h"
#include "stap-probe.h"
#include "ax.h"
@@ -51,6 +52,7 @@
#include "user-regs.h"
#include "cli/cli-utils.h"
#include <ctype.h>
+#include <elf.h>
#include "features/s390-linux32.c"
#include "features/s390-linux32v1.c"
@@ -58,9 +60,11 @@
#include "features/s390-linux64.c"
#include "features/s390-linux64v1.c"
#include "features/s390-linux64v2.c"
+#include "features/s390-te-linux64.c"
#include "features/s390x-linux64.c"
#include "features/s390x-linux64v1.c"
#include "features/s390x-linux64v2.c"
+#include "features/s390x-te-linux64.c"
/* The tdep structure. */
@@ -568,6 +572,30 @@ const short s390_regmap_system_call[] =
-1, -1
};
+const short s390_regmap_tdb[] =
+ {
+ 0x00, S390_TDB_DWORD0_REGNUM,
+ 0x08, S390_TDB_ABORT_CODE_REGNUM,
+ 0x10, S390_TDB_CONFLICT_TOKEN_REGNUM,
+ 0x18, S390_TDB_ATIA_REGNUM,
+ 0x80, S390_TDB_R0_REGNUM,
+ 0x88, S390_TDB_R1_REGNUM,
+ 0x90, S390_TDB_R2_REGNUM,
+ 0x98, S390_TDB_R3_REGNUM,
+ 0xa0, S390_TDB_R4_REGNUM,
+ 0xa8, S390_TDB_R5_REGNUM,
+ 0xb0, S390_TDB_R6_REGNUM,
+ 0xb8, S390_TDB_R7_REGNUM,
+ 0xc0, S390_TDB_R8_REGNUM,
+ 0xc8, S390_TDB_R9_REGNUM,
+ 0xd0, S390_TDB_R10_REGNUM,
+ 0xd8, S390_TDB_R11_REGNUM,
+ 0xe0, S390_TDB_R12_REGNUM,
+ 0xe8, S390_TDB_R13_REGNUM,
+ 0xf0, S390_TDB_R14_REGNUM,
+ 0xf8, S390_TDB_R15_REGNUM,
+ -1, -1
+ };
/* Supply register REGNUM from the register set REGSET to register cache
@@ -639,6 +667,12 @@ static const struct regset s390_system_c
s390_collect_regset
};
+static const struct regset s390_tdb_regset = {
+ s390_regmap_tdb,
+ s390_supply_regset,
+ s390_collect_regset
+};
+
static struct core_regset_section s390_linux32_regset_sections[] =
{
{ ".reg", s390_sizeof_gregset, "general-purpose" },
@@ -687,6 +721,7 @@ static struct core_regset_section s390_l
{ ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
{ ".reg-s390-last-break", 8, "s930 last-break address" },
{ ".reg-s390-system-call", 4, "s390 system-call" },
+ { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
{ NULL, 0}
};
@@ -711,6 +746,7 @@ static struct core_regset_section s390x_
{ ".reg2", s390_sizeof_fpregset, "floating-point" },
{ ".reg-s390-last-break", 8, "s930 last-break address" },
{ ".reg-s390-system-call", 4, "s390 system-call" },
+ { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
{ NULL, 0}
};
@@ -739,6 +775,9 @@ s390_regset_from_core_section (struct gd
if (strcmp (sect_name, ".reg-s390-system-call") == 0 && sect_size >= 4)
return &s390_system_call_regset;
+ if (strcmp (sect_name, ".reg-s390-tdb") == 0 && sect_size >= 256)
+ return &s390_tdb_regset;
+
return NULL;
}
@@ -750,6 +789,9 @@ s390_core_read_description (struct gdbar
asection *v1 = bfd_get_section_by_name (abfd, ".reg-s390-last-break");
asection *v2 = bfd_get_section_by_name (abfd, ".reg-s390-system-call");
asection *section = bfd_get_section_by_name (abfd, ".reg");
+ unsigned long hwcap = 0;
+
+ target_auxv_search (target, AT_HWCAP, &hwcap);
if (!section)
return NULL;
@@ -757,14 +799,16 @@ s390_core_read_description (struct gdbar
{
case s390_sizeof_gregset:
if (high_gprs)
- return (v2? tdesc_s390_linux64v2 :
+ return ((hwcap & HWCAP_S390_TE) ? tdesc_s390_te_linux64 :
+ v2? tdesc_s390_linux64v2 :
v1? tdesc_s390_linux64v1 : tdesc_s390_linux64);
else
return (v2? tdesc_s390_linux32v2 :
v1? tdesc_s390_linux32v1 : tdesc_s390_linux32);
case s390x_sizeof_gregset:
- return (v2? tdesc_s390x_linux64v2 :
+ return ((hwcap & HWCAP_S390_TE) ? tdesc_s390x_te_linux64 :
+ v2? tdesc_s390x_linux64v2 :
v1? tdesc_s390x_linux64v1 : tdesc_s390x_linux64);
default:
@@ -3011,6 +3055,11 @@ s390_gdbarch_init (struct gdbarch_info i
"r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
"r8h", "r9h", "r10h", "r11h", "r12h", "r13h", "r14h", "r15h"
};
+ static const char *const tdb_regs[] = {
+ "tdb0", "tac", "tct", "atia",
+ "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7",
+ "tr8", "tr9", "tr10", "tr11", "tr12", "tr13", "tr14", "tr15"
+ };
const struct tdesc_feature *feature;
int i, valid_p = 1;
@@ -3088,6 +3137,16 @@ s390_gdbarch_init (struct gdbarch_info i
valid_p = 0;
}
+ /* Transaction diagnostic block. */
+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.tdb");
+ if (feature)
+ {
+ for (i = 0; i < ARRAY_SIZE (tdb_regs); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ S390_TDB_DWORD0_REGNUM + i,
+ tdb_regs[i]);
+ }
+
if (!valid_p)
{
tdesc_data_cleanup (tdesc_data);
@@ -3304,7 +3363,9 @@ _initialize_s390_tdep (void)
initialize_tdesc_s390_linux64 ();
initialize_tdesc_s390_linux64v1 ();
initialize_tdesc_s390_linux64v2 ();
+ initialize_tdesc_s390_te_linux64 ();
initialize_tdesc_s390x_linux64 ();
initialize_tdesc_s390x_linux64v1 ();
initialize_tdesc_s390x_linux64v2 ();
+ initialize_tdesc_s390x_te_linux64 ();
}
Index: gdb/gdb/s390-tdep.h
===================================================================
--- gdb.orig/gdb/s390-tdep.h
+++ gdb/gdb/s390-tdep.h
@@ -19,6 +19,16 @@
#ifndef S390_TDEP_H
#define S390_TDEP_H
+/* Hardware capabilities. */
+
+#ifndef HWCAP_S390_HIGH_GPRS
+#define HWCAP_S390_HIGH_GPRS 512
+#endif
+
+#ifndef HWCAP_S390_TE
+#define HWCAP_S390_TE 1024
+#endif
+
/* Register information. */
/* Program Status Word. */
@@ -98,8 +108,29 @@
#define S390_ORIG_R2_REGNUM 67
#define S390_LAST_BREAK_REGNUM 68
#define S390_SYSTEM_CALL_REGNUM 69
+/* Transaction diagnostic block. */
+#define S390_TDB_DWORD0_REGNUM 70
+#define S390_TDB_ABORT_CODE_REGNUM 71
+#define S390_TDB_CONFLICT_TOKEN_REGNUM 72
+#define S390_TDB_ATIA_REGNUM 73
+#define S390_TDB_R0_REGNUM 74
+#define S390_TDB_R1_REGNUM 75
+#define S390_TDB_R2_REGNUM 76
+#define S390_TDB_R3_REGNUM 77
+#define S390_TDB_R4_REGNUM 78
+#define S390_TDB_R5_REGNUM 79
+#define S390_TDB_R6_REGNUM 80
+#define S390_TDB_R7_REGNUM 81
+#define S390_TDB_R8_REGNUM 82
+#define S390_TDB_R9_REGNUM 83
+#define S390_TDB_R10_REGNUM 84
+#define S390_TDB_R11_REGNUM 85
+#define S390_TDB_R12_REGNUM 86
+#define S390_TDB_R13_REGNUM 87
+#define S390_TDB_R14_REGNUM 88
+#define S390_TDB_R15_REGNUM 89
/* Total. */
-#define S390_NUM_REGS 70
+#define S390_NUM_REGS 90
/* Special register usage. */
#define S390_SP_REGNUM S390_R15_REGNUM
@@ -114,6 +145,9 @@
#define S390_IS_FPREGSET_REGNUM(i) \
((i) >= S390_FPC_REGNUM && (i) <= S390_F15_REGNUM)
+#define S390_IS_TDBREGSET_REGNUM(i) \
+ ((i) >= S390_TDB_DWORD0_REGNUM && (i) <= S390_TDB_R15_REGNUM)
+
/* Core file register sets, defined in s390-tdep.c. */
#define s390_sizeof_gregset 0x90
extern const short s390_regmap_gregset[];
@@ -124,6 +158,8 @@ extern const short s390_regmap_fpregset[
extern const short s390_regmap_last_break[];
extern const short s390x_regmap_last_break[];
extern const short s390_regmap_system_call[];
+extern const short s390_regmap_tdb[];
+#define s390_sizeof_tdbregset 0x100
/* GNU/Linux target descriptions. */
extern struct target_desc *tdesc_s390_linux32;
@@ -132,9 +168,11 @@ extern struct target_desc *tdesc_s390_li
extern struct target_desc *tdesc_s390_linux64;
extern struct target_desc *tdesc_s390_linux64v1;
extern struct target_desc *tdesc_s390_linux64v2;
+extern struct target_desc *tdesc_s390_te_linux64;
extern struct target_desc *tdesc_s390x_linux64;
extern struct target_desc *tdesc_s390x_linux64v1;
extern struct target_desc *tdesc_s390x_linux64v2;
+extern struct target_desc *tdesc_s390x_te_linux64;
#endif
Index: gdb/gdb/s390-nat.c
===================================================================
--- gdb.orig/gdb/s390-nat.c
+++ gdb/gdb/s390-nat.c
@@ -37,10 +37,6 @@
#include <sys/ucontext.h>
#include <elf.h>
-#ifndef HWCAP_S390_HIGH_GPRS
-#define HWCAP_S390_HIGH_GPRS 512
-#endif
-
#ifndef PTRACE_GETREGSET
#define PTRACE_GETREGSET 0x4204
#endif
@@ -51,6 +47,7 @@
static int have_regset_last_break = 0;
static int have_regset_system_call = 0;
+static int have_regset_tdb = 0;
/* Map registers to gregset/ptrace offsets.
These arrays are defined in s390-tdep.c. */
@@ -68,7 +65,7 @@ s390_native_supply (struct regcache *reg
const gdb_byte *regp)
{
for (; map[0] >= 0; map += 2)
- regcache_raw_supply (regcache, map[1], regp + map[0]);
+ regcache_raw_supply (regcache, map[1], regp ? regp + map[0] : NULL);
}
static void
@@ -305,9 +302,14 @@ fetch_regset (struct regcache *regcache,
iov.iov_len = regsize;
if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
- perror_with_name (_("Couldn't get register set"));
-
- s390_native_supply (regcache, regmap, buf);
+ {
+ if (errno == ENODATA)
+ s390_native_supply (regcache, regmap, NULL);
+ else
+ perror_with_name (_("Couldn't get register set"));
+ }
+ else
+ s390_native_supply (regcache, regmap, buf);
}
/* Store all registers in the kernel's register set whose number is REGSET,
@@ -343,10 +345,10 @@ check_regset (int tid, int regset, int r
iov.iov_base = buf;
iov.iov_len = regsize;
- if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
- return 0;
- else
+ if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) >= 0
+ || errno == ENODATA)
return 1;
+ return 0;
}
/* Fetch register REGNUM from the child process. If REGNUM is -1, do
@@ -373,6 +375,11 @@ s390_linux_fetch_inferior_registers (str
if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
fetch_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
s390_regmap_system_call);
+
+ if (have_regset_tdb)
+ if (regnum == -1 || S390_IS_TDBREGSET_REGNUM (regnum))
+ fetch_regset (regcache, tid, NT_S390_TDB, s390_sizeof_tdbregset,
+ s390_regmap_tdb);
}
/* Store register REGNUM back into the child process. If REGNUM is
@@ -615,6 +622,8 @@ s390_read_description (struct target_ops
= check_regset (tid, NT_S390_LAST_BREAK, 8);
have_regset_system_call
= check_regset (tid, NT_S390_SYSTEM_CALL, 4);
+ have_regset_tdb
+ = check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
#ifdef __s390x__
/* If GDB itself is compiled as 64-bit, we are running on a machine in
@@ -624,12 +633,14 @@ s390_read_description (struct target_ops
that mode, report s390 architecture with 64-bit GPRs. */
if (s390_target_wordsize () == 8)
- return (have_regset_system_call? tdesc_s390x_linux64v2 :
+ return (have_regset_tdb ? tdesc_s390x_te_linux64 :
+ have_regset_system_call? tdesc_s390x_linux64v2 :
have_regset_last_break? tdesc_s390x_linux64v1 :
tdesc_s390x_linux64);
if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
- return (have_regset_system_call? tdesc_s390_linux64v2 :
+ return (have_regset_tdb ? tdesc_s390_te_linux64 :
+ have_regset_system_call? tdesc_s390_linux64v2 :
have_regset_last_break? tdesc_s390_linux64v1 :
tdesc_s390_linux64);
#endif
Index: gdb/gdb/testsuite/gdb.arch/s390-tdbregs.c
===================================================================
--- /dev/null
+++ gdb/gdb/testsuite/gdb.arch/s390-tdbregs.c
@@ -0,0 +1,62 @@
+/* Copyright 2008-2013 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+
+static void
+my_tbegin ()
+{
+ asm volatile ( "1: tbegin 0, 0xff00\n"
+ " jnz 1b"
+ : /* no return value */
+ : /* no inputs */
+ : "cc", "memory" );
+}
+
+static void
+my_tend ()
+{
+ asm volatile ( " tend"
+ : /* no return value */
+ : /* no inputs */
+ : "cc");
+}
+
+void
+try_transaction (void)
+{
+ my_tbegin ();
+ my_tend ();
+}
+
+void
+crash_in_transaction (void)
+{
+ volatile char *p = 0;
+
+ my_tbegin ();
+ *p = 5; /* FAULT */
+ my_tend ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ try_transaction ();
+ crash_in_transaction ();
+ return 0;
+}
Index: gdb/gdb/testsuite/gdb.arch/s390-tdbregs.exp
===================================================================
--- /dev/null
+++ gdb/gdb/testsuite/gdb.arch/s390-tdbregs.exp
@@ -0,0 +1,75 @@
+# Copyright 2004-2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file is part of the gdb testsuite.
+
+
+if { ![istarget s390-*-*] && ![istarget s390x-*-* ] } {
+ verbose "Skipping s390 TDB register tests."
+ return
+}
+
+set testfile "s390-tdbregs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [get_compiler_info] } {
+ return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable [list debug additional_flags=-march=zEC12]] != "" } {
+ unsupported "No TE support (compile failed)."
+ return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if { ![runto_main] } then {
+ gdb_suppress_tests
+}
+
+gdb_test_multiple "next" "check for TE support" {
+ -re "Program received signal SIGILL,.*\r\n$gdb_prompt $" {
+ unsupported "No TE support."
+ return
+ }
+ -re "\[0-9\]+.*\r\n$gdb_prompt $" {
+ pass "TE support available"
+ }
+ -re "$gdb_prompt $" {
+ unsupported "No TE support (unknown error)."
+ return
+ }
+}
+
+set crashline [gdb_get_line_number "FAULT"]
+
+gdb_test "print \$tdb0" "\\\$\[0-9\]+ = <unavailable>" "tdb0 unavailable"
+gdb_test "print \$tr0" "\\\$\[0-9\]+ = <unavailable>" "tr0 unavailable"
+gdb_test "next" \
+ "Program received signal SIGSEGV, .*" \
+ "crash in transaction"
+gdb_test "print/x \$tdb0" "\\\$\[0-9\]+ = 0x1.*" "tdb0 available"
+gdb_test "set print symbol-filename" "" "set print symbol-filename"
+gdb_test "print/a \$atia" \
+ "<crash_in_transaction.*:$crashline>" \
+ "ATIA points to crash"
Index: gdb/gdb/gdbserver/linux-s390-low.c
===================================================================
--- gdb.orig/gdb/gdbserver/linux-s390-low.c
+++ gdb/gdb/gdbserver/linux-s390-low.c
@@ -64,6 +64,10 @@ extern const struct target_desc *tdesc_s
void init_registers_s390_linux64v2 (void);
extern const struct target_desc *tdesc_s390_linux64v2;
+/* Defined in auto-generated file s390-te-linux64.c. */
+void init_registers_s390_te_linux64 (void);
+extern const struct target_desc *tdesc_s390_te_linux64;
+
/* Defined in auto-generated file s390x-linux64.c. */
void init_registers_s390x_linux64 (void);
extern const struct target_desc *tdesc_s390x_linux64;
@@ -76,6 +80,10 @@ extern const struct target_desc *tdesc_s
void init_registers_s390x_linux64v2 (void);
extern const struct target_desc *tdesc_s390x_linux64v2;
+/* Defined in auto-generated file s390x-te-linux64.c. */
+void init_registers_s390x_te_linux64 (void);
+extern const struct target_desc *tdesc_s390x_te_linux64;
+
#define s390_num_regs 52
static int s390_regmap[] = {
@@ -391,10 +399,10 @@ s390_check_regset (int pid, int regset,
iov.iov_base = buf;
iov.iov_len = regsize;
- if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) < 0)
- return 0;
- else
+ if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
+ || errno == ENODATA)
return 1;
+ return 0;
}
#ifdef __s390x__
@@ -415,6 +423,7 @@ s390_arch_setup (void)
= s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
int have_regset_system_call
= s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
+ int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
/* Update target_regsets according to available register sets. */
for (regset = s390_regsets; regset->fill_function != NULL; regset++)
@@ -427,6 +436,8 @@ s390_arch_setup (void)
case NT_S390_SYSTEM_CALL:
regset->size = have_regset_system_call? 4 : 0;
break;
+ case NT_S390_TDB:
+ regset->size = have_regset_tdb ? 256 : 0;
default:
break;
}
@@ -451,6 +462,8 @@ s390_arch_setup (void)
if (pswm & 1)
{
+ if (have_regset_tdb)
+ tdesc = tdesc_s390x_te_linux64;
if (have_regset_system_call)
tdesc = tdesc_s390x_linux64v2;
else if (have_regset_last_break)
@@ -465,7 +478,9 @@ s390_arch_setup (void)
{
have_hwcap_s390_high_gprs = 1;
- if (have_regset_system_call)
+ if (have_regset_tdb)
+ tdesc = tdesc_s390_te_linux64;
+ else if (have_regset_system_call)
tdesc = tdesc_s390_linux64v2;
else if (have_regset_last_break)
tdesc = tdesc_s390_linux64v1;
@@ -575,9 +590,11 @@ initialize_low_arch (void)
init_registers_s390_linux64 ();
init_registers_s390_linux64v1 ();
init_registers_s390_linux64v2 ();
+ init_registers_s390_te_linux64 ();
init_registers_s390x_linux64 ();
init_registers_s390x_linux64v1 ();
init_registers_s390x_linux64v2 ();
+ init_registers_s390x_te_linux64 ();
initialize_regsets_info (&s390_regsets_info);
#ifdef __s390x__
Index: gdb/gdb/NEWS
===================================================================
--- gdb.orig/gdb/NEWS
+++ gdb/gdb/NEWS
@@ -98,6 +98,10 @@ show range-stepping
* GDB now understands the element 'tvar' in the XML traceframe info.
It has the id of the collected trace state variables.
+* On S/390 targets that provide the transactional-execution feature,
+ the program interruption transaction diagnostic block (TDB) is now
+ represented as a number of additional "registers" in GDB.
+
* New remote packets
vCont;r
Index: gdb/gdb/doc/gdb.texinfo
===================================================================
--- gdb.orig/gdb/doc/gdb.texinfo
+++ gdb/gdb/doc/gdb.texinfo
@@ -13832,8 +13832,8 @@ specified by the extension to support de
There are two encodings in use, depending on the architecture: BID (Binary
Integer Decimal) for x86 and x86-64, and DPD (Densely Packed Decimal) for
-PowerPC. @value{GDBN} will use the appropriate encoding for the configured
-target.
+PowerPC and S/390. @value{GDBN} will use the appropriate encoding for the
+configured target.
Because of a limitation in @file{libdecnumber}, the library used by @value{GDBN}
to manipulate decimal floating point numbers, it is not possible to convert
@@ -42443,6 +42443,7 @@ registers using the capitalization used
* M68K Features::
* Nios II Features::
* PowerPC Features::
+* S/390 and System z Features::
* TIC6x Features::
@end menu
@@ -42632,6 +42633,39 @@ contain registers @samp{ev0h} through @s
these to present registers @samp{ev0} through @samp{ev31} to the
user.
+@node S/390 and System z Features
+@subsection S/390 and System z Features
+@cindex target descriptions, S/390 features
+@cindex target descriptions, System z features
+
+The @samp{org.gnu.gdb.s390.core} feature is required for S/390 and
+System z targets. It should contain the PSW and the 16 general
+registers. In particular, System z targets should provide the 64-bit
+registers @samp{pswm}, @samp{pswa}, and @samp{r0} through @samp{r15}.
+S/390 targets should provide the 32-bit versions of these registers.
+A System z target that runs in 31-bit addressing mode should provide
+32-bit versions of @samp{pswm} and @samp{pswa}, as well as the general
+register's upper halves @samp{r0h} through @samp{r15h}, and their
+lower halves @samp{r0l} through @samp{r15l}.
+
+The @samp{org.gnu.gdb.s390.fpr} feature is required. It should
+contain the 64-bit registers @samp{f0} through @samp{f15}, and
+@samp{fpc}.
+
+The @samp{org.gnu.gdb.s390.acr} feature is required. It should
+contain the 32-bit registers @samp{acr0} through @samp{acr15}.
+
+The @samp{org.gnu.gdb.s390.linux} feature is optional. It should
+contain the register @samp{orig_r2}, which is 64-bit wide on System z
+targets and 32-bit otherwise. In addition, the feature may contain
+the @samp{last_break} register, whose width depends on the addressing
+mode, as well as the @samp{system_call} register, which is always
+32-bit wide.
+
+The @samp{org.gnu.gdb.s390.tdb} feature is optional. It should
+contain the 64-bit registers @samp{tdb0}, @samp{tac}, @samp{tct},
+@samp{atia}, and @samp{tr0} through @samp{tr15}.
+
@node TIC6x Features
@subsection TMS320C6x Features
@cindex target descriptions, TIC6x features
Index: gdb/gdb/features/s390-te-linux64.xml
===================================================================
--- /dev/null
+++ gdb/gdb/features/s390-te-linux64.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- S/390 31-bit user-level code on a machine operating
+ in z/Architecture mode. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>s390:31-bit</architecture>
+ <xi:include href="s390-core64.xml"/>
+ <xi:include href="s390-acr.xml"/>
+ <xi:include href="s390-fpr.xml"/>
+
+ <feature name="org.gnu.gdb.s390.linux">
+ <reg name="orig_r2" bitsize="32" type="uint32" group="system"/>
+ <reg name="last_break" bitsize="32" type="code_ptr" group="system" save-restore="no"/>
+ <reg name="system_call" bitsize="32" type="uint32" group="system"/>
+ </feature>
+
+ <xi:include href="s390-tdb.xml"/>
+</target>
Index: gdb/gdb/features/s390x-te-linux64.xml
===================================================================
--- /dev/null
+++ gdb/gdb/features/s390x-te-linux64.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- S/390 64-bit user-level code. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>s390:64-bit</architecture>
+ <xi:include href="s390x-core64.xml"/>
+ <xi:include href="s390-acr.xml"/>
+ <xi:include href="s390-fpr.xml"/>
+
+ <feature name="org.gnu.gdb.s390.linux">
+ <reg name="orig_r2" bitsize="64" type="uint64" group="system"/>
+ <reg name="last_break" bitsize="64" type="code_ptr" group="system" save-restore="no"/>
+ <reg name="system_call" bitsize="32" type="uint32" group="system"/>
+ </feature>
+
+ <xi:include href="s390-tdb.xml"/>
+</target>
Index: gdb/gdb/features/Makefile
===================================================================
--- gdb.orig/gdb/features/Makefile
+++ gdb/gdb/features/Makefile
@@ -50,6 +50,7 @@ WHICH = aarch64 \
s390-linux32 s390-linux64 s390x-linux64 \
s390-linux32v1 s390-linux64v1 s390x-linux64v1 \
s390-linux32v2 s390-linux64v2 s390x-linux64v2 \
+ s390-te-linux64 s390x-te-linux64 \
tic6x-c64xp tic6x-c64x tic6x-c62x \
tic6x-c64xp-linux tic6x-c64x-linux tic6x-c62x-linux
@@ -84,9 +85,11 @@ s390-linux32v2-expedite = r14,r15,pswa
s390-linux64-expedite = r14l,r15l,pswa
s390-linux64v1-expedite = r14l,r15l,pswa
s390-linux64v2-expedite = r14l,r15l,pswa
+s390-te-linux64-expedite = r14,r15,pswa
s390x-linux64-expedite = r14,r15,pswa
s390x-linux64v1-expedite = r14,r15,pswa
s390x-linux64v2-expedite = r14,r15,pswa
+s390x-te-linux64-expedite = r14,r15,pswa
tic6x-c64xp-expedite = A15,PC
tic6x-c64x-expedite = A15,PC
tic6x-c62x-expedite = A15,PC
Index: gdb/gdb/features/s390-te-linux64.c
===================================================================
--- /dev/null
+++ gdb/gdb/features/s390-te-linux64.c
@@ -0,0 +1,118 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: s390-te-linux64.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_s390_te_linux64;
+static void
+initialize_tdesc_s390_te_linux64 (void)
+{
+ struct target_desc *result = allocate_target_description ();
+ struct tdesc_feature *feature;
+
+ set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit"));
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core");
+ tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32");
+ tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32");
+ tdesc_create_reg (feature, "r0h", 2, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r0l", 3, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r1h", 4, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r1l", 5, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r2h", 6, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r2l", 7, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r3h", 8, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r3l", 9, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r4h", 10, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r4l", 11, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r5h", 12, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r5l", 13, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r6h", 14, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r6l", 15, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r7h", 16, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r7l", 17, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r8h", 18, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r8l", 19, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r9h", 20, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r9l", 21, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r10h", 22, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r10l", 23, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r11h", 24, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r11l", 25, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r12h", 26, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r12l", 27, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r13h", 28, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r13l", 29, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r14h", 30, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r14l", 31, 1, "lower", 32, "uint32");
+ tdesc_create_reg (feature, "r15h", 32, 1, "upper", 32, "uint32");
+ tdesc_create_reg (feature, "r15l", 33, 1, "lower", 32, "uint32");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.acr");
+ tdesc_create_reg (feature, "acr0", 34, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr1", 35, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr2", 36, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr3", 37, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr4", 38, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr5", 39, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr6", 40, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr7", 41, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr8", 42, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr9", 43, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr10", 44, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr11", 45, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr12", 46, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr13", 47, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr14", 48, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr15", 49, 1, "access", 32, "uint32");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.fpr");
+ tdesc_create_reg (feature, "fpc", 50, 1, "float", 32, "uint32");
+ tdesc_create_reg (feature, "f0", 51, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f1", 52, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f2", 53, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f3", 54, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f4", 55, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f5", 56, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f6", 57, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f7", 58, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f8", 59, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f9", 60, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f10", 61, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f11", 62, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f12", 63, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f13", 64, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f14", 65, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f15", 66, 1, "float", 64, "ieee_double");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.linux");
+ tdesc_create_reg (feature, "orig_r2", 67, 1, "system", 32, "uint32");
+ tdesc_create_reg (feature, "last_break", 68, 0, "system", 32, "code_ptr");
+ tdesc_create_reg (feature, "system_call", 69, 1, "system", 32, "uint32");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.tdb");
+ tdesc_create_reg (feature, "tdb0", 70, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tac", 71, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tct", 72, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "atia", 73, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr0", 74, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr1", 75, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr2", 76, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr3", 77, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr4", 78, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr5", 79, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr6", 80, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr7", 81, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr8", 82, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr9", 83, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr10", 84, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr11", 85, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr12", 86, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr13", 87, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr14", 88, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr15", 89, 1, "tdb", 64, "uint64");
+
+ tdesc_s390_te_linux64 = result;
+}
Index: gdb/gdb/features/s390x-te-linux64.c
===================================================================
--- /dev/null
+++ gdb/gdb/features/s390x-te-linux64.c
@@ -0,0 +1,102 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: s390x-te-linux64.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_s390x_te_linux64;
+static void
+initialize_tdesc_s390x_te_linux64 (void)
+{
+ struct target_desc *result = allocate_target_description ();
+ struct tdesc_feature *feature;
+
+ set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit"));
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core");
+ tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64");
+ tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64");
+ tdesc_create_reg (feature, "r0", 2, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r1", 3, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r2", 4, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r3", 5, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r4", 6, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r5", 7, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r6", 8, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r7", 9, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r8", 10, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r9", 11, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r10", 12, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r11", 13, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r12", 14, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r13", 15, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r14", 16, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "r15", 17, 1, "general", 64, "uint64");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.acr");
+ tdesc_create_reg (feature, "acr0", 18, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr1", 19, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr2", 20, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr3", 21, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr4", 22, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr5", 23, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr6", 24, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr7", 25, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr8", 26, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr9", 27, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr10", 28, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr11", 29, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr12", 30, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr13", 31, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr14", 32, 1, "access", 32, "uint32");
+ tdesc_create_reg (feature, "acr15", 33, 1, "access", 32, "uint32");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.fpr");
+ tdesc_create_reg (feature, "fpc", 34, 1, "float", 32, "uint32");
+ tdesc_create_reg (feature, "f0", 35, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f1", 36, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f2", 37, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f3", 38, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f4", 39, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f5", 40, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f6", 41, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f7", 42, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f8", 43, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f9", 44, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f10", 45, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f11", 46, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f12", 47, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f13", 48, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f14", 49, 1, "float", 64, "ieee_double");
+ tdesc_create_reg (feature, "f15", 50, 1, "float", 64, "ieee_double");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.linux");
+ tdesc_create_reg (feature, "orig_r2", 51, 1, "system", 64, "uint64");
+ tdesc_create_reg (feature, "last_break", 52, 0, "system", 64, "code_ptr");
+ tdesc_create_reg (feature, "system_call", 53, 1, "system", 32, "uint32");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.s390.tdb");
+ tdesc_create_reg (feature, "tdb0", 54, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tac", 55, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tct", 56, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "atia", 57, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr0", 58, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr1", 59, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr2", 60, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr3", 61, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr4", 62, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr5", 63, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr6", 64, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr7", 65, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr8", 66, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr9", 67, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr10", 68, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr11", 69, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr12", 70, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr13", 71, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr14", 72, 1, "tdb", 64, "uint64");
+ tdesc_create_reg (feature, "tr15", 73, 1, "tdb", 64, "uint64");
+
+ tdesc_s390x_te_linux64 = result;
+}
Index: gdb/gdb/regformats/s390-te-linux64.dat
===================================================================
--- /dev/null
+++ gdb/gdb/regformats/s390-te-linux64.dat
@@ -0,0 +1,94 @@
+# DO NOT EDIT: generated from s390-te-linux64.xml
+name:s390_te_linux64
+xmltarget:s390-te-linux64.xml
+expedite:r14,r15,pswa
+32:pswm
+32:pswa
+32:r0h
+32:r0l
+32:r1h
+32:r1l
+32:r2h
+32:r2l
+32:r3h
+32:r3l
+32:r4h
+32:r4l
+32:r5h
+32:r5l
+32:r6h
+32:r6l
+32:r7h
+32:r7l
+32:r8h
+32:r8l
+32:r9h
+32:r9l
+32:r10h
+32:r10l
+32:r11h
+32:r11l
+32:r12h
+32:r12l
+32:r13h
+32:r13l
+32:r14h
+32:r14l
+32:r15h
+32:r15l
+32:acr0
+32:acr1
+32:acr2
+32:acr3
+32:acr4
+32:acr5
+32:acr6
+32:acr7
+32:acr8
+32:acr9
+32:acr10
+32:acr11
+32:acr12
+32:acr13
+32:acr14
+32:acr15
+32:fpc
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
+32:orig_r2
+32:last_break
+32:system_call
+64:tdb0
+64:tac
+64:tct
+64:atia
+64:tr0
+64:tr1
+64:tr2
+64:tr3
+64:tr4
+64:tr5
+64:tr6
+64:tr7
+64:tr8
+64:tr9
+64:tr10
+64:tr11
+64:tr12
+64:tr13
+64:tr14
+64:tr15
Index: gdb/gdb/regformats/s390x-te-linux64.dat
===================================================================
--- /dev/null
+++ gdb/gdb/regformats/s390x-te-linux64.dat
@@ -0,0 +1,78 @@
+# DO NOT EDIT: generated from s390x-te-linux64.xml
+name:s390x_te_linux64
+xmltarget:s390x-te-linux64.xml
+expedite:r14,r15,pswa
+64:pswm
+64:pswa
+64:r0
+64:r1
+64:r2
+64:r3
+64:r4
+64:r5
+64:r6
+64:r7
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+32:acr0
+32:acr1
+32:acr2
+32:acr3
+32:acr4
+32:acr5
+32:acr6
+32:acr7
+32:acr8
+32:acr9
+32:acr10
+32:acr11
+32:acr12
+32:acr13
+32:acr14
+32:acr15
+32:fpc
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
+64:orig_r2
+64:last_break
+32:system_call
+64:tdb0
+64:tac
+64:tct
+64:atia
+64:tr0
+64:tr1
+64:tr2
+64:tr3
+64:tr4
+64:tr5
+64:tr6
+64:tr7
+64:tr8
+64:tr9
+64:tr10
+64:tr11
+64:tr12
+64:tr13
+64:tr14
+64:tr15
Index: gdb/gdb/gdbserver/Makefile.in
===================================================================
--- gdb.orig/gdb/gdbserver/Makefile.in
+++ gdb/gdb/gdbserver/Makefile.in
@@ -334,6 +334,9 @@ clean:
rm -f powerpc-isa205-altivec32l.c powerpc-isa205-vsx32l.c powerpc-isa205-altivec64l.c
rm -f powerpc-isa205-vsx64l.c
rm -f s390-linux32.c s390-linux64.c s390x-linux64.c
+ rm -f s390-linux32v1.c s390-linux32v2.c s390-linux64v1.c
+ rm -f s390-linux64v2.c s390x-linux64v1.c s390x-linux64v2.c
+ rm -f s390-te-linux32.c s390-te-linux64.c
rm -f tic6x-c64xp-linux.c tic6x-c64x-linux.c tic6x-c62x-linux.c
rm -f xml-builtin.c stamp-xml
rm -f i386-avx.c i386-avx-linux.c
@@ -660,12 +663,16 @@ s390-linux64v1.c : $(srcdir)/../regforma
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390-linux64v1.dat s390-linux64v1.c
s390-linux64v2.c : $(srcdir)/../regformats/s390-linux64v2.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390-linux64v2.dat s390-linux64v2.c
+s390-te-linux64.c : $(srcdir)/../regformats/s390-te-linux64.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390-te-linux64.dat s390-te-linux64.c
s390x-linux64.c : $(srcdir)/../regformats/s390x-linux64.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-linux64.dat s390x-linux64.c
s390x-linux64v1.c : $(srcdir)/../regformats/s390x-linux64v1.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-linux64v1.dat s390x-linux64v1.c
s390x-linux64v2.c : $(srcdir)/../regformats/s390x-linux64v2.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-linux64v2.dat s390x-linux64v2.c
+s390x-te-linux64.c : $(srcdir)/../regformats/s390x-te-linux64.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-te-linux64.dat s390x-te-linux64.c
tic6x-c64xp-linux.c : $(srcdir)/../regformats/tic6x-c64xp-linux.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/tic6x-c64xp-linux.dat tic6x-c64xp-linux.c
Index: gdb/gdb/gdbserver/configure.srv
===================================================================
--- gdb.orig/gdb/gdbserver/configure.srv
+++ gdb/gdb/gdbserver/configure.srv
@@ -267,9 +267,11 @@ case "${target}" in
srv_regobj="${srv_regobj} s390-linux64.o"
srv_regobj="${srv_regobj} s390-linux64v1.o"
srv_regobj="${srv_regobj} s390-linux64v2.o"
+ srv_regobj="${srv_regobj} s390-te-linux64.o"
srv_regobj="${srv_regobj} s390x-linux64.o"
srv_regobj="${srv_regobj} s390x-linux64v1.o"
srv_regobj="${srv_regobj} s390x-linux64v2.o"
+ srv_regobj="${srv_regobj} s390x-te-linux64.o"
srv_tgtobj="linux-low.o linux-osdata.o linux-s390-low.o linux-procfs.o"
srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
srv_xmlfiles="s390-linux32.xml"
@@ -278,14 +280,17 @@ case "${target}" in
srv_xmlfiles="${srv_xmlfiles} s390-linux64.xml"
srv_xmlfiles="${srv_xmlfiles} s390-linux64v1.xml"
srv_xmlfiles="${srv_xmlfiles} s390-linux64v2.xml"
+ srv_xmlfiles="${srv_xmlfiles} s390-te-linux64.xml"
srv_xmlfiles="${srv_xmlfiles} s390x-linux64.xml"
srv_xmlfiles="${srv_xmlfiles} s390x-linux64v1.xml"
srv_xmlfiles="${srv_xmlfiles} s390x-linux64v2.xml"
+ srv_xmlfiles="${srv_xmlfiles} s390x-te-linux64.xml"
srv_xmlfiles="${srv_xmlfiles} s390-core32.xml"
srv_xmlfiles="${srv_xmlfiles} s390-core64.xml"
srv_xmlfiles="${srv_xmlfiles} s390x-core64.xml"
srv_xmlfiles="${srv_xmlfiles} s390-acr.xml"
srv_xmlfiles="${srv_xmlfiles} s390-fpr.xml"
+ srv_xmlfiles="${srv_xmlfiles} s390-tdb.xml"
srv_linux_usrregs=yes
srv_linux_regsets=yes
srv_linux_thread_db=yes
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFA][PATCH v4 3/5] Dynamic core regset sections support
2013-07-03 16:57 [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
2013-07-03 17:00 ` [RFA][PATCH v4 1/5] S/390 regmap rework Andreas Arnez
2013-07-03 17:02 ` [RFA][PATCH v4 2/5] S/390: Add TDB regset Andreas Arnez
@ 2013-07-03 17:04 ` Andreas Arnez
2013-07-03 17:11 ` [RFA][PATCH v4 4/5] S/390: Exploit dynamic core regset sections Andreas Arnez
` (2 subsequent siblings)
5 siblings, 0 replies; 19+ messages in thread
From: Andreas Arnez @ 2013-07-03 17:04 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
Introduce a new way of specifying core file register note sections on
GNU/Linux targets. So far the target-dependent code provides a static
list of supported register note sections. This change enables the use
of an iterator function instead. The existing "static list" interface
is preserved.
A dynamic selection of regset sections is needed on z/Architecture
systems with transactional-execution support. With the static
approach, gcore always writes the TDB regset into the core file, even
if the inferior was stopped outside transactions and thus the TDB
registers are currently invalid. This results in writing zeroes,
which is wrong.
The use of an iterator function can also reduce complexity in the tdep
code for targets with many different register set combinations.
2013-07-03 Andreas Arnez <arnez@linux.vnet.ibm.com>
* regset.h (regset_iterate_over_sections): New function
declaration.
* regset.c (regset_iterate_over_sections): New function.
* gdbarch.sh: Add typedef for iterate_over_regset_sections_cb.
Support predicate functions with invalid_p.
(function_list): Add iterate_over_regset_sections.
* gdbarch.h: Regenerate.
* gdbarch.c: Regenerate.
* linux-tdep.c (linux_collect_regset_section_cb_data): New
structure.
(linux_collect_regset_section_cb): New function.
(linux_collect_thread_registers): Replace loop by iteration
through gdbarch_iterate_over_regset_sections.
(linux_make_corefile_notes_1): Adjust check.
* corelow.c (get_core_registers_cb): New function.
(get_core_registers): Instead of looping through the list returned
by gdbarch_core_regset_sections, iterate get_core_registers_cb via
gdbarch_iterate_over_regset_sections.
Index: gdb/gdb/gdbarch.sh
===================================================================
--- gdb.orig/gdb/gdbarch.sh
+++ gdb/gdb/gdbarch.sh
@@ -99,9 +99,7 @@ EOF
esac
case "${class}" in
- F | V | M )
- case "${invalid_p}" in
- "" )
+ F | V | M )
if test -n "${predefault}"
then
#invalid_p="gdbarch->${function} == ${predefault}"
@@ -114,12 +112,6 @@ EOF
predicate="gdbarch->${function} != NULL"
fi
;;
- * )
- echo "Predicate function ${function} with invalid_p." 1>&2
- kill $$
- exit 1
- ;;
- esac
esac
# PREDEFAULT is a valid fallback definition of MEMBER when
@@ -635,7 +627,15 @@ F:CORE_ADDR:fetch_pointer_argument:struc
# name SECT_NAME and size SECT_SIZE.
M:const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size
-# Supported register notes in a core file.
+# Iterate over all supported register notes in a core file. For each
+# supported register note section, the iterator must call CB and pass
+# CB_DATA unchanged. If CB returns non-zero, the iterator must stop.
+# If REGCACHE is not NULL, the iterator can limit the supported
+# register note sections based on the current register values.
+# Otherwise it should enumerate all supported register note sections.
+M:void:iterate_over_regset_sections:iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache:cb, cb_data, regcache:::regset_iterate_over_sections:gdbarch->core_regset_sections && !gdbarch->iterate_over_regset_sections
+# Old way of specifying supported register notes in a core file, as a
+# static list. This overrides the iterator function above.
v:struct core_regset_section *:core_regset_sections:const char *name, int len::::::host_address_to_string (gdbarch->core_regset_sections)
# Create core file notes
@@ -992,12 +992,6 @@ EOF
do
eval echo \"\ \ \ \ ${r}=\${${r}}\"
done
- if class_is_predicate_p && fallback_default_p
- then
- echo "Error: predicate function ${function} can not have a non- multi-arch default" 1>&2
- kill $$
- exit 1
- fi
if [ "x${invalid_p}" = "x0" -a -n "${postdefault}" ]
then
echo "Error: postdefault is useless when invalid_p=0" 1>&2
@@ -1120,6 +1114,9 @@ extern struct gdbarch startup_gdbarch;
typedef int (iterate_over_objfiles_in_search_order_cb_ftype)
(struct objfile *objfile, void *cb_data);
+
+typedef int (iterate_over_regset_sections_cb)
+ (const char *sect_name, int size, const char *human_name, void *cb_data);
EOF
# function typedef's
@@ -1432,6 +1429,7 @@ cat <<EOF
#include "gdb_obstack.h"
#include "observer.h"
#include "regcache.h"
+#include "regset.h"
#include "objfiles.h"
/* Static function declarations */
@@ -1700,14 +1698,14 @@ do
if [ "x${invalid_p}" = "x0" ]
then
printf " /* Skip verify of ${function}, invalid_p == 0 */\n"
- elif class_is_predicate_p
- then
- printf " /* Skip verify of ${function}, has predicate. */\n"
# FIXME: See do_read for potential simplification
elif [ -n "${invalid_p}" -a -n "${postdefault}" ]
then
printf " if (${invalid_p})\n"
printf " gdbarch->${function} = ${postdefault};\n"
+ elif class_is_predicate_p
+ then
+ printf " /* Skip verify of ${function}, has predicate. */\n"
elif [ -n "${predefault}" -a -n "${postdefault}" ]
then
printf " if (gdbarch->${function} == ${predefault})\n"
Index: gdb/gdb/linux-tdep.c
===================================================================
--- gdb.orig/gdb/linux-tdep.c
+++ gdb/gdb/linux-tdep.c
@@ -1010,6 +1010,54 @@ linux_make_mappings_corefile_notes (stru
return note_data;
}
+/* Structure for passing information from
+ linux_collect_thread_registers via an iterator to
+ linux_collect_regset_section_cb. */
+
+struct linux_collect_regset_section_cb_data
+{
+ struct gdbarch *gdbarch;
+ const struct regcache *regcache;
+ bfd *obfd;
+ char *note_data;
+ int *note_size;
+ unsigned long lwp;
+ enum gdb_signal stop_signal;
+};
+
+/* Callback for iterate_over_regset_sections that records a single
+ regset in the corefile note section. */
+
+static int
+linux_collect_regset_section_cb (const char *sect_name, int size,
+ const char *human_name, void *cb_data)
+{
+ const struct regset *regset;
+ char *buf;
+ struct linux_collect_regset_section_cb_data *data = cb_data;
+
+ regset = gdbarch_regset_from_core_section (data->gdbarch, sect_name, size);
+ gdb_assert (regset && regset->collect_regset);
+
+ buf = xmalloc (size);
+ regset->collect_regset (regset, data->regcache, -1, buf, size);
+
+ /* PRSTATUS still needs to be treated specially. */
+ if (strcmp (sect_name, ".reg") == 0)
+ data->note_data = (char *) elfcore_write_prstatus
+ (data->obfd, data->note_data, data->note_size, data->lwp,
+ gdb_signal_to_host (data->stop_signal), buf);
+ else
+ data->note_data = (char *) elfcore_write_register_note
+ (data->obfd, data->note_data, data->note_size,
+ sect_name, buf, size);
+ xfree (buf);
+
+ if (!data->note_data)
+ return 1; /* Abort iteration. */
+ return 0;
+}
+
/* Records the thread's register state for the corefile note
section. */
@@ -1020,47 +1068,24 @@ linux_collect_thread_registers (const st
enum gdb_signal stop_signal)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct core_regset_section *sect_list;
- unsigned long lwp;
+ struct linux_collect_regset_section_cb_data data;
- sect_list = gdbarch_core_regset_sections (gdbarch);
- gdb_assert (sect_list);
+ data.gdbarch = gdbarch;
+ data.regcache = regcache;
+ data.obfd = obfd;
+ data.note_data = note_data;
+ data.note_size = note_size;
+ data.stop_signal = stop_signal;
/* For remote targets the LWP may not be available, so use the TID. */
- lwp = ptid_get_lwp (ptid);
- if (!lwp)
- lwp = ptid_get_tid (ptid);
-
- while (sect_list->sect_name != NULL)
- {
- const struct regset *regset;
- char *buf;
-
- regset = gdbarch_regset_from_core_section (gdbarch,
- sect_list->sect_name,
- sect_list->size);
- gdb_assert (regset && regset->collect_regset);
-
- buf = xmalloc (sect_list->size);
- regset->collect_regset (regset, regcache, -1, buf, sect_list->size);
-
- /* PRSTATUS still needs to be treated specially. */
- if (strcmp (sect_list->sect_name, ".reg") == 0)
- note_data = (char *) elfcore_write_prstatus
- (obfd, note_data, note_size, lwp,
- gdb_signal_to_host (stop_signal), buf);
- else
- note_data = (char *) elfcore_write_register_note
- (obfd, note_data, note_size,
- sect_list->sect_name, buf, sect_list->size);
- xfree (buf);
- sect_list++;
-
- if (!note_data)
- return NULL;
- }
-
- return note_data;
+ data.lwp = ptid_get_lwp (ptid);
+ if (!data.lwp)
+ data.lwp = ptid_get_tid (ptid);
+
+ gdbarch_iterate_over_regset_sections (gdbarch,
+ linux_collect_regset_section_cb,
+ &data, regcache);
+ return data.note_data;
}
/* Fetch the siginfo data for the current thread, if it exists. If
@@ -1440,7 +1465,7 @@ linux_make_corefile_notes_1 (struct gdba
converted to gdbarch_core_regset_sections, we no longer need to fall back
to the target method at this point. */
- if (!gdbarch_core_regset_sections (gdbarch))
+ if (!gdbarch_iterate_over_regset_sections_p (gdbarch))
return target_make_corefile_notes (obfd, note_size);
else
return linux_make_corefile_notes (gdbarch, obfd, note_size,
Index: gdb/gdb/gdbarch.c
===================================================================
--- gdb.orig/gdb/gdbarch.c
+++ gdb/gdb/gdbarch.c
@@ -49,6 +49,7 @@
#include "gdb_obstack.h"
#include "observer.h"
#include "regcache.h"
+#include "regset.h"
#include "objfiles.h"
/* Static function declarations */
@@ -236,6 +237,7 @@ struct gdbarch
gdbarch_register_reggroup_p_ftype *register_reggroup_p;
gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument;
gdbarch_regset_from_core_section_ftype *regset_from_core_section;
+ gdbarch_iterate_over_regset_sections_ftype *iterate_over_regset_sections;
struct core_regset_section * core_regset_sections;
gdbarch_make_corefile_notes_ftype *make_corefile_notes;
gdbarch_elfcore_write_linux_prpsinfo_ftype *elfcore_write_linux_prpsinfo;
@@ -408,6 +410,7 @@ struct gdbarch startup_gdbarch =
default_register_reggroup_p, /* register_reggroup_p */
0, /* fetch_pointer_argument */
0, /* regset_from_core_section */
+ 0, /* iterate_over_regset_sections */
0, /* core_regset_sections */
0, /* make_corefile_notes */
0, /* elfcore_write_linux_prpsinfo */
@@ -712,6 +715,8 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of register_reggroup_p, invalid_p == 0 */
/* Skip verify of fetch_pointer_argument, has predicate. */
/* Skip verify of regset_from_core_section, has predicate. */
+ if (gdbarch->core_regset_sections && !gdbarch->iterate_over_regset_sections)
+ gdbarch->iterate_over_regset_sections = regset_iterate_over_sections;
/* Skip verify of make_corefile_notes, has predicate. */
/* Skip verify of elfcore_write_linux_prpsinfo, has predicate. */
/* Skip verify of find_memory_regions, has predicate. */
@@ -1102,6 +1107,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
"gdbarch_dump: iterate_over_objfiles_in_search_order = <%s>\n",
host_address_to_string (gdbarch->iterate_over_objfiles_in_search_order));
fprintf_unfiltered (file,
+ "gdbarch_dump: gdbarch_iterate_over_regset_sections_p() = %d\n",
+ gdbarch_iterate_over_regset_sections_p (gdbarch));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: iterate_over_regset_sections = <%s>\n",
+ host_address_to_string (gdbarch->iterate_over_regset_sections));
+ fprintf_unfiltered (file,
"gdbarch_dump: long_bit = %s\n",
plongest (gdbarch->long_bit));
fprintf_unfiltered (file,
@@ -3345,6 +3356,30 @@ set_gdbarch_regset_from_core_section (st
gdbarch->regset_from_core_section = regset_from_core_section;
}
+int
+gdbarch_iterate_over_regset_sections_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->iterate_over_regset_sections != NULL;
+}
+
+void
+gdbarch_iterate_over_regset_sections (struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->iterate_over_regset_sections != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_iterate_over_regset_sections called\n");
+ gdbarch->iterate_over_regset_sections (gdbarch, cb, cb_data, regcache);
+}
+
+void
+set_gdbarch_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ gdbarch_iterate_over_regset_sections_ftype iterate_over_regset_sections)
+{
+ gdbarch->iterate_over_regset_sections = iterate_over_regset_sections;
+}
+
struct core_regset_section *
gdbarch_core_regset_sections (struct gdbarch *gdbarch)
{
Index: gdb/gdb/gdbarch.h
===================================================================
--- gdb.orig/gdb/gdbarch.h
+++ gdb/gdb/gdbarch.h
@@ -85,6 +85,9 @@ extern struct gdbarch startup_gdbarch;
typedef int (iterate_over_objfiles_in_search_order_cb_ftype)
(struct objfile *objfile, void *cb_data);
+typedef int (iterate_over_regset_sections_cb)
+ (const char *sect_name, int size, const char *human_name, void *cb_data);
+
/* The following are pre-initialized by GDBARCH. */
@@ -724,7 +727,21 @@ typedef const struct regset * (gdbarch_r
extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size);
extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section);
-/* Supported register notes in a core file. */
+/* Iterate over all supported register notes in a core file. For each
+ supported register note section, the iterator must call CB and pass
+ CB_DATA unchanged. If CB returns non-zero, the iterator must stop.
+ If REGCACHE is not NULL, the iterator can limit the supported
+ register note sections based on the current register values.
+ Otherwise it should enumerate all supported register note sections. */
+
+extern int gdbarch_iterate_over_regset_sections_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_iterate_over_regset_sections_ftype) (struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache);
+extern void gdbarch_iterate_over_regset_sections (struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache);
+extern void set_gdbarch_iterate_over_regset_sections (struct gdbarch *gdbarch, gdbarch_iterate_over_regset_sections_ftype *iterate_over_regset_sections);
+
+/* Old way of specifying supported register notes in a core file, as a
+ static list. This overrides the iterator function above. */
extern struct core_regset_section * gdbarch_core_regset_sections (struct gdbarch *gdbarch);
extern void set_gdbarch_core_regset_sections (struct gdbarch *gdbarch, struct core_regset_section * core_regset_sections);
Index: gdb/gdb/regset.h
===================================================================
--- gdb.orig/gdb/regset.h
+++ gdb/gdb/regset.h
@@ -66,4 +66,11 @@ extern struct regset *regset_alloc (stru
supply_regset_ftype *supply_regset,
collect_regset_ftype *collect_regset);
+/* Iterate over the list of regsets specified with
+ gdbarch_set_core_regset_sections. */
+extern void regset_iterate_over_sections (struct gdbarch *arch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache);
+
#endif /* regset.h */
Index: gdb/gdb/corelow.c
===================================================================
--- gdb.orig/gdb/corelow.c
+++ gdb/gdb/corelow.c
@@ -547,6 +547,24 @@ get_core_register_section (struct regcac
bfd_section_vma (core_bfd, section)));
}
+/* Callback for get_core_registers that handles a single core file
+ register note section. */
+
+static int
+get_core_registers_cb (const char *sect_name, int size,
+ const char *human_name, void *cb_data)
+{
+ struct regcache *regcache = (struct regcache *) cb_data;
+
+ if (strcmp (sect_name, ".reg") == 0)
+ get_core_register_section (regcache, sect_name, 0, human_name, 1);
+ else if (strcmp (sect_name, ".reg2") == 0)
+ get_core_register_section (regcache, sect_name, 2, human_name, 0);
+ else
+ get_core_register_section (regcache, sect_name, 3, human_name, 0);
+
+ return 0;
+}
/* Get the registers out of a core file. This is the machine-
independent part. Fetch_core_registers is the machine-dependent
@@ -559,8 +577,8 @@ static void
get_core_registers (struct target_ops *ops,
struct regcache *regcache, int regno)
{
- struct core_regset_section *sect_list;
int i;
+ struct gdbarch *gdbarch;
if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
&& (core_vec == NULL || core_vec->core_read_registers == NULL))
@@ -570,23 +588,11 @@ get_core_registers (struct target_ops *o
return;
}
- sect_list = gdbarch_core_regset_sections (get_regcache_arch (regcache));
- if (sect_list)
- while (sect_list->sect_name != NULL)
- {
- if (strcmp (sect_list->sect_name, ".reg") == 0)
- get_core_register_section (regcache, sect_list->sect_name,
- 0, sect_list->human_name, 1);
- else if (strcmp (sect_list->sect_name, ".reg2") == 0)
- get_core_register_section (regcache, sect_list->sect_name,
- 2, sect_list->human_name, 0);
- else
- get_core_register_section (regcache, sect_list->sect_name,
- 3, sect_list->human_name, 0);
-
- sect_list++;
- }
-
+ gdbarch = get_regcache_arch (regcache);
+ if (gdbarch_iterate_over_regset_sections_p (gdbarch))
+ gdbarch_iterate_over_regset_sections (gdbarch,
+ get_core_registers_cb,
+ (void *) regcache, NULL);
else
{
get_core_register_section (regcache,
Index: gdb/gdb/regset.c
===================================================================
--- gdb.orig/gdb/regset.c
+++ gdb/gdb/regset.c
@@ -42,3 +42,25 @@ regset_alloc (struct gdbarch *arch,
return regset;
}
+
+/* Iterate over the list of regsets specified with
+ gdbarch_set_core_regset_sections. This is a convenience function
+ for targets which do not need a complex iterator. */
+
+void
+regset_iterate_over_sections (struct gdbarch *arch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ struct core_regset_section *sect_list;
+
+ sect_list = gdbarch_core_regset_sections (arch);
+ while (sect_list->sect_name != NULL)
+ {
+ if (cb (sect_list->sect_name, sect_list->size,
+ sect_list->human_name, cb_data))
+ return;
+ sect_list++;
+ }
+}
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFA][PATCH v4 4/5] S/390: Exploit dynamic core regset sections
2013-07-03 16:57 [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
` (2 preceding siblings ...)
2013-07-03 17:04 ` [RFA][PATCH v4 3/5] Dynamic core regset sections support Andreas Arnez
@ 2013-07-03 17:11 ` Andreas Arnez
2013-07-03 17:21 ` [RFA][PATCH v4 5/5] PowerPC: " Andreas Arnez
2013-07-08 15:44 ` [ping] [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
5 siblings, 0 replies; 19+ messages in thread
From: Andreas Arnez @ 2013-07-03 17:11 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
Exploit dynamic core regset sections on S/390, such that the presence of
the TDB regset in a gcore-written core file depends on the validity of
the TDB registers.
2013-07-03 Andreas Arnez <arnez@linux.vnet.ibm.com>
* s390-tdep.c (gdbarch_tdep): New fields "have_linux_v1" and
"have_linux_v2".
(s390_linux32_regset_sections): Remove array.
(s390_linux32v1_regset_sections): Likewise.
(s390_linux32v2_regset_sections): Likewise.
(s390_linux64_regset_sections): Likewise.
(s390_linux64v1_regset_sections): Likewise.
(s390_linux64v2_regset_sections): Likewise.
(s390x_linux64_regset_sections): Likewise.
(s390x_linux64v1_regset_sections): Likewise.
(s390x_linux64v2_regset_sections): Likewise.
(s390_iterate_over_regset_sections ): New function.
(s390_gdbarch_init): Initialize new tdep fields "have_linux_v1"
and "have_linux_v2". Remove all invocations of
set_gdbarch_core_regset_sections; instead, call
set_gdbarch_iterate_over_regset_sections.
Index: gdb/gdb/s390-tdep.c
===================================================================
--- gdb.orig/gdb/s390-tdep.c
+++ gdb/gdb/s390-tdep.c
@@ -84,6 +84,9 @@ struct gdbarch_tdep
const struct regset *fpregset;
int sizeof_fpregset;
+
+ int have_linux_v1;
+ int have_linux_v2;
};
@@ -673,83 +676,38 @@ static const struct regset s390_tdb_regs
s390_collect_regset
};
-static struct core_regset_section s390_linux32_regset_sections[] =
-{
- { ".reg", s390_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { NULL, 0}
-};
-
-static struct core_regset_section s390_linux32v1_regset_sections[] =
-{
- { ".reg", s390_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { ".reg-s390-last-break", 8, "s390 last-break address" },
- { NULL, 0}
-};
-
-static struct core_regset_section s390_linux32v2_regset_sections[] =
-{
- { ".reg", s390_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { ".reg-s390-last-break", 8, "s390 last-break address" },
- { ".reg-s390-system-call", 4, "s390 system-call" },
- { NULL, 0}
-};
-
-static struct core_regset_section s390_linux64_regset_sections[] =
-{
- { ".reg", s390_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
- { NULL, 0}
-};
-
-static struct core_regset_section s390_linux64v1_regset_sections[] =
-{
- { ".reg", s390_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
- { ".reg-s390-last-break", 8, "s930 last-break address" },
- { NULL, 0}
-};
-
-static struct core_regset_section s390_linux64v2_regset_sections[] =
-{
- { ".reg", s390_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
- { ".reg-s390-last-break", 8, "s930 last-break address" },
- { ".reg-s390-system-call", 4, "s390 system-call" },
- { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
- { NULL, 0}
-};
-
-static struct core_regset_section s390x_linux64_regset_sections[] =
-{
- { ".reg", s390x_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { NULL, 0}
-};
-
-static struct core_regset_section s390x_linux64v1_regset_sections[] =
-{
- { ".reg", s390x_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { ".reg-s390-last-break", 8, "s930 last-break address" },
- { NULL, 0}
-};
+/* Iterate over supported core file register note sections. */
-static struct core_regset_section s390x_linux64v2_regset_sections[] =
+static void
+s390_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
{
- { ".reg", s390x_sizeof_gregset, "general-purpose" },
- { ".reg2", s390_sizeof_fpregset, "floating-point" },
- { ".reg-s390-last-break", 8, "s930 last-break address" },
- { ".reg-s390-system-call", 4, "s390 system-call" },
- { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
- { NULL, 0}
-};
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int is_32_bit = tdep->abi == ABI_LINUX_S390 && tdep->gpr_full_regnum == -1;
+ if (cb (".reg", is_32_bit ? s390_sizeof_gregset : s390x_sizeof_gregset,
+ "general-purpose", cb_data))
+ return;
+ if (cb (".reg2", s390_sizeof_fpregset, "floating-point", cb_data))
+ return;
+ if (tdep->abi == ABI_LINUX_S390 && tdep->gpr_full_regnum != -1)
+ if (cb (".reg-s390-high-gprs", 16*4, "s390 GPR upper halves", cb_data))
+ return;
+ if (tdep->have_linux_v1)
+ if (cb (".reg-s390-last-break", 8, "s930 last-break address", cb_data))
+ return;
+ if (tdep->have_linux_v2)
+ {
+ if (cb (".reg-s390-system-call", 4, "s390 system-call", cb_data))
+ return;
+ if (regcache == NULL
+ || REG_VALID == regcache_register_status (regcache,
+ S390_TDB_DWORD0_REGNUM))
+ cb (".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB", cb_data);
+ }
+}
/* Return the appropriate register set for the core section identified
by SECT_NAME and SECT_SIZE. */
@@ -3160,20 +3118,23 @@ s390_gdbarch_init (struct gdbarch_info i
arches = gdbarch_list_lookup_by_info (arches->next, &info))
{
tdep = gdbarch_tdep (arches->gdbarch);
- if (!tdep)
- continue;
- if (tdep->abi != tdep_abi)
- continue;
- if ((tdep->gpr_full_regnum != -1) != have_upper)
- continue;
- if (tdesc_data != NULL)
- tdesc_data_cleanup (tdesc_data);
- return arches->gdbarch;
+ if (tdep
+ && tdep->abi == tdep_abi
+ && (tdep->gpr_full_regnum != -1) == have_upper
+ && tdep->have_linux_v1 == have_linux_v1
+ && tdep->have_linux_v2 == have_linux_v2)
+ {
+ if (tdesc_data != NULL)
+ tdesc_data_cleanup (tdesc_data);
+ return arches->gdbarch;
+ }
}
/* Otherwise create a new gdbarch for the specified machine type. */
tdep = XCALLOC (1, struct gdbarch_tdep);
tdep->abi = tdep_abi;
+ tdep->have_linux_v1 = have_linux_v1;
+ tdep->have_linux_v2 = have_linux_v2;
gdbarch = gdbarch_alloc (&info, tdep);
set_gdbarch_believe_pcc_promotion (gdbarch, 0);
@@ -3204,6 +3165,8 @@ s390_gdbarch_init (struct gdbarch_info i
set_gdbarch_regset_from_core_section (gdbarch,
s390_regset_from_core_section);
set_gdbarch_core_read_description (gdbarch, s390_core_read_description);
+ set_gdbarch_iterate_over_regset_sections (gdbarch,
+ s390_iterate_over_regset_sections);
set_gdbarch_cannot_store_register (gdbarch, s390_cannot_store_register);
set_gdbarch_write_pc (gdbarch, s390_write_pc);
set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read);
@@ -3271,31 +3234,6 @@ s390_gdbarch_init (struct gdbarch_info i
set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- if (have_upper)
- {
- if (have_linux_v2)
- set_gdbarch_core_regset_sections (gdbarch,
- s390_linux64v2_regset_sections);
- else if (have_linux_v1)
- set_gdbarch_core_regset_sections (gdbarch,
- s390_linux64v1_regset_sections);
- else
- set_gdbarch_core_regset_sections (gdbarch,
- s390_linux64_regset_sections);
- }
- else
- {
- if (have_linux_v2)
- set_gdbarch_core_regset_sections (gdbarch,
- s390_linux32v2_regset_sections);
- else if (have_linux_v1)
- set_gdbarch_core_regset_sections (gdbarch,
- s390_linux32v1_regset_sections);
- else
- set_gdbarch_core_regset_sections (gdbarch,
- s390_linux32_regset_sections);
- }
break;
case ABI_LINUX_ZSERIES:
@@ -3315,16 +3253,6 @@ s390_gdbarch_init (struct gdbarch_info i
s390_address_class_type_flags_to_name);
set_gdbarch_address_class_name_to_type_flags (gdbarch,
s390_address_class_name_to_type_flags);
-
- if (have_linux_v2)
- set_gdbarch_core_regset_sections (gdbarch,
- s390x_linux64v2_regset_sections);
- else if (have_linux_v1)
- set_gdbarch_core_regset_sections (gdbarch,
- s390x_linux64v1_regset_sections);
- else
- set_gdbarch_core_regset_sections (gdbarch,
- s390x_linux64_regset_sections);
break;
}
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFA][PATCH v4 5/5] PowerPC: Exploit dynamic core regset sections
2013-07-03 16:57 [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
` (3 preceding siblings ...)
2013-07-03 17:11 ` [RFA][PATCH v4 4/5] S/390: Exploit dynamic core regset sections Andreas Arnez
@ 2013-07-03 17:21 ` Andreas Arnez
2013-07-08 15:44 ` [ping] [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
5 siblings, 0 replies; 19+ messages in thread
From: Andreas Arnez @ 2013-07-03 17:21 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
Use a dynamic iterator function for enumerating the supported core
regset sections on a PowerPC target. Compared to the previous approach
of selecting one out of six static lists, this simplifies the code.
2013-07-03 Andreas Arnez <arnez@linux.vnet.ibm.com>
* ppc-linux-tdep.c (ppc_linux_vsx_regset_sections): Remove array.
(ppc_linux_vmx_regset_sections): Likewise.
(ppc_linux_fp_regset_sections): Likewise.
(ppc64_linux_vsx_regset_sections): Likewise.
(ppc64_linux_vmx_regset_sections): Likewise.
(ppc64_linux_fp_regset_sections): Likewise.
(ppc_linux_iterate_over_regset_sections): New function.
(ppc_linux_init_abi): Remove all invocations of
set_gdbarch_core_regset_sections; instead, call
set_gdbarch_iterate_over_regset_sections.
Index: gdb/gdb/ppc-linux-tdep.c
===================================================================
--- gdb.orig/gdb/ppc-linux-tdep.c
+++ gdb/gdb/ppc-linux-tdep.c
@@ -256,53 +256,28 @@ ppc_linux_return_value (struct gdbarch *
readbuf, writebuf);
}
-static struct core_regset_section ppc_linux_vsx_regset_sections[] =
-{
- { ".reg", 48 * 4, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { ".reg-ppc-vsx", 256, "POWER7 VSX" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc_linux_vmx_regset_sections[] =
-{
- { ".reg", 48 * 4, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc_linux_fp_regset_sections[] =
-{
- { ".reg", 48 * 4, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc64_linux_vsx_regset_sections[] =
-{
- { ".reg", 48 * 8, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { ".reg-ppc-vsx", 256, "POWER7 VSX" },
- { NULL, 0}
-};
+/* Iterate over supported core file register note sections. */
-static struct core_regset_section ppc64_linux_vmx_regset_sections[] =
+static void
+ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
{
- { ".reg", 48 * 8, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { NULL, 0}
-};
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int have_vsx = tdep->ppc_vr0_regnum != -1;
+ int have_altivec = tdep->ppc_vsr0_upper_regnum != -1;
-static struct core_regset_section ppc64_linux_fp_regset_sections[] =
-{
- { ".reg", 48 * 8, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { NULL, 0}
-};
+ if (cb (".reg", 48 * tdep->wordsize, "general-purpose", cb_data))
+ return;
+ if (cb (".reg2", 264, "floating-point", cb_data))
+ return;
+ if (have_altivec)
+ if (cb (".reg-ppc-vmx", 544, "ppc Altivec", cb_data))
+ return;
+ if (have_vsx)
+ cb (".reg-ppc-vsx", 256, "POWER7 VSX", cb_data);
+}
/* PLT stub in executable. */
static struct ppc_insn_pattern powerpc32_plt_stub[] =
@@ -1305,19 +1280,6 @@ ppc_linux_init_abi (struct gdbarch_info
else
set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
- /* Supported register sections. */
- if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.vsx"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc_linux_vsx_regset_sections);
- else if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.altivec"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc_linux_vmx_regset_sections);
- else
- set_gdbarch_core_regset_sections (gdbarch,
- ppc_linux_fp_regset_sections);
-
if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
{
powerpc_so_ops = svr4_so_ops;
@@ -1359,19 +1321,6 @@ ppc_linux_init_abi (struct gdbarch_info
set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle");
else
set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
-
- /* Supported register sections. */
- if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.vsx"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc64_linux_vsx_regset_sections);
- else if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.altivec"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc64_linux_vmx_regset_sections);
- else
- set_gdbarch_core_regset_sections (gdbarch,
- ppc64_linux_fp_regset_sections);
}
/* PPC32 uses a different prpsinfo32 compared to most other Linux
@@ -1383,6 +1332,8 @@ ppc_linux_init_abi (struct gdbarch_info
set_gdbarch_regset_from_core_section (gdbarch,
ppc_linux_regset_from_core_section);
set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
+ set_gdbarch_iterate_over_regset_sections (gdbarch,
+ ppc_linux_iterate_over_regset_sections);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFA][PATCH v4 2/5] S/390: Add TDB regset
2013-07-03 17:02 ` [RFA][PATCH v4 2/5] S/390: Add TDB regset Andreas Arnez
@ 2013-07-03 19:25 ` Eli Zaretskii
0 siblings, 0 replies; 19+ messages in thread
From: Eli Zaretskii @ 2013-07-03 19:25 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Ulrich.Weigand
> From: Andreas Arnez <arnez@linux.vnet.ibm.com>
> Cc: Ulrich.Weigand@de.ibm.com
> Date: Wed, 03 Jul 2013 19:02:32 +0200
>
> The z/Architecture transactional-execution facility includes support
> for a "transaction diagnostic block" (TDB) that is written by the
> hardware upon interrupted transactions. From a running inferior the
> TDB can be retrieved via PTRACE_GETREGSET, but ENODATA is returned if
> the inferior was interrupted outside transactions. Analogously, a
> core file conditionally contains the TDB, depending on whether the
> process died within a transaction or not.
>
> This patch represents the TDB as a new regset in GDB. A new feature
> "org.gnu.gdb.s390.tdb" is defined and new target descriptions are
> provided.
Thanks, the documentation parts are OK.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [ping] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-03 16:57 [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
` (4 preceding siblings ...)
2013-07-03 17:21 ` [RFA][PATCH v4 5/5] PowerPC: " Andreas Arnez
@ 2013-07-08 15:44 ` Andreas Arnez
2013-07-15 8:49 ` [ping 2] " Andreas Arnez
5 siblings, 1 reply; 19+ messages in thread
From: Andreas Arnez @ 2013-07-08 15:44 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
Is this good to go now? Any remaining concerns with the patch set?
Andreas Arnez <arnez@linux.vnet.ibm.com> writes:
> This is another iteration of GDB support for the "transaction diagnostic
> block", TDB, which is provided by the transactional-execution facility
> in newer z/Architecture systems.
>
> There was some discussion on previous versions of this patch,
> specifically about the part that introduces dynamic core file register
> notes support. Thus this version continues supporting the old "static"
> interface. Also, the architecture-specific patches are now separated
> out for easier review.
>
> NEWS | 4
> corelow.c | 42 +--
> doc/gdb.texinfo | 38 ++
> features/Makefile | 3
> gdbarch.c | 35 ++
> gdbarch.h | 19 +
> gdbarch.sh | 36 +-
> gdbserver/Makefile.in | 7
> gdbserver/configure.srv | 5
> gdbserver/linux-s390-low.c | 25 +
> linux-tdep.c | 103 ++++---
> ppc-linux-tdep.c | 93 +------
> regset.c | 22 +
> regset.h | 7
> s390-nat.c | 256 +++++++++----------
> s390-tdep.c | 590 +++++++++++++++++++++------------------------
> s390-tdep.h | 60 ++++
> 17 files changed, 739 insertions(+), 606 deletions(-)
^ permalink raw reply [flat|nested] 19+ messages in thread
* [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-08 15:44 ` [ping] [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
@ 2013-07-15 8:49 ` Andreas Arnez
2013-07-15 13:27 ` Luis Machado
0 siblings, 1 reply; 19+ messages in thread
From: Andreas Arnez @ 2013-07-15 8:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand
Did I miss anything, or is the patch set OK now?
Andreas Arnez <arnez@linux.vnet.ibm.com> writes:
> Is this good to go now? Any remaining concerns with the patch set?
>
> Andreas Arnez <arnez@linux.vnet.ibm.com> writes:
>
>> This is another iteration of GDB support for the "transaction diagnostic
>> block", TDB, which is provided by the transactional-execution facility
>> in newer z/Architecture systems.
>>
>> [...]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-15 8:49 ` [ping 2] " Andreas Arnez
@ 2013-07-15 13:27 ` Luis Machado
2013-07-15 15:34 ` Andreas Arnez
0 siblings, 1 reply; 19+ messages in thread
From: Luis Machado @ 2013-07-15 13:27 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Ulrich.Weigand
Hi,
On 07/15/2013 05:49 AM, Andreas Arnez wrote:
> Did I miss anything, or is the patch set OK now?
>
> Andreas Arnez <arnez@linux.vnet.ibm.com> writes:
>
>> Is this good to go now? Any remaining concerns with the patch set?
>>
>> Andreas Arnez <arnez@linux.vnet.ibm.com> writes:
>>
>>> This is another iteration of GDB support for the "transaction diagnostic
>>> block", TDB, which is provided by the transactional-execution facility
>>> in newer z/Architecture systems.
>>>
>>> [...]
>
>
>
I didn't go through your last update of the patch, but FTR i still think
we should make the core file sections static and store them in some form
of array instead of hardcoding their contents in numerous function calls.
Luis
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFA][PATCH v4 1/5] S/390 regmap rework
2013-07-03 17:00 ` [RFA][PATCH v4 1/5] S/390 regmap rework Andreas Arnez
@ 2013-07-15 14:46 ` Luis Machado
2013-07-15 17:15 ` Andreas Arnez
0 siblings, 1 reply; 19+ messages in thread
From: Luis Machado @ 2013-07-15 14:46 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Ulrich.Weigand
Hi,
A few nits and only nits.
On 07/03/2013 02:00 PM, Andreas Arnez wrote:
> S/390 regmap rework: Represent register maps in a less redundant and
> more readable way. Also remove some code repetition.
>
> /* GNU/Linux target descriptions. */
> extern struct target_desc *tdesc_s390_linux32;
> Index: gdb/gdb/s390-nat.c
> ===================================================================
> --- gdb.orig/gdb/s390-nat.c
> +++ gdb/gdb/s390-nat.c
> @@ -63,139 +63,129 @@ static int have_regset_system_call = 0;
>
> #define regmap_fpregset s390_regmap_fpregset
>
> -/* When debugging a 32-bit executable running under a 64-bit kernel,
> - we have to fix up the 64-bit registers we get from the kernel
> - to make them look like 32-bit registers. */
> +static void
> +s390_native_supply (struct regcache *regcache, const short *map,
> + const gdb_byte *regp)
> +{
> + for (; map[0] >= 0; map += 2)
> + regcache_raw_supply (regcache, map[1], regp + map[0]);
> +}
>
> static void
> -s390_native_supply (struct regcache *regcache, int regno,
> - const gdb_byte *regp, int *regmap)
> +s390_native_collect (const struct regcache *regcache, const short *map,
> + int regno, gdb_byte *regp)
> {
> - int offset = regmap[regno];
> + for (; map[0] >= 0; map += 2)
> + if (regno == -1 || regno == map[1])
> + regcache_raw_collect (regcache, map[1], regp + map[0]);
> +}
Maybe add a comment to these? Observing that...
> +
> +/* Fill GDB's register array with the general-purpose register values
> + in *REGP.
>
> + When debugging a 32-bit executable running under a 64-bit kernel,
> + we have to fix up the 64-bit registers we get from the kernel to
> + make them look like 32-bit registers. */
> +void
> +supply_gregset (struct regcache *regcache, const gregset_t *regp)
> +{
... you need a empty line between the comment of a function and the
declaration of that function.
> #ifdef __s390x__
> struct gdbarch *gdbarch = get_regcache_arch (regcache);
> - if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
> + if (gdbarch_ptr_bit (gdbarch) == 32)
> {
> enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> + ULONGEST pswm = 0, pswa = 0;
> + gdb_byte buf[4];
> + const short *map;
>
> - if (regno == S390_PSWM_REGNUM)
> - {
> - ULONGEST pswm;
> - gdb_byte buf[4];
> -
> - pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
> - 8, byte_order);
> -
> - store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
> - regcache_raw_supply (regcache, regno, buf);
> - return;
> - }
> -
> - if (regno == S390_PSWA_REGNUM)
> + for (map = regmap_gregset; map[0] >= 0; map += 2)
> {
> - ULONGEST pswm, pswa;
> - gdb_byte buf[4];
> + const gdb_byte *p = (const gdb_byte *) regp + map[0];
> + int regno = map[1];
>
> - pswa = extract_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
> - 8, byte_order);
> - pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
> - 8, byte_order);
> -
> - store_unsigned_integer (buf, 4, byte_order,
> - (pswa & 0x7fffffff) | (pswm & 0x80000000));
> - regcache_raw_supply (regcache, regno, buf);
> - return;
> + if (regno == S390_PSWM_REGNUM)
> + pswm = extract_unsigned_integer (p, 8, byte_order);
> + else if (regno == S390_PSWA_REGNUM)
> + pswa = extract_unsigned_integer (p, 8, byte_order);
> + else
> + {
> + if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
> + || regno == S390_ORIG_R2_REGNUM)
> + p += 4;
> + regcache_raw_supply (regcache, regno, p);
> + }
> }
>
> - if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
> - || regno == S390_ORIG_R2_REGNUM)
> - offset += 4;
> + store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
> + regcache_raw_supply (regcache, S390_PSWM_REGNUM, buf);
> + store_unsigned_integer (buf, 4, byte_order,
> + (pswa & 0x7fffffff) | (pswm & 0x80000000));
> + regcache_raw_supply (regcache, S390_PSWA_REGNUM, buf);
> + return;
> }
> #endif
>
> - if (offset != -1)
> - regcache_raw_supply (regcache, regno, regp + offset);
> + s390_native_supply (regcache, regmap_gregset, (const gdb_byte *) regp);
> }
>
> -static void
> -s390_native_collect (const struct regcache *regcache, int regno,
> - gdb_byte *regp, int *regmap)
> +/* Fill register REGNO (if it is a general-purpose register) in
> + *REGP with the value in GDB's register array. If REGNO is -1,
> + do this for all registers. */
> +void
> +fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
Another instance of a missing empty line after the comment.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-15 13:27 ` Luis Machado
@ 2013-07-15 15:34 ` Andreas Arnez
2013-07-15 15:40 ` Luis Machado
2013-07-15 15:58 ` Mark Kettenis
0 siblings, 2 replies; 19+ messages in thread
From: Andreas Arnez @ 2013-07-15 15:34 UTC (permalink / raw)
To: lgustavo; +Cc: gdb-patches, Ulrich.Weigand
Luis Machado <lgustavo@codesourcery.com> writes:
> I didn't go through your last update of the patch, but FTR i still
> think we should make the core file sections static and store them in
> some form of array instead of hardcoding their contents in numerous
> function calls.
In the PowerPC case the patch includes four call-back invocations, all
contained in a 20-line iterator function. I'd hardly call that
"numerous function calls". And I consider it an improvement over the
original code, which had six hard-coded static array initializers with
various copy-/pasted lines, plus the logic for selecting the correct
array. The improvement is even more drastic for S/390. Don't you
agree? Or do you see even more potential for improvement?
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-15 15:34 ` Andreas Arnez
@ 2013-07-15 15:40 ` Luis Machado
2013-07-15 16:30 ` Andreas Arnez
2013-07-15 15:58 ` Mark Kettenis
1 sibling, 1 reply; 19+ messages in thread
From: Luis Machado @ 2013-07-15 15:40 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Ulrich.Weigand
On 07/15/2013 12:34 PM, Andreas Arnez wrote:
> Luis Machado <lgustavo@codesourcery.com> writes:
>
>> I didn't go through your last update of the patch, but FTR i still
>> think we should make the core file sections static and store them in
>> some form of array instead of hardcoding their contents in numerous
>> function calls.
>
> In the PowerPC case the patch includes four call-back invocations, all
> contained in a 20-line iterator function. I'd hardly call that
> "numerous function calls". And I consider it an improvement over the
> original code, which had six hard-coded static array initializers with
> various copy-/pasted lines, plus the logic for selecting the correct
> array. The improvement is even more drastic for S/390. Don't you
> agree? Or do you see even more potential for improvement?
What i don't see now is an obvious way of telling which register sets
are available for core files in PowerPC. You'd have to infer that based
on dynamic data.
It is my personal view on the change, really. I don't claim it is right
or wrong.
Also, why is the PowerPC backend being modified together with S390? Is
this a change to account for POWER8? The introductory mail does not
mention anything PowerPC-specific.
Luis
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-15 15:34 ` Andreas Arnez
2013-07-15 15:40 ` Luis Machado
@ 2013-07-15 15:58 ` Mark Kettenis
1 sibling, 0 replies; 19+ messages in thread
From: Mark Kettenis @ 2013-07-15 15:58 UTC (permalink / raw)
To: arnez; +Cc: lgustavo, gdb-patches, Ulrich.Weigand
> From: Andreas Arnez <arnez@linux.vnet.ibm.com>
> Date: Mon, 15 Jul 2013 17:34:17 +0200
>
> Luis Machado <lgustavo@codesourcery.com> writes:
>
> > I didn't go through your last update of the patch, but FTR i still
> > think we should make the core file sections static and store them in
> > some form of array instead of hardcoding their contents in numerous
> > function calls.
>
> In the PowerPC case the patch includes four call-back invocations, all
> contained in a 20-line iterator function. I'd hardly call that
> "numerous function calls". And I consider it an improvement over the
> original code, which had six hard-coded static array initializers with
> various copy-/pasted lines, plus the logic for selecting the correct
> array. The improvement is even more drastic for S/390. Don't you
> agree? Or do you see even more potential for improvement?
Well, I really do agree with Luis. Your solution is just harder to
read and I don't see the limited amout of copy/pasted lines as a
problem. The logic to select the right array is fairly
straightforword.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-15 15:40 ` Luis Machado
@ 2013-07-15 16:30 ` Andreas Arnez
2013-07-16 15:26 ` Andreas Arnez
0 siblings, 1 reply; 19+ messages in thread
From: Andreas Arnez @ 2013-07-15 16:30 UTC (permalink / raw)
To: lgustavo; +Cc: gdb-patches, Ulrich.Weigand
Luis Machado <lgustavo@codesourcery.com> writes:
> On 07/15/2013 12:34 PM, Andreas Arnez wrote:
>> Luis Machado <lgustavo@codesourcery.com> writes:
>>
>>> I didn't go through your last update of the patch, but FTR i still
>>> think we should make the core file sections static and store them in
>>> some form of array instead of hardcoding their contents in numerous
>>> function calls.
>>
>> In the PowerPC case the patch includes four call-back invocations, all
>> contained in a 20-line iterator function. I'd hardly call that
>> "numerous function calls". And I consider it an improvement over the
>> original code, which had six hard-coded static array initializers with
>> various copy-/pasted lines, plus the logic for selecting the correct
>> array. The improvement is even more drastic for S/390. Don't you
>> agree? Or do you see even more potential for improvement?
>
> What i don't see now is an obvious way of telling which register sets
> are available for core files in PowerPC. You'd have to infer that
> based on dynamic data.
>
> It is my personal view on the change, really. I don't claim it is
> right or wrong.
>
> Also, why is the PowerPC backend being modified together with S390? Is
> this a change to account for POWER8? The introductory mail does not
> mention anything PowerPC-specific.
Because I saw the potential for code simplification here. Also, in an
informal conversation with Ulrich Weigand he indicated that he was
interested in such a change.
In the scope of this patch set the PowerPC change is purely optional.
I'll just remove it from the next version of the patch set.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFA][PATCH v4 1/5] S/390 regmap rework
2013-07-15 14:46 ` Luis Machado
@ 2013-07-15 17:15 ` Andreas Arnez
0 siblings, 0 replies; 19+ messages in thread
From: Andreas Arnez @ 2013-07-15 17:15 UTC (permalink / raw)
To: lgustavo; +Cc: gdb-patches, Ulrich.Weigand
Luis,
Thanks for you comments!
Luis Machado <lgustavo@codesourcery.com> writes:
>> static void
>> -s390_native_supply (struct regcache *regcache, int regno,
>> - const gdb_byte *regp, int *regmap)
>> +s390_native_collect (const struct regcache *regcache, const short *map,
>> + int regno, gdb_byte *regp)
>> {
>> - int offset = regmap[regno];
>> + for (; map[0] >= 0; map += 2)
>> + if (regno == -1 || regno == map[1])
>> + regcache_raw_collect (regcache, map[1], regp + map[0]);
>> +}
>
> Maybe add a comment to these? Observing that...
Done.
>
>> +
>> +/* Fill GDB's register array with the general-purpose register values
>> + in *REGP.
>>
>> + When debugging a 32-bit executable running under a 64-bit kernel,
>> + we have to fix up the 64-bit registers we get from the kernel to
>> + make them look like 32-bit registers. */
>> +void
>> +supply_gregset (struct regcache *regcache, const gregset_t *regp)
>> +{
>
> ... you need a empty line between the comment of a function and the
> declaration of that function.
Done.
>> +/* Fill register REGNO (if it is a general-purpose register) in
>> + *REGP with the value in GDB's register array. If REGNO is -1,
>> + do this for all registers. */
>> +void
>> +fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
>
> Another instance of a missing empty line after the comment.
Done. (Note that now the file has incosistent style, because I followed
the dominant style.)
--- gdb.orig/gdb/s390-nat.c
+++ gdb/gdb/s390-nat.c
@@ -63,139 +63,139 @@ static int have_regset_system_call = 0;
#define regmap_fpregset s390_regmap_fpregset
-/* When debugging a 32-bit executable running under a 64-bit kernel,
- we have to fix up the 64-bit registers we get from the kernel
- to make them look like 32-bit registers. */
+/* Fill the regset described by MAP into REGCACHE, using the values
+ from REGP. The MAP array represents each register as a pair
+ (offset, regno) of short integers and is terminated with -1. */
static void
-s390_native_supply (struct regcache *regcache, int regno,
- const gdb_byte *regp, int *regmap)
+s390_native_supply (struct regcache *regcache, const short *map,
+ const gdb_byte *regp)
{
- int offset = regmap[regno];
+ for (; map[0] >= 0; map += 2)
+ regcache_raw_supply (regcache, map[1], regp + map[0]);
+}
+
+/* Collect the register REGNO out of the regset described by MAP from
+ REGCACHE into REGP. If REGNO == -1, do this for all registers in
+ this regset. */
+static void
+s390_native_collect (const struct regcache *regcache, const short *map,
+ int regno, gdb_byte *regp)
+{
+ for (; map[0] >= 0; map += 2)
+ if (regno == -1 || regno == map[1])
+ regcache_raw_collect (regcache, map[1], regp + map[0]);
+}
+
+/* Fill GDB's register array with the general-purpose register values
+ in *REGP.
+
+ When debugging a 32-bit executable running under a 64-bit kernel,
+ we have to fix up the 64-bit registers we get from the kernel to
+ make them look like 32-bit registers. */
+
+void
+supply_gregset (struct regcache *regcache, const gregset_t *regp)
+{
#ifdef __s390x__
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
+ if (gdbarch_ptr_bit (gdbarch) == 32)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ ULONGEST pswm = 0, pswa = 0;
+ gdb_byte buf[4];
+ const short *map;
- if (regno == S390_PSWM_REGNUM)
- {
- ULONGEST pswm;
- gdb_byte buf[4];
-
- pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
- 8, byte_order);
-
- store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
- regcache_raw_supply (regcache, regno, buf);
- return;
- }
-
- if (regno == S390_PSWA_REGNUM)
+ for (map = regmap_gregset; map[0] >= 0; map += 2)
{
- ULONGEST pswm, pswa;
- gdb_byte buf[4];
+ const gdb_byte *p = (const gdb_byte *) regp + map[0];
+ int regno = map[1];
- pswa = extract_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
- 8, byte_order);
- pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
- 8, byte_order);
-
- store_unsigned_integer (buf, 4, byte_order,
- (pswa & 0x7fffffff) | (pswm & 0x80000000));
- regcache_raw_supply (regcache, regno, buf);
- return;
+ if (regno == S390_PSWM_REGNUM)
+ pswm = extract_unsigned_integer (p, 8, byte_order);
+ else if (regno == S390_PSWA_REGNUM)
+ pswa = extract_unsigned_integer (p, 8, byte_order);
+ else
+ {
+ if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
+ || regno == S390_ORIG_R2_REGNUM)
+ p += 4;
+ regcache_raw_supply (regcache, regno, p);
+ }
}
- if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
- || regno == S390_ORIG_R2_REGNUM)
- offset += 4;
+ store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
+ regcache_raw_supply (regcache, S390_PSWM_REGNUM, buf);
+ store_unsigned_integer (buf, 4, byte_order,
+ (pswa & 0x7fffffff) | (pswm & 0x80000000));
+ regcache_raw_supply (regcache, S390_PSWA_REGNUM, buf);
+ return;
}
#endif
- if (offset != -1)
- regcache_raw_supply (regcache, regno, regp + offset);
+ s390_native_supply (regcache, regmap_gregset, (const gdb_byte *) regp);
}
-static void
-s390_native_collect (const struct regcache *regcache, int regno,
- gdb_byte *regp, int *regmap)
-{
- int offset = regmap[regno];
+/* Fill register REGNO (if it is a general-purpose register) in
+ *REGP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+void
+fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
+{
#ifdef __s390x__
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
+ if (gdbarch_ptr_bit (gdbarch) == 32)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ gdb_byte *psw_p[2];
+ const short *map;
- if (regno == S390_PSWM_REGNUM)
+ for (map = regmap_gregset; map[0] >= 0; map += 2)
{
- ULONGEST pswm;
- gdb_byte buf[4];
+ gdb_byte *p = (gdb_byte *) regp + map[0];
+ int reg = map[1];
- regcache_raw_collect (regcache, regno, buf);
- pswm = extract_unsigned_integer (buf, 4, byte_order);
+ if (reg >= S390_PSWM_REGNUM && reg <= S390_PSWA_REGNUM)
+ psw_p[reg - S390_PSWM_REGNUM] = p;
- /* We don't know the final addressing mode until the PSW address
- is known, so leave it as-is. When the PSW address is collected
- (below), the addressing mode will be updated. */
- store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
- 4, byte_order, pswm & 0xfff7ffff);
- return;
+ else if (regno == -1 || regno == reg)
+ {
+ if ((reg >= S390_R0_REGNUM && reg <= S390_R15_REGNUM)
+ || reg == S390_ORIG_R2_REGNUM)
+ {
+ memset (p, 0, 4);
+ p += 4;
+ }
+ regcache_raw_collect (regcache, reg, p + 4);
+ }
}
- if (regno == S390_PSWA_REGNUM)
+ if (regno == -1
+ || regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM)
{
- ULONGEST pswa;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ ULONGEST pswa, pswm;
gdb_byte buf[4];
- regcache_raw_collect (regcache, regno, buf);
+ regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
+ pswm = extract_unsigned_integer (buf, 4, byte_order);
+ regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
pswa = extract_unsigned_integer (buf, 4, byte_order);
- store_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
- 8, byte_order, pswa & 0x7fffffff);
-
- /* Update basic addressing mode bit in PSW mask, see above. */
- store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM] + 4,
- 4, byte_order, pswa & 0x80000000);
- return;
- }
-
- if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
- || regno == S390_ORIG_R2_REGNUM)
- {
- memset (regp + offset, 0, 4);
- offset += 4;
+ if (regno == -1 || regno == S390_PSWM_REGNUM)
+ store_unsigned_integer (psw_p[0], 8, byte_order,
+ ((pswm & 0xfff7ffff) << 32) |
+ (pswa & 0x80000000));
+ if (regno == -1 || regno == S390_PSWA_REGNUM)
+ store_unsigned_integer (psw_p[1], 8, byte_order,
+ pswa & 0x7fffffff);
}
+ return;
}
#endif
- if (offset != -1)
- regcache_raw_collect (regcache, regno, regp + offset);
-}
-
-/* Fill GDB's register array with the general-purpose register values
- in *REGP. */
-void
-supply_gregset (struct regcache *regcache, const gregset_t *regp)
-{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_gregset);
-}
-
-/* Fill register REGNO (if it is a general-purpose register) in
- *REGP with the value in GDB's register array. If REGNO is -1,
- do this for all registers. */
-void
-fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
-{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- if (regno == -1 || regno == i)
- s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_gregset);
+ s390_native_collect (regcache, regmap_gregset, regno, (gdb_byte *) regp);
}
/* Fill GDB's register array with the floating-point register values
@@ -203,9 +203,7 @@ fill_gregset (const struct regcache *reg
void
supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_fpregset);
+ s390_native_supply (regcache, regmap_fpregset, (const gdb_byte *) regp);
}
/* Fill register REGNO (if it is a general-purpose register) in
@@ -214,10 +212,7 @@ supply_fpregset (struct regcache *regcac
void
fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
{
- int i;
- for (i = 0; i < S390_NUM_REGS; i++)
- if (regno == -1 || regno == i)
- s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_fpregset);
+ s390_native_collect (regcache, regmap_fpregset, regno, (gdb_byte *) regp);
}
/* Find the TID for the current inferior thread to use with ptrace. */
@@ -311,12 +306,10 @@ store_fpregs (const struct regcache *reg
process/thread TID and store their values in GDB's register cache. */
static void
fetch_regset (struct regcache *regcache, int tid,
- int regset, int regsize, int *regmap)
+ int regset, int regsize, const short *regmap)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
gdb_byte *buf = alloca (regsize);
struct iovec iov;
- int i;
iov.iov_base = buf;
iov.iov_len = regsize;
@@ -324,8 +317,7 @@ fetch_regset (struct regcache *regcache,
if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
perror_with_name (_("Couldn't get register set"));
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_supply (regcache, i, buf, regmap);
+ s390_native_supply (regcache, regmap, buf);
}
/* Store all registers in the kernel's register set whose number is REGSET,
@@ -333,12 +325,10 @@ fetch_regset (struct regcache *regcache,
GDB's register cache back to process/thread TID. */
static void
store_regset (struct regcache *regcache, int tid,
- int regset, int regsize, int *regmap)
+ int regset, int regsize, const short *regmap)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
gdb_byte *buf = alloca (regsize);
struct iovec iov;
- int i;
iov.iov_base = buf;
iov.iov_len = regsize;
@@ -346,8 +336,7 @@ store_regset (struct regcache *regcache,
if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
perror_with_name (_("Couldn't get register set"));
- for (i = 0; i < S390_NUM_REGS; i++)
- s390_native_collect (regcache, i, buf, regmap);
+ s390_native_collect (regcache, regmap, -1, buf);
if (ptrace (PTRACE_SETREGSET, tid, (long) regset, (long) &iov) < 0)
perror_with_name (_("Couldn't set register set"));
@@ -378,12 +367,10 @@ s390_linux_fetch_inferior_registers (str
{
int tid = s390_inferior_tid ();
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
fetch_regs (regcache, tid);
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
fetch_fpregs (regcache, tid);
if (have_regset_last_break)
@@ -406,12 +393,10 @@ s390_linux_store_inferior_registers (str
{
int tid = s390_inferior_tid ();
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
store_regs (regcache, tid, regnum);
- if (regnum == -1
- || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
+ if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
store_fpregs (regcache, tid, regnum);
/* S390_LAST_BREAK_REGNUM is read-only. */
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-15 16:30 ` Andreas Arnez
@ 2013-07-16 15:26 ` Andreas Arnez
2013-07-16 16:03 ` Ulrich Weigand
0 siblings, 1 reply; 19+ messages in thread
From: Andreas Arnez @ 2013-07-16 15:26 UTC (permalink / raw)
To: lgustavo; +Cc: gdb-patches, Ulrich.Weigand
Andreas Arnez <arnez@linux.vnet.ibm.com> writes:
> In the scope of this patch set the PowerPC change is purely optional.
> I'll just remove it from the next version of the patch set.
Actually, before I do that, here's another try.
Would it help to merge the iterator function with the logic of
ppc_regset_from_core_section(), like outlined in the patch below?
I see the following advantages:
- One less gdbarch function needed: gdbarch_regset_from_core_section
becomes obsolete.
- The regset description is more "self-contained": it now includes the
name, description, and size.
- Even less code than the previous version, all condensed in a single
function.
Thoughts?
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index fc09560..854b356 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -256,54 +256,6 @@ ppc_linux_return_value (struct gdbarch *gdbarch, struct value *function,
readbuf, writebuf);
}
-static struct core_regset_section ppc_linux_vsx_regset_sections[] =
-{
- { ".reg", 48 * 4, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { ".reg-ppc-vsx", 256, "POWER7 VSX" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc_linux_vmx_regset_sections[] =
-{
- { ".reg", 48 * 4, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc_linux_fp_regset_sections[] =
-{
- { ".reg", 48 * 4, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc64_linux_vsx_regset_sections[] =
-{
- { ".reg", 48 * 8, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { ".reg-ppc-vsx", 256, "POWER7 VSX" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc64_linux_vmx_regset_sections[] =
-{
- { ".reg", 48 * 8, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { ".reg-ppc-vmx", 544, "ppc Altivec" },
- { NULL, 0}
-};
-
-static struct core_regset_section ppc64_linux_fp_regset_sections[] =
-{
- { ".reg", 48 * 8, "general-purpose" },
- { ".reg2", 264, "floating-point" },
- { NULL, 0}
-};
-
/* PLT stub in executable. */
static struct ppc_insn_pattern powerpc32_plt_stub[] =
{
@@ -498,35 +450,40 @@ static const struct regset ppc32_linux_gregset = {
&ppc32_linux_reg_offsets,
ppc_linux_supply_gregset,
ppc_linux_collect_gregset,
- NULL
+ NULL,
+ ".reg", "general-purpose", 48 * 4
};
static const struct regset ppc64_linux_gregset = {
&ppc64_linux_reg_offsets,
ppc_linux_supply_gregset,
ppc_linux_collect_gregset,
- NULL
+ NULL,
+ ".reg", "general-purpose", 48 * 8
};
static const struct regset ppc32_linux_fpregset = {
&ppc32_linux_reg_offsets,
ppc_supply_fpregset,
ppc_collect_fpregset,
- NULL
+ NULL,
+ ".reg2", "floating-point", 264
};
static const struct regset ppc32_linux_vrregset = {
&ppc32_linux_reg_offsets,
ppc_supply_vrregset,
ppc_collect_vrregset,
- NULL
+ NULL,
+ ".reg-ppc-vmx", "ppc Altivec", 544
};
static const struct regset ppc32_linux_vsxregset = {
&ppc32_linux_reg_offsets,
ppc_supply_vsxregset,
ppc_collect_vsxregset,
- NULL
+ NULL,
+ ".reg-ppc-vsx", "POWER7 VSX", 256
};
const struct regset *
@@ -541,25 +498,26 @@ ppc_linux_fpregset (void)
return &ppc32_linux_fpregset;
}
-static const struct regset *
-ppc_linux_regset_from_core_section (struct gdbarch *core_arch,
- const char *sect_name, size_t sect_size)
+static void
+ppc_linux_iterate_over_regset_sections (struct gdbarch *core_arch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (core_arch);
- if (strcmp (sect_name, ".reg") == 0)
- {
- if (tdep->wordsize == 4)
- return &ppc32_linux_gregset;
- else
- return &ppc64_linux_gregset;
- }
- if (strcmp (sect_name, ".reg2") == 0)
- return &ppc32_linux_fpregset;
- if (strcmp (sect_name, ".reg-ppc-vmx") == 0)
- return &ppc32_linux_vrregset;
- if (strcmp (sect_name, ".reg-ppc-vsx") == 0)
- return &ppc32_linux_vsxregset;
- return NULL;
+ int have_vsx = tdep->ppc_vr0_regnum != -1;
+ int have_altivec = tdep->ppc_vsr0_upper_regnum != -1;
+ int res;
+
+ res = cb (tdep->wordsize == 4 ?
+ &ppc32_linux_gregset : &ppc64_linux_gregset,
+ cb_data);
+ if (!res)
+ res = cb (&ppc32_linux_fpregset, cb_data);
+ if (!res && have_altivec)
+ res = cb (&ppc32_linux_vrregset, cb_data);
+ if (!res && have_vsx)
+ cb (&ppc32_linux_vsxregset, cb_data);
}
static void
@@ -1305,19 +1263,6 @@ ppc_linux_init_abi (struct gdbarch_info info,
else
set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
- /* Supported register sections. */
- if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.vsx"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc_linux_vsx_regset_sections);
- else if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.altivec"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc_linux_vmx_regset_sections);
- else
- set_gdbarch_core_regset_sections (gdbarch,
- ppc_linux_fp_regset_sections);
-
if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
{
powerpc_so_ops = svr4_so_ops;
@@ -1359,19 +1304,6 @@ ppc_linux_init_abi (struct gdbarch_info info,
set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle");
else
set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
-
- /* Supported register sections. */
- if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.vsx"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc64_linux_vsx_regset_sections);
- else if (tdesc_find_feature (info.target_desc,
- "org.gnu.gdb.power.altivec"))
- set_gdbarch_core_regset_sections (gdbarch,
- ppc64_linux_vmx_regset_sections);
- else
- set_gdbarch_core_regset_sections (gdbarch,
- ppc64_linux_fp_regset_sections);
}
/* PPC32 uses a different prpsinfo32 compared to most other Linux
@@ -1383,6 +1315,8 @@ ppc_linux_init_abi (struct gdbarch_info info,
set_gdbarch_regset_from_core_section (gdbarch,
ppc_linux_regset_from_core_section);
set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
+ set_gdbarch_iterate_over_regset_sections (gdbarch,
+ ppc_linux_iterate_over_regset_sections);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-16 15:26 ` Andreas Arnez
@ 2013-07-16 16:03 ` Ulrich Weigand
2013-07-16 17:06 ` Andreas Arnez
0 siblings, 1 reply; 19+ messages in thread
From: Ulrich Weigand @ 2013-07-16 16:03 UTC (permalink / raw)
To: Andreas Arnez; +Cc: lgustavo, gdb-patches
Andreas Arnez wrote:
> Would it help to merge the iterator function with the logic of
> ppc_regset_from_core_section(), like outlined in the patch below?
>
> I see the following advantages:
>
> - One less gdbarch function needed: gdbarch_regset_from_core_section
> becomes obsolete.
>
> - The regset description is more "self-contained": it now includes the
> name, description, and size.
>
> - Even less code than the previous version, all condensed in a single
> function.
In general, I agree it would be nice to merge the information from
core_regset_section into struct regset itself, for the reasons you
mention.
However, one reason to keep them distinct in the past has been that
many platforms do not actually provide a core_regset_section, only
a struct regset; in particular, the sizes of the regsets are not
there. These are the platforms that fall back to sizeof (gregset)
etc. for native code and do not support cross-corefile debugging
and/or generation.
It has always been a goal to provide core_regset_section info for
all platforms and get rid of the various legacy methods, but so
far this has not been done. As usual, one of the problem is that
you'd need to test on those platforms, which may be hard to do.
Your patch below doesn't show the common code changes, so I'm not
sure how you planned to handle legacy platforms. I guess it might
be possible to detect them using zero markers in those fields ...
As an aside, I'm wondering:
> + res = cb (tdep->wordsize == 4 ?
> + &ppc32_linux_gregset : &ppc64_linux_gregset,
> + cb_data);
> + if (!res)
> + res = cb (&ppc32_linux_fpregset, cb_data);
> + if (!res && have_altivec)
> + res = cb (&ppc32_linux_vrregset, cb_data);
> + if (!res && have_vsx)
> + cb (&ppc32_linux_vsxregset, cb_data);
Why does the callback need to return a flag that has to be handled
by the caller? If there is indeed a requirement for treating
error conditions specially, couldn't the callback store error data
in the cb_data and handle it on subsequent calls?
This would make the gdbarch implementations in the targets yet
easier and simpler to write, something along the lines of:
if (tdep->wordsize == 4)
cb (&ppc32_linux_gregset, cb_data);
else
cb (&ppc64_linux_gregset, cb_data);
cb (&ppc32_linux_fpregset, cb_data);
if (have_altivec)
cb (&ppc32_linux_vrregset, cb_data);
if (have_vsx)
cb (&ppc32_linux_vsxregset, cb_data);
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [ping 2] [RFA][PATCH v4 0/5] Add TDB regset support
2013-07-16 16:03 ` Ulrich Weigand
@ 2013-07-16 17:06 ` Andreas Arnez
0 siblings, 0 replies; 19+ messages in thread
From: Andreas Arnez @ 2013-07-16 17:06 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: lgustavo, gdb-patches
"Ulrich Weigand" <uweigand@de.ibm.com> writes:
> Your patch below doesn't show the common code changes, so I'm not
> sure how you planned to handle legacy platforms. I guess it might
> be possible to detect them using zero markers in those fields ...
Right, before coming up with a complete patch I wanted to get some
feedback on this general idea. So I guess it's worth giving it a try?
> As an aside, I'm wondering:
>
>> + res = cb (tdep->wordsize == 4 ?
>> + &ppc32_linux_gregset : &ppc64_linux_gregset,
>> + cb_data);
>> + if (!res)
>> + res = cb (&ppc32_linux_fpregset, cb_data);
>> + if (!res && have_altivec)
>> + res = cb (&ppc32_linux_vrregset, cb_data);
>> + if (!res && have_vsx)
>> + cb (&ppc32_linux_vsxregset, cb_data);
>
> Why does the callback need to return a flag that has to be handled
> by the caller? If there is indeed a requirement for treating
> error conditions specially, couldn't the callback store error data
> in the cb_data and handle it on subsequent calls?
This is a good point. Yes, this is for error handling, and yes, the
error indication could be moved to cb_data.
> This would make the gdbarch implementations in the targets yet
> easier and simpler to write, something along the lines of:
>
> if (tdep->wordsize == 4)
> cb (&ppc32_linux_gregset, cb_data);
> else
> cb (&ppc64_linux_gregset, cb_data);
> cb (&ppc32_linux_fpregset, cb_data);
> if (have_altivec)
> cb (&ppc32_linux_vrregset, cb_data);
> if (have_vsx)
> cb (&ppc32_linux_vsxregset, cb_data);
Yup.
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2013-07-16 17:06 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-03 16:57 [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
2013-07-03 17:00 ` [RFA][PATCH v4 1/5] S/390 regmap rework Andreas Arnez
2013-07-15 14:46 ` Luis Machado
2013-07-15 17:15 ` Andreas Arnez
2013-07-03 17:02 ` [RFA][PATCH v4 2/5] S/390: Add TDB regset Andreas Arnez
2013-07-03 19:25 ` Eli Zaretskii
2013-07-03 17:04 ` [RFA][PATCH v4 3/5] Dynamic core regset sections support Andreas Arnez
2013-07-03 17:11 ` [RFA][PATCH v4 4/5] S/390: Exploit dynamic core regset sections Andreas Arnez
2013-07-03 17:21 ` [RFA][PATCH v4 5/5] PowerPC: " Andreas Arnez
2013-07-08 15:44 ` [ping] [RFA][PATCH v4 0/5] Add TDB regset support Andreas Arnez
2013-07-15 8:49 ` [ping 2] " Andreas Arnez
2013-07-15 13:27 ` Luis Machado
2013-07-15 15:34 ` Andreas Arnez
2013-07-15 15:40 ` Luis Machado
2013-07-15 16:30 ` Andreas Arnez
2013-07-16 15:26 ` Andreas Arnez
2013-07-16 16:03 ` Ulrich Weigand
2013-07-16 17:06 ` Andreas Arnez
2013-07-15 15:58 ` Mark Kettenis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox