From: "Ulrich Weigand" <uweigand@de.ibm.com>
To: gdb-patches@sourceware.org
Subject: [rfc][2/3] gdbserver bi-arch support: core s390x part
Date: Mon, 21 Jan 2008 17:46:00 -0000 [thread overview]
Message-ID: <200801211745.m0LHjqHo002475@d12av02.megacenter.de.ibm.com> (raw)
Hello,
this patch makes gdbserver on s390x bi-arch capabable: it will now detect
whether the target is 31-bit or 64-bit and select the appropriate register
format definition.
The basic idea is to simply link gdbserver with both reg-s390.o and
reg-s390x.o (which no longer conflict), and change the compile-time
selection of the linux-s390-low version of the_low_target.arch_setup
into a run-time selection.
However, this isn't really sufficient: at the time the arch_setup routine
is currently called, there is no target attached, and thus there is no
way of detecting whether to use the 31-bit or 64-bit register set.
Thus the patch also changes the call location of arch_setup in linux-low.c
to just after the inferior is attached (but before any register access).
This point happens to be in linux_wait_for_process (when called for the
first time).
This exposes another problem: at this time, common code has already set up
a register cache for the initial thread, which may now turn out to be of
the wrong size. To fix this, the set_register_cache routine (which is
called by the generated init_register_... routine) now goes through all
register caches that may already have been allocated and re-sizes them
to the new size. (As a nice side-effect, this now also allows to call
init_register_... multiple times.)
Finally, the patch adapted s390_get_pc and s390_set_pc to properly work
in the bi-arch configuration. (Note that even so there are a couple of
problems that need to be fixed in a follow-on patch.)
Tested (together with the follow-on patch) on s390-linux and s390x-linux.
Bye,
Ulrich
ChangeLog:
* configure.srv [s390x-*-linux*]: Set srv_regobj to include both
reg-s390.o and reg-s390x.o.
* linux-low.c (linux_wait_for_process): Call the_low_target.arch_setup
after the target has stopped for the first time.
(initialize_low): Do not call the_low_target.arch_setup.
* linux-s390-low.c (s390_get_pc): Support bi-arch operation.
(s390_set_pc): Likewise.
(s390_arch_setup): New function.
(the_low_target): Use s390_arch_setup as arch_setup routine.
* regcache.c (realloc_register_cache): New function.
(set_register_cache): Call it for each existing regcache.
diff -urNp gdb-orig/gdb/gdbserver/configure.srv gdb-head/gdb/gdbserver/configure.srv
--- gdb-orig/gdb/gdbserver/configure.srv 2008-01-18 00:57:40.000000000 +0100
+++ gdb-head/gdb/gdbserver/configure.srv 2008-01-17 22:29:26.000000000 +0100
@@ -138,7 +138,7 @@ case "${target}" in
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
- s390x-*-linux*) srv_regobj=reg-s390x.o
+ s390x-*-linux*) srv_regobj="reg-s390.o reg-s390x.o"
srv_tgtobj="linux-low.o linux-s390-low.o"
srv_linux_usrregs=yes
srv_linux_regsets=yes
diff -urNp gdb-orig/gdb/gdbserver/linux-low.c gdb-head/gdb/gdbserver/linux-low.c
--- gdb-orig/gdb/gdbserver/linux-low.c 2008-01-18 00:57:40.000000000 +0100
+++ gdb-head/gdb/gdbserver/linux-low.c 2008-01-18 00:57:34.000000000 +0100
@@ -548,6 +548,7 @@ status_pending_p (struct inferior_list_e
static void
linux_wait_for_process (struct process_info **childp, int *wstatp)
{
+ static int arch_setup_done = 0;
int ret;
int to_wait_for = -1;
@@ -606,6 +607,16 @@ retry:
(*childp)->last_status = *wstatp;
+ /* Architecture-specific setup after inferior is running.
+ This needs to happen after we have attached to the inferior
+ and it is stopped for the first time, but before we access
+ any inferior registers. */
+ if (!arch_setup_done)
+ {
+ the_low_target.arch_setup ();
+ arch_setup_done = 1;
+ }
+
if (debug_threads
&& WIFSTOPPED (*wstatp))
{
@@ -2060,7 +2071,6 @@ initialize_low (void)
set_target_ops (&linux_target_ops);
set_breakpoint_data (the_low_target.breakpoint,
the_low_target.breakpoint_len);
- the_low_target.arch_setup ();
linux_init_signals ();
linux_test_for_tracefork ();
}
diff -urNp gdb-orig/gdb/gdbserver/linux-s390-low.c gdb-head/gdb/gdbserver/linux-s390-low.c
--- gdb-orig/gdb/gdbserver/linux-s390-low.c 2008-01-18 00:57:40.000000000 +0100
+++ gdb-head/gdb/gdbserver/linux-s390-low.c 2008-01-18 01:00:18.000000000 +0100
@@ -102,24 +102,61 @@ static const unsigned char s390_breakpoi
static CORE_ADDR
s390_get_pc ()
{
- unsigned long pc;
- collect_register_by_name ("pswa", &pc);
+ if (register_size (0) == 4)
+ {
+ unsigned int pc;
+ collect_register_by_name ("pswa", &pc);
#ifndef __s390x__
- pc &= 0x7fffffff;
+ pc &= 0x7fffffff;
#endif
- return pc;
+ return pc;
+ }
+ else
+ {
+ unsigned long pc;
+ collect_register_by_name ("pswa", &pc);
+ return pc;
+ }
}
static void
s390_set_pc (CORE_ADDR newpc)
{
- unsigned long pc = newpc;
+ if (register_size (0) == 4)
+ {
+ unsigned int pc = newpc;
#ifndef __s390x__
- pc |= 0x80000000;
+ pc |= 0x80000000;
#endif
- supply_register_by_name ("pswa", &pc);
+ supply_register_by_name ("pswa", &pc);
+ }
+ else
+ {
+ unsigned long pc = newpc;
+ supply_register_by_name ("pswa", &pc);
+ }
}
+
+static void
+s390_arch_setup (void)
+{
+ /* Assume 31-bit inferior process. */
+ init_registers_s390 ();
+
+ /* On a 64-bit host, check the low bit of the (31-bit) PSWM
+ -- if this is one, we actually have a 64-bit inferior. */
+#ifdef __s390x__
+ {
+ unsigned int pswm;
+ collect_register_by_name ("pswm", &pswm);
+ if (pswm & 1)
+ init_registers_s390x ();
+ }
+#endif
+}
+
+
static int
s390_breakpoint_at (CORE_ADDR pc)
{
@@ -130,11 +167,7 @@ s390_breakpoint_at (CORE_ADDR pc)
struct linux_target_ops the_low_target = {
-#ifndef __s390x__
- init_registers_s390,
-#else
- init_registers_s390x,
-#endif
+ s390_arch_setup,
s390_num_regs,
s390_regmap,
s390_cannot_fetch_register,
diff -urNp gdb-orig/gdb/gdbserver/regcache.c gdb-head/gdb/gdbserver/regcache.c
--- gdb-orig/gdb/gdbserver/regcache.c 2008-01-18 00:57:40.000000000 +0100
+++ gdb-head/gdb/gdbserver/regcache.c 2008-01-17 22:29:26.000000000 +0100
@@ -121,6 +121,15 @@ free_register_cache (void *regcache_p)
free (regcache);
}
+static void
+realloc_register_cache (struct inferior_list_entry *thread_p)
+{
+ struct thread_info *thread = (struct thread_info *) thread_p;
+
+ free_register_cache (inferior_regcache_data (thread));
+ set_inferior_regcache_data (thread, new_register_cache ());
+}
+
void
set_register_cache (struct reg *regs, int n)
{
@@ -137,6 +146,9 @@ set_register_cache (struct reg *regs, in
}
register_bytes = offset / 8;
+
+ /* Re-allocate all pre-existing register caches. */
+ for_each_inferior (&all_threads, realloc_register_cache);
}
void
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
next reply other threads:[~2008-01-21 17:46 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-21 17:46 Ulrich Weigand [this message]
2008-01-29 20:28 ` Daniel Jacobowitz
2008-01-29 23:35 ` Ulrich Weigand
2008-02-01 0:04 ` Ulrich Weigand
2008-02-26 3:57 ` Daniel Jacobowitz
2008-02-27 3:44 ` Ulrich Weigand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200801211745.m0LHjqHo002475@d12av02.megacenter.de.ibm.com \
--to=uweigand@de.ibm.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox