mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-14 05:08:32 +08:00
espcoredump: Add support to RISC-V core dump
Add support to core dump files generated by ESP32C3 boards. GDB is now aware on how to parse the core dump regs structure. Port from: esp-binutils-develop
This commit is contained in:
committed by
Alexey Lapshin
parent
67f1fadfa3
commit
945f35c160
@@ -56,6 +56,8 @@
|
|||||||
#include "arch/riscv.h"
|
#include "arch/riscv.h"
|
||||||
#include "riscv-ravenscar-thread.h"
|
#include "riscv-ravenscar-thread.h"
|
||||||
#include "gdbsupport/gdb-safe-ctype.h"
|
#include "gdbsupport/gdb-safe-ctype.h"
|
||||||
|
#include "regset.h"
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
/* The stack must be 16-byte aligned. */
|
/* The stack must be 16-byte aligned. */
|
||||||
#define SP_ALIGNMENT 16
|
#define SP_ALIGNMENT 16
|
||||||
@@ -4169,6 +4171,74 @@ static const char *const stap_register_indirection_suffixes[] =
|
|||||||
")", nullptr
|
")", nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Supply register REGNUM from the buffer specified by GREGS and LEN
|
||||||
|
in the general-purpose register set REGSET to register cache
|
||||||
|
REGCACHE. If REGNUM is -1 do this for all registers in REGSET. */
|
||||||
|
static void
|
||||||
|
riscv_supply_gregset (const struct regset *regset,
|
||||||
|
struct regcache *rc,
|
||||||
|
int regnum,
|
||||||
|
const void *gregs,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
riscv_regs *regs = (riscv_regs *) gregs;
|
||||||
|
int i = 0;
|
||||||
|
static const uint32_t zero = 0;
|
||||||
|
|
||||||
|
assert (regnum >= -1 && regnum <= RISCV_LAST_REGNUM);
|
||||||
|
|
||||||
|
if (regnum == RISCV_PC_REGNUM) {
|
||||||
|
/* For some reasons, GDB doesn't work properly if RISCV_PC_REGNUM is
|
||||||
|
* assigned to 0. While debugging, PC will be set correctly when the core
|
||||||
|
* file is loaded but "info registers" will show that $pc is 0.
|
||||||
|
* Thus, let's keep this macro as it is and manage it manually.
|
||||||
|
*/
|
||||||
|
rc->raw_supply (RISCV_PC_REGNUM, ®s->pc);
|
||||||
|
} else if (regnum == RISCV_ZERO_REGNUM) {
|
||||||
|
rc->raw_supply (RISCV_ZERO_REGNUM, &zero);
|
||||||
|
} else if (regnum > RISCV_ZERO_REGNUM && regnum < RISCV_GP_REGS_COUNT) {
|
||||||
|
/* Dump a single GP register */
|
||||||
|
rc->raw_supply (regnum, ®s->as_array[regnum]);
|
||||||
|
} else if (regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_REGNUM) {
|
||||||
|
/* Dump any unsupported register. It will be set to 0. */
|
||||||
|
rc->raw_supply (regnum, &zero);
|
||||||
|
} else {
|
||||||
|
/* Dump all registers.
|
||||||
|
* In regs structure, the first 32-bit value is the PC and not the zero reg
|
||||||
|
* as expected by the gdbarch for RISC-V, so we have to manually fill both
|
||||||
|
* $pc and $zero register */
|
||||||
|
rc->raw_supply (RISCV_ZERO_REGNUM, &zero);
|
||||||
|
|
||||||
|
for (i = 1; i < RISCV_GP_REGS_COUNT; ++i)
|
||||||
|
rc->raw_supply (i, ®s->as_array[i]);
|
||||||
|
|
||||||
|
rc->raw_supply (RISCV_PC_REGNUM, ®s->pc);
|
||||||
|
|
||||||
|
for (i = RISCV_FIRST_FP_REGNUM; i <= RISCV_LAST_REGNUM; i++)
|
||||||
|
rc->raw_supply (i, &zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RISC-V register set. */
|
||||||
|
static struct regset riscv_gregset =
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
riscv_supply_gregset,
|
||||||
|
NULL,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Iterate over supported core file register note sections. */
|
||||||
|
static void
|
||||||
|
riscv_iterate_over_regset_sections (struct gdbarch *gdbarch,
|
||||||
|
iterate_over_regset_sections_cb *cb,
|
||||||
|
void *cb_data,
|
||||||
|
const struct regcache *regcache)
|
||||||
|
{
|
||||||
|
cb (".reg", sizeof(riscv_regs), sizeof(riscv_regs), &riscv_gregset,
|
||||||
|
NULL, cb_data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the current architecture based on INFO. If possible,
|
/* Initialize the current architecture based on INFO. If possible,
|
||||||
re-use an architecture from ARCHES, which is a list of
|
re-use an architecture from ARCHES, which is a list of
|
||||||
architectures already created during this debugging session.
|
architectures already created during this debugging session.
|
||||||
@@ -4399,6 +4469,10 @@ riscv_gdbarch_init (struct gdbarch_info info,
|
|||||||
for (const auto &alias : pending_aliases)
|
for (const auto &alias : pending_aliases)
|
||||||
alias.create (gdbarch);
|
alias.create (gdbarch);
|
||||||
|
|
||||||
|
/* Provide a function to iterate over the regset section in a core dump file. */
|
||||||
|
set_gdbarch_iterate_over_regset_sections
|
||||||
|
(gdbarch, riscv_iterate_over_regset_sections);
|
||||||
|
|
||||||
/* Compile command hooks. */
|
/* Compile command hooks. */
|
||||||
set_gdbarch_gcc_target_options (gdbarch, riscv_gcc_target_options);
|
set_gdbarch_gcc_target_options (gdbarch, riscv_gcc_target_options);
|
||||||
set_gdbarch_gnu_triplet_regexp (gdbarch, riscv_gnu_triplet_regexp);
|
set_gdbarch_gnu_triplet_regexp (gdbarch, riscv_gnu_triplet_regexp);
|
||||||
|
|||||||
@@ -75,6 +75,55 @@ enum
|
|||||||
RISCV_DWARF_LAST_CSR = 8191,
|
RISCV_DWARF_LAST_CSR = 8191,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Union representing the registers of the CPU.
|
||||||
|
* Registers can be adressed with their names thanks to the structure, or as
|
||||||
|
* an array of 32 words.
|
||||||
|
*/
|
||||||
|
#define RISCV_GP_REGS_COUNT 32
|
||||||
|
|
||||||
|
union _riscv_regs {
|
||||||
|
struct {
|
||||||
|
uint32_t pc;
|
||||||
|
uint32_t ra;
|
||||||
|
uint32_t sp;
|
||||||
|
uint32_t gp;
|
||||||
|
uint32_t tp;
|
||||||
|
uint32_t t0;
|
||||||
|
uint32_t t1;
|
||||||
|
uint32_t t2;
|
||||||
|
uint32_t s0;
|
||||||
|
uint32_t s1;
|
||||||
|
uint32_t a0;
|
||||||
|
uint32_t a1;
|
||||||
|
uint32_t a2;
|
||||||
|
uint32_t a3;
|
||||||
|
uint32_t a4;
|
||||||
|
uint32_t a5;
|
||||||
|
uint32_t a6;
|
||||||
|
uint32_t a7;
|
||||||
|
uint32_t s2;
|
||||||
|
uint32_t s3;
|
||||||
|
uint32_t s4;
|
||||||
|
uint32_t s5;
|
||||||
|
uint32_t s6;
|
||||||
|
uint32_t s7;
|
||||||
|
uint32_t s8;
|
||||||
|
uint32_t s9;
|
||||||
|
uint32_t s10;
|
||||||
|
uint32_t s11;
|
||||||
|
uint32_t t3;
|
||||||
|
uint32_t t4;
|
||||||
|
uint32_t t5;
|
||||||
|
uint32_t t6;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t as_array[RISCV_GP_REGS_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union _riscv_regs riscv_regs;
|
||||||
|
|
||||||
|
|
||||||
/* RISC-V specific per-architecture information. */
|
/* RISC-V specific per-architecture information. */
|
||||||
struct riscv_gdbarch_tdep : gdbarch_tdep_base
|
struct riscv_gdbarch_tdep : gdbarch_tdep_base
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user