From ee1a7ae44068868a9351a2eef5d4be107bb8d024 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Wed, 27 Feb 2008 03:33:07 +0000 Subject: [PATCH] * linux-low.h (struct linux_target_ops): Replace left_pad_xfer field by collect_ptrace_register and supply_ptrace_register hooks. * linux-low.c (fetch_register): Use supply_ptrace_register callback instead of checking for the_low_target.left_pad_xfer. (usr_store_inferior_registers): Use collect_ptrace_register callback instead of checking for the_low_target.left_pad_xfer. * linux-s390-low.c (s390_collect_ptrace_register): New function. (s390_supply_ptrace_register): Likewise. (s390_fill_gregset): Call s390_collect_ptrace_register. (the_low_target): Update. * linux-ppc64-low.c (ppc_collect_ptrace_register): New function. (ppc_supply_ptrace_register): Likewise. (the_low_target): Update. * linux-i386-low.c (the_low_target): Update. * linux-x86-64-low.c (the_low_target): Update. --- gdb/gdbserver/ChangeLog | 21 ++++++++++++++ gdb/gdbserver/linux-i386-low.c | 3 +- gdb/gdbserver/linux-low.c | 15 +++++----- gdb/gdbserver/linux-low.h | 7 +++-- gdb/gdbserver/linux-ppc64-low.c | 23 +++++++++++++++- gdb/gdbserver/linux-s390-low.c | 47 +++++++++++++++++++++++++++++++- gdb/gdbserver/linux-x86-64-low.c | 3 +- 7 files changed, 104 insertions(+), 15 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index ae63d4e6cd5..d8e5c7ff2ae 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,24 @@ +2008-02-27 Ulrich Weigand + + * linux-low.h (struct linux_target_ops): Replace left_pad_xfer field + by collect_ptrace_register and supply_ptrace_register hooks. + * linux-low.c (fetch_register): Use supply_ptrace_register callback + instead of checking for the_low_target.left_pad_xfer. + (usr_store_inferior_registers): Use collect_ptrace_register callback + instead of checking for the_low_target.left_pad_xfer. + + * linux-s390-low.c (s390_collect_ptrace_register): New function. + (s390_supply_ptrace_register): Likewise. + (s390_fill_gregset): Call s390_collect_ptrace_register. + (the_low_target): Update. + + * linux-ppc64-low.c (ppc_collect_ptrace_register): New function. + (ppc_supply_ptrace_register): Likewise. + (the_low_target): Update. + + * linux-i386-low.c (the_low_target): Update. + * linux-x86-64-low.c (the_low_target): Update. + 2008-02-27 Ulrich Weigand * configure.srv [s390x-*-linux*]: Set srv_regobj to include both diff --git a/gdb/gdbserver/linux-i386-low.c b/gdb/gdbserver/linux-i386-low.c index 433d0855c71..c3cccb663ab 100644 --- a/gdb/gdbserver/linux-i386-low.c +++ b/gdb/gdbserver/linux-i386-low.c @@ -205,6 +205,7 @@ struct linux_target_ops the_low_target = { NULL, NULL, NULL, - 0, + NULL, + NULL, "i386" }; diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 732aafbc80f..1d2b422377b 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -1401,10 +1401,9 @@ fetch_register (int regno) goto error_exit; } } - if (the_low_target.left_pad_xfer - && register_size (regno) < sizeof (PTRACE_XFER_TYPE)) - supply_register (regno, (buf + sizeof (PTRACE_XFER_TYPE) - - register_size (regno))); + + if (the_low_target.supply_ptrace_register) + the_low_target.supply_ptrace_register (regno, buf); else supply_register (regno, buf); @@ -1448,12 +1447,12 @@ usr_store_inferior_registers (int regno) & - sizeof (PTRACE_XFER_TYPE); buf = alloca (size); memset (buf, 0, size); - if (the_low_target.left_pad_xfer - && register_size (regno) < sizeof (PTRACE_XFER_TYPE)) - collect_register (regno, (buf + sizeof (PTRACE_XFER_TYPE) - - register_size (regno))); + + if (the_low_target.collect_ptrace_register) + the_low_target.collect_ptrace_register (regno, buf); else collect_register (regno, buf); + for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h index 698a1b07f6d..ccbeb254f7c 100644 --- a/gdb/gdbserver/linux-low.h +++ b/gdb/gdbserver/linux-low.h @@ -69,9 +69,10 @@ struct linux_target_ops int (*stopped_by_watchpoint) (void); CORE_ADDR (*stopped_data_address) (void); - /* Whether to left-pad registers for PEEKUSR/POKEUSR if they are smaller - than an xfer unit. */ - int left_pad_xfer; + /* Hooks to reformat register data for PEEKUSR/POKEUSR (in particular + for registers smaller than an xfer unit). */ + void (*collect_ptrace_register) (int regno, char *buf); + void (*supply_ptrace_register) (int regno, const char *buf); /* What string to report to GDB when it asks for the architecture, or NULL not to answer. */ diff --git a/gdb/gdbserver/linux-ppc64-low.c b/gdb/gdbserver/linux-ppc64-low.c index 3897d73b102..f216e9dc7b8 100644 --- a/gdb/gdbserver/linux-ppc64-low.c +++ b/gdb/gdbserver/linux-ppc64-low.c @@ -64,6 +64,26 @@ ppc_cannot_fetch_register (int regno) return 0; } +static void +ppc_collect_ptrace_register (int regno, char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + collect_register (regno, buf + sizeof (long) - size); + else + collect_register (regno, buf); +} + +static void +ppc_supply_ptrace_register (int regno, const char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + supply_register (regno, buf + sizeof (long) - size); + else + supply_register (regno, buf); +} + static CORE_ADDR ppc_get_pc (void) { @@ -187,5 +207,6 @@ struct linux_target_ops the_low_target = { NULL, NULL, NULL, - 1 + ppc_collect_ptrace_register, + ppc_supply_ptrace_register, }; diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c index d6739ab1be8..090ef275a2d 100644 --- a/gdb/gdbserver/linux-s390-low.c +++ b/gdb/gdbserver/linux-s390-low.c @@ -79,6 +79,45 @@ s390_cannot_store_register (int regno) return 0; } +static void +s390_collect_ptrace_register (int regno, char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + { + memset (buf, 0, sizeof (long)); + + if (regno == find_regno ("pswa") + || (regno >= find_regno ("r0") && regno <= find_regno ("r15"))) + collect_register (regno, buf + sizeof (long) - size); + else + collect_register (regno, buf); + + /* When debugging a 32-bit inferior on a 64-bit host, make sure + the 31-bit addressing mode bit is set in the PSW mask. */ + if (regno == find_regno ("pswm")) + buf[size] |= 0x80; + } + else + collect_register (regno, buf); +} + +static void +s390_supply_ptrace_register (int regno, const char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + { + if (regno == find_regno ("pswa") + || (regno >= find_regno ("r0") && regno <= find_regno ("r15"))) + supply_register (regno, buf + sizeof (long) - size); + else + supply_register (regno, buf); + } + else + supply_register (regno, buf); +} + /* Provide only a fill function for the general register set. ps_lgetregs will use this for NPTL support. */ @@ -87,7 +126,7 @@ static void s390_fill_gregset (void *buf) int i; for (i = 0; i < 34; i++) - collect_register (i, (char *) buf + s390_regmap[i]); + s390_collect_ptrace_register (i, (char *) buf + s390_regmap[i]); } struct regset_info target_regsets[] = { @@ -179,5 +218,11 @@ struct linux_target_ops the_low_target = { NULL, s390_breakpoint_len, s390_breakpoint_at, + NULL, + NULL, + NULL, + NULL, + s390_collect_ptrace_register, + s390_supply_ptrace_register, }; diff --git a/gdb/gdbserver/linux-x86-64-low.c b/gdb/gdbserver/linux-x86-64-low.c index 80f5c6dbc38..b4a2f6be594 100644 --- a/gdb/gdbserver/linux-x86-64-low.c +++ b/gdb/gdbserver/linux-x86-64-low.c @@ -179,6 +179,7 @@ struct linux_target_ops the_low_target = { NULL, NULL, NULL, - 0, + NULL, + NULL, "i386:x86-64", }; -- 2.30.2