* [RFA 3/3] Add ravenscar-thread support for powerpc.
2012-12-14 15:02 [RFA/commit 1/3] minor ravenscar-thread cleanup Joel Brobecker
@ 2012-12-14 15:03 ` Joel Brobecker
2012-12-14 17:34 ` Pedro Alves
2012-12-14 15:03 ` [RFA 2/3] gdbarch-ification of ravenscar-thread support Joel Brobecker
2012-12-14 17:03 ` [RFA/commit 1/3] minor ravenscar-thread cleanup Pedro Alves
2 siblings, 1 reply; 8+ messages in thread
From: Joel Brobecker @ 2012-12-14 15:03 UTC (permalink / raw)
To: gdb-patches; +Cc: Joel Brobecker
This patch adds ravenscar-thread support for PowerPC.
There are two variants, which differ only by the list
and location of their registers.
gdb/ChangeLog:
* ravenscar-ppc-thread.h, ravenscar-ppc-thread.c: New files.
* Makefile.in (ALL_TARGET_OBS): Add ravenscar-ppc-thread.o.
(HFILES_NO_SRCDIR): Add ravenscar-ppc-thread.h.
(ALLDEPFILES): Add ravenscar-ppc-thread.c.
* configure.tgt: Add ravenscar-ppc-thread.o to gdb_target_obs
for every target that uses rs6000-tdep.o.
* rs6000-tdep.c: #include "ravenscar-ppc-thread.h".
(rs6000_gdbarch_init): Call register_e500_ravenscar_ops
or register_ppc_ravenscar_ops.
Tested on x86_64-linux. Also tested on powerpc-elf with AdaCore's
testsuite.
---
gdb/Makefile.in | 6 +-
gdb/configure.tgt | 12 +-
gdb/ravenscar-ppc-thread.c | 291 ++++++++++++++++++++++++++++++++++++++++++++
gdb/ravenscar-ppc-thread.h | 29 +++++
gdb/rs6000-tdep.c | 7 ++
5 files changed, 337 insertions(+), 8 deletions(-)
create mode 100644 gdb/ravenscar-ppc-thread.c
create mode 100644 gdb/ravenscar-ppc-thread.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 03f9693..b92f99a 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -563,7 +563,7 @@ ALL_TARGET_OBS = \
nto-tdep.o \
ppc-linux-tdep.o ppcnbsd-tdep.o ppcobsd-tdep.o ppc-sysv-tdep.o \
rl78-tdep.o \
- rs6000-aix-tdep.o rs6000-tdep.o \
+ rs6000-aix-tdep.o rs6000-tdep.o ravenscar-ppc-thread.o \
rx-tdep.o \
s390-tdep.o \
score-tdep.o \
@@ -829,7 +829,7 @@ gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/format.h common/host-defs.h utils.h \
common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \
-gdb_bfd.h ravenscar-sparc-thread.h
+gdb_bfd.h ravenscar-sparc-thread.h ravenscar-ppc-thread.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -1485,7 +1485,7 @@ ALLDEPFILES = \
remote-sim.c \
dcache.c \
rl78-tdep.c \
- rs6000-nat.c rs6000-tdep.c \
+ rs6000-nat.c rs6000-tdep.c ravenscar-ppc-thread.c \
rx-tdep.c \
s390-tdep.c s390-nat.c \
score-tdep.c \
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 8c442a7..f7218bd 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -386,31 +386,33 @@ mt-*-*)
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
# Target: NetBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o \
- solib-svr4.o"
+ solib-svr4.o ravenscar-ppc-thread.o"
gdb_sim=../sim/ppc/libsim.a
;;
powerpc-*-openbsd*)
# Target: OpenBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppcobsd-tdep.o \
- solib-svr4.o"
+ solib-svr4.o ravenscar-ppc-thread.o"
;;
powerpc-*-aix* | rs6000-*-*)
# Target: PowerPC running AIX
gdb_target_obs="rs6000-tdep.o rs6000-aix-tdep.o xcoffread.o \
- ppc-sysv-tdep.o solib-svr4.o"
+ ppc-sysv-tdep.o solib-svr4.o ravenscar-ppc-thread.o"
;;
powerpc-*-linux* | powerpc64-*-linux*)
# Target: PowerPC running Linux
gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
solib-svr4.o solib-spu.o spu-multiarch.o \
- glibc-tdep.o symfile-mem.o linux-tdep.o"
+ glibc-tdep.o symfile-mem.o linux-tdep.o \
+ ravenscar-ppc-thread.o"
gdb_sim=../sim/ppc/libsim.a
build_gdbserver=yes
;;
powerpc*-*-*)
# Target: PowerPC running eabi
gdb_target_obs="rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o \
- dink32-rom.o ppc-sysv-tdep.o solib-svr4.o"
+ dink32-rom.o ppc-sysv-tdep.o solib-svr4.o \
+ ravenscar-ppc-thread.o"
if test -f ../sim/ppc/Makefile; then
gdb_sim=../sim/ppc/libsim.a
fi
diff --git a/gdb/ravenscar-ppc-thread.c b/gdb/ravenscar-ppc-thread.c
new file mode 100644
index 0000000..adc5c62
--- /dev/null
+++ b/gdb/ravenscar-ppc-thread.c
@@ -0,0 +1,291 @@
+/* Ravenscar PowerPC target support.
+
+ Copyright 2011-2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "ppc-tdep.h"
+#include "inferior.h"
+#include "ravenscar-thread.h"
+#include "ravenscar-ppc-thread.h"
+
+#define NO_OFFSET -1
+
+/* See ppc-tdep.h for register numbers. */
+
+static const int powerpc_context_offsets[] =
+{
+ /* R0 - R32 */
+ NO_OFFSET, 0, 4, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, 8, 12, 16,
+ 20, 24, 28, 32,
+ 36, 40, 44, 48,
+ 52, 56, 60, 64,
+ 68, 72, 76, 80,
+
+ /* F0 - F31 */
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, 96, 104,
+ 112, 120, 128, 136,
+ 144, 152, 160, 168,
+ 176, 184, 192, 200,
+ 208, 216, 224, 232,
+
+ /* PC, MSR, CR, LR */
+ 88, NO_OFFSET, 84, NO_OFFSET,
+
+ /* CTR, XER, FPSCR */
+ NO_OFFSET, NO_OFFSET, 240
+};
+
+static const int e500_context_offsets[] =
+{
+ /* R0 - R32 */
+ NO_OFFSET, 4, 12, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, 20, 28, 36,
+ 44, 52, 60, 68,
+ 76, 84, 92, 100,
+ 108, 116, 124, 132,
+ 140, 148, 156, 164,
+
+ /* F0 - F31 */
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+
+ /* PC, MSR, CR, LR */
+ 172, NO_OFFSET, 168, NO_OFFSET,
+
+ /* CTR, XER, FPSCR, MQ */
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+
+ /* Upper R0-R32. */
+ NO_OFFSET, 0, 8, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
+ NO_OFFSET, 16, 24, 32,
+ 40, 48, 56, 64,
+ 72, 80, 88, 96,
+ 104, 112, 120, 128,
+ 136, 144, 152, 160,
+
+ /* ACC, FSCR */
+ NO_OFFSET, 176
+};
+
+/* The register layout info. */
+
+struct ravenscar_reg_info
+{
+ /* A table providing the offset relative to the context structure
+ where each register is saved. */
+ const int *context_offsets;
+
+ /* The number of elements in the context_offsets table above. */
+ int context_offsets_size;
+};
+
+/* supply register REGNUM, which has been saved on REGISTER_ADDR, to the
+ regcache. */
+
+static void
+supply_register_at_address (struct regcache *regcache, int regnum,
+ CORE_ADDR register_addr)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int buf_size = register_size (gdbarch, regnum);
+ char *buf;
+
+ buf = (char *) alloca (buf_size);
+ read_memory (register_addr, buf, buf_size);
+ regcache_raw_supply (regcache, regnum, buf);
+}
+
+/* Return true if, for a non-running thread, REGNUM has been saved on the
+ Thread_Descriptor. */
+
+static int
+register_in_thread_descriptor_p (const struct ravenscar_reg_info *reg_info,
+ int regnum)
+{
+ return (regnum < reg_info->context_offsets_size
+ && reg_info->context_offsets[regnum] != NO_OFFSET);
+}
+
+/* to_fetch_registers when inferior_ptid is different from the running
+ thread. */
+
+static void
+ravenscar_generic_ppc_fetch_registers
+ (const struct ravenscar_reg_info *reg_info,
+ struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const int sp_regnum = gdbarch_sp_regnum (gdbarch);
+ const int num_regs = gdbarch_num_regs (gdbarch);
+ int current_regnum;
+ CORE_ADDR current_address;
+ CORE_ADDR thread_descriptor_address;
+
+ /* The tid is the thread_id field, which is a pointer to the thread. */
+ thread_descriptor_address = (CORE_ADDR) ptid_get_tid (inferior_ptid);
+
+ /* Read registers. */
+ for (current_regnum = 0; current_regnum < num_regs; current_regnum++)
+ {
+ if (register_in_thread_descriptor_p (reg_info, current_regnum))
+ {
+ current_address = thread_descriptor_address
+ + reg_info->context_offsets[current_regnum];
+ supply_register_at_address (regcache, current_regnum,
+ current_address);
+ }
+ }
+}
+
+/* to_prepare_to_store when inferior_ptid is different from the running
+ thread. */
+
+static void
+ravenscar_generic_ppc_prepare_to_store (struct regcache *regcache)
+{
+ /* Nothing to do. */
+}
+
+/* to_store_registers when inferior_ptid is different from the running
+ thread. */
+
+static void
+ravenscar_generic_ppc_store_registers
+ (const struct ravenscar_reg_info *reg_info,
+ struct regcache *regcache, int regnum)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int buf_size = register_size (gdbarch, regnum);
+ char buf [buf_size];
+ ULONGEST register_address;
+
+ if (register_in_thread_descriptor_p (reg_info, regnum))
+ register_address
+ = ptid_get_tid (inferior_ptid) + reg_info->context_offsets [regnum];
+ else
+ return;
+
+ regcache_raw_collect (regcache, regnum, buf);
+ write_memory (register_address,
+ buf,
+ buf_size);
+}
+
+/* The ravenscar_reg_info for most PowerPC targets. */
+
+static const struct ravenscar_reg_info ppc_reg_info =
+{
+ powerpc_context_offsets,
+ ARRAY_SIZE (powerpc_context_offsets),
+};
+
+/* Implement the to_fetch_registers ravenscar_arch_ops method
+ for most PowerPC targets. */
+
+static void
+ravenscar_powerpc_fetch_registers (struct regcache *regcache, int regnum)
+{
+ ravenscar_generic_ppc_fetch_registers (&ppc_reg_info, regcache, regnum);
+}
+
+/* Implement the to_store_registers ravenscar_arch_ops method
+ for most PowerPC targets. */
+
+static void
+ravenscar_powerpc_store_registers (struct regcache *regcache, int regnum)
+{
+ ravenscar_generic_ppc_store_registers (&ppc_reg_info, regcache, regnum);
+}
+
+/* The ravenscar_arch_ops vector for most PowerPC targets. */
+
+static struct ravenscar_arch_ops ravenscar_powerpc_ops =
+{
+ ravenscar_powerpc_fetch_registers,
+ ravenscar_powerpc_store_registers,
+ ravenscar_generic_ppc_prepare_to_store
+};
+
+/* Register ravenscar_powerpc_ops in GDBARCH. */
+
+void
+register_ppc_ravenscar_ops (struct gdbarch *gdbarch)
+{
+ set_gdbarch_ravenscar_ops (gdbarch, &ravenscar_powerpc_ops);
+}
+
+/* The ravenscar_reg_info for E500 targets. */
+
+static const struct ravenscar_reg_info e500_reg_info =
+{
+ e500_context_offsets,
+ ARRAY_SIZE (e500_context_offsets),
+};
+
+/* Implement the to_fetch_registers ravenscar_arch_ops method
+ for E500 targets. */
+
+static void
+ravenscar_e500_fetch_registers (struct regcache *regcache, int regnum)
+{
+ ravenscar_generic_ppc_fetch_registers (&e500_reg_info, regcache, regnum);
+}
+
+/* Implement the to_store_registers ravenscar_arch_ops method
+ for E500 targets. */
+
+static void
+ravenscar_e500_store_registers (struct regcache *regcache, int regnum)
+{
+ ravenscar_generic_ppc_store_registers (&e500_reg_info, regcache, regnum);
+}
+
+/* The ravenscar_arch_ops vector for E500 targets. */
+
+static struct ravenscar_arch_ops ravenscar_e500_ops =
+{
+ ravenscar_e500_fetch_registers,
+ ravenscar_e500_store_registers,
+ ravenscar_generic_ppc_prepare_to_store
+};
+
+/* Register ravenscar_e500_ops in GDBARCH. */
+
+void
+register_e500_ravenscar_ops (struct gdbarch *gdbarch)
+{
+ set_gdbarch_ravenscar_ops (gdbarch, &ravenscar_e500_ops);
+}
diff --git a/gdb/ravenscar-ppc-thread.h b/gdb/ravenscar-ppc-thread.h
new file mode 100644
index 0000000..334153b
--- /dev/null
+++ b/gdb/ravenscar-ppc-thread.h
@@ -0,0 +1,29 @@
+/* Ravenscar PowerPC target support.
+
+ Copyright 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef RAVENSCAR_PPC_THREAD_H
+#define RAVENSCAR_PPC_THREAD_H
+
+struct gdbarch;
+
+extern void register_ppc_ravenscar_ops (struct gdbarch *gdbarch);
+
+extern void register_e500_ravenscar_ops (struct gdbarch *gdbarch);
+
+#endif
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 07b81bc..95b5e1b 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -52,6 +52,7 @@
#include "solib-svr4.h"
#include "ppc-tdep.h"
+#include "ravenscar-ppc-thread.h"
#include "gdb_assert.h"
#include "dis-asm.h"
@@ -4153,6 +4154,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
gdb_assert (gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch) == cur_reg);
+ /* Register the ravenscar_arch_ops. */
+ if (mach == bfd_mach_ppc_e500)
+ register_e500_ravenscar_ops (gdbarch);
+ else
+ register_ppc_ravenscar_ops (gdbarch);
+
return gdbarch;
}
--
1.7.10.4
^ permalink raw reply [flat|nested] 8+ messages in thread* [RFA 2/3] gdbarch-ification of ravenscar-thread support.
2012-12-14 15:02 [RFA/commit 1/3] minor ravenscar-thread cleanup Joel Brobecker
2012-12-14 15:03 ` [RFA 3/3] Add ravenscar-thread support for powerpc Joel Brobecker
@ 2012-12-14 15:03 ` Joel Brobecker
2012-12-14 17:17 ` Pedro Alves
2012-12-14 17:03 ` [RFA/commit 1/3] minor ravenscar-thread cleanup Pedro Alves
2 siblings, 1 reply; 8+ messages in thread
From: Joel Brobecker @ 2012-12-14 15:03 UTC (permalink / raw)
To: gdb-patches; +Cc: Joel Brobecker
Hello,
This one is the biggie, moving ravenscar-thread to the gdbarch age.
The changes in the ravenscar modules themselves are quite
straightforward, but the changes to Makefile.in (adding the
right files to the right lists), and configure.tgt (adding
ravenscar-sparc-thread.o everywhere sparc-tdep.o is listed)
where slightly trickier. Also, I have a question, hence the
RFA.
The question: Right now, I put ravenscar-thread.o in the list of
objects to always be built, regardless of whether or not GDB is
configured with a target that can take advantage of it. I seems
slightly wasteful, but somehow consistent with have solib-target
always available, for instance. It's really easy to change: we
just have to remove ravenscar-thread.o from Makefile.in, and
add it to the gdb_target_obs instead. WDYT?
gdb/ChangeLog:
* gdbarch.sh: Add "struct ravenscar_arch_ops" advance
declaration.
(ravenscar_ops): New gdbarch variable.
* gdbarch.h, gdbarch.c: Regenerate.
* ravenscar-thread.h (ravenscar_register_arch_ops): Delete.
* ravenscar-thread.c (current_arch_ops): Delete.
(ravenscar_fetch_registers): Get the ravenscar_arch_ops
from the gdbarch.
(ravenscar_store_registers, ravenscar_prepare_to_store): Likewise.
(ravenscar_inferior_created): Add gdbarch_ravenscar_ops check.
(ravenscar_register_arch_ops): Delete.
* ravenscar-sparc-thread.h: New file.
* ravenscar-sparc-thread.c: #include "ravenscar-sparc-thread.h".
(ravenscar_sparc_ops): Define value statically.
(_initialize_ravenscar_sparc): Delete.
(register_sparc_ravenscar_ops): New function.
* sparc-tdep.c: #include "ravenscar-sparc-thread.h".
(sparc32_gdbarch_init): Add call to register_sparc_ravenscar_ops.
* Makefile.in (ALL_TARGET_OBS): Add ravenscar-sparc-thread.o.
(SFILES): Add ravenscar-thread.c.
(HFILES_NO_SRCDIR): Add ravenscar-sparc-thread.h.
(COMMON_OBS): Add ravenscar-thread.o.
(ALLDEPFILES): ravenscar-sparc-thread.c.
* configure.tgt: Add ravenscar-sparc-thread.o to gdb_target_obs
for all the targets that use sparc-tdep.o.
Tested on x86_64-linux. Also tested on sparc-elf with AdaCore's
testsuite.
---
gdb/Makefile.in | 9 ++++++---
gdb/configure.tgt | 30 ++++++++++++++++------------
gdb/gdbarch.c | 24 +++++++++++++++++++++++
gdb/gdbarch.h | 6 ++++++
gdb/gdbarch.sh | 3 +++
gdb/ravenscar-sparc-thread.c | 20 ++++++++++---------
gdb/ravenscar-sparc-thread.h | 26 +++++++++++++++++++++++++
gdb/ravenscar-thread.c | 44 +++++++++++++++++++++++++-----------------
gdb/ravenscar-thread.h | 9 ---------
gdb/sparc-tdep.c | 3 +++
10 files changed, 123 insertions(+), 51 deletions(-)
create mode 100644 gdb/ravenscar-sparc-thread.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 22f2acb..03f9693 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -569,7 +569,7 @@ ALL_TARGET_OBS = \
score-tdep.o \
sh64-tdep.o sh-linux-tdep.o shnbsd-tdep.o sh-tdep.o \
sparc-linux-tdep.o sparcnbsd-tdep.o sparcobsd-tdep.o \
- sparc-sol2-tdep.o sparc-tdep.o \
+ sparc-sol2-tdep.o sparc-tdep.o ravenscar-sparc-thread.o \
spu-tdep.o spu-multiarch.o solib-spu.o \
tic6x-tdep.o tic6x-linux-tdep.o \
tilegx-tdep.o tilegx-linux-tdep.o \
@@ -729,6 +729,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
proc-service.list progspace.c \
prologue-value.c psymtab.c \
+ ravenscar-thread.c \
regcache.c reggroups.c remote.c remote-fileio.c reverse.c \
sentinel-frame.c \
serial.c ser-base.c ser-unix.c skip.c \
@@ -827,7 +828,8 @@ gnulib/import/extra/snippet/warn-on-use.h \
gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/format.h common/host-defs.h utils.h \
-common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h
+common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \
+gdb_bfd.h ravenscar-sparc-thread.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -918,7 +920,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
gdb_vecs.o jit.o progspace.o skip.o probe.o \
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
- format.o registry.o
+ format.o registry.o ravenscar-thread.o
TSOBS = inflow.o
@@ -1497,6 +1499,7 @@ ALLDEPFILES = \
sparc64-nat.c sparc64-tdep.c sparc64fbsd-nat.c sparc64fbsd-tdep.c \
sparc64nbsd-nat.c sparc64nbsd-tdep.c sparc64obsd-tdep.c \
sparcnbsd-nat.c sparcnbsd-tdep.c sparcobsd-tdep.c \
+ ravenscar-sparc-thread.c \
spu-linux-nat.c spu-tdep.c spu-multiarch.c solib-spu.c \
tilegx-linux-nat.c tilegx-tdep.c tilegx-linux-tdep.c \
v850-tdep.c \
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 36d4304..8c442a7 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -475,7 +475,7 @@ sparc-*-linux*)
# Target: GNU/Linux SPARC
gdb_target_obs="sparc-tdep.o sparc-sol2-tdep.o sol2-tdep.o \
sparc-linux-tdep.o solib-svr4.o symfile-mem.o \
- linux-tdep.o"
+ linux-tdep.o ravenscar-sparc-thread.o"
if test "x$enable_64_bit_bfd" = "xyes"; then
# Target: GNU/Linux UltraSPARC
gdb_target_obs="sparc64-tdep.o sparc64-sol2-tdep.o \
@@ -487,52 +487,58 @@ sparc64-*-linux*)
# Target: GNU/Linux UltraSPARC
gdb_target_obs="sparc64-tdep.o sparc64-sol2-tdep.o sol2-tdep.o \
sparc64-linux-tdep.o sparc-tdep.o sparc-sol2-tdep.o \
- sparc-linux-tdep.o solib-svr4.o linux-tdep.o"
+ sparc-linux-tdep.o solib-svr4.o linux-tdep.o \
+ ravenscar-sparc-thread.o"
build_gdbserver=yes
;;
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
# Target: FreeBSD/sparc64
gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64fbsd-tdep.o \
- solib-svr4.o"
+ solib-svr4.o ravenscar-sparc-thread.o"
;;
sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
# Target: NetBSD/sparc
- gdb_target_obs="sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o solib-svr4.o"
+ gdb_target_obs="sparc-tdep.o sparcnbsd-tdep.o nbsd-tdep.o \
+ solib-svr4.o ravenscar-sparc-thread.o"
;;
sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu)
# Target: NetBSD/sparc64
gdb_target_obs="sparc64-tdep.o sparc64nbsd-tdep.o sparc-tdep.o \
- sparcnbsd-tdep.o nbsd-tdep.o solib-svr4.o"
+ sparcnbsd-tdep.o nbsd-tdep.o solib-svr4.o \
+ ravenscar-sparc-thread.o"
;;
sparc-*-openbsd*)
# Target: OpenBSD/sparc
gdb_target_obs="sparc-tdep.o sparcnbsd-tdep.o sparcobsd-tdep.o \
- nbsd-tdep.o obsd-tdep.o bsd-uthread.o solib-svr4.o"
+ nbsd-tdep.o obsd-tdep.o bsd-uthread.o solib-svr4.o \
+ ravenscar-sparc-thread.o"
;;
sparc64-*-openbsd*)
# Target: OpenBSD/sparc64
gdb_target_obs="sparc64-tdep.o sparc64nbsd-tdep.o sparc64obsd-tdep.o \
sparc-tdep.o sparcnbsd-tdep.o sparcobsd-tdep.o \
- nbsd-tdep.o obsd-tdep.o bsd-uthread.o solib-svr4.o"
+ nbsd-tdep.o obsd-tdep.o bsd-uthread.o solib-svr4.o \
+ ravenscar-sparc-thread.o"
;;
sparc-*-solaris2.[0-6] | sparc-*-solaris2.[0-6].*)
# Target: Solaris SPARC
- gdb_target_obs="sparc-tdep.o sparc-sol2-tdep.o sol2-tdep.o solib-svr4.o"
+ gdb_target_obs="sparc-tdep.o sparc-sol2-tdep.o sol2-tdep.o \
+ solib-svr4.o ravenscar-sparc-thread.o"
;;
sparc-*-solaris2* | sparcv9-*-solaris2* | sparc64-*-solaris2*)
# Target: Solaris UltraSPARC
gdb_target_obs="sparc64-tdep.o sparc64-sol2-tdep.o sparc-tdep.o \
- sparc-sol2-tdep.o sol2-tdep.o solib-svr4.o"
+ sparc-sol2-tdep.o sol2-tdep.o solib-svr4.o \
+ ravenscar-sparc-thread.o"
;;
sparc-*-*)
# Target: SPARC
- gdb_target_obs="sparc-tdep.o ravenscar-thread.o \
- ravenscar-sparc-thread.o"
+ gdb_target_obs="sparc-tdep.o ravenscar-sparc-thread.o"
gdb_sim=../sim/erc32/libsim.a
;;
sparc64-*-*)
# Target: UltraSPARC
- gdb_target_obs="sparc-tdep.o sparc64-tdep.o"
+ gdb_target_obs="sparc-tdep.o sparc64-tdep.o ravenscar-sparc-thread.o"
;;
spu*-*-*)
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 6ae453e..dd44d55 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -284,6 +284,7 @@ struct gdbarch
gdbarch_gen_return_address_ftype *gen_return_address;
gdbarch_info_proc_ftype *info_proc;
gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order;
+ struct ravenscar_arch_ops * ravenscar_ops;
};
@@ -452,6 +453,7 @@ struct gdbarch startup_gdbarch =
default_gen_return_address, /* gen_return_address */
0, /* info_proc */
default_iterate_over_objfiles_in_search_order, /* iterate_over_objfiles_in_search_order */
+ NULL, /* ravenscar_ops */
/* startup_gdbarch() */
};
@@ -542,6 +544,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
gdbarch->auto_wide_charset = default_auto_wide_charset;
gdbarch->gen_return_address = default_gen_return_address;
gdbarch->iterate_over_objfiles_in_search_order = default_iterate_over_objfiles_in_search_order;
+ gdbarch->ravenscar_ops = NULL;
/* gdbarch_alloc() */
return gdbarch;
@@ -751,6 +754,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of gen_return_address, invalid_p == 0 */
/* Skip verify of info_proc, has predicate. */
/* Skip verify of iterate_over_objfiles_in_search_order, invalid_p == 0 */
+ /* Skip verify of ravenscar_ops, invalid_p == 0 */
buf = ui_file_xstrdup (log, &length);
make_cleanup (xfree, buf);
if (length > 0)
@@ -1192,6 +1196,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: push_dummy_code = <%s>\n",
host_address_to_string (gdbarch->push_dummy_code));
fprintf_unfiltered (file,
+ "gdbarch_dump: ravenscar_ops = %s\n",
+ host_address_to_string (gdbarch->ravenscar_ops));
+ fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_read_pc_p() = %d\n",
gdbarch_read_pc_p (gdbarch));
fprintf_unfiltered (file,
@@ -4267,6 +4274,23 @@ set_gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch,
gdbarch->iterate_over_objfiles_in_search_order = iterate_over_objfiles_in_search_order;
}
+struct ravenscar_arch_ops *
+gdbarch_ravenscar_ops (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of ravenscar_ops, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_ravenscar_ops called\n");
+ return gdbarch->ravenscar_ops;
+}
+
+void
+set_gdbarch_ravenscar_ops (struct gdbarch *gdbarch,
+ struct ravenscar_arch_ops * ravenscar_ops)
+{
+ gdbarch->ravenscar_ops = ravenscar_ops;
+}
+
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 3d9dc79..f0bef30 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -57,6 +57,7 @@ struct syscall;
struct agent_expr;
struct axs_value;
struct stap_parse_info;
+struct ravenscar_arch_ops;
/* The architecture associated with the inferior through the
connection to the target.
@@ -1211,6 +1212,11 @@ typedef void (gdbarch_iterate_over_objfiles_in_search_order_ftype) (struct gdbar
extern void gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile);
extern void set_gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order);
+/* Ravenscar arch-dependent ops. */
+
+extern struct ravenscar_arch_ops * gdbarch_ravenscar_ops (struct gdbarch *gdbarch);
+extern void set_gdbarch_ravenscar_ops (struct gdbarch *gdbarch, struct ravenscar_arch_ops * ravenscar_ops);
+
/* Definition for an unknown syscall, used basically in error-cases. */
#define UNKNOWN_SYSCALL (-1)
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 8a56106..1f53144 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -958,6 +958,8 @@ M:void:info_proc:char *args, enum info_proc_what what:args, what
# inspected when the symbol search was requested.
m:void:iterate_over_objfiles_in_search_order:iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile:cb, cb_data, current_objfile:0:default_iterate_over_objfiles_in_search_order::0
+# Ravenscar arch-dependent ops.
+v:struct ravenscar_arch_ops *:ravenscar_ops:::NULL:NULL::0:host_address_to_string (gdbarch->ravenscar_ops)
EOF
}
@@ -1075,6 +1077,7 @@ struct syscall;
struct agent_expr;
struct axs_value;
struct stap_parse_info;
+struct ravenscar_arch_ops;
/* The architecture associated with the inferior through the
connection to the target.
diff --git a/gdb/ravenscar-sparc-thread.c b/gdb/ravenscar-sparc-thread.c
index 2a27a63..93888c8 100644
--- a/gdb/ravenscar-sparc-thread.c
+++ b/gdb/ravenscar-sparc-thread.c
@@ -23,8 +23,7 @@
#include "sparc-tdep.h"
#include "inferior.h"
#include "ravenscar-thread.h"
-
-static struct ravenscar_arch_ops ravenscar_sparc_ops;
+#include "ravenscar-sparc-thread.h"
static void ravenscar_sparc_fetch_registers (struct regcache *regcache,
int regnum);
@@ -179,14 +178,17 @@ ravenscar_sparc_store_registers (struct regcache *regcache, int regnum)
buf_size);
}
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern void _initialize_ravenscar_sparc (void);
+static struct ravenscar_arch_ops ravenscar_sparc_ops =
+{
+ ravenscar_sparc_fetch_registers,
+ ravenscar_sparc_store_registers,
+ ravenscar_sparc_prepare_to_store
+};
+
+/* Register ravenscar_arch_ops in GDBARCH. */
void
-_initialize_ravenscar_sparc (void)
+register_sparc_ravenscar_ops (struct gdbarch *gdbarch)
{
- ravenscar_sparc_ops.to_fetch_registers = ravenscar_sparc_fetch_registers;
- ravenscar_sparc_ops.to_store_registers = ravenscar_sparc_store_registers;
- ravenscar_sparc_ops.to_prepare_to_store = ravenscar_sparc_prepare_to_store;
- ravenscar_register_arch_ops (&ravenscar_sparc_ops);
+ set_gdbarch_ravenscar_ops (gdbarch, &ravenscar_sparc_ops);
}
diff --git a/gdb/ravenscar-sparc-thread.h b/gdb/ravenscar-sparc-thread.h
new file mode 100644
index 0000000..fc86e69
--- /dev/null
+++ b/gdb/ravenscar-sparc-thread.h
@@ -0,0 +1,26 @@
+/* Ravenscar SPARC target support.
+
+ Copyright 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef RAVENSCAR_SPARC_THREAD_H
+#define RAVENSCAR_SPARC_THREAD_H
+
+struct gdbarch;
+
+extern void register_sparc_ravenscar_ops (struct gdbarch *gdbarch);
+#endif
diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index ddbaea6..2d32cd8 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -54,9 +54,6 @@ static const char ravenscar_runtime_initializer[] =
static struct observer *update_target_observer = NULL;
-/* Architecture-specific hooks. */
-static struct ravenscar_arch_ops* current_arch_ops;
-
static void ravenscar_find_new_threads (struct target_ops *ops);
static ptid_t ravenscar_running_thread (void);
static char *ravenscar_extra_thread_info (struct thread_info *tp);
@@ -276,7 +273,13 @@ ravenscar_fetch_registers (struct target_ops *ops,
|| ptid_equal (inferior_ptid, ravenscar_running_thread ()))
beneath->to_fetch_registers (beneath, regcache, regnum);
else
- current_arch_ops->to_fetch_registers (regcache, regnum);
+ {
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct ravenscar_arch_ops *arch_ops
+ = gdbarch_ravenscar_ops (gdbarch);
+
+ arch_ops->to_fetch_registers (regcache, regnum);
+ }
}
static void
@@ -290,7 +293,13 @@ ravenscar_store_registers (struct target_ops *ops,
|| ptid_equal (inferior_ptid, ravenscar_running_thread ()))
beneath->to_store_registers (beneath, regcache, regnum);
else
- current_arch_ops->to_store_registers (regcache, regnum);
+ {
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct ravenscar_arch_ops *arch_ops
+ = gdbarch_ravenscar_ops (gdbarch);
+
+ arch_ops->to_store_registers (regcache, regnum);
+ }
}
static void
@@ -303,7 +312,13 @@ ravenscar_prepare_to_store (struct regcache *regcache)
|| ptid_equal (inferior_ptid, ravenscar_running_thread ()))
beneath->to_prepare_to_store (regcache);
else
- current_arch_ops->to_prepare_to_store (regcache);
+ {
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct ravenscar_arch_ops *arch_ops
+ = gdbarch_ravenscar_ops (gdbarch);
+
+ arch_ops->to_prepare_to_store (regcache);
+ }
}
static void
@@ -321,7 +336,11 @@ ravenscar_mourn_inferior (struct target_ops *ops)
static void
ravenscar_inferior_created (struct target_ops *target, int from_tty)
{
- if (!ravenscar_task_support || !has_ravenscar_runtime ())
+ struct ravenscar_arch_ops *ops;
+
+ if (!ravenscar_task_support
+ || gdbarch_ravenscar_ops (current_inferior ()->gdbarch) == NULL
+ || !has_ravenscar_runtime ())
return;
base_magic_null_ptid = inferior_ptid;
@@ -329,17 +348,6 @@ ravenscar_inferior_created (struct target_ops *target, int from_tty)
push_target (&ravenscar_ops);
}
-void
-ravenscar_register_arch_ops (struct ravenscar_arch_ops *ops)
-{
- /* FIXME: To be clean, we would need to handle a list of
- architectures, just like in remote-wtx-hw.c. However, for now the
- only Ravenscar run-time for bare board that is implemented in
- GNAT is for only one architecture: erc32-elf. So no need to care about
- that for now... */
- current_arch_ops = ops;
-}
-
static ptid_t
ravenscar_get_ada_task_ptid (long lwp, long thread)
{
diff --git a/gdb/ravenscar-thread.h b/gdb/ravenscar-thread.h
index 5eeab38..9edc9d7 100644
--- a/gdb/ravenscar-thread.h
+++ b/gdb/ravenscar-thread.h
@@ -29,13 +29,4 @@ struct ravenscar_arch_ops
void (*to_prepare_to_store) (struct regcache *);
};
-/* Register implementations for target ops to_store_registers,
- to_prepare_to_store and to_fetch_registers when the inferior_ptid
- is different from the running thread. In that case, the registers
- are saved in a architecture-specific location. */
-/* FIXME: only one architecture can be registered for now. See
- implementation. */
-
-extern void ravenscar_register_arch_ops (struct ravenscar_arch_ops *ops);
-
#endif /* !defined (RAVENSCAR_THREAD_H) */
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 3164ed3..7dfa7da 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -39,6 +39,7 @@
#include "gdb_string.h"
#include "sparc-tdep.h"
+#include "ravenscar-sparc-thread.h"
struct regset;
@@ -1683,6 +1684,8 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_regset_from_core_section (gdbarch,
sparc_regset_from_core_section);
+ register_sparc_ravenscar_ops (gdbarch);
+
return gdbarch;
}
\f
--
1.7.10.4
^ permalink raw reply [flat|nested] 8+ messages in thread