(Ada) Add ravenscar tasking support on AArch64

This patch adds support for debugging Ravenscar tasks, similar to what
is done for ppc and sparc.

gdb/ChangeLog:

        * aarch64-ravenscar-thread.h, aarch64-ravenscar-thread.c:
        New files.
        * aarch64-tdep.c: #include "aarch64-ravenscar-thread.h".
        (aarch64_gdbarch_init): Add call to register_aarch64_ravenscar_ops.
        * Makefile.in (ALL_64_TARGET_OBS): Add aarch64-ravenscar-thread.o.
        (HFILES_NO_SRCDIR): Add aarch64-ravenscar-thread.h.
        (ALLDEPFILES): Add aarch64-ravenscar-thread.c.
        * configure.tgt (cpu_obs) [aarch64*-*-*]: Add ravenscar-thread.o
        and aarch64-ravenscar-thread.o.
        * NEWS: Add entry documenting Ravenscar tasking support
        on AArch64 ELF.
This commit is contained in:
Joel Brobecker 2018-11-02 12:37:29 -05:00
parent d54cfd762b
commit e8bf1ce461
7 changed files with 266 additions and 1 deletions

View File

@ -1,3 +1,16 @@
2018-12-02 Joel Brobecker <brobecker@adacore.com>
* aarch64-ravenscar-thread.h, aarch64-ravenscar-thread.c: New files.
* aarch64-tdep.c: #include "aarch64-ravenscar-thread.h".
(aarch64_gdbarch_init): Add call to register_aarch64_ravenscar_ops.
* Makefile.in (ALL_64_TARGET_OBS): Add aarch64-ravenscar-thread.o.
(HFILES_NO_SRCDIR): Add aarch64-ravenscar-thread.h.
(ALLDEPFILES): Add aarch64-ravenscar-thread.c.
* configure.tgt (cpu_obs) [aarch64*-*-*]: Add ravenscar-thread.o
and aarch64-ravenscar-thread.o.
* NEWS: Add entry documenting Ravenscar tasking support
on AArch64 ELF.
2018-11-02 Matthew Malcomson <matthew.malcomson@arm.com> 2018-11-02 Matthew Malcomson <matthew.malcomson@arm.com>
* symtab.c (info_functions_command): Initialize quiet flag. * symtab.c (info_functions_command): Initialize quiet flag.

View File

@ -627,6 +627,7 @@ ALL_64_TARGET_OBS = \
aarch64-fbsd-tdep.o \ aarch64-fbsd-tdep.o \
aarch64-linux-tdep.o \ aarch64-linux-tdep.o \
aarch64-newlib-tdep.o \ aarch64-newlib-tdep.o \
aarch64-ravenscar-thread.o \
aarch64-tdep.o \ aarch64-tdep.o \
alpha-bsd-tdep.o \ alpha-bsd-tdep.o \
alpha-linux-tdep.o \ alpha-linux-tdep.o \
@ -1168,6 +1169,7 @@ SFILES = \
# right, it is probably easiest just to list .h files here directly. # right, it is probably easiest just to list .h files here directly.
HFILES_NO_SRCDIR = \ HFILES_NO_SRCDIR = \
aarch64-ravenscar-thread.h \
aarch64-tdep.h \ aarch64-tdep.h \
ada-lang.h \ ada-lang.h \
addrmap.h \ addrmap.h \
@ -2174,6 +2176,7 @@ ALLDEPFILES = \
aarch64-linux-nat.c \ aarch64-linux-nat.c \
aarch64-linux-tdep.c \ aarch64-linux-tdep.c \
aarch64-newlib-tdep.c \ aarch64-newlib-tdep.c \
aarch64-ravenscar-thread.c \
aarch64-tdep.c \ aarch64-tdep.c \
aix-thread.c \ aix-thread.c \
alpha-bsd-nat.c \ alpha-bsd-nat.c \

View File

@ -22,6 +22,11 @@
* DWARF index cache: GDB can now automatically save indices of DWARF * DWARF index cache: GDB can now automatically save indices of DWARF
symbols on disk to speed up further loading of the same binaries. symbols on disk to speed up further loading of the same binaries.
* Ada task switching is now supported on aarch64-elf targets when
debugging a program using the Ravenscar Profile. For more information,
see the "Tasking Support when using the Ravenscar Profile" section
in the GDB user manual.
* GDB in batch mode now exits with status 1 if the last command to be * GDB in batch mode now exits with status 1 if the last command to be
executed failed. executed failed.

View File

@ -0,0 +1,213 @@
/* Ravenscar Aarch64 target support.
Copyright (C) 2017-2018 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 "aarch64-tdep.h"
#include "inferior.h"
#include "ravenscar-thread.h"
#include "aarch64-ravenscar-thread.h"
#define NO_OFFSET -1
/* See aarch64-tdep.h for register numbers. */
static const int aarch64_context_offsets[] =
{
/* X0 - X28 */
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, 0,
8, 16, 24, 32,
40, 48, 56, 64,
72,
/* FP, LR, SP, PC, CPSR */
/* Note that as task switch is synchronous, PC is in fact the LR here */
80, 88, 96, 88,
NO_OFFSET,
/* Q0 - Q31 */
112, 128, 144, 160,
176, 192, 208, 224,
240, 256, 272, 288,
304, 320, 336, 352,
368, 384, 400, 416,
432, 448, 464, 480,
496, 512, 528, 544,
560, 576, 592, 608,
/* FPSR, FPCR */
104, 108,
/* FPU Saved field */
624
};
/* 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 = regcache->arch ();
int buf_size = register_size (gdbarch, regnum);
gdb_byte *buf;
buf = (gdb_byte *) alloca (buf_size);
read_memory (register_addr, buf, buf_size);
regcache->raw_supply (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)
{
/* Check FPU registers */
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
aarch64_ravenscar_generic_fetch_registers
(const struct ravenscar_reg_info *reg_info,
struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = regcache->arch ();
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) inferior_ptid.tid ();
/* 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
aarch64_ravenscar_generic_prepare_to_store (struct regcache *regcache)
{
/* Nothing to do. */
}
/* to_store_registers when inferior_ptid is different from the running
thread. */
static void
aarch64_ravenscar_generic_store_registers
(const struct ravenscar_reg_info *reg_info,
struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = regcache->arch ();
int buf_size = register_size (gdbarch, regnum);
gdb_byte buf[buf_size];
ULONGEST register_address;
if (register_in_thread_descriptor_p (reg_info, regnum))
register_address
= inferior_ptid.tid () + reg_info->context_offsets [regnum];
else
return;
regcache->raw_collect (regnum, buf);
write_memory (register_address,
buf,
buf_size);
}
/* The ravenscar_reg_info for most Aarch64 targets. */
static const struct ravenscar_reg_info aarch64_reg_info =
{
aarch64_context_offsets,
ARRAY_SIZE (aarch64_context_offsets),
};
/* Implement the to_fetch_registers ravenscar_arch_ops method
for most Aarch64 targets. */
static void
aarch64_ravenscar_fetch_registers (struct regcache *regcache, int regnum)
{
aarch64_ravenscar_generic_fetch_registers
(&aarch64_reg_info, regcache, regnum);
}
/* Implement the to_store_registers ravenscar_arch_ops method
for most Aarch64 targets. */
static void
aarch64_ravenscar_store_registers (struct regcache *regcache, int regnum)
{
aarch64_ravenscar_generic_store_registers
(&aarch64_reg_info, regcache, regnum);
}
/* The ravenscar_arch_ops vector for most Aarch64 targets. */
static struct ravenscar_arch_ops aarch64_ravenscar_ops =
{
aarch64_ravenscar_fetch_registers,
aarch64_ravenscar_store_registers,
aarch64_ravenscar_generic_prepare_to_store
};
/* Register aarch64_ravenscar_ops in GDBARCH. */
void
register_aarch64_ravenscar_ops (struct gdbarch *gdbarch)
{
set_gdbarch_ravenscar_ops (gdbarch, &aarch64_ravenscar_ops);
}

View File

@ -0,0 +1,27 @@
/* Ravenscar Aarch64 target support.
Copyright (C) 2017-2018 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 AARCH64_RAVENSCAR_THREAD_H
#define AARCH64_RAVENSCAR_THREAD_H
struct gdbarch;
extern void register_aarch64_ravenscar_ops (struct gdbarch *gdbarch);
#endif

View File

@ -46,6 +46,7 @@
#include "selftest.h" #include "selftest.h"
#include "aarch64-tdep.h" #include "aarch64-tdep.h"
#include "aarch64-ravenscar-thread.h"
#include "elf-bfd.h" #include "elf-bfd.h"
#include "elf/aarch64.h" #include "elf/aarch64.h"
@ -3173,6 +3174,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
value_of_aarch64_user_reg, value_of_aarch64_user_reg,
&aarch64_register_aliases[i].regnum); &aarch64_register_aliases[i].regnum);
register_aarch64_ravenscar_ops (gdbarch);
return gdbarch; return gdbarch;
} }

View File

@ -48,7 +48,8 @@ amd64_tobjs="amd64-tdep.o arch/amd64.o ${x86_tobjs}"
case "${targ}" in case "${targ}" in
aarch64*-*-*) aarch64*-*-*)
cpu_obs="aarch64-tdep.o arch/aarch64-insn.o arch/aarch64.o";; cpu_obs="aarch64-tdep.o arch/aarch64-insn.o arch/aarch64.o \
ravenscar-thread.o aarch64-ravenscar-thread.o";;
alpha*-*-*) alpha*-*-*)
# Target: Alpha # Target: Alpha