* [PATCH v2 08/13] M32R Linux: Fill 'collect_regset' in regset structure.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 06/13] FRV Linux: Fill 'collect_regset' in regset structures Andreas Arnez
` (12 subsequent siblings)
13 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches
gdb/
* m32r-linux-tdep.c (M32R_LINUX_GREGS_SIZE): New macro.
(m32r_linux_supply_gregset): Make platform-independent and don't
write to read-only input buffer.
(m32r_linux_collect_gregset): New function.
(m32r_linux_gregset): Add collect method.
---
gdb/m32r-linux-tdep.c | 81 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 63 insertions(+), 18 deletions(-)
diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c
index bf1ffff..5eaca6e 100644
--- a/gdb/m32r-linux-tdep.c
+++ b/gdb/m32r-linux-tdep.c
@@ -346,19 +346,26 @@ static int m32r_pt_regs_offset[] = {
#define SPU_OFFSET (4 * 23)
#define SPI_OFFSET (4 * 26)
+#define M32R_LINUX_GREGS_SIZE (4 * 27)
+
static void
m32r_linux_supply_gregset (const struct regset *regset,
struct regcache *regcache, int regnum,
const void *gregs, size_t size)
{
- const char *regs = gregs;
- unsigned long psw, bbpsw;
+ const gdb_byte *regs = gregs;
+ enum bfd_endian byte_order =
+ gdbarch_byte_order (get_regcache_arch (regcache));
+ ULONGEST psw, bbpsw;
+ gdb_byte buf[4];
+ const gdb_byte *p;
int i;
- psw = *((unsigned long *) (regs + PSW_OFFSET));
- bbpsw = *((unsigned long *) (regs + BBPSW_OFFSET));
+ psw = extract_unsigned_integer (regs + PSW_OFFSET, 4, byte_order);
+ bbpsw = extract_unsigned_integer (regs + BBPSW_OFFSET, 4, byte_order);
+ psw = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
- for (i = 0; i < sizeof (m32r_pt_regs_offset) / 4; i++)
+ for (i = 0; i < ARRAY_SIZE (m32r_pt_regs_offset); i++)
{
if (regnum != -1 && regnum != i)
continue;
@@ -366,30 +373,68 @@ m32r_linux_supply_gregset (const struct regset *regset,
switch (i)
{
case PSW_REGNUM:
- *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
- ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
+ store_unsigned_integer (buf, 4, byte_order, psw);
+ p = buf;
break;
case CBR_REGNUM:
- *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
- ((psw >> 8) & 1);
+ store_unsigned_integer (buf, 4, byte_order, psw & 1);
+ p = buf;
break;
case M32R_SP_REGNUM:
- if (psw & 0x8000)
- *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
- *((unsigned long *) (regs + SPU_OFFSET));
- else
- *((unsigned long *) (regs + m32r_pt_regs_offset[i])) =
- *((unsigned long *) (regs + SPI_OFFSET));
+ p = regs + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET);
break;
+ default:
+ p = regs + m32r_pt_regs_offset[i];
}
- regcache_raw_supply (regcache, i,
- regs + m32r_pt_regs_offset[i]);
+ regcache_raw_supply (regcache, i, p);
+ }
+}
+
+static void
+m32r_linux_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t size)
+{
+ gdb_byte *regs = gregs;
+ int i;
+ enum bfd_endian byte_order =
+ gdbarch_byte_order (get_regcache_arch (regcache));
+ ULONGEST psw;
+ gdb_byte buf[4];
+
+ regcache_raw_collect (regcache, PSW_REGNUM, buf);
+ psw = extract_unsigned_integer (buf, 4, byte_order);
+
+ for (i = 0; i < ARRAY_SIZE (m32r_pt_regs_offset); i++)
+ {
+ if (regnum != -1 && regnum != i)
+ continue;
+
+ switch (i)
+ {
+ case PSW_REGNUM:
+ store_unsigned_integer (regs + PSW_OFFSET, 4, byte_order,
+ (psw & 0xc1) << 8);
+ store_unsigned_integer (regs + BBPSW_OFFSET, 4, byte_order,
+ (psw >> 8) & 0xc1);
+ break;
+ case CBR_REGNUM:
+ break;
+ case M32R_SP_REGNUM:
+ regcache_raw_collect (regcache, i, regs
+ + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET));
+ break;
+ default:
+ regcache_raw_collect (regcache, i,
+ regs + m32r_pt_regs_offset[i]);
+ }
}
}
static const struct regset m32r_linux_gregset = {
- NULL, m32r_linux_supply_gregset
+ NULL,
+ m32r_linux_supply_gregset, m32r_linux_collect_gregset
};
static const struct regset *
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 06/13] FRV Linux: Fill 'collect_regset' in regset structures.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 08/13] M32R Linux: Fill 'collect_regset' in regset structure Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 13/13] IA64 Linux: Define " Andreas Arnez
` (11 subsequent siblings)
13 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches
gdb/
* frv-linux-tdep.c (FRV_PT_PSR, FRV_PT_ISR, FRV_PT_CCR)
(FRV_PT_CCCR, FRV_PT_LR, FRV_PT_LCR, FRV_PT_PC, FRV_PT_GNER0)
(FRV_PT_GNER1, FRV_PT_IACC0H, FRV_PT_IACC0L, FRV_PT_GR)
(FRV_PT_TBR, FRV_PT_GR, FRV_PT_EXEC_FDPIC_LOADMAP)
(FRV_PT_INTERP_FDPIC_LOADMAP): Delete macros.
(frv_linux_gregmap, frv_linux_fpregmap): New register maps.
(frv_linux_supply_gregset): Replace main logic by call to
regcache_supply_regset, but keep clearing gr32-gr63.
(frv_linux_supply_fpregset): Delete function.
(frv_linux_gregset): Refer to appropriate register map and add
regcache_collect_regset as the collect method.
(frv_linux_fpregset): Likewise. Also exchange the supply method
by regcache_supply_regset.
---
gdb/frv-linux-tdep.c | 141 ++++++++++++++++++++-------------------------------
1 file changed, 54 insertions(+), 87 deletions(-)
diff --git a/gdb/frv-linux-tdep.c b/gdb/frv-linux-tdep.c
index fb163a8..104e6c1 100644
--- a/gdb/frv-linux-tdep.c
+++ b/gdb/frv-linux-tdep.c
@@ -360,37 +360,52 @@ typedef struct
frv_elf_fpreg_t fsr[1];
} frv_elf_fpregset_t;
-/* Constants for accessing elements of frv_elf_gregset_t. */
-
-#define FRV_PT_PSR 0
-#define FRV_PT_ISR 1
-#define FRV_PT_CCR 2
-#define FRV_PT_CCCR 3
-#define FRV_PT_LR 4
-#define FRV_PT_LCR 5
-#define FRV_PT_PC 6
-#define FRV_PT_GNER0 10
-#define FRV_PT_GNER1 11
-#define FRV_PT_IACC0H 12
-#define FRV_PT_IACC0L 13
-
-/* Note: Only 32 of the GRs will be found in the corefile. */
-#define FRV_PT_GR(j) ( 14 + (j)) /* GRj for 0<=j<=63. */
-
-#define FRV_PT_TBR FRV_PT_GR(0) /* gr0 is always 0, so TBR is stuffed
- there. */
-
-/* Technically, the loadmap addresses are not part of `pr_reg' as
- found in the elf_prstatus struct. The fields which communicate the
- loadmap address appear (by design) immediately after `pr_reg'
- though, and the BFD function elf32_frv_grok_prstatus() has been
- implemented to include these fields in the register section that it
- extracts from the core file. So, for our purposes, they may be
- viewed as registers. */
-
-#define FRV_PT_EXEC_FDPIC_LOADMAP 46
-#define FRV_PT_INTERP_FDPIC_LOADMAP 47
-
+/* Register maps. */
+
+static const struct regcache_map_entry frv_linux_gregmap[] =
+ {
+ { 1, psr_regnum },
+ { 4, REGCACHE_MAP_SKIP_BYTES }, /* isr */
+ { 1, ccr_regnum },
+ { 1, cccr_regnum },
+ { 1, lr_regnum },
+ { 1, lcr_regnum },
+ { 1, pc_regnum },
+ { 4, REGCACHE_MAP_SKIP_BYTES }, /* __status */
+ { 4, REGCACHE_MAP_SKIP_BYTES }, /* syscallno */
+ { 4, REGCACHE_MAP_SKIP_BYTES }, /* orig_gr8 */
+ { 1, gner0_regnum },
+ { 1, gner1_regnum },
+ { 8, REGCACHE_MAP_SKIP_BYTES }, /* iacc0 */
+ { 1, tbr_regnum },
+ { 31, first_gpr_regnum + 1 }, /* gr1 ... gr31 */
+
+ /* Technically, the loadmap addresses are not part of `pr_reg' as
+ found in the elf_prstatus struct. The fields which communicate
+ the loadmap address appear (by design) immediately after
+ `pr_reg' though, and the BFD function elf32_frv_grok_prstatus()
+ has been implemented to include these fields in the register
+ section that it extracts from the core file. So, for our
+ purposes, they may be viewed as registers. */
+
+ { 1, fdpic_loadmap_exec_regnum },
+ { 1, fdpic_loadmap_interp_regnum },
+ { 0 }
+ };
+
+static const struct regcache_map_entry frv_linux_fpregmap[] =
+ {
+ { 64, first_fpr_regnum }, /* fr0 ... fr63 */
+ { 1, fner0_regnum },
+ { 1, fner1_regnum },
+ { 1, msr0_regnum },
+ { 1, msr1_regnum },
+ { 8, acc0_regnum }, /* acc0 ... acc7 */
+ { 1, accg0123_regnum },
+ { 1, accg4567_regnum },
+ { 1, fsr0_regnum },
+ { 0 }
+ };
/* Unpack an frv_elf_gregset_t into GDB's register cache. */
@@ -401,7 +416,6 @@ frv_linux_supply_gregset (const struct regset *regset,
{
int regi;
char zerobuf[MAX_REGISTER_SIZE];
- const frv_elf_gregset_t *gregsetp = gregs;
memset (zerobuf, 0, MAX_REGISTER_SIZE);
@@ -409,72 +423,25 @@ frv_linux_supply_gregset (const struct regset *regset,
this slot. */
regcache_raw_supply (regcache, first_gpr_regnum, zerobuf);
- for (regi = first_gpr_regnum + 1; regi <= last_gpr_regnum; regi++)
- {
- if (regi >= first_gpr_regnum + 32)
- regcache_raw_supply (regcache, regi, zerobuf);
- else
- regcache_raw_supply (regcache, regi,
- gregsetp->reg[FRV_PT_GR (regi
- - first_gpr_regnum)]);
- }
-
- regcache_raw_supply (regcache, pc_regnum, gregsetp->reg[FRV_PT_PC]);
- regcache_raw_supply (regcache, psr_regnum, gregsetp->reg[FRV_PT_PSR]);
- regcache_raw_supply (regcache, ccr_regnum, gregsetp->reg[FRV_PT_CCR]);
- regcache_raw_supply (regcache, cccr_regnum, gregsetp->reg[FRV_PT_CCCR]);
- regcache_raw_supply (regcache, lr_regnum, gregsetp->reg[FRV_PT_LR]);
- regcache_raw_supply (regcache, lcr_regnum, gregsetp->reg[FRV_PT_LCR]);
- regcache_raw_supply (regcache, gner0_regnum, gregsetp->reg[FRV_PT_GNER0]);
- regcache_raw_supply (regcache, gner1_regnum, gregsetp->reg[FRV_PT_GNER1]);
- regcache_raw_supply (regcache, tbr_regnum, gregsetp->reg[FRV_PT_TBR]);
- regcache_raw_supply (regcache, fdpic_loadmap_exec_regnum,
- gregsetp->reg[FRV_PT_EXEC_FDPIC_LOADMAP]);
- regcache_raw_supply (regcache, fdpic_loadmap_interp_regnum,
- gregsetp->reg[FRV_PT_INTERP_FDPIC_LOADMAP]);
-}
-
-/* Unpack an frv_elf_fpregset_t into GDB's register cache. */
-
-static void
-frv_linux_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
-{
- int regi;
- const frv_elf_fpregset_t *fpregsetp = gregs;
-
- for (regi = first_fpr_regnum; regi <= last_fpr_regnum; regi++)
- regcache_raw_supply (regcache, regi,
- fpregsetp->fr[regi - first_fpr_regnum]);
-
- regcache_raw_supply (regcache, fner0_regnum, fpregsetp->fner[0]);
- regcache_raw_supply (regcache, fner1_regnum, fpregsetp->fner[1]);
-
- regcache_raw_supply (regcache, msr0_regnum, fpregsetp->msr[0]);
- regcache_raw_supply (regcache, msr1_regnum, fpregsetp->msr[1]);
+ /* Fill gr32, ..., gr63 with zeros. */
+ for (regi = first_gpr_regnum + 32; regi <= last_gpr_regnum; regi++)
+ regcache_raw_supply (regcache, regi, zerobuf);
- for (regi = acc0_regnum; regi <= acc7_regnum; regi++)
- regcache_raw_supply (regcache, regi, fpregsetp->acc[regi - acc0_regnum]);
-
- regcache_raw_supply (regcache, accg0123_regnum, fpregsetp->accg);
- regcache_raw_supply (regcache, accg4567_regnum, fpregsetp->accg + 4);
-
- regcache_raw_supply (regcache, fsr0_regnum, fpregsetp->fsr[0]);
+ regcache_supply_regset (regset, regcache, regnum, gregs, len);
}
/* FRV Linux kernel register sets. */
static const struct regset frv_linux_gregset =
{
- NULL,
- frv_linux_supply_gregset
+ frv_linux_gregmap,
+ frv_linux_supply_gregset, regcache_collect_regset
};
static const struct regset frv_linux_fpregset =
{
- NULL,
- frv_linux_supply_fpregset
+ frv_linux_fpregmap,
+ regcache_supply_regset, regcache_collect_regset
};
static const struct regset *
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 13/13] IA64 Linux: Define regset structures.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 08/13] M32R Linux: Fill 'collect_regset' in regset structure Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 06/13] FRV Linux: Fill 'collect_regset' in regset structures Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-15 13:01 ` Ulrich Weigand
2014-06-25 16:49 ` [PATCH v2 10/13] SCORE: Fill 'collect_regset' in regset structure Andreas Arnez
` (10 subsequent siblings)
13 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Jeff Johnston
gdb/
* ia64-linux-tdep.c: Include "regset.h".
(ia64_linux_gregmap, ia64_linux_fpregmap): New register maps.
(IA64_LINUX_GREGS_SIZE, IA64_LINUX_FPREGS_SIZE): New macros.
(ia64_linux_supply_fpregset): New function.
(ia64_linux_gregset, ia64_linux_fpregset): New regsets.
(ia64_linux_regset_from_core_section): New function.
(ia64_linux_init_abi): Set regset_from_core_section gdbarch
method.
---
gdb/ia64-linux-tdep.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c
index 128924e..9989602 100644
--- a/gdb/ia64-linux-tdep.c
+++ b/gdb/ia64-linux-tdep.c
@@ -26,6 +26,7 @@
#include "solib-svr4.h"
#include "symtab.h"
#include "linux-tdep.h"
+#include "regset.h"
#include <ctype.h>
@@ -131,6 +132,88 @@ ia64_linux_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
|| isdigit (*s)); /* Literal number. */
}
+/* Core file support. */
+
+static const struct regcache_map_entry ia64_linux_gregmap[] =
+ {
+ { 32, IA64_GR0_REGNUM }, /* r0 ... r31 */
+ { 8, REGCACHE_MAP_SKIP_BYTES }, /* FIXME: NAT collection bits? */
+ { 1, IA64_PR_REGNUM },
+ { 8, IA64_BR0_REGNUM }, /* b0 ... b7 */
+ { 1, IA64_IP_REGNUM },
+ { 1, IA64_CFM_REGNUM },
+ { 1, IA64_PSR_REGNUM },
+ { 1, IA64_RSC_REGNUM },
+ { 1, IA64_BSP_REGNUM },
+ { 1, IA64_BSPSTORE_REGNUM },
+ { 1, IA64_RNAT_REGNUM },
+ { 1, IA64_CCV_REGNUM },
+ { 1, IA64_UNAT_REGNUM },
+ { 1, IA64_FPSR_REGNUM },
+ { 1, IA64_PFS_REGNUM },
+ { 1, IA64_LC_REGNUM },
+ { 1, IA64_EC_REGNUM },
+ { 0 }
+ };
+
+#define IA64_LINUX_GREGS_SIZE (55 * 8)
+
+static const struct regcache_map_entry ia64_linux_fpregmap[] =
+ {
+ { 128, IA64_FR0_REGNUM }, /* f0 ... f127 */
+ { 0 }
+ };
+
+#define IA64_LINUX_FPREGS_SIZE (128 * 8)
+
+static void
+ia64_linux_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *regs, size_t len)
+{
+ const gdb_byte f_zero[16] = { 0 };
+ const gdb_byte f_one[16] =
+ { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 };
+
+ regcache_supply_regset (regset, regcache, regnum, regs, len);
+
+ /* Kernel generated cores have fr1==0 instead of 1.0. Older GDBs
+ did the same. So ignore whatever might be recorded in fpregset_t
+ for fr0/fr1 and always supply their expected values. */
+ if (regnum == -1 || regnum == IA64_FR0_REGNUM)
+ regcache_raw_supply (regcache, IA64_FR0_REGNUM, f_zero);
+ if (regnum == -1 || regnum == IA64_FR1_REGNUM)
+ regcache_raw_supply (regcache, IA64_FR1_REGNUM, f_one);
+}
+
+static const struct regset ia64_linux_gregset =
+ {
+ ia64_linux_gregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+static const struct regset ia64_linux_fpregset =
+ {
+ ia64_linux_fpregmap,
+ ia64_linux_supply_fpregset, regcache_collect_regset
+ };
+
+static const struct regset *
+ia64_linux_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name,
+ size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0
+ && sect_size >= IA64_LINUX_GREGS_SIZE)
+ return &ia64_linux_gregset;
+
+ if (strcmp (sect_name, ".reg2") == 0
+ && sect_size >= IA64_LINUX_FPREGS_SIZE)
+ return &ia64_linux_fpregset;
+
+ return NULL;
+}
+
static void
ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -161,6 +244,10 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
+ /* Core file support. */
+ set_gdbarch_regset_from_core_section (gdbarch,
+ ia64_linux_regset_from_core_section);
+
/* SystemTap related. */
set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
set_gdbarch_stap_register_indirection_prefixes (gdbarch,
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 13/13] IA64 Linux: Define regset structures.
2014-06-25 16:49 ` [PATCH v2 13/13] IA64 Linux: Define " Andreas Arnez
@ 2014-07-15 13:01 ` Ulrich Weigand
2014-07-18 9:06 ` Andreas Arnez
0 siblings, 1 reply; 31+ messages in thread
From: Ulrich Weigand @ 2014-07-15 13:01 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Jeff Johnston
Andreas Arnez wrote:
> +static const struct regcache_map_entry ia64_linux_gregmap[] =
> + {
> + { 32, IA64_GR0_REGNUM }, /* r0 ... r31 */
> + { 8, REGCACHE_MAP_SKIP_BYTES }, /* FIXME: NAT collection bits? */
> + { 1, IA64_PR_REGNUM },
> + { 8, IA64_BR0_REGNUM }, /* b0 ... b7 */
> + { 1, IA64_IP_REGNUM },
> + { 1, IA64_CFM_REGNUM },
> + { 1, IA64_PSR_REGNUM },
> + { 1, IA64_RSC_REGNUM },
> + { 1, IA64_BSP_REGNUM },
> + { 1, IA64_BSPSTORE_REGNUM },
> + { 1, IA64_RNAT_REGNUM },
> + { 1, IA64_CCV_REGNUM },
> + { 1, IA64_UNAT_REGNUM },
> + { 1, IA64_FPSR_REGNUM },
> + { 1, IA64_PFS_REGNUM },
> + { 1, IA64_LC_REGNUM },
> + { 1, IA64_EC_REGNUM },
> + { 0 }
> + };
> +
> +#define IA64_LINUX_GREGS_SIZE (55 * 8)
If I'm reading the kernel sources correctly, the core file note will actually
contain 128 register slots.
> +static const struct regcache_map_entry ia64_linux_fpregmap[] =
> + {
> + { 128, IA64_FR0_REGNUM }, /* f0 ... f127 */
> + { 0 }
> + };
> +
> +#define IA64_LINUX_FPREGS_SIZE (128 * 8)
The size of one FP register should be 16 bytes, not 8.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 13/13] IA64 Linux: Define regset structures.
2014-07-15 13:01 ` Ulrich Weigand
@ 2014-07-18 9:06 ` Andreas Arnez
0 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-07-18 9:06 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, Jeff Johnston
On Tue, Jul 15 2014, Ulrich Weigand wrote:
> Andreas Arnez wrote:
>
>> +static const struct regcache_map_entry ia64_linux_gregmap[] =
>> + {
>> + { 32, IA64_GR0_REGNUM }, /* r0 ... r31 */
>> + { 8, REGCACHE_MAP_SKIP_BYTES }, /* FIXME: NAT collection bits? */
>> + { 1, IA64_PR_REGNUM },
>> + { 8, IA64_BR0_REGNUM }, /* b0 ... b7 */
>> + { 1, IA64_IP_REGNUM },
>> + { 1, IA64_CFM_REGNUM },
>> + { 1, IA64_PSR_REGNUM },
>> + { 1, IA64_RSC_REGNUM },
>> + { 1, IA64_BSP_REGNUM },
>> + { 1, IA64_BSPSTORE_REGNUM },
>> + { 1, IA64_RNAT_REGNUM },
>> + { 1, IA64_CCV_REGNUM },
>> + { 1, IA64_UNAT_REGNUM },
>> + { 1, IA64_FPSR_REGNUM },
>> + { 1, IA64_PFS_REGNUM },
>> + { 1, IA64_LC_REGNUM },
>> + { 1, IA64_EC_REGNUM },
>> + { 0 }
>> + };
>> +
>> +#define IA64_LINUX_GREGS_SIZE (55 * 8)
>
> If I'm reading the kernel sources correctly, the core file note will actually
> contain 128 register slots.
Right... the comment to the definition of ELF_NREG says "we really need
just 72 but let's leave some headroom..." In fact, GDB only uses 55
slots. And the change would make GDB consistent in itself; that's why I
just declared 55 slots here.
However, an old GDB rejects a core file that doesn't have exactly 128
register slots. Thus it certainly makes sense to increase this constant
to 128 * 8, such that users can write a core file with a new GDB and
read it with an old one.
OK, done.
>
>> +static const struct regcache_map_entry ia64_linux_fpregmap[] =
>> + {
>> + { 128, IA64_FR0_REGNUM }, /* f0 ... f127 */
>> + { 0 }
>> + };
>> +
>> +#define IA64_LINUX_FPREGS_SIZE (128 * 8)
>
> The size of one FP register should be 16 bytes, not 8.
Absolutely. Fixed.
Incremental patch below.
--
diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c
index 9989602..ff44d80 100644
--- a/gdb/ia64-linux-tdep.c
+++ b/gdb/ia64-linux-tdep.c
@@ -156,7 +156,10 @@ static const struct regcache_map_entry ia64_linux_gregmap[] =
{ 0 }
};
-#define IA64_LINUX_GREGS_SIZE (55 * 8)
+/* Size of 'gregset_t', as defined by the Linux kernel. Note that
+ this is more than actually mapped in the regmap above. */
+
+#define IA64_LINUX_GREGS_SIZE (128 * 8)
static const struct regcache_map_entry ia64_linux_fpregmap[] =
{
@@ -164,7 +167,7 @@ static const struct regcache_map_entry ia64_linux_fpregmap[] =
{ 0 }
};
-#define IA64_LINUX_FPREGS_SIZE (128 * 8)
+#define IA64_LINUX_FPREGS_SIZE (128 * 16)
static void
ia64_linux_supply_fpregset (const struct regset *regset,
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 10/13] SCORE: Fill 'collect_regset' in regset structure.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (2 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 13/13] IA64 Linux: Define " Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-15 10:01 ` Ulrich Weigand
2014-06-25 16:49 ` [PATCH v2 09/13] NIOS2 Linux: " Andreas Arnez
` (9 subsequent siblings)
13 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Qinwei
gdb/
* score-tdep.c (score7_linux_supply_gregset): Delete function.
Move logic to...
(score7_linux_gregmap): ... this new register map.
(SCORE7_LINUX_SIZEOF_GREGSET): New macro.
(score7_linux_gregset): Refer to register map, replace supply
method by regcache_supply_regset, and add collect method.
(score7_linux_regset_from_core_section): Replace
sizeof(elf_gregset_t) by SCORE7_LINUX_SIZEOF_GREGSET.
* score-tdep.h (SCORE_EPC_REGNUM): New enum value.
(struct pt_regs): Delete structure definition.
(elf_gregset_t): Delete typedef.
---
gdb/score-tdep.c | 72 +++++++++++++++++++-------------------------------------
gdb/score-tdep.h | 34 +-------------------------
2 files changed, 25 insertions(+), 81 deletions(-)
diff --git a/gdb/score-tdep.c b/gdb/score-tdep.c
index c224189..90afdf3 100644
--- a/gdb/score-tdep.c
+++ b/gdb/score-tdep.c
@@ -1398,59 +1398,34 @@ score_prologue_frame_base_sniffer (struct frame_info *this_frame)
return &score_prologue_frame_base;
}
-/* Core file support (dirty hack)
-
- The core file MUST be generated by GNU/Linux on S+core. */
-
-static void
-score7_linux_supply_gregset(const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs_buf, size_t len)
-{
- int regno;
- elf_gregset_t *gregs;
-
- gdb_assert (regset != NULL);
- gdb_assert ((regcache != NULL) && (gregs_buf != NULL));
-
- gregs = (elf_gregset_t *) gregs_buf;
-
- for (regno = 0; regno < 32; regno++)
- if (regnum == -1 || regnum == regno)
- regcache_raw_supply (regcache, regno, gregs->regs + regno);
+/* Core file support. */
+static const struct regcache_map_entry score7_linux_gregmap[] =
{
- struct sreg {
- int regnum;
- void *buf;
- } sregs [] = {
- { 55, &(gregs->cel) }, /* CEL */
- { 54, &(gregs->ceh) }, /* CEH */
- { 53, &(gregs->sr0) }, /* sr0, i.e. cnt or COUNTER */
- { 52, &(gregs->sr1) }, /* sr1, i.e. lcr or LDCR */
- { 51, &(gregs->sr1) }, /* sr2, i.e. scr or STCR */
-
- /* Exception occured at this address, exactly the PC we want */
- { 49, &(gregs->cp0_epc) }, /* PC */
-
- { 38, &(gregs->cp0_ema) }, /* EMA */
- { 37, &(gregs->cp0_epc) }, /* EPC */
- { 34, &(gregs->cp0_ecr) }, /* ECR */
- { 33, &(gregs->cp0_condition) }, /* COND */
- { 32, &(gregs->cp0_psr) }, /* PSR */
- };
+ { 7 * 4, REGCACHE_MAP_SKIP_BYTES },
+ { 32, 0 }, /* r0 ... r31 */
+ { 1, 55 }, /* CEL */
+ { 1, 54 }, /* CEH */
+ { 1, 53 }, /* sr0, i.e. cnt or COUNTER */
+ { 1, 52 }, /* sr1, i.e. lcr or LDCR */
+ { 1, 51 }, /* sr2, i.e. scr or STCR */
+ /* EPC and PC are stored in the same slot. */
+ { 1, 37 }, /* EPC */
+ { -4, REGCACHE_MAP_SKIP_BYTES },
+ { 1, 49 }, /* PC */
+ { 1, 38 }, /* EMA */
+ { 1, 32 }, /* PSR */
+ { 1, 34 }, /* ECR */
+ { 1, 33 }, /* COND */
+ { 0 }
+ };
- for (regno = 0; regno < sizeof(sregs)/sizeof(sregs[0]); regno++)
- if (regnum == -1 || regnum == sregs[regno].regnum)
- regcache_raw_supply (regcache,
- sregs[regno].regnum, sregs[regno].buf);
- }
-}
+#define SCORE7_LINUX_SIZEOF_GREGSET 196
static const struct regset score7_linux_gregset =
{
- NULL,
- score7_linux_supply_gregset, NULL
+ score7_linux_gregmap,
+ regcache_supply_regset, regcache_collect_regset
};
/* Return the appropriate register set from the core section identified
@@ -1463,7 +1438,8 @@ score7_linux_regset_from_core_section(struct gdbarch *gdbarch,
gdb_assert (gdbarch != NULL);
gdb_assert (sect_name != NULL);
- if (strcmp(sect_name, ".reg") == 0 && sect_size == sizeof(elf_gregset_t))
+ if (strcmp(sect_name, ".reg") == 0
+ && sect_size == SCORE7_LINUX_SIZEOF_GREGSET)
return &score7_linux_gregset;
return NULL;
diff --git a/gdb/score-tdep.h b/gdb/score-tdep.h
index 02a334e..cef0e6a 100644
--- a/gdb/score-tdep.h
+++ b/gdb/score-tdep.h
@@ -32,6 +32,7 @@ enum gdb_regnum
SCORE_RA_REGNUM = 3,
SCORE_A0_REGNUM = 4,
SCORE_AL_REGNUM = 7,
+ SCORE_EPC_REGNUM = 37,
SCORE_PC_REGNUM = 49,
};
@@ -46,37 +47,4 @@ enum gdb_regnum
#define SCORE_INSTLEN 4
#define SCORE16_INSTLEN 2
-/* Forward declarations. */
-struct regset;
-
-/* Linux Core file support (dirty hack)
-
- S+core Linux register set definition, copy from S+core Linux. */
-struct pt_regs {
- /* Pad bytes for argument save space on the stack. */
- unsigned long pad0[6]; /* may be 4, MIPS accept 6var, SCore
- accepts 4 Var--yuchen */
-
- /* Saved main processor registers. */
- unsigned long orig_r4;
- unsigned long regs[32];
-
- /* Other saved registers. */
- unsigned long cel;
- unsigned long ceh;
-
- unsigned long sr0; /*cnt*/
- unsigned long sr1; /*lcr*/
- unsigned long sr2; /*scr*/
-
- /* saved cp0 registers */
- unsigned long cp0_epc;
- unsigned long cp0_ema;
- unsigned long cp0_psr;
- unsigned long cp0_ecr;
- unsigned long cp0_condition;
-};
-
-typedef struct pt_regs elf_gregset_t;
-
#endif /* SCORE_TDEP_H */
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 10/13] SCORE: Fill 'collect_regset' in regset structure.
2014-06-25 16:49 ` [PATCH v2 10/13] SCORE: Fill 'collect_regset' in regset structure Andreas Arnez
@ 2014-07-15 10:01 ` Ulrich Weigand
2014-07-15 12:25 ` Andreas Arnez
0 siblings, 1 reply; 31+ messages in thread
From: Ulrich Weigand @ 2014-07-15 10:01 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Qinwei
Andreas Arnez wrote:
> diff --git a/gdb/score-tdep.h b/gdb/score-tdep.h
> index 02a334e..cef0e6a 100644
> --- a/gdb/score-tdep.h
> +++ b/gdb/score-tdep.h
> @@ -32,6 +32,7 @@ enum gdb_regnum
> SCORE_RA_REGNUM = 3,
> SCORE_A0_REGNUM = 4,
> SCORE_AL_REGNUM = 7,
> + SCORE_EPC_REGNUM = 37,
> SCORE_PC_REGNUM = 49,
> };
This doesn't appear to be used anywhere?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 10/13] SCORE: Fill 'collect_regset' in regset structure.
2014-07-15 10:01 ` Ulrich Weigand
@ 2014-07-15 12:25 ` Andreas Arnez
0 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-07-15 12:25 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, Qinwei
On Tue, Jul 15 2014, Ulrich Weigand wrote:
> Andreas Arnez wrote:
>
>> diff --git a/gdb/score-tdep.h b/gdb/score-tdep.h
>> index 02a334e..cef0e6a 100644
>> --- a/gdb/score-tdep.h
>> +++ b/gdb/score-tdep.h
>> @@ -32,6 +32,7 @@ enum gdb_regnum
>> SCORE_RA_REGNUM = 3,
>> SCORE_A0_REGNUM = 4,
>> SCORE_AL_REGNUM = 7,
>> + SCORE_EPC_REGNUM = 37,
>> SCORE_PC_REGNUM = 49,
>> };
>
> This doesn't appear to be used anywhere?
Right. This might be a left-over from an earlier version of the patch,
related to the special handling required for PC and EPC.
Removed.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 09/13] NIOS2 Linux: Fill 'collect_regset' in regset structure.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (3 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 10/13] SCORE: Fill 'collect_regset' in regset structure Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 11/13] TILEGX " Andreas Arnez
` (8 subsequent siblings)
13 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Yao Qi
gdb/
* nios2-linux-tdep.c (nios2_collect_gregset): New function.
(nios2_core_regset): Add collect method.
---
gdb/nios2-linux-tdep.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/gdb/nios2-linux-tdep.c b/gdb/nios2-linux-tdep.c
index 84ab576..0f53477 100644
--- a/gdb/nios2-linux-tdep.c
+++ b/gdb/nios2-linux-tdep.c
@@ -73,11 +73,30 @@ nios2_supply_gregset (const struct regset *regset,
}
}
+/* Implement the collect_regset hook for core files. */
+
+static void
+nios2_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs_buf, size_t len)
+{
+ gdb_byte *gregs = gregs_buf;
+ int regno;
+
+ for (regno = NIOS2_Z_REGNUM; regno <= NIOS2_MPUACC_REGNUM; regno++)
+ if (regnum == -1 || regnum == regno)
+ {
+ if (reg_offsets[regno] != -1)
+ regcache_raw_collect (regcache, regno,
+ gregs + 4 * reg_offsets[regno]);
+ }
+}
+
static const struct regset nios2_core_regset =
{
NULL,
nios2_supply_gregset,
- NULL,
+ nios2_collect_gregset
};
/* Implement the regset_from_core_section gdbarch method. */
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 11/13] TILEGX Linux: Fill 'collect_regset' in regset structure.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (4 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 09/13] NIOS2 Linux: " Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-15 10:12 ` Ulrich Weigand
2014-06-25 16:49 ` [PATCH v2 03/13] S390: Migrate to regcache_supply/collect_regset Andreas Arnez
` (7 subsequent siblings)
13 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Jiong Wang
gdb/
* tilegx-linux-tdep.c (tilegx_linux_supply_regset): Delete
function. Move logic to...
(tilegx_linux_regmap): ... this new register map.
(TILEGX_GREGS_SIZE): New enum value.
(tilegx_linux_regset): Refer to register map, replace supply
method by regcache_supply_regset, and add collect method.
---
gdb/tilegx-linux-tdep.c | 37 +++++++++++++++----------------------
1 file changed, 15 insertions(+), 22 deletions(-)
diff --git a/gdb/tilegx-linux-tdep.c b/gdb/tilegx-linux-tdep.c
index 98b03db..4169433 100644
--- a/gdb/tilegx-linux-tdep.c
+++ b/gdb/tilegx-linux-tdep.c
@@ -73,34 +73,27 @@ static const struct tramp_frame tilegx_linux_rt_sigframe =
tilegx_linux_sigframe_init
};
-/* Supply raw registers from REGCACHE to REGS. */
+/* Register map; must match struct pt_regs in "ptrace.h". */
-static void
-tilegx_linux_supply_regset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *regs, size_t len)
-{
- struct gdbarch *arch = get_regcache_arch (regcache);
- const char *ptr = regs;
- int i;
-
- /* This logic must match that of struct pt_regs in "ptrace.h". */
- for (i = 0; i < TILEGX_NUM_EASY_REGS + 2; i++, ptr += tilegx_reg_size)
- {
- int gri = (i < TILEGX_NUM_EASY_REGS)
- ? i : (i == TILEGX_NUM_EASY_REGS)
- ? TILEGX_PC_REGNUM : TILEGX_FAULTNUM_REGNUM;
+static const struct regcache_map_entry tilegx_linux_regmap[] =
+ {
+ { TILEGX_NUM_EASY_REGS, 0 },
+ { 1, TILEGX_PC_REGNUM },
+ { 1, TILEGX_FAULTNUM_REGNUM },
+ { 0 }
+ };
- if (regnum == gri || regnum == -1)
- regcache_raw_supply (regcache, gri, ptr);
- }
-}
+enum
+{
+ TILEGX_GREGS_SIZE = (TILEGX_NUM_EASY_REGS + 2) * tilegx_reg_size
+};
/* TILE-Gx Linux kernel register set. */
+
static const struct regset tilegx_linux_regset =
{
- NULL,
- tilegx_linux_supply_regset
+ tilegx_linux_regmap,
+ regcache_supply_regset, regcache_collect_regset
};
static const struct regset *
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 11/13] TILEGX Linux: Fill 'collect_regset' in regset structure.
2014-06-25 16:49 ` [PATCH v2 11/13] TILEGX " Andreas Arnez
@ 2014-07-15 10:12 ` Ulrich Weigand
2014-07-16 13:30 ` Andreas Arnez
0 siblings, 1 reply; 31+ messages in thread
From: Ulrich Weigand @ 2014-07-15 10:12 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Jiong Wang
Andreas Arnez wrote:
> gdb/
> * tilegx-linux-tdep.c (tilegx_linux_supply_regset): Delete
> function. Move logic to...
> (tilegx_linux_regmap): ... this new register map.
> (TILEGX_GREGS_SIZE): New enum value.
> (tilegx_linux_regset): Refer to register map, replace supply
> method by regcache_supply_regset, and add collect method.
> +static const struct regcache_map_entry tilegx_linux_regmap[] =
> + {
> + { TILEGX_NUM_EASY_REGS, 0 },
Maybe TILEGX_R0_REGNUM instead of 0?
> + { 1, TILEGX_PC_REGNUM },
This seems to get the register size wrong in 32-bit mode; note
that TILEGX_PC_REGNUM has type builtin_func_ptr, which may be
4 bytes in size ...
> + { 1, TILEGX_FAULTNUM_REGNUM },
> + { 0 }
> + };
>
> - if (regnum == gri || regnum == -1)
> - regcache_raw_supply (regcache, gri, ptr);
> - }
> -}
> +enum
> +{
> + TILEGX_GREGS_SIZE = (TILEGX_NUM_EASY_REGS + 2) * tilegx_reg_size
> +};
This doesn't appear to be used here.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 11/13] TILEGX Linux: Fill 'collect_regset' in regset structure.
2014-07-15 10:12 ` Ulrich Weigand
@ 2014-07-16 13:30 ` Andreas Arnez
0 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-07-16 13:30 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, Jiong Wang
On Tue, Jul 15 2014, Ulrich Weigand wrote:
> Andreas Arnez wrote:
>
>> gdb/
>> * tilegx-linux-tdep.c (tilegx_linux_supply_regset): Delete
>> function. Move logic to...
>> (tilegx_linux_regmap): ... this new register map.
>> (TILEGX_GREGS_SIZE): New enum value.
>> (tilegx_linux_regset): Refer to register map, replace supply
>> method by regcache_supply_regset, and add collect method.
>
>> +static const struct regcache_map_entry tilegx_linux_regmap[] =
>> + {
>> + { TILEGX_NUM_EASY_REGS, 0 },
>
> Maybe TILEGX_R0_REGNUM instead of 0?
Maybe. Or, thinking about this again, I'd more clearly indicate the
group of "easy" registers with a new enum value
TILEGX_FIRST_EASY_REGNUM = TILEGX_R0_REGNUM
OK?
>
>> + { 1, TILEGX_PC_REGNUM },
>
> This seems to get the register size wrong in 32-bit mode; note
> that TILEGX_PC_REGNUM has type builtin_func_ptr, which may be
> 4 bytes in size ...
Hm, I didn't realize that 32-bit mode is actually supported. Note that
tilegx_register_type() unconditionally assigns a 64-bit type to *all
other* registers:
if (regnum == TILEGX_PC_REGNUM)
return builtin_type (gdbarch)->builtin_func_ptr;
else
return builtin_type (gdbarch)->builtin_uint64;
Also, the original logic in tilegx_linux_supply_regset() maps an 8-byte
slot to each register. In 32-bit mode, this behavior doesn't seem to
match the Linux kernel code, which -- if I interpret it correctly --
assigns the same type 'pt_reg_t' to all registers in pt_regs, and:
pt_reg_t == uint_reg_t == __uint_reg_t == unsigned long
Thus, each register should be in a 4-byte slot, and the register type
for everything but the PC should be builtin_uint32, right?
Has GDB ever been used for 32-bit TILE-Gx core files? Or am I getting
something wrong here?
>
>> + { 1, TILEGX_FAULTNUM_REGNUM },
>> + { 0 }
>> + };
>>
>> - if (regnum == gri || regnum == -1)
>> - regcache_raw_supply (regcache, gri, ptr);
>> - }
>> -}
>> +enum
>> +{
>> + TILEGX_GREGS_SIZE = (TILEGX_NUM_EASY_REGS + 2) * tilegx_reg_size
>> +};
>
> This doesn't appear to be used here.
Removed.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 03/13] S390: Migrate to regcache_supply/collect_regset.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (5 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 11/13] TILEGX " Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-15 9:27 ` Ulrich Weigand
2014-06-25 16:49 ` [PATCH v2 07/13] HPPA Linux: Fill 'collect_regset' in regset structures Andreas Arnez
` (6 subsequent siblings)
13 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich Weigand
Rather than supplying own supply/collect functions, use the generic
functions regcache_supply_regset and regcache_collect_regset instead.
The register maps are rewritten accordingly and become much shorter
(and better readable) than before.
gdb/
* s390-linux-nat.c: Include "regset.h".
(regmap_gregset): Delete macro.
(s390_64_regmap_gregset): New register map for
regcache_supply/_collect_regset.
(s390_64_gregset): New regset.
(S390_PSWM_OFFSET, S390_PSWA_OFFSET): New macros.
(regmap_fpregset): Delete macro.
(s390_native_supply, s390_native_collect): Delete functions.
(supply_gregset, fill_gregset): Replace s390-specific regmap
handling by a call to regcache_supply/_collect_regset.
(supply_fpregset, fill_fpregset): Call regcache_supply/
_collect_regset instead of s390_native_supply/_collect.
(fetch_regset, store_regset): Likewise. Also change the last
parameter to a regset instead of a regmap.
(s390_linux_fetch_inferior_registers)
(390_linux_store_inferior_registers): Adjust last parameter in
calls to fetch_regset and store_regset.
* s390-linux-tdep.c (s390_regmap_gregset): Rename to...
(s390_gregmap): ... this. Also make static const and convert to
regcache_map_entry format.
(s390x_regmap_gregset): Delete.
(s390_regmap_fpregset): Rename to...
(s390_fpregmap): ... this. Make static const and convert to
regcache_map_entry format.
(s390_regmap_upper, s390_regmap_last_break)
(s390x_regmap_last_break, s390_regmap_system_call)
(s390_regmap_tdb): Likewise.
(s390_supply_regset, s390_collect_regset): Remove functions.
(s390_supply_tdb_regset): Call regcache_supply_regset instead of
s390_supply_regset.
(s390_gregset, s390_fpregset, s390_upper_regset)
(s390_last_break_regset, s390x_last_break_regset)
(s390_system_call_regset, s390_tdb_regset): Make global and
replace s390_supply/_collect_regset by regcache_supply/
_collect_regset.
(s390x_gregset): Delete.
(s390_gdbarch_init): Replace s390x_gregset by s390_gregset.
* s390-linux-tdep.h (s390_regmap_gregset, s390x_regmap_gregset)
(s390_regmap_fpregset, s390_regmap_last_break)
(s390x_regmap_last_break, s390_regmap_system_call)
(s390_regmap_tdb): Delete global variable declarations.
(s390_gregset, s390_fpregset, s390_last_break_regset)
(s390x_last_break_regset, s390_system_call_regset)
(s390_tdb_regset): New global variable declarations.
---
gdb/s390-linux-nat.c | 177 ++++++++++++++------------------
gdb/s390-linux-tdep.c | 278 +++++++++++---------------------------------------
gdb/s390-linux-tdep.h | 13 ++-
3 files changed, 140 insertions(+), 328 deletions(-)
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 45db7c9..8d8cf59 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -26,6 +26,7 @@
#include "linux-nat.h"
#include "auxv.h"
#include "gregset.h"
+#include "regset.h"
#include "s390-linux-tdep.h"
#include "elf/common.h"
@@ -49,42 +50,46 @@ 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. */
+/* Register map for 32-bit executables running under a 64-bit
+ kernel. */
#ifdef __s390x__
-#define regmap_gregset s390x_regmap_gregset
-#else
-#define regmap_gregset s390_regmap_gregset
+static const struct regcache_map_entry s390_64_regmap_gregset[] =
+ {
+ /* Skip PSWM and PSWA, since they must be handled specially. */
+ { 16, REGCACHE_MAP_SKIP_BYTES },
+ { 1, S390_R0_UPPER_REGNUM }, { 1, S390_R0_REGNUM },
+ { 1, S390_R1_UPPER_REGNUM }, { 1, S390_R1_REGNUM },
+ { 1, S390_R2_UPPER_REGNUM }, { 1, S390_R2_REGNUM },
+ { 1, S390_R3_UPPER_REGNUM }, { 1, S390_R3_REGNUM },
+ { 1, S390_R4_UPPER_REGNUM }, { 1, S390_R4_REGNUM },
+ { 1, S390_R5_UPPER_REGNUM }, { 1, S390_R5_REGNUM },
+ { 1, S390_R6_UPPER_REGNUM }, { 1, S390_R6_REGNUM },
+ { 1, S390_R7_UPPER_REGNUM }, { 1, S390_R7_REGNUM },
+ { 1, S390_R8_UPPER_REGNUM }, { 1, S390_R8_REGNUM },
+ { 1, S390_R9_UPPER_REGNUM }, { 1, S390_R9_REGNUM },
+ { 1, S390_R10_UPPER_REGNUM }, { 1, S390_R10_REGNUM },
+ { 1, S390_R11_UPPER_REGNUM }, { 1, S390_R11_REGNUM },
+ { 1, S390_R12_UPPER_REGNUM }, { 1, S390_R12_REGNUM },
+ { 1, S390_R13_UPPER_REGNUM }, { 1, S390_R13_REGNUM },
+ { 1, S390_R14_UPPER_REGNUM }, { 1, S390_R14_REGNUM },
+ { 1, S390_R15_UPPER_REGNUM }, { 1, S390_R15_REGNUM },
+ { 16, S390_A0_REGNUM },
+ { 4, REGCACHE_MAP_SKIP_BYTES }, { 1, S390_ORIG_R2_REGNUM },
+ { 0 }
+ };
+
+static const struct regset s390_64_gregset =
+ {
+ s390_64_regmap_gregset,
+ regcache_supply_regset,
+ regcache_collect_regset
+ };
+
+#define S390_PSWM_OFFSET 0
+#define S390_PSWA_OFFSET 8
#endif
-#define regmap_fpregset s390_regmap_fpregset
-
-/* 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, const short *map,
- const gdb_byte *regp)
-{
- for (; map[0] >= 0; map += 2)
- regcache_raw_supply (regcache, map[1], regp ? regp + map[0] : NULL);
-}
-
-/* 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.
@@ -100,28 +105,15 @@ supply_gregset (struct regcache *regcache, const gregset_t *regp)
if (gdbarch_ptr_bit (gdbarch) == 32)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST pswm = 0, pswa = 0;
+ ULONGEST pswm, pswa;
gdb_byte buf[4];
- const short *map;
-
- for (map = regmap_gregset; map[0] >= 0; map += 2)
- {
- const gdb_byte *p = (const gdb_byte *) regp + map[0];
- int regno = map[1];
-
- 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);
- }
- }
+ regcache_supply_regset (&s390_64_gregset, regcache, -1,
+ regp, sizeof (gregset_t));
+ pswm = extract_unsigned_integer ((const gdb_byte *) regp
+ + S390_PSWM_OFFSET, 8, byte_order);
+ pswa = extract_unsigned_integer ((const gdb_byte *) regp
+ + S390_PSWA_OFFSET, 8, byte_order);
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,
@@ -131,7 +123,8 @@ supply_gregset (struct regcache *regcache, const gregset_t *regp)
}
#endif
- s390_native_supply (regcache, regmap_gregset, (const gdb_byte *) regp);
+ regcache_supply_regset (&s390_gregset, regcache, -1, regp,
+ sizeof (gregset_t));
}
/* Fill register REGNO (if it is a general-purpose register) in
@@ -145,28 +138,8 @@ fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (gdbarch_ptr_bit (gdbarch) == 32)
{
- gdb_byte *psw_p[2];
- const short *map;
-
- for (map = regmap_gregset; map[0] >= 0; map += 2)
- {
- gdb_byte *p = (gdb_byte *) regp + map[0];
- int reg = map[1];
-
- if (reg >= S390_PSWM_REGNUM && reg <= S390_PSWA_REGNUM)
- psw_p[reg - S390_PSWM_REGNUM] = p;
-
- 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);
- }
- }
+ regcache_collect_regset (&s390_64_gregset, regcache, regno,
+ regp, sizeof (gregset_t));
if (regno == -1
|| regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM)
@@ -181,18 +154,19 @@ fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
pswa = extract_unsigned_integer (buf, 4, byte_order);
if (regno == -1 || regno == S390_PSWM_REGNUM)
- store_unsigned_integer (psw_p[0], 8, byte_order,
- ((pswm & 0xfff7ffff) << 32) |
+ store_unsigned_integer ((gdb_byte *) regp + S390_PSWM_OFFSET, 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);
+ store_unsigned_integer ((gdb_byte *) regp + S390_PSWA_OFFSET, 8,
+ byte_order, pswa & 0x7fffffff);
}
return;
}
#endif
- s390_native_collect (regcache, regmap_gregset, regno, (gdb_byte *) regp);
+ regcache_collect_regset (&s390_gregset, regcache, regno, regp,
+ sizeof (gregset_t));
}
/* Fill GDB's register array with the floating-point register values
@@ -200,7 +174,8 @@ fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
void
supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
{
- s390_native_supply (regcache, regmap_fpregset, (const gdb_byte *) regp);
+ regcache_supply_regset (&s390_fpregset, regcache, -1, regp,
+ sizeof (fpregset_t));
}
/* Fill register REGNO (if it is a general-purpose register) in
@@ -209,7 +184,8 @@ supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
void
fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
{
- s390_native_collect (regcache, regmap_fpregset, regno, (gdb_byte *) regp);
+ regcache_collect_regset (&s390_fpregset, regcache, regno, regp,
+ sizeof (fpregset_t));
}
/* Find the TID for the current inferior thread to use with ptrace. */
@@ -298,12 +274,13 @@ store_fpregs (const struct regcache *regcache, int tid, int regnum)
perror_with_name (_("Couldn't write floating point status"));
}
-/* Fetch all registers in the kernel's register set whose number is REGSET,
- whose size is REGSIZE, and whose layout is described by REGMAP, from
- process/thread TID and store their values in GDB's register cache. */
+/* Fetch all registers in the kernel's register set whose number is
+ REGSET_ID, whose size is REGSIZE, and whose layout is described by
+ REGSET, from 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, const short *regmap)
+ int regset_id, int regsize, const struct regset *regset)
{
gdb_byte *buf = alloca (regsize);
struct iovec iov;
@@ -311,23 +288,23 @@ fetch_regset (struct regcache *regcache, int tid,
iov.iov_base = buf;
iov.iov_len = regsize;
- if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
+ if (ptrace (PTRACE_GETREGSET, tid, (long) regset_id, (long) &iov) < 0)
{
if (errno == ENODATA)
- s390_native_supply (regcache, regmap, NULL);
+ regcache_supply_regset (regset, regcache, -1, NULL, regsize);
else
perror_with_name (_("Couldn't get register set"));
}
else
- s390_native_supply (regcache, regmap, buf);
+ regcache_supply_regset (regset, regcache, -1, buf, regsize);
}
-/* Store all registers in the kernel's register set whose number is REGSET,
- whose size is REGSIZE, and whose layout is described by REGMAP, from
- GDB's register cache back to process/thread TID. */
+/* Store all registers in the kernel's register set whose number is
+ REGSET_ID, whose size is REGSIZE, and whose layout is described by
+ REGSET, from GDB's register cache back to process/thread TID. */
static void
store_regset (struct regcache *regcache, int tid,
- int regset, int regsize, const short *regmap)
+ int regset_id, int regsize, const struct regset *regset)
{
gdb_byte *buf = alloca (regsize);
struct iovec iov;
@@ -335,12 +312,12 @@ store_regset (struct regcache *regcache, int tid,
iov.iov_base = buf;
iov.iov_len = regsize;
- if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
+ if (ptrace (PTRACE_GETREGSET, tid, (long) regset_id, (long) &iov) < 0)
perror_with_name (_("Couldn't get register set"));
- s390_native_collect (regcache, regmap, -1, buf);
+ regcache_collect_regset (regset, regcache, -1, buf, regsize);
- if (ptrace (PTRACE_SETREGSET, tid, (long) regset, (long) &iov) < 0)
+ if (ptrace (PTRACE_SETREGSET, tid, (long) regset_id, (long) &iov) < 0)
perror_with_name (_("Couldn't set register set"));
}
@@ -379,17 +356,17 @@ s390_linux_fetch_inferior_registers (struct target_ops *ops,
if (regnum == -1 || regnum == S390_LAST_BREAK_REGNUM)
fetch_regset (regcache, tid, NT_S390_LAST_BREAK, 8,
(gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32
- ? s390_regmap_last_break : s390x_regmap_last_break));
+ ? &s390_last_break_regset : &s390x_last_break_regset));
if (have_regset_system_call)
if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
fetch_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
- s390_regmap_system_call);
+ &s390_system_call_regset);
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);
+ &s390_tdb_regset);
}
/* Store register REGNUM back into the child process. If REGNUM is
@@ -411,7 +388,7 @@ s390_linux_store_inferior_registers (struct target_ops *ops,
if (have_regset_system_call)
if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
store_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
- s390_regmap_system_call);
+ &s390_system_call_regset);
}
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 3658033..f67ba9c 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -420,204 +420,61 @@ s390_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
/* Maps for register sets. */
-const short s390_regmap_gregset[] =
+static const struct regcache_map_entry s390_gregmap[] =
{
- 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
+ { 1, S390_PSWM_REGNUM },
+ { 1, S390_PSWA_REGNUM },
+ { 16, S390_R0_REGNUM },
+ { 16, S390_A0_REGNUM },
+ { 1, S390_ORIG_R2_REGNUM },
+ { 0 }
};
-const short s390x_regmap_gregset[] =
+static const struct regcache_map_entry s390_fpregmap[] =
{
- 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
+ { 1, S390_FPC_REGNUM }, { 4, REGCACHE_MAP_SKIP_BYTES },
+ { 16, S390_F0_REGNUM },
+ { 0 }
};
-const short s390_regmap_fpregset[] =
+static const struct regcache_map_entry s390_regmap_upper[] =
{
- 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
+ { 16, S390_R0_UPPER_REGNUM },
+ { 0 }
};
-const short s390_regmap_upper[] =
+static const struct regcache_map_entry s390_regmap_last_break[] =
{
- 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
+ { 1, S390_LAST_BREAK_REGNUM },
+ { 0 }
};
-const short s390_regmap_last_break[] =
+static const struct regcache_map_entry s390x_regmap_last_break[] =
{
- 0x04, S390_LAST_BREAK_REGNUM,
- -1, -1
+ { 1, S390_LAST_BREAK_REGNUM },
+ { 0 }
};
-const short s390x_regmap_last_break[] =
+static const struct regcache_map_entry s390_regmap_system_call[] =
{
- 0x00, S390_LAST_BREAK_REGNUM,
- -1, -1
+ { 1, S390_SYSTEM_CALL_REGNUM },
+ { 0 }
};
-const short s390_regmap_system_call[] =
+static const struct regcache_map_entry s390_regmap_tdb[] =
{
- 0x00, S390_SYSTEM_CALL_REGNUM,
- -1, -1
+ { 1, S390_TDB_DWORD0_REGNUM },
+ { 1, S390_TDB_ABORT_CODE_REGNUM },
+ { 1, S390_TDB_CONFLICT_TOKEN_REGNUM },
+ { 1, S390_TDB_ATIA_REGNUM },
+ { 96, REGCACHE_MAP_SKIP_BYTES },
+ { 16, S390_TDB_R0_REGNUM },
+ { 0 }
};
-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
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-static void
-s390_supply_regset (const struct regset *regset, struct regcache *regcache,
- int regnum, const void *regs, size_t len)
-{
- const short *map;
- for (map = regset->regmap; map[0] >= 0; map += 2)
- if (regnum == -1 || regnum == map[1])
- regcache_raw_supply (regcache, map[1],
- regs ? (const char *)regs + map[0] : NULL);
-}
-/* Supply the TDB regset. Like s390_supply_regset, but invalidate the
- TDB registers unless the TDB format field is valid. */
+/* Supply the TDB regset. Like regcache_supply_regset, but invalidate
+ the TDB registers unless the TDB format field is valid. */
static void
s390_supply_tdb_regset (const struct regset *regset, struct regcache *regcache,
@@ -627,73 +484,52 @@ s390_supply_tdb_regset (const struct regset *regset, struct regcache *regcache,
enum register_status ret;
int i;
- s390_supply_regset (regset, regcache, regnum, regs, len);
+ regcache_supply_regset (regset, regcache, regnum, regs, len);
ret = regcache_cooked_read_unsigned (regcache, S390_TDB_DWORD0_REGNUM, &tdw);
if (ret != REG_VALID || (tdw >> 56) != 1)
- s390_supply_regset (regset, regcache, regnum, NULL, len);
+ regcache_supply_regset (regset, regcache, regnum, NULL, len);
}
-/* Collect register REGNUM from the register cache REGCACHE and store
- it in the buffer specified by REGS and LEN as described by the
- general-purpose register set REGSET. If REGNUM is -1, do this for
- all registers in REGSET. */
-static void
-s390_collect_regset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *regs, size_t len)
-{
- const short *map;
- for (map = regset->regmap; 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 = {
- s390_regmap_gregset,
- s390_supply_regset,
- s390_collect_regset
+const struct regset s390_gregset = {
+ s390_gregmap,
+ regcache_supply_regset,
+ regcache_collect_regset
};
-static const struct regset s390x_gregset = {
- s390x_regmap_gregset,
- s390_supply_regset,
- s390_collect_regset
-};
-
-static const struct regset s390_fpregset = {
- s390_regmap_fpregset,
- s390_supply_regset,
- s390_collect_regset
+const struct regset s390_fpregset = {
+ s390_fpregmap,
+ regcache_supply_regset,
+ regcache_collect_regset
};
static const struct regset s390_upper_regset = {
s390_regmap_upper,
- s390_supply_regset,
- s390_collect_regset
+ regcache_supply_regset,
+ regcache_collect_regset
};
-static const struct regset s390_last_break_regset = {
+const struct regset s390_last_break_regset = {
s390_regmap_last_break,
- s390_supply_regset,
- s390_collect_regset
+ regcache_supply_regset,
+ regcache_collect_regset
};
-static const struct regset s390x_last_break_regset = {
+const struct regset s390x_last_break_regset = {
s390x_regmap_last_break,
- s390_supply_regset,
- s390_collect_regset
+ regcache_supply_regset,
+ regcache_collect_regset
};
-static const struct regset s390_system_call_regset = {
+const struct regset s390_system_call_regset = {
s390_regmap_system_call,
- s390_supply_regset,
- s390_collect_regset
+ regcache_supply_regset,
+ regcache_collect_regset
};
-static const struct regset s390_tdb_regset = {
+const struct regset s390_tdb_regset = {
s390_regmap_tdb,
s390_supply_tdb_regset,
- s390_collect_regset
+ regcache_collect_regset
};
static struct core_regset_section s390_linux32_regset_sections[] =
@@ -3371,7 +3207,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
break;
case ABI_LINUX_ZSERIES:
- tdep->gregset = &s390x_gregset;
+ tdep->gregset = &s390_gregset;
tdep->sizeof_gregset = s390x_sizeof_gregset;
tdep->fpregset = &s390_fpregset;
tdep->sizeof_fpregset = s390_sizeof_fpregset;
diff --git a/gdb/s390-linux-tdep.h b/gdb/s390-linux-tdep.h
index 52bed9d..1e12000 100644
--- a/gdb/s390-linux-tdep.h
+++ b/gdb/s390-linux-tdep.h
@@ -150,15 +150,14 @@
/* Core file register sets, defined in s390-tdep.c. */
#define s390_sizeof_gregset 0x90
-extern const short s390_regmap_gregset[];
#define s390x_sizeof_gregset 0xd8
-extern const short s390x_regmap_gregset[];
+extern const struct regset s390_gregset;
#define s390_sizeof_fpregset 0x88
-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[];
+extern const struct regset s390_fpregset;
+extern const struct regset s390_last_break_regset;
+extern const struct regset s390x_last_break_regset;
+extern const struct regset s390_system_call_regset;
+extern const struct regset s390_tdb_regset;
#define s390_sizeof_tdbregset 0x100
/* GNU/Linux target descriptions. */
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 03/13] S390: Migrate to regcache_supply/collect_regset.
2014-06-25 16:49 ` [PATCH v2 03/13] S390: Migrate to regcache_supply/collect_regset Andreas Arnez
@ 2014-07-15 9:27 ` Ulrich Weigand
2014-07-15 12:07 ` Andreas Arnez
0 siblings, 1 reply; 31+ messages in thread
From: Ulrich Weigand @ 2014-07-15 9:27 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches
Andreas Arnez wrote:
> gdb/
> * s390-linux-nat.c: Include "regset.h".
> (regmap_gregset): Delete macro.
> (s390_64_regmap_gregset): New register map for
> regcache_supply/_collect_regset.
> (s390_64_gregset): New regset.
> (S390_PSWM_OFFSET, S390_PSWA_OFFSET): New macros.
> (regmap_fpregset): Delete macro.
> (s390_native_supply, s390_native_collect): Delete functions.
> (supply_gregset, fill_gregset): Replace s390-specific regmap
> handling by a call to regcache_supply/_collect_regset.
> (supply_fpregset, fill_fpregset): Call regcache_supply/
> _collect_regset instead of s390_native_supply/_collect.
> (fetch_regset, store_regset): Likewise. Also change the last
> parameter to a regset instead of a regmap.
> (s390_linux_fetch_inferior_registers)
> (390_linux_store_inferior_registers): Adjust last parameter in
> calls to fetch_regset and store_regset.
> * s390-linux-tdep.c (s390_regmap_gregset): Rename to...
> (s390_gregmap): ... this. Also make static const and convert to
> regcache_map_entry format.
> (s390x_regmap_gregset): Delete.
> (s390_regmap_fpregset): Rename to...
> (s390_fpregmap): ... this. Make static const and convert to
> regcache_map_entry format.
> (s390_regmap_upper, s390_regmap_last_break)
> (s390x_regmap_last_break, s390_regmap_system_call)
> (s390_regmap_tdb): Likewise.
> (s390_supply_regset, s390_collect_regset): Remove functions.
> (s390_supply_tdb_regset): Call regcache_supply_regset instead of
> s390_supply_regset.
> (s390_gregset, s390_fpregset, s390_upper_regset)
> (s390_last_break_regset, s390x_last_break_regset)
> (s390_system_call_regset, s390_tdb_regset): Make global and
> replace s390_supply/_collect_regset by regcache_supply/
> _collect_regset.
> (s390x_gregset): Delete.
> (s390_gdbarch_init): Replace s390x_gregset by s390_gregset.
> * s390-linux-tdep.h (s390_regmap_gregset, s390x_regmap_gregset)
> (s390_regmap_fpregset, s390_regmap_last_break)
> (s390x_regmap_last_break, s390_regmap_system_call)
> (s390_regmap_tdb): Delete global variable declarations.
> (s390_gregset, s390_fpregset, s390_last_break_regset)
> (s390x_last_break_regset, s390_system_call_regset)
> (s390_tdb_regset): New global variable declarations.
This is OK, except that:
> -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
> - };
These two are deliberately different, but the replacements
are identical:
> +static const struct regcache_map_entry s390_regmap_last_break[] =
> + {
> + { 1, S390_LAST_BREAK_REGNUM },
> + { 0 }
> + };
>
> +static const struct regcache_map_entry s390x_regmap_last_break[] =
> + {
> + { 1, S390_LAST_BREAK_REGNUM },
> + { 0 }
> + };
That seems wrong, I think s390_regmap_last_break needs to
skip the initial 4 bytes.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 03/13] S390: Migrate to regcache_supply/collect_regset.
2014-07-15 9:27 ` Ulrich Weigand
@ 2014-07-15 12:07 ` Andreas Arnez
0 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-07-15 12:07 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches
On Tue, Jul 15 2014, Ulrich Weigand wrote:
> This is OK, except that:
>
>> -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
>> - };
>
> These two are deliberately different, but the replacements
> are identical:
>
>> +static const struct regcache_map_entry s390_regmap_last_break[] =
>> + {
>> + { 1, S390_LAST_BREAK_REGNUM },
>> + { 0 }
>> + };
>>
>> +static const struct regcache_map_entry s390x_regmap_last_break[] =
>> + {
>> + { 1, S390_LAST_BREAK_REGNUM },
>> + { 0 }
>> + };
>
> That seems wrong, I think s390_regmap_last_break needs to
> skip the initial 4 bytes.
Good catch! With my original patch the register was always shown as
zero for 31-bit ABI inferiors. After the correction below we get real
values again.
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index f67ba9c..a4e9342 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -445,6 +445,7 @@ static const struct regcache_map_entry s390_regmap_upper[] =
static const struct regcache_map_entry s390_regmap_last_break[] =
{
+ { 4, REGCACHE_MAP_SKIP_BYTES },
{ 1, S390_LAST_BREAK_REGNUM },
{ 0 }
};
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 07/13] HPPA Linux: Fill 'collect_regset' in regset structures.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (6 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 03/13] S390: Migrate to regcache_supply/collect_regset Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 12/13] M68K Linux: Define " Andreas Arnez
` (5 subsequent siblings)
13 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Randolph Chung
gdb/
* hppa-linux-tdep.c (greg_map): Rename to...
(hppa_linux_gregmap): ... this. Also convert to
regcache_map_entry format.
(hppa_linux_supply_regset): Delete function.
(hppa_linux_supply_fpregset): Delete function. Move logic to...
(hppa_linux_fpregmap): ... this new register map.
(hppa_linux_regset, hppa_linux_fpregset): Refer to appropriate
register map, replace supply method by regcache_supply_regset, and
add collect method regcache_collect_regset.
---
gdb/hppa-linux-tdep.c | 101 +++++++++++++++++---------------------------------
1 file changed, 34 insertions(+), 67 deletions(-)
diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c
index 7a765a2..af57e6c 100644
--- a/gdb/hppa-linux-tdep.c
+++ b/gdb/hppa-linux-tdep.c
@@ -423,84 +423,51 @@ hppa_linux_find_global_pointer (struct gdbarch *gdbarch,
* cr10, cr15
*/
-#define GR_REGNUM(_n) (HPPA_R0_REGNUM+_n)
-#define TR_REGNUM(_n) (HPPA_TR0_REGNUM+_n)
-static const int greg_map[] =
+static const struct regcache_map_entry hppa_linux_gregmap[] =
{
- GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
- GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
- GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
- GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
- GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
- GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
- GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
- GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
-
- HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
- HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
-
- HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
- HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
-
- HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
- HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
-
- TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
- TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
-
- HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
- HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
+ { 32, HPPA_R0_REGNUM },
+ { 1, HPPA_SR4_REGNUM+1 },
+ { 1, HPPA_SR4_REGNUM+2 },
+ { 1, HPPA_SR4_REGNUM+3 },
+ { 1, HPPA_SR4_REGNUM+4 },
+ { 1, HPPA_SR4_REGNUM },
+ { 1, HPPA_SR4_REGNUM+5 },
+ { 1, HPPA_SR4_REGNUM+6 },
+ { 1, HPPA_SR4_REGNUM+7 },
+ { 1, HPPA_PCOQ_HEAD_REGNUM },
+ { 1, HPPA_PCOQ_TAIL_REGNUM },
+ { 1, HPPA_PCSQ_HEAD_REGNUM },
+ { 1, HPPA_PCSQ_TAIL_REGNUM },
+ { 1, HPPA_SAR_REGNUM },
+ { 1, HPPA_IIR_REGNUM },
+ { 1, HPPA_ISR_REGNUM },
+ { 1, HPPA_IOR_REGNUM },
+ { 1, HPPA_IPSW_REGNUM },
+ { 1, HPPA_RCR_REGNUM },
+ { 8, HPPA_TR0_REGNUM },
+ { 4, HPPA_PID0_REGNUM },
+ { 1, HPPA_CCR_REGNUM },
+ { 1, HPPA_EIEM_REGNUM },
+ { 0 }
};
-static void
-hppa_linux_supply_regset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *regs, size_t len)
-{
- struct gdbarch *arch = get_regcache_arch (regcache);
- struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
- const char *buf = regs;
- int i, offset;
-
- offset = 0;
- for (i = 0; i < ARRAY_SIZE (greg_map); i++)
- {
- if (regnum == greg_map[i] || regnum == -1)
- regcache_raw_supply (regcache, greg_map[i], buf + offset);
-
- offset += tdep->bytes_per_address;
- }
-}
-
-static void
-hppa_linux_supply_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *regs, size_t len)
-{
- const char *buf = regs;
- int i, offset;
-
- offset = 0;
- for (i = 0; i < 64; i++)
- {
- if (regnum == HPPA_FP0_REGNUM + i || regnum == -1)
- regcache_raw_supply (regcache, HPPA_FP0_REGNUM + i,
- buf + offset);
- offset += 4;
- }
-}
+static const struct regcache_map_entry hppa_linux_fpregmap[] =
+ {
+ { 64, HPPA_FP0_REGNUM },
+ { 0 }
+ };
/* HPPA Linux kernel register set. */
static const struct regset hppa_linux_regset =
{
- NULL,
- hppa_linux_supply_regset
+ hppa_linux_gregmap,
+ regcache_supply_regset, regcache_collect_regset
};
static const struct regset hppa_linux_fpregset =
{
- NULL,
- hppa_linux_supply_fpregset
+ hppa_linux_fpregmap,
+ regcache_supply_regset, regcache_collect_regset
};
static const struct regset *
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 12/13] M68K Linux: Define regset structures.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (7 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 07/13] HPPA Linux: Fill 'collect_regset' in regset structures Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-15 12:13 ` Ulrich Weigand
2014-06-25 16:49 ` [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect Andreas Arnez
` (4 subsequent siblings)
13 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Andreas Schwab
gdb/
* m68klinux-tdep.c: Include "regset.h".
(m68k_linux_gregmap, m68k_linux_fpregmap): New register maps.
(M68K_LINUX_GREGS_SIZE, M68K_LINUX_FPREGS_SIZE): New macros.
(m68k_linux_gregset, m68k_linux_fpregset): New regsets.
(m68k_linux_regset_from_core_section): New function.
(m68k_linux_init_abi): Set regset_from_core_section gdbarch
method.
---
gdb/m68klinux-tdep.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/gdb/m68klinux-tdep.c b/gdb/m68klinux-tdep.c
index f6fed38..8967d28 100644
--- a/gdb/m68klinux-tdep.c
+++ b/gdb/m68klinux-tdep.c
@@ -38,6 +38,7 @@
#include "observer.h"
#include "elf/common.h"
#include "linux-tdep.h"
+#include "regset.h"
\f
/* Offsets (in target ints) into jmp_buf. */
@@ -327,6 +328,66 @@ static const struct frame_unwind m68k_linux_sigtramp_frame_unwind =
m68k_linux_sigtramp_frame_sniffer
};
+/* Register maps for supply/collect regset functions. */
+
+static const struct regcache_map_entry m68k_linux_gregmap[] =
+ {
+ { 7, M68K_D1_REGNUM }, /* d1 ... d7 */
+ { 7, M68K_A0_REGNUM }, /* a0 ... a6 */
+ { 1, M68K_D0_REGNUM },
+ { 1, M68K_SP_REGNUM },
+ { 4, REGCACHE_MAP_SKIP_BYTES }, /* orig_d0 (skip) */
+ { 1, M68K_PS_REGNUM },
+ { 1, M68K_PC_REGNUM },
+ { 0 }
+ };
+
+#define M68K_LINUX_GREGS_SIZE (19 * 4)
+
+static const struct regcache_map_entry m68k_linux_fpregmap[] =
+ {
+ { 8, M68K_FP0_REGNUM }, /* fp0 ... fp7 */
+ { 1, M68K_FPC_REGNUM },
+ { 1, M68K_FPS_REGNUM },
+ { 1, M68K_FPI_REGNUM },
+ { 0 }
+ };
+
+#define M68K_LINUX_FPREGS_SIZE (27 * 4)
+
+/* Register sets. */
+
+static const struct regset m68k_linux_gregset =
+ {
+ m68k_linux_gregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+static const struct regset m68k_linux_fpregset =
+ {
+ m68k_linux_fpregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+m68k_linux_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name,
+ size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0
+ && sect_size >= M68K_LINUX_GREGS_SIZE)
+ return &m68k_linux_gregset;
+
+ if (strcmp (sect_name, ".reg2") == 0
+ && sect_size >= M68K_LINUX_FPREGS_SIZE)
+ return &m68k_linux_fpregset;
+
+ return NULL;
+}
+
static void
m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -361,6 +422,10 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+ /* Core file support. */
+ set_gdbarch_regset_from_core_section
+ (gdbarch, m68k_linux_regset_from_core_section);
+
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 12/13] M68K Linux: Define regset structures.
2014-06-25 16:49 ` [PATCH v2 12/13] M68K Linux: Define " Andreas Arnez
@ 2014-07-15 12:13 ` Ulrich Weigand
2014-07-16 18:01 ` Andreas Arnez
0 siblings, 1 reply; 31+ messages in thread
From: Ulrich Weigand @ 2014-07-15 12:13 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Andreas Schwab
Andreas Arnez wrote:
> +static const struct regcache_map_entry m68k_linux_fpregmap[] =
> + {
> + { 8, M68K_FP0_REGNUM }, /* fp0 ... fp7 */
> + { 1, M68K_FPC_REGNUM },
> + { 1, M68K_FPS_REGNUM },
> + { 1, M68K_FPI_REGNUM },
> + { 0 }
> + };
> +
> +#define M68K_LINUX_FPREGS_SIZE (27 * 4)
Hmm. Not sure what happens on m68k_coldfire_flavour, where the GDB
FP registers have builtin_double type (i.e. 8 instead of 12 bytes).
On the other hand, the current m68klinux-nat.c supply_fpregset
doesn't make any provisions for that case either ... is coldfire
supported on Linux at all?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 12/13] M68K Linux: Define regset structures.
2014-07-15 12:13 ` Ulrich Weigand
@ 2014-07-16 18:01 ` Andreas Arnez
0 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-07-16 18:01 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, Andreas Schwab
On Tue, Jul 15 2014, Ulrich Weigand wrote:
> Andreas Arnez wrote:
>
>> +static const struct regcache_map_entry m68k_linux_fpregmap[] =
>> + {
>> + { 8, M68K_FP0_REGNUM }, /* fp0 ... fp7 */
>> + { 1, M68K_FPC_REGNUM },
>> + { 1, M68K_FPS_REGNUM },
>> + { 1, M68K_FPI_REGNUM },
>> + { 0 }
>> + };
>> +
>> +#define M68K_LINUX_FPREGS_SIZE (27 * 4)
>
> Hmm. Not sure what happens on m68k_coldfire_flavour, where the GDB
> FP registers have builtin_double type (i.e. 8 instead of 12 bytes).
> On the other hand, the current m68klinux-nat.c supply_fpregset
> doesn't make any provisions for that case either ... is coldfire
> supported on Linux at all?
At least in the Linux kernel source, e.g. in arch/m68k/Kconfig.cpu, it
looks to be supported. And it seems that the registers are still
assigned to 12-byte slots, even if they fit in 8 bytes. So,
supply_fpregset may work correctly on ColdFire, but then the new code
doesn't.
Maybe it helps to add a "register slot size" field to each regmap entry?
So we'd write:
static const struct regcache_map_entry m68k_linux_fpregmap[] =
{
{ 8, M68K_FP0_REGNUM, 12 }, /* fp0 ... fp7 */
{ 1, M68K_FPC_REGNUM, 4 },
{ 1, M68K_FPS_REGNUM, 4 },
{ 1, M68K_FPI_REGNUM, 4 },
{ 0 }
};
This approach would also make the offsets and total size more obvious --
in this case 8 * 12 + 3 * 4. On the downside, it doesn't allow re-using
the same map for different word sizes. Perhaps we could additionally
permit the 'size' field to be zero and then use the register size
instead. Thoughts?
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (8 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 12/13] M68K Linux: Define " Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-07 9:32 ` Omair Javaid
2014-06-25 16:49 ` [PATCH v2 01/13] Rename 'descr' field in regset structure to 'regmap' Andreas Arnez
` (3 subsequent siblings)
13 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Yao Qi, Mark Kettenis
These functions are intended to suit all targets that don't require too
special logic in their regset supply/collect methods. Having such
generic functions helps reducing target-specific complexity.
gdb/
* regcache.c: Include "regset.h".
(regcache_supply_regset, regcache_collect_regset): New functions.
* regcache.h (struct regcache_map_entry): New structure.
(REGCACHE_MAP_SKIP_BYTES): New enum value.
(regcache_supply_regset, regcache_collect_regset): New prototypes.
---
gdb/regcache.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/regcache.h | 44 +++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+)
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 5ee90b0..78fd962 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -30,6 +30,7 @@
#include "exceptions.h"
#include "remote.h"
#include "valprint.h"
+#include "regset.h"
/*
* DATA STRUCTURE
@@ -1068,6 +1069,71 @@ regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf)
memcpy (buf, regbuf, size);
}
+/* Supply register REGNUM from BUF to REGCACHE, using the register map
+ in REGSET. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+void
+regcache_supply_regset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *buf, size_t size)
+{
+ const struct regcache_map_entry *map = regset->regmap;
+ int offs = 0;
+ int i, count;
+
+ for (i = 0; (count = map[i].count) != 0; i++)
+ {
+ int regno = map[i].regno;
+
+ if (regno == REGCACHE_MAP_SKIP_BYTES)
+ offs += count;
+ else
+ for (; count--; regno++)
+ {
+ int new_offs = offs + regcache->descr->sizeof_register[regno];
+
+ if (new_offs <= size && (regnum == -1 || regnum == regno))
+ regcache_raw_supply (regcache, regno,
+ buf ? (const gdb_byte *) buf + offs
+ : NULL);
+ offs = new_offs;
+ }
+ }
+}
+
+/* Collect register REGNUM from REGCACHE to BUF, using the register
+ map in REGSET. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+void
+regcache_collect_regset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *buf, size_t size)
+{
+ const struct regcache_map_entry *map = regset->regmap;
+ int offs = 0;
+ int i, count;
+
+ for (i = 0; (count = map[i].count) != 0; i++)
+ {
+ int regno = map[i].regno;
+
+ if (regno == REGCACHE_MAP_SKIP_BYTES)
+ offs += count;
+ else
+ for (; count--; regno++)
+ {
+ int new_offs = offs + regcache->descr->sizeof_register[regno];
+
+ if (new_offs <= size && (regnum == -1 || regnum == regno))
+ regcache_raw_collect (regcache, regno,
+ (gdb_byte *) buf + offs);
+ offs = new_offs;
+ }
+ }
+}
+
/* Special handling for register PC. */
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 8423f57..73ee043 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -147,6 +147,50 @@ extern void regcache_raw_supply (struct regcache *regcache,
extern void regcache_raw_collect (const struct regcache *regcache,
int regnum, void *buf);
+/* Mapping between register numbers and offsets in a buffer, for use
+ in the '*regset' functions below. In an array of
+ 'regcache_map_entry' each element is interpreted like follows:
+
+ - If 'regno' is a register number: Map register 'regno' to the
+ current offset (starting with 0) and increase the current offset
+ by the register's size. Repeat this with consecutive register
+ numbers up to 'regno+count-1'.
+
+ - If 'regno' is REGCACHE_MAP_SKIP_BYTES: Add 'count' to the current
+ offset.
+
+ - If count=0: End of the map. */
+
+struct regcache_map_entry
+{
+ int count;
+ int regno;
+};
+
+/* Special value for the 'regno' field in the struct above. */
+
+enum
+ {
+ REGCACHE_MAP_SKIP_BYTES = -1,
+ };
+
+/* Transfer a set of registers (as described by REGSET) between
+ REGCACHE and BUF. If REGNUM == -1, transfer all registers
+ belonging to the regset, otherwise just the register numbered
+ REGNUM. The REGSET's 'regmap' field must point to an array of
+ 'struct regcache_map_entry'.
+
+ These functions are suitable for the 'regset_supply' and
+ 'regset_collect' fields in a regset structure. */
+
+extern void regcache_supply_regset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *buf,
+ size_t size);
+extern void regcache_collect_regset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *buf, size_t size);
+
/* The type of a register. This function is slightly more efficient
then its gdbarch vector counterpart since it returns a precomputed
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect.
2014-06-25 16:49 ` [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect Andreas Arnez
@ 2014-07-07 9:32 ` Omair Javaid
2014-07-08 11:32 ` Andreas Arnez
0 siblings, 1 reply; 31+ messages in thread
From: Omair Javaid @ 2014-07-07 9:32 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Yao Qi, Mark Kettenis
On 25 June 2014 21:48, Andreas Arnez <arnez@linux.vnet.ibm.com> wrote:
> These functions are intended to suit all targets that don't require too
> special logic in their regset supply/collect methods. Having such
> generic functions helps reducing target-specific complexity.
>
> gdb/
> * regcache.c: Include "regset.h".
> (regcache_supply_regset, regcache_collect_regset): New functions.
> * regcache.h (struct regcache_map_entry): New structure.
> (REGCACHE_MAP_SKIP_BYTES): New enum value.
> (regcache_supply_regset, regcache_collect_regset): New prototypes.
> ---
> gdb/regcache.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> gdb/regcache.h | 44 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 110 insertions(+)
>
> diff --git a/gdb/regcache.c b/gdb/regcache.c
> index 5ee90b0..78fd962 100644
> --- a/gdb/regcache.c
> +++ b/gdb/regcache.c
> @@ -30,6 +30,7 @@
> #include "exceptions.h"
> #include "remote.h"
> #include "valprint.h"
> +#include "regset.h"
>
> /*
> * DATA STRUCTURE
> @@ -1068,6 +1069,71 @@ regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf)
> memcpy (buf, regbuf, size);
> }
>
> +/* Supply register REGNUM from BUF to REGCACHE, using the register map
> + in REGSET. If REGNUM is -1, do this for all registers in
> + REGSET. */
> +
> +void
> +regcache_supply_regset (const struct regset *regset,
> + struct regcache *regcache,
> + int regnum, const void *buf, size_t size)
> +{
> + const struct regcache_map_entry *map = regset->regmap;
> + int offs = 0;
> + int i, count;
> +
> + for (i = 0; (count = map[i].count) != 0; i++)
> + {
> + int regno = map[i].regno;
> +
> + if (regno == REGCACHE_MAP_SKIP_BYTES)
> + offs += count;
> + else
> + for (; count--; regno++)
> + {
> + int new_offs = offs + regcache->descr->sizeof_register[regno];
> +
> + if (new_offs <= size && (regnum == -1 || regnum == regno))
> + regcache_raw_supply (regcache, regno,
> + buf ? (const gdb_byte *) buf + offs
> + : NULL);
> + offs = new_offs;
> + }
> + }
> +}
> +
> +/* Collect register REGNUM from REGCACHE to BUF, using the register
> + map in REGSET. If REGNUM is -1, do this for all registers in
> + REGSET. */
> +
> +void
> +regcache_collect_regset (const struct regset *regset,
> + const struct regcache *regcache,
> + int regnum, void *buf, size_t size)
> +{
> + const struct regcache_map_entry *map = regset->regmap;
> + int offs = 0;
> + int i, count;
> +
> + for (i = 0; (count = map[i].count) != 0; i++)
> + {
> + int regno = map[i].regno;
> +
> + if (regno == REGCACHE_MAP_SKIP_BYTES)
> + offs += count;
> + else
> + for (; count--; regno++)
> + {
> + int new_offs = offs + regcache->descr->sizeof_register[regno];
> +
> + if (new_offs <= size && (regnum == -1 || regnum == regno))
> + regcache_raw_collect (regcache, regno,
> + (gdb_byte *) buf + offs);
> + offs = new_offs;
> + }
> + }
> +}
> +
>
> /* Special handling for register PC. */
>
> diff --git a/gdb/regcache.h b/gdb/regcache.h
> index 8423f57..73ee043 100644
> --- a/gdb/regcache.h
> +++ b/gdb/regcache.h
> @@ -147,6 +147,50 @@ extern void regcache_raw_supply (struct regcache *regcache,
> extern void regcache_raw_collect (const struct regcache *regcache,
> int regnum, void *buf);
>
> +/* Mapping between register numbers and offsets in a buffer, for use
> + in the '*regset' functions below. In an array of
> + 'regcache_map_entry' each element is interpreted like follows:
> +
> + - If 'regno' is a register number: Map register 'regno' to the
> + current offset (starting with 0) and increase the current offset
> + by the register's size. Repeat this with consecutive register
> + numbers up to 'regno+count-1'.
> +
> + - If 'regno' is REGCACHE_MAP_SKIP_BYTES: Add 'count' to the current
> + offset.
> +
> + - If count=0: End of the map. */
> +
> +struct regcache_map_entry
> +{
> + int count;
> + int regno;
> +};
> +
> +/* Special value for the 'regno' field in the struct above. */
> +
> +enum
> + {
> + REGCACHE_MAP_SKIP_BYTES = -1,
> + };
> +
> +/* Transfer a set of registers (as described by REGSET) between
> + REGCACHE and BUF. If REGNUM == -1, transfer all registers
> + belonging to the regset, otherwise just the register numbered
> + REGNUM. The REGSET's 'regmap' field must point to an array of
> + 'struct regcache_map_entry'.
> +
> + These functions are suitable for the 'regset_supply' and
> + 'regset_collect' fields in a regset structure. */
> +
> +extern void regcache_supply_regset (const struct regset *regset,
> + struct regcache *regcache,
> + int regnum, const void *buf,
> + size_t size);
> +extern void regcache_collect_regset (const struct regset *regset,
> + const struct regcache *regcache,
> + int regnum, void *buf, size_t size);
> +
>
> /* The type of a register. This function is slightly more efficient
> then its gdbarch vector counterpart since it returns a precomputed
> --
> 1.8.4.2
>
Is there a way around avoiding the loop in supply/collect where regnum
!= -1? It should be more efficient in cases where we are looking for a
register with regnum > 0.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect.
2014-07-07 9:32 ` Omair Javaid
@ 2014-07-08 11:32 ` Andreas Arnez
2014-07-08 19:09 ` Omair Javaid
0 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-07-08 11:32 UTC (permalink / raw)
To: Omair Javaid; +Cc: gdb-patches, Yao Qi, Mark Kettenis
On Mon, Jul 07 2014, Omair Javaid wrote:
> Is there a way around avoiding the loop in supply/collect where regnum
> != -1? It should be more efficient in cases where we are looking for a
> register with regnum > 0.
Good question. The most straightforward way would be a register map
format where regnum is used as an index into an array of offsets, like
this:
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,
};
This is a real example. For the full example refer to:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/s390-tdep.c;h=72d55450225e89da4394079efac1fa33b36cb68c;hb=d91fab15e7eb04f6c9b7fee5859d8815b7aa84ee#l412
As you see, this is where the s390 implementation came from. Then I
realized that regnum > 0 is a very rare case, and that the common case
was suboptimal with this format, because the supply/collect functions
had to iterate over *all* registers, not just those of a specific
regset.
Patch #3 in this series expresses the regmap from above like this:
static const struct regcache_map_entry s390_gregmap[] =
{
{ 1, S390_PSWM_REGNUM },
{ 1, S390_PSWA_REGNUM },
{ 16, S390_R0_REGNUM },
{ 16, S390_A0_REGNUM },
{ 1, S390_ORIG_R2_REGNUM },
{ 0 }
};
In addition to being more efficient in the common case, I also consider
this version much easier to read and maintain.
We could certainly spend more effort on supplying and collecting a
single register more efficiently. For instance, we could offer
additional routines for that special case, perhaps in conjunction with a
preparation function that converts a regmap to an indexed-by-regnum
array. However, I wouldn't focus on that too much before actually
making use of it. Note that currently these functions are *always*
called with regnum == -1.
In fact, it may be more adequate to completely get rid of the parameter
regnum in the regset supply/collect functions. Any reason why we
shouldn't?
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect.
2014-07-08 11:32 ` Andreas Arnez
@ 2014-07-08 19:09 ` Omair Javaid
2014-07-10 7:54 ` Andreas Arnez
0 siblings, 1 reply; 31+ messages in thread
From: Omair Javaid @ 2014-07-08 19:09 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Yao Qi, Mark Kettenis
On 8 July 2014 16:31, Andreas Arnez <arnez@linux.vnet.ibm.com> wrote:
> On Mon, Jul 07 2014, Omair Javaid wrote:
>
>> Is there a way around avoiding the loop in supply/collect where regnum
>> != -1? It should be more efficient in cases where we are looking for a
>> register with regnum > 0.
>
> Good question. The most straightforward way would be a register map
> format where regnum is used as an index into an array of offsets, like
> this:
>
> 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,
> };
>
> This is a real example. For the full example refer to:
>
> https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/s390-tdep.c;h=72d55450225e89da4394079efac1fa33b36cb68c;hb=d91fab15e7eb04f6c9b7fee5859d8815b7aa84ee#l412
>
> As you see, this is where the s390 implementation came from. Then I
> realized that regnum > 0 is a very rare case, and that the common case
> was suboptimal with this format, because the supply/collect functions
> had to iterate over *all* registers, not just those of a specific
> regset.
>
> Patch #3 in this series expresses the regmap from above like this:
>
> static const struct regcache_map_entry s390_gregmap[] =
> {
> { 1, S390_PSWM_REGNUM },
> { 1, S390_PSWA_REGNUM },
> { 16, S390_R0_REGNUM },
> { 16, S390_A0_REGNUM },
> { 1, S390_ORIG_R2_REGNUM },
> { 0 }
> };
>
> In addition to being more efficient in the common case, I also consider
> this version much easier to read and maintain.
>
> We could certainly spend more effort on supplying and collecting a
> single register more efficiently. For instance, we could offer
> additional routines for that special case, perhaps in conjunction with a
> preparation function that converts a regmap to an indexed-by-regnum
> array. However, I wouldn't focus on that too much before actually
> making use of it. Note that currently these functions are *always*
> called with regnum == -1.
>
> In fact, it may be more adequate to completely get rid of the parameter
> regnum in the regset supply/collect functions. Any reason why we
> shouldn't?
I think you are right its better off if we leave the single register
variants to target specific *-tdep where they can be retrieved using
regcache_raw_ supply/collect functions. All other options to get
around the loops wont be trivial.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect.
2014-07-08 19:09 ` Omair Javaid
@ 2014-07-10 7:54 ` Andreas Arnez
2014-07-19 13:10 ` Omair Javaid
0 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-07-10 7:54 UTC (permalink / raw)
To: Omair Javaid; +Cc: gdb-patches, Yao Qi, Mark Kettenis
On Tue, Jul 08 2014, Omair Javaid wrote:
> I think you are right its better off if we leave the single register
> variants to target specific *-tdep where they can be retrieved using
> regcache_raw_ supply/collect functions. All other options to get
> around the loops wont be trivial.
Hm, I'd actually prefer if the new functions could be used for any
case where registers are supplied to the regcache from a buffer, or
collected from the regcache to a buffer.
Which variants do you mean? Do you have examples where they are used?
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect.
2014-07-10 7:54 ` Andreas Arnez
@ 2014-07-19 13:10 ` Omair Javaid
0 siblings, 0 replies; 31+ messages in thread
From: Omair Javaid @ 2014-07-19 13:10 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Yao Qi, Mark Kettenis
On 10 July 2014 12:54, Andreas Arnez <arnez@linux.vnet.ibm.com> wrote:
> On Tue, Jul 08 2014, Omair Javaid wrote:
>
>> I think you are right its better off if we leave the single register
>> variants to target specific *-tdep where they can be retrieved using
>> regcache_raw_ supply/collect functions. All other options to get
>> around the loops wont be trivial.
>
> Hm, I'd actually prefer if the new functions could be used for any
> case where registers are supplied to the regcache from a buffer, or
> collected from the regcache to a buffer.
>
> Which variants do you mean? Do you have examples where they are used?
>
Here's one implementation I saw for PPC, this is done for rs6000-tdep.c
ppc_supply_reg (struct regcache *regcache, int regnum,
const gdb_byte *regs, size_t offset, int regsize)
{
if (regnum != -1 && offset != -1)
{
if (regsize > 4)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
int gdb_regsize = register_size (gdbarch, regnum);
if (gdb_regsize < regsize
&& gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
offset += regsize - gdb_regsize;
}
regcache_raw_supply (regcache, regnum, regs + offset);
}
}
But I agree that its better the way its been done already.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 01/13] Rename 'descr' field in regset structure to 'regmap'.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (9 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 02/13] regcache: Add functions suitable for regset_supply/collect Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-06-25 16:49 ` [PATCH v2 04/13] AARCH64 Linux: Fill 'collect_regset' in regset structures Andreas Arnez
` (2 subsequent siblings)
13 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich Weigand, Kevin Buettner, Yao Qi
The regset structure's 'descr' field is intended to represent some
kind of "register map". Thus, before making more use of it, this
change renames it to 'regmap' and adjusts the comment appropriately.
(See: https://sourceware.org/ml/gdb-patches/2014-05/msg00664.html)
gdb/
* regset.h (struct regset): Rename 'descr' field to 'regmap'.
* ppc-linux-tdep.c (ppc_linux_supply_gregset)
(ppc_linux_collect_gregset ): Likewise.
* rs6000-tdep.c (ppc_supply_gregset, ppc_supply_fpregset)
(ppc_supply_vrregset, ppc_collect_gregset, ppc_collect_fpregset)
(ppc_collect_vrregset): Likewise.
* s390-linux-tdep.c (s390_supply_regset, s390_collect_regset):
Likewise.
---
gdb/ppc-linux-tdep.c | 4 ++--
gdb/regset.h | 7 ++++---
gdb/rs6000-tdep.c | 12 ++++++------
gdb/s390-linux-tdep.c | 4 ++--
4 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 5410554..f443f55 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -395,7 +395,7 @@ ppc_linux_supply_gregset (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *gregs, size_t len)
{
- const struct ppc_reg_offsets *offsets = regset->descr;
+ const struct ppc_reg_offsets *offsets = regset->regmap;
ppc_supply_gregset (regset, regcache, regnum, gregs, len);
@@ -420,7 +420,7 @@ ppc_linux_collect_gregset (const struct regset *regset,
const struct regcache *regcache,
int regnum, void *gregs, size_t len)
{
- const struct ppc_reg_offsets *offsets = regset->descr;
+ const struct ppc_reg_offsets *offsets = regset->regmap;
/* Clear areas in the linux gregset not written elsewhere. */
if (regnum == -1)
diff --git a/gdb/regset.h b/gdb/regset.h
index 03dbdaa..37ed99a 100644
--- a/gdb/regset.h
+++ b/gdb/regset.h
@@ -41,9 +41,10 @@ typedef void (collect_regset_ftype) (const struct regset *,
struct regset
{
- /* Data pointer for private use by the methods below, presumably
- providing some sort of description of the register set. */
- const void *descr;
+ /* Pointer to a "register map", for private use by the methods
+ below. Typically describes how the regset's registers are
+ arranged in the buffer collected to or supplied from. */
+ const void *regmap;
/* Function supplying values in a register set to a register cache. */
supply_regset_ftype *supply_regset;
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index c4ce51c..85919e4 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -506,7 +506,7 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const struct ppc_reg_offsets *offsets = regset->descr;
+ const struct ppc_reg_offsets *offsets = regset->regmap;
size_t offset;
int regsize;
@@ -558,7 +558,7 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->descr;
+ offsets = regset->regmap;
if (regnum == -1)
{
int i;
@@ -626,7 +626,7 @@ ppc_supply_vrregset (const struct regset *regset, struct regcache *regcache,
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->descr;
+ offsets = regset->regmap;
if (regnum == -1)
{
int i;
@@ -665,7 +665,7 @@ ppc_collect_gregset (const struct regset *regset,
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const struct ppc_reg_offsets *offsets = regset->descr;
+ const struct ppc_reg_offsets *offsets = regset->regmap;
size_t offset;
int regsize;
@@ -719,7 +719,7 @@ ppc_collect_fpregset (const struct regset *regset,
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->descr;
+ offsets = regset->regmap;
if (regnum == -1)
{
int i;
@@ -792,7 +792,7 @@ ppc_collect_vrregset (const struct regset *regset,
return;
tdep = gdbarch_tdep (gdbarch);
- offsets = regset->descr;
+ offsets = regset->regmap;
if (regnum == -1)
{
int i;
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index ea743b5..3658033 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -610,7 +610,7 @@ s390_supply_regset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *regs, size_t len)
{
const short *map;
- for (map = regset->descr; map[0] >= 0; map += 2)
+ for (map = regset->regmap; map[0] >= 0; map += 2)
if (regnum == -1 || regnum == map[1])
regcache_raw_supply (regcache, map[1],
regs ? (const char *)regs + map[0] : NULL);
@@ -643,7 +643,7 @@ s390_collect_regset (const struct regset *regset,
int regnum, void *regs, size_t len)
{
const short *map;
- for (map = regset->descr; map[0] >= 0; map += 2)
+ for (map = regset->regmap; map[0] >= 0; map += 2)
if (regnum == -1 || regnum == map[1])
regcache_raw_collect (regcache, map[1], (char *)regs + map[0]);
}
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 04/13] AARCH64 Linux: Fill 'collect_regset' in regset structures.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (10 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 01/13] Rename 'descr' field in regset structure to 'regmap' Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-07 9:57 ` Omair Javaid
2014-06-25 16:49 ` [PATCH v2 05/13] ALPHA " Andreas Arnez
2014-07-01 8:00 ` [ping][PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
13 siblings, 1 reply; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Richard Earnshaw
In order to provide 'collect_regset' support, the generic function
regcache_collect_regset is exploited. Since this requires writing
appropriate register maps, these can be used for supply_regset as
well.
gdb/
* aarch64-linux-nat.c (fill_gregset, fill_fpregset): Replace logic
by call to regcache_collect_regset.
(supply_gregset, supply_fpregset): Call regcache_supply_regset
instead of aarch64_linux_supply_gregset/_fpregset.
* aarch64-linux-tdep.c (AARCH64_LINUX_SIZEOF_GREGSET)
(AARCH64_LINUX_SIZEOF_FPREGSET): Delete macros here, move to
header file instead.
(aarch64_linux_supply_gregset, supply_gregset_from_core)
(aarch64_linux_suply_fpregset, supply_fpregset_from_core): Delete
functions. Move logic to ...
(aarch64_linux_gregmap, aarch64_linux_fpregmap): ... these new
register maps.
(aarch64_linux_gregset, aarch64_linux_fpregset): Make global,
refer to new register maps, replace *_regset_from_core by
regcache_supply_regset, and also use regcache_collect_regset.
* aarch64-linux-tdep.h: Include "regset.h".
(aarch64_linux_supply_gregset, aarch64_linux_supply_fpregset):
Delete prototypes.
(AARCH64_LINUX_SIZEOF_GREGSET, AARCH64_LINUX_SIZEOF_FPREGSET): New
macros, moved from C source file.
(aarch64_linux_gregset, aarch64_linux_fpregset): New global
variable declarations.
---
gdb/aarch64-linux-nat.c | 38 +++++++-------------
gdb/aarch64-linux-tdep.c | 90 +++++++++++++-----------------------------------
gdb/aarch64-linux-tdep.h | 18 +++++++---
3 files changed, 48 insertions(+), 98 deletions(-)
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 877e702..4ae789b 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -616,14 +616,9 @@ void
fill_gregset (const struct regcache *regcache,
gdb_gregset_t *gregsetp, int regno)
{
- gdb_byte *gregs_buf = (gdb_byte *) gregsetp;
- int i;
-
- for (i = AARCH64_X0_REGNUM; i <= AARCH64_CPSR_REGNUM; i++)
- if (regno == -1 || regno == i)
- regcache_raw_collect (regcache, i,
- gregs_buf + X_REGISTER_SIZE
- * (i - AARCH64_X0_REGNUM));
+ regcache_collect_regset (&aarch64_linux_gregset, regcache,
+ regno, (gdb_byte *) gregsetp,
+ AARCH64_LINUX_SIZEOF_GREGSET);
}
/* Fill GDB's register array with the general-purpose register values
@@ -632,7 +627,9 @@ fill_gregset (const struct regcache *regcache,
void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
{
- aarch64_linux_supply_gregset (regcache, (const gdb_byte *) gregsetp);
+ regcache_supply_regset (&aarch64_linux_gregset, regcache, -1,
+ (const gdb_byte *) gregsetp,
+ AARCH64_LINUX_SIZEOF_GREGSET);
}
/* Fill register REGNO (if it is a floating-point register) in
@@ -643,22 +640,9 @@ void
fill_fpregset (const struct regcache *regcache,
gdb_fpregset_t *fpregsetp, int regno)
{
- gdb_byte *fpregs_buf = (gdb_byte *) fpregsetp;
- int i;
-
- for (i = AARCH64_V0_REGNUM; i <= AARCH64_V31_REGNUM; i++)
- if (regno == -1 || regno == i)
- regcache_raw_collect (regcache, i,
- fpregs_buf + V_REGISTER_SIZE
- * (i - AARCH64_V0_REGNUM));
-
- if (regno == -1 || regno == AARCH64_FPSR_REGNUM)
- regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM,
- fpregs_buf + V_REGISTER_SIZE * 32);
-
- if (regno == -1 || regno == AARCH64_FPCR_REGNUM)
- regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM,
- fpregs_buf + V_REGISTER_SIZE * 32 + 4);
+ regcache_collect_regset (&aarch64_linux_fpregset, regcache,
+ regno, (gdb_byte *) fpregsetp,
+ AARCH64_LINUX_SIZEOF_FPREGSET);
}
/* Fill GDB's register array with the floating-point register values
@@ -667,7 +651,9 @@ fill_fpregset (const struct regcache *regcache,
void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
{
- aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) fpregsetp);
+ regcache_supply_regset (&aarch64_linux_fpregset, regcache, -1,
+ (const gdb_byte *) fpregsetp,
+ AARCH64_LINUX_SIZEOF_FPREGSET);
}
/* Called when resuming a thread.
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 30ed73f..b3eaa95 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -41,16 +41,6 @@
#include "user-regs.h"
#include <ctype.h>
-/* The general-purpose regset consists of 31 X registers, plus SP, PC,
- and PSTATE registers, as defined in the AArch64 port of the Linux
- kernel. */
-#define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
-
-/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
- are 4 bytes wide each, and the whole structure is padded to 128 bit
- alignment. */
-#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
-
/* Signal frame handling.
+------------+ ^
@@ -190,71 +180,37 @@ static const struct tramp_frame aarch64_linux_rt_sigframe =
aarch64_linux_sigframe_init
};
-/* Fill GDB's register array with the general-purpose register values
- in the buffer pointed by GREGS_BUF. */
-
-void
-aarch64_linux_supply_gregset (struct regcache *regcache,
- const gdb_byte *gregs_buf)
-{
- int regno;
-
- for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
- regcache_raw_supply (regcache, regno,
- gregs_buf + X_REGISTER_SIZE
- * (regno - AARCH64_X0_REGNUM));
-}
-
-/* The "supply_regset" function for the general-purpose register set. */
-
-static void
-supply_gregset_from_core (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *regbuf, size_t len)
-{
- aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
-}
-
-/* Fill GDB's register array with the floating-point register values
- in the buffer pointed by FPREGS_BUF. */
+/* Register maps. */
-void
-aarch64_linux_supply_fpregset (struct regcache *regcache,
- const gdb_byte *fpregs_buf)
-{
- int regno;
-
- for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
- regcache_raw_supply (regcache, regno,
- fpregs_buf + V_REGISTER_SIZE
- * (regno - AARCH64_V0_REGNUM));
-
- regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
- fpregs_buf + V_REGISTER_SIZE * 32);
- regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
- fpregs_buf + V_REGISTER_SIZE * 32 + 4);
-}
-
-/* The "supply_regset" function for the floating-point register set. */
+static const struct regcache_map_entry aarch64_linux_gregmap[] =
+ {
+ { 31, AARCH64_X0_REGNUM }, /* x0 ... x30 */
+ { 1, AARCH64_SP_REGNUM },
+ { 1, AARCH64_PC_REGNUM },
+ { 1, AARCH64_CPSR_REGNUM },
+ { 0 }
+ };
-static void
-supply_fpregset_from_core (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *regbuf, size_t len)
-{
- aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
-}
+static const struct regcache_map_entry aarch64_linux_fpregmap[] =
+ {
+ { 32, AARCH64_V0_REGNUM }, /* v0 ... v31 */
+ { 1, AARCH64_FPSR_REGNUM },
+ { 1, AARCH64_FPCR_REGNUM },
+ { 0 }
+ };
-/* Register set definitions. */
+/* Register set definitions. */
-static const struct regset aarch64_linux_gregset =
+const struct regset aarch64_linux_gregset =
{
- NULL, supply_gregset_from_core, NULL
+ aarch64_linux_gregmap,
+ regcache_supply_regset, regcache_collect_regset
};
-static const struct regset aarch64_linux_fpregset =
+const struct regset aarch64_linux_fpregset =
{
- NULL, supply_fpregset_from_core, NULL
+ aarch64_linux_fpregmap,
+ regcache_supply_regset, regcache_collect_regset
};
/* Implement the "regset_from_core_section" gdbarch method. */
diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
index 48c7092..2e1de60 100644
--- a/gdb/aarch64-linux-tdep.h
+++ b/gdb/aarch64-linux-tdep.h
@@ -18,9 +18,17 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-struct regcache;
+#include "regset.h"
-extern void aarch64_linux_supply_gregset (struct regcache *regcache,
- const gdb_byte *gregs_buf);
-extern void aarch64_linux_supply_fpregset (struct regcache *regcache,
- const gdb_byte *fpregs_buf);
+/* The general-purpose regset consists of 31 X registers, plus SP, PC,
+ and PSTATE registers, as defined in the AArch64 port of the Linux
+ kernel. */
+#define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
+
+/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
+ are 4 bytes wide each, and the whole structure is padded to 128 bit
+ alignment. */
+#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
+
+extern const struct regset aarch64_linux_gregset;
+extern const struct regset aarch64_linux_fpregset;
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v2 04/13] AARCH64 Linux: Fill 'collect_regset' in regset structures.
2014-06-25 16:49 ` [PATCH v2 04/13] AARCH64 Linux: Fill 'collect_regset' in regset structures Andreas Arnez
@ 2014-07-07 9:57 ` Omair Javaid
0 siblings, 0 replies; 31+ messages in thread
From: Omair Javaid @ 2014-07-07 9:57 UTC (permalink / raw)
To: Andreas Arnez; +Cc: gdb-patches, Richard Earnshaw
On 25 June 2014 21:49, Andreas Arnez <arnez@linux.vnet.ibm.com> wrote:
> In order to provide 'collect_regset' support, the generic function
> regcache_collect_regset is exploited. Since this requires writing
> appropriate register maps, these can be used for supply_regset as
> well.
>
> gdb/
> * aarch64-linux-nat.c (fill_gregset, fill_fpregset): Replace logic
> by call to regcache_collect_regset.
> (supply_gregset, supply_fpregset): Call regcache_supply_regset
> instead of aarch64_linux_supply_gregset/_fpregset.
> * aarch64-linux-tdep.c (AARCH64_LINUX_SIZEOF_GREGSET)
> (AARCH64_LINUX_SIZEOF_FPREGSET): Delete macros here, move to
> header file instead.
> (aarch64_linux_supply_gregset, supply_gregset_from_core)
> (aarch64_linux_suply_fpregset, supply_fpregset_from_core): Delete
> functions. Move logic to ...
> (aarch64_linux_gregmap, aarch64_linux_fpregmap): ... these new
> register maps.
> (aarch64_linux_gregset, aarch64_linux_fpregset): Make global,
> refer to new register maps, replace *_regset_from_core by
> regcache_supply_regset, and also use regcache_collect_regset.
> * aarch64-linux-tdep.h: Include "regset.h".
> (aarch64_linux_supply_gregset, aarch64_linux_supply_fpregset):
> Delete prototypes.
> (AARCH64_LINUX_SIZEOF_GREGSET, AARCH64_LINUX_SIZEOF_FPREGSET): New
> macros, moved from C source file.
> (aarch64_linux_gregset, aarch64_linux_fpregset): New global
> variable declarations.
> ---
> gdb/aarch64-linux-nat.c | 38 +++++++-------------
> gdb/aarch64-linux-tdep.c | 90 +++++++++++++-----------------------------------
> gdb/aarch64-linux-tdep.h | 18 +++++++---
> 3 files changed, 48 insertions(+), 98 deletions(-)
>
> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> index 877e702..4ae789b 100644
> --- a/gdb/aarch64-linux-nat.c
> +++ b/gdb/aarch64-linux-nat.c
> @@ -616,14 +616,9 @@ void
> fill_gregset (const struct regcache *regcache,
> gdb_gregset_t *gregsetp, int regno)
> {
> - gdb_byte *gregs_buf = (gdb_byte *) gregsetp;
> - int i;
> -
> - for (i = AARCH64_X0_REGNUM; i <= AARCH64_CPSR_REGNUM; i++)
> - if (regno == -1 || regno == i)
> - regcache_raw_collect (regcache, i,
> - gregs_buf + X_REGISTER_SIZE
> - * (i - AARCH64_X0_REGNUM));
> + regcache_collect_regset (&aarch64_linux_gregset, regcache,
> + regno, (gdb_byte *) gregsetp,
> + AARCH64_LINUX_SIZEOF_GREGSET);
> }
>
> /* Fill GDB's register array with the general-purpose register values
> @@ -632,7 +627,9 @@ fill_gregset (const struct regcache *regcache,
> void
> supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
> {
> - aarch64_linux_supply_gregset (regcache, (const gdb_byte *) gregsetp);
> + regcache_supply_regset (&aarch64_linux_gregset, regcache, -1,
> + (const gdb_byte *) gregsetp,
> + AARCH64_LINUX_SIZEOF_GREGSET);
> }
>
> /* Fill register REGNO (if it is a floating-point register) in
> @@ -643,22 +640,9 @@ void
> fill_fpregset (const struct regcache *regcache,
> gdb_fpregset_t *fpregsetp, int regno)
> {
> - gdb_byte *fpregs_buf = (gdb_byte *) fpregsetp;
> - int i;
> -
> - for (i = AARCH64_V0_REGNUM; i <= AARCH64_V31_REGNUM; i++)
> - if (regno == -1 || regno == i)
> - regcache_raw_collect (regcache, i,
> - fpregs_buf + V_REGISTER_SIZE
> - * (i - AARCH64_V0_REGNUM));
> -
> - if (regno == -1 || regno == AARCH64_FPSR_REGNUM)
> - regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM,
> - fpregs_buf + V_REGISTER_SIZE * 32);
> -
> - if (regno == -1 || regno == AARCH64_FPCR_REGNUM)
> - regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM,
> - fpregs_buf + V_REGISTER_SIZE * 32 + 4);
> + regcache_collect_regset (&aarch64_linux_fpregset, regcache,
> + regno, (gdb_byte *) fpregsetp,
> + AARCH64_LINUX_SIZEOF_FPREGSET);
> }
>
> /* Fill GDB's register array with the floating-point register values
> @@ -667,7 +651,9 @@ fill_fpregset (const struct regcache *regcache,
> void
> supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
> {
> - aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) fpregsetp);
> + regcache_supply_regset (&aarch64_linux_fpregset, regcache, -1,
> + (const gdb_byte *) fpregsetp,
> + AARCH64_LINUX_SIZEOF_FPREGSET);
> }
>
> /* Called when resuming a thread.
> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> index 30ed73f..b3eaa95 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -41,16 +41,6 @@
> #include "user-regs.h"
> #include <ctype.h>
>
> -/* The general-purpose regset consists of 31 X registers, plus SP, PC,
> - and PSTATE registers, as defined in the AArch64 port of the Linux
> - kernel. */
> -#define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
> -
> -/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
> - are 4 bytes wide each, and the whole structure is padded to 128 bit
> - alignment. */
> -#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
> -
> /* Signal frame handling.
>
> +------------+ ^
> @@ -190,71 +180,37 @@ static const struct tramp_frame aarch64_linux_rt_sigframe =
> aarch64_linux_sigframe_init
> };
>
> -/* Fill GDB's register array with the general-purpose register values
> - in the buffer pointed by GREGS_BUF. */
> -
> -void
> -aarch64_linux_supply_gregset (struct regcache *regcache,
> - const gdb_byte *gregs_buf)
> -{
> - int regno;
> -
> - for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
> - regcache_raw_supply (regcache, regno,
> - gregs_buf + X_REGISTER_SIZE
> - * (regno - AARCH64_X0_REGNUM));
> -}
> -
> -/* The "supply_regset" function for the general-purpose register set. */
> -
> -static void
> -supply_gregset_from_core (const struct regset *regset,
> - struct regcache *regcache,
> - int regnum, const void *regbuf, size_t len)
> -{
> - aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
> -}
> -
> -/* Fill GDB's register array with the floating-point register values
> - in the buffer pointed by FPREGS_BUF. */
> +/* Register maps. */
>
> -void
> -aarch64_linux_supply_fpregset (struct regcache *regcache,
> - const gdb_byte *fpregs_buf)
> -{
> - int regno;
> -
> - for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
> - regcache_raw_supply (regcache, regno,
> - fpregs_buf + V_REGISTER_SIZE
> - * (regno - AARCH64_V0_REGNUM));
> -
> - regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
> - fpregs_buf + V_REGISTER_SIZE * 32);
> - regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
> - fpregs_buf + V_REGISTER_SIZE * 32 + 4);
> -}
> -
> -/* The "supply_regset" function for the floating-point register set. */
> +static const struct regcache_map_entry aarch64_linux_gregmap[] =
> + {
> + { 31, AARCH64_X0_REGNUM }, /* x0 ... x30 */
> + { 1, AARCH64_SP_REGNUM },
> + { 1, AARCH64_PC_REGNUM },
> + { 1, AARCH64_CPSR_REGNUM },
> + { 0 }
> + };
>
> -static void
> -supply_fpregset_from_core (const struct regset *regset,
> - struct regcache *regcache,
> - int regnum, const void *regbuf, size_t len)
> -{
> - aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
> -}
> +static const struct regcache_map_entry aarch64_linux_fpregmap[] =
> + {
> + { 32, AARCH64_V0_REGNUM }, /* v0 ... v31 */
> + { 1, AARCH64_FPSR_REGNUM },
> + { 1, AARCH64_FPCR_REGNUM },
> + { 0 }
> + };
>
> -/* Register set definitions. */
> +/* Register set definitions. */
>
> -static const struct regset aarch64_linux_gregset =
> +const struct regset aarch64_linux_gregset =
> {
> - NULL, supply_gregset_from_core, NULL
> + aarch64_linux_gregmap,
> + regcache_supply_regset, regcache_collect_regset
> };
>
> -static const struct regset aarch64_linux_fpregset =
> +const struct regset aarch64_linux_fpregset =
> {
> - NULL, supply_fpregset_from_core, NULL
> + aarch64_linux_fpregmap,
> + regcache_supply_regset, regcache_collect_regset
> };
>
> /* Implement the "regset_from_core_section" gdbarch method. */
> diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
> index 48c7092..2e1de60 100644
> --- a/gdb/aarch64-linux-tdep.h
> +++ b/gdb/aarch64-linux-tdep.h
> @@ -18,9 +18,17 @@
> You should have received a copy of the GNU General Public License
> along with this program. If not, see <http://www.gnu.org/licenses/>. */
>
> -struct regcache;
> +#include "regset.h"
>
> -extern void aarch64_linux_supply_gregset (struct regcache *regcache,
> - const gdb_byte *gregs_buf);
> -extern void aarch64_linux_supply_fpregset (struct regcache *regcache,
> - const gdb_byte *fpregs_buf);
> +/* The general-purpose regset consists of 31 X registers, plus SP, PC,
> + and PSTATE registers, as defined in the AArch64 port of the Linux
> + kernel. */
> +#define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
> +
> +/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
> + are 4 bytes wide each, and the whole structure is padded to 128 bit
> + alignment. */
> +#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
> +
> +extern const struct regset aarch64_linux_gregset;
> +extern const struct regset aarch64_linux_fpregset;
> --
> 1.8.4.2
>
Looks good to me.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v2 05/13] ALPHA Linux: Fill 'collect_regset' in regset structures.
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (11 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 04/13] AARCH64 Linux: Fill 'collect_regset' in regset structures Andreas Arnez
@ 2014-06-25 16:49 ` Andreas Arnez
2014-07-01 8:00 ` [ping][PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
13 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-06-25 16:49 UTC (permalink / raw)
To: gdb-patches; +Cc: Richard Henderson
gdb/
* alpha-linux-tdep.c (alpha_linux_supply_gregset): Replace logic
by call to alpha_supply_int_regs.
(alpha_linux_collect_gregset): New function.
(alpha_linux_supply_fpregset): Replace logic by call to
alpha_supply_fp_regs.
(alpha_linux_collect_fpregset): New function.
(alpha_linux_gregset, alpha_linux_fpregset): Add collect method.
---
gdb/alpha-linux-tdep.c | 56 +++++++++++++++++++++++++++++++-------------------
1 file changed, 35 insertions(+), 21 deletions(-)
diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c
index 52f19d0..51bce4f 100644
--- a/gdb/alpha-linux-tdep.c
+++ b/gdb/alpha-linux-tdep.c
@@ -166,21 +166,27 @@ alpha_linux_supply_gregset (const struct regset *regset,
int regnum, const void *gregs, size_t len)
{
const gdb_byte *regs = gregs;
- int i;
+
gdb_assert (len >= 32 * 8);
+ alpha_supply_int_regs (regcache, regnum, regs, regs + 31 * 8,
+ len >= 33 * 8 ? regs + 32 * 8 : NULL);
+}
- for (i = 0; i < ALPHA_ZERO_REGNUM; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + i * 8);
- }
+/* Collect register REGNUM from the register cache REGCACHE and store
+ it in the buffer specified by GREGS and LEN as described by the
+ general-purpose register set REGSET. If REGNUM is -1, do this for
+ all registers in REGSET. */
- if (regnum == ALPHA_PC_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
+static void
+alpha_linux_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t len)
+{
+ gdb_byte *regs = gregs;
- if (regnum == ALPHA_UNIQUE_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, ALPHA_UNIQUE_REGNUM,
- len >= 33 * 8 ? regs + 32 * 8 : NULL);
+ gdb_assert (len >= 32 * 8);
+ alpha_fill_int_regs (regcache, regnum, regs, regs + 31 * 8,
+ len >= 33 * 8 ? regs + 32 * 8 : NULL);
}
/* Supply register REGNUM from the buffer specified by FPREGS and LEN
@@ -193,29 +199,37 @@ alpha_linux_supply_fpregset (const struct regset *regset,
int regnum, const void *fpregs, size_t len)
{
const gdb_byte *regs = fpregs;
- int i;
+
gdb_assert (len >= 32 * 8);
+ alpha_supply_fp_regs (regcache, regnum, regs, regs + 31 * 8);
+}
- for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++)
- {
- if (regnum == i || regnum == -1)
- regcache_raw_supply (regcache, i, regs + (i - ALPHA_FP0_REGNUM) * 8);
- }
+/* Collect register REGNUM from the register cache REGCACHE and store
+ it in the buffer specified by FPREGS and LEN as described by the
+ general-purpose register set REGSET. If REGNUM is -1, do this for
+ all registers in REGSET. */
- if (regnum == ALPHA_FPCR_REGNUM || regnum == -1)
- regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, regs + 31 * 8);
+static void
+alpha_linux_collect_fpregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *fpregs, size_t len)
+{
+ gdb_byte *regs = fpregs;
+
+ gdb_assert (len >= 32 * 8);
+ alpha_fill_fp_regs (regcache, regnum, regs, regs + 31 * 8);
}
static const struct regset alpha_linux_gregset =
{
NULL,
- alpha_linux_supply_gregset
+ alpha_linux_supply_gregset, alpha_linux_collect_gregset
};
static const struct regset alpha_linux_fpregset =
{
NULL,
- alpha_linux_supply_fpregset
+ alpha_linux_supply_fpregset, alpha_linux_collect_fpregset
};
/* Return the appropriate register set for the core section identified
--
1.8.4.2
^ permalink raw reply [flat|nested] 31+ messages in thread
* [ping][PATCH v2 00/13] Regset rework preparations part 2
2014-06-25 16:49 [PATCH v2 00/13] Regset rework preparations part 2 Andreas Arnez
` (12 preceding siblings ...)
2014-06-25 16:49 ` [PATCH v2 05/13] ALPHA " Andreas Arnez
@ 2014-07-01 8:00 ` Andreas Arnez
13 siblings, 0 replies; 31+ messages in thread
From: Andreas Arnez @ 2014-07-01 8:00 UTC (permalink / raw)
To: Mark Kettenis; +Cc: Ulrich Weigand, Kevin Buettner, Pedro Alves, gdb-patches
Ping: https://sourceware.org/ml/gdb-patches/2014-06/msg00881.html
On Wed, Jun 25 2014, Andreas Arnez wrote:
> Version 1 is here:
>
> https://sourceware.org/ml/gdb-patches/2014-05/msg00631.html
>
> Changes in version 2:
>
> * New patch #1 that renames 'descr' -> 'regmap.
> * Improved comment for 'struct regcache_map_entry'.
> * Minor corrections in NIOS2 patch.
^ permalink raw reply [flat|nested] 31+ messages in thread