gdb/riscv: Add read_description method for riscv_linux_nat_target

Adds riscv_linux_nat_target::read_description method to find a
suitable target description for the native linux target we are running
on.

Currently this will supply a suitably sized set of x-registers, and
will probe the kernel to see if the f-registers are readable.  If they
are readable then we currently assume that the f-registers are the
same size as the x-registers as I don't know of a good way to probe
the f-register length.  This will obviously need fixing in future.

As of Linux 4.19 there is no ptrace support for reading the
f-registers, this should appear in 4.20, so right now we only return
target descriptions without f-registers.

gdb/ChangeLog:

	* riscv-linux-nat.c: Add 'inferior.h' and 'target-descriptions.h'
	header files.
	(riscv_linux_nat_target::read_description): New method.
This commit is contained in:
Andrew Burgess 2018-11-28 22:42:27 +00:00
parent 634494366c
commit 92528b6772
2 changed files with 44 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2018-11-30 Andrew Burgess <andrew.burgess@embecosm.com>
* riscv-linux-nat.c: Add 'inferior.h' and 'target-descriptions.h'
header files.
(riscv_linux_nat_target::read_description): New method.
2018-11-30 Andrew Burgess <andrew.burgess@embecosm.com>
* arch/riscv.h (riscv_gdbarch_features::hash): New method.

View File

@ -21,6 +21,8 @@
#include "gregset.h"
#include "linux-nat.h"
#include "riscv-tdep.h"
#include "inferior.h"
#include "target-descriptions.h"
#include "elf/common.h"
@ -34,6 +36,9 @@ public:
/* Add our register access methods. */
void fetch_registers (struct regcache *regcache, int regnum) override;
void store_registers (struct regcache *regcache, int regnum) override;
/* Read suitable target description. */
const struct target_desc *read_description () override;
};
static riscv_linux_nat_target the_riscv_linux_nat_target;
@ -155,6 +160,39 @@ fill_fpregset (const struct regcache *regcache, prfpregset_t *fpregs,
regcache->raw_collect (RISCV_CSR_FCSR_REGNUM, &fpregs->__d.__fcsr);
}
/* Return a target description for the current target. */
const struct target_desc *
riscv_linux_nat_target::read_description ()
{
struct riscv_gdbarch_features features;
struct iovec iov;
elf_fpregset_t regs;
int tid;
/* Figuring out xlen is easy. */
features.xlen = sizeof (elf_greg_t);
tid = inferior_ptid.lwp ();
iov.iov_base = &regs;
iov.iov_len = sizeof (regs);
/* Can we fetch the f-registers? */
if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET,
(PTRACE_TYPE_ARG3) &iov) == -1)
features.flen = 0; /* No f-registers. */
else
{
/* TODO: We need a way to figure out the actual length of the
f-registers. We could have 64-bit x-registers, with 32-bit
f-registers. For now, just assumed xlen and flen match. */
features.flen = features.xlen;
}
return riscv_create_target_description (features);
}
/* Fetch REGNUM (or all registers if REGNUM == -1) from the target
into REGCACHE using PTRACE_GETREGSET. */