Changeset View
Changeset View
Standalone View
Standalone View
head/devel/gdb/files/kgdb/ppcfbsd-kern.c
Show All 39 Lines | |||||
#ifdef __powerpc__ | #ifdef __powerpc__ | ||||
#include <machine/pcb.h> | #include <machine/pcb.h> | ||||
#include <machine/frame.h> | #include <machine/frame.h> | ||||
#endif | #endif | ||||
#include "kgdb.h" | #include "kgdb.h" | ||||
#define PCB_OFF_R12 0 | |||||
#define PCB_OFF_CR 20 | |||||
#define PCB_OFF_SP 21 | |||||
#define PCB_OFF_TOC 22 | |||||
#define PCB_OFF_LR 23 | |||||
#ifdef __powerpc__ | #ifdef __powerpc__ | ||||
_Static_assert(offsetof(struct pcb, pcb_context) | |||||
== PCB_OFF_R12 * sizeof(register_t), "r12 offset"); | |||||
_Static_assert(offsetof(struct pcb, pcb_cr) == PCB_OFF_CR * sizeof(register_t), | |||||
"cr offset"); | |||||
_Static_assert(offsetof(struct pcb, pcb_sp) == PCB_OFF_SP * sizeof(register_t), | |||||
"sp offset"); | |||||
_Static_assert(offsetof(struct pcb, pcb_toc) == PCB_OFF_TOC * sizeof(register_t), | |||||
"toc offset"); | |||||
_Static_assert(offsetof(struct pcb, pcb_lr) == PCB_OFF_LR * sizeof(register_t), | |||||
"lr offset"); | |||||
#endif | |||||
static void | static void | ||||
ppcfbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) | ppcfbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) | ||||
{ | { | ||||
struct pcb pcb; | struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ()); | ||||
struct gdbarch_tdep *tdep; | gdb_byte buf[24 * tdep->wordsize]; | ||||
int i; | int i; | ||||
tdep = gdbarch_tdep (regcache->arch ()); | /* Always give a value for PC in case the PCB isn't readable. */ | ||||
regcache->raw_supply_zeroed (PPC_PC_REGNUM); | |||||
if (target_read_memory (pcb_addr, buf, sizeof buf) != 0) | |||||
return; | |||||
if (target_read_memory(pcb_addr, (gdb_byte *)&pcb, sizeof(pcb)) != 0) | /* r12 - r31 */ | ||||
memset(&pcb, 0, sizeof(pcb)); | for (i = 0; i < 20; i++) | ||||
regcache->raw_supply (tdep->ppc_gp0_regnum + 12 + i, | |||||
buf + tdep->wordsize * i); | |||||
/* | |||||
* r14-r31 are saved in the pcb | |||||
*/ | |||||
for (i = 14; i <= 31; i++) { | |||||
regcache->raw_supply(tdep->ppc_gp0_regnum + i, | |||||
(char *)&pcb.pcb_context[i]); | |||||
} | |||||
/* r1 is saved in the sp field */ | /* r1 is saved in the sp field */ | ||||
regcache->raw_supply(tdep->ppc_gp0_regnum + 1, | regcache->raw_supply (tdep->ppc_gp0_regnum + 1, | ||||
(char *)&pcb.pcb_sp); | buf + tdep->wordsize * PCB_OFF_SP); | ||||
if (tdep->wordsize == 8) | if (tdep->wordsize == 8) | ||||
/* r2 is saved in the toc field */ | /* r2 is saved in the toc field */ | ||||
regcache->raw_supply(tdep->ppc_gp0_regnum + 2, | regcache->raw_supply (tdep->ppc_gp0_regnum + 2, | ||||
(char *)&pcb.pcb_toc); | buf + tdep->wordsize * PCB_OFF_TOC); | ||||
regcache->raw_supply(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); | regcache->raw_supply (tdep->ppc_lr_regnum, buf + tdep->wordsize * PCB_OFF_LR); | ||||
regcache->raw_supply(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); | regcache->raw_supply (PPC_PC_REGNUM, buf + tdep->wordsize * PCB_OFF_LR); | ||||
regcache->raw_supply (tdep->ppc_cr_regnum, buf + tdep->wordsize * PCB_OFF_CR); | |||||
} | } | ||||
#endif | |||||
#define OFF_FIXREG 0 | #define OFF_FIXREG 0 | ||||
#define OFF_LR 32 | #define OFF_LR 32 | ||||
#define OFF_CR 33 | #define OFF_CR 33 | ||||
#define OFF_XER 34 | #define OFF_XER 34 | ||||
#define OFF_CTR 35 | #define OFF_CTR 35 | ||||
#define OFF_SRR0 36 | #define OFF_SRR0 36 | ||||
#define TRAPFRAME_SIZE 42 | #define TRAPFRAME_SIZE 42 | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | ppcfbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) | ||||
trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, base | trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, base | ||||
+ OFF_CTR * tdep->wordsize); | + OFF_CTR * tdep->wordsize); | ||||
/* SRR0? */ | /* SRR0? */ | ||||
trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), base | trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), base | ||||
+ OFF_SRR0 * tdep->wordsize); | + OFF_SRR0 * tdep->wordsize); | ||||
/* Construct the frame ID using the function start. */ | /* Construct the frame ID using the function start. */ | ||||
trad_frame_set_id (cache, frame_id_build (base, get_frame_func (this_frame))); | trad_frame_set_id (cache, frame_id_build (base, get_frame_func (this_frame))); | ||||
return cache; | return cache; | ||||
} | } | ||||
static void | static void | ||||
ppcfbsd_trapframe_this_id (struct frame_info *this_frame, | ppcfbsd_trapframe_this_id (struct frame_info *this_frame, | ||||
void **this_cache, struct frame_id *this_id) | void **this_cache, struct frame_id *this_id) | ||||
{ | { | ||||
struct trad_frame_cache *cache = | struct trad_frame_cache *cache = | ||||
Show All 17 Lines | ppcfbsd_trapframe_sniffer (const struct frame_unwind *self, | ||||
struct frame_info *this_frame, | struct frame_info *this_frame, | ||||
void **this_cache) | void **this_cache) | ||||
{ | { | ||||
CORE_ADDR pc; | CORE_ADDR pc; | ||||
const char *name; | const char *name; | ||||
pc = get_frame_func (this_frame); | pc = get_frame_func (this_frame); | ||||
find_pc_partial_function (pc, &name, NULL, NULL); | find_pc_partial_function (pc, &name, NULL, NULL); | ||||
if (name && (strcmp(name, "asttrapexit") == 0 | if (name && (strcmp(name, "trapagain") == 0 | ||||
|| strcmp(name, "trapexit") == 0)) | || strcmp(name, "trapexit") == 0 | ||||
|| strcmp(name, "dbtrap") == 0)) | |||||
return 1; | return 1; | ||||
return 0; | return 0; | ||||
} | } | ||||
static const struct frame_unwind ppcfbsd_trapframe_unwind = | static const struct frame_unwind ppcfbsd_trapframe_unwind = | ||||
{ | { | ||||
SIGTRAMP_FRAME, | SIGTRAMP_FRAME, | ||||
default_frame_unwind_stop_reason, | default_frame_unwind_stop_reason, | ||||
ppcfbsd_trapframe_this_id, | ppcfbsd_trapframe_this_id, | ||||
ppcfbsd_trapframe_prev_register, | ppcfbsd_trapframe_prev_register, | ||||
NULL, | NULL, | ||||
ppcfbsd_trapframe_sniffer | ppcfbsd_trapframe_sniffer | ||||
}; | }; | ||||
static void | static void | ||||
ppcfbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) | ppcfbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) | ||||
{ | { | ||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); | ||||
frame_unwind_prepend_unwinder(gdbarch, &ppcfbsd_trapframe_unwind); | frame_unwind_prepend_unwinder(gdbarch, &ppcfbsd_trapframe_unwind); | ||||
set_solib_ops(gdbarch, &kld_so_ops); | set_solib_ops(gdbarch, &kld_so_ops); | ||||
#ifdef __powerpc__ | |||||
if (tdep->wordsize == sizeof(register_t)) | |||||
{ | |||||
fbsd_vmcore_set_supply_pcb(gdbarch, ppcfbsd_supply_pcb); | fbsd_vmcore_set_supply_pcb(gdbarch, ppcfbsd_supply_pcb); | ||||
fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); | fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); | ||||
} | |||||
#endif | |||||
/* FreeBSD doesn't support the 128-bit `long double' from the psABI. */ | /* FreeBSD doesn't support the 128-bit `long double' from the psABI. */ | ||||
set_gdbarch_long_double_bit (gdbarch, 64); | set_gdbarch_long_double_bit (gdbarch, 64); | ||||
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); | set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); | ||||
if (tdep->wordsize == 4) | if (tdep->wordsize == 4) | ||||
{ | { | ||||
set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value); | set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value); | ||||
Show All 29 Lines |