diff --git a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c index f2d8f6511ff7..0c3a5d445e61 100644 --- a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c +++ b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c @@ -41,7 +41,12 @@ #include "kgdb.h" -static const struct regcache_map_entry aarch64_fbsd_pcbmap[] = +#define AARCH64_FBSD13_PCBSZ (8 * 33) +#define AARCH64_FBSD14_PCBSZ (8 * 13) +#define AARCH64_MAX_PCBSZ AARCH64_FBSD13_PCBSZ + +/* Pre-14.0 */ +static const struct regcache_map_entry aarch64_fbsd13_pcbmap[] = { { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ { 1, AARCH64_PC_REGNUM, 8 }, @@ -50,22 +55,73 @@ static const struct regcache_map_entry aarch64_fbsd_pcbmap[] = { 0 } }; -static const struct regset aarch64_fbsd_pcbregset = +/* 14.0+ */ +static const struct regcache_map_entry aarch64_fbsd14_pcbmap[] = + { + { 12, AARCH64_X0_REGNUM + 19, 8 }, /* x19 ... x30 */ + { 1, AARCH64_SP_REGNUM, 8 }, + { 0 } + }; + +static const struct regset aarch64_fbsd13_pcbregset = { - aarch64_fbsd_pcbmap, + aarch64_fbsd13_pcbmap, + regcache_supply_regset, regcache_collect_regset + }; + +static const struct regset aarch64_fbsd14_pcbregset = + { + aarch64_fbsd14_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void aarch64_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { - gdb_byte buf[8 * 33]; + gdb_byte buf[AARCH64_MAX_PCBSZ]; + const struct regset *pcbregset; + size_t pcbsz; + + if (kgdb_osreldate > 1400082) { + pcbregset = &aarch64_fbsd14_pcbregset; + pcbsz = AARCH64_FBSD14_PCBSZ; + } else { + pcbregset = &aarch64_fbsd13_pcbregset; + pcbsz = sizeof(buf); + } + + if (target_read_memory (pcb_addr, buf, pcbsz) == 0) { + regcache_supply_regset (pcbregset, regcache, -1, buf, + pcbsz); - if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) - regcache_supply_regset (&aarch64_fbsd_pcbregset, regcache, -1, buf, - sizeof (buf)); + /* PC = pcb_x[PCB_LR] */ + if (pcbregset == &aarch64_fbsd14_pcbregset) + regcache->raw_supply (AARCH64_PC_REGNUM, buf + (8 * 11)); + } } +static const struct regcache_map_entry aarch64_fbsd13_tfmap[] = + { + { 1, AARCH64_SP_REGNUM, 0 }, + { 1, AARCH64_LR_REGNUM, 0 }, + { 1, AARCH64_PC_REGNUM, 0 }, + { 1, AARCH64_CPSR_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 4 }, + { 30, AARCH64_X0_REGNUM, 0 }, + { 0 }, + }; + +static const struct regcache_map_entry aarch64_fbsd14_tfmap[] = + { + { 1, AARCH64_SP_REGNUM, 0 }, + { 1, AARCH64_LR_REGNUM, 0 }, + { 1, AARCH64_PC_REGNUM, 0 }, + { 1, AARCH64_CPSR_REGNUM, 0 }, + { 2, REGCACHE_MAP_SKIP, 0 }, + { 30, AARCH64_X0_REGNUM, 0 }, + { 0 }, + }; + static struct trad_frame_cache * aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) { @@ -74,6 +130,8 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) struct trad_frame_cache *cache; CORE_ADDR func, pc, sp; const char *name; + const struct regcache_map_entry *tfmap; + size_t tfsz; int i; if (*this_cache != NULL) @@ -82,6 +140,17 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; + if (kgdb_osreldate > 1400082) + { + tfmap = &aarch64_fbsd14_tfmap[0]; + tfsz = 8 * 36; + } + else + { + tfmap = &aarch64_fbsd13_tfmap[0]; + tfsz = 8 * 34; + } + func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM); @@ -94,12 +163,8 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) sp = get_frame_register_unsigned (this_frame, AARCH64_X0_REGNUM + 2); } - trad_frame_set_reg_addr (cache, AARCH64_SP_REGNUM, sp); - trad_frame_set_reg_addr (cache, AARCH64_LR_REGNUM, sp + 8); - trad_frame_set_reg_addr (cache, AARCH64_PC_REGNUM, sp + 16); - trad_frame_set_reg_addr (cache, AARCH64_CPSR_REGNUM, sp + 24); - for (i = 0; i < 30; i++) - trad_frame_set_reg_addr (cache, AARCH64_X0_REGNUM + i, sp + 32 + i * 8); + /* XXX */ + trad_frame_set_reg_regmap (cache, tfmap, sp, tfsz); /* Read $PC from trap frame. */ pc = read_memory_unsigned_integer (sp + 16, 8, byte_order); @@ -112,7 +177,7 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) else { /* Construct the frame ID using the function start. */ - trad_frame_set_id (cache, frame_id_build (sp + 8 * 34, func)); + trad_frame_set_id (cache, frame_id_build (sp + tfsz, func)); } return cache; diff --git a/devel/gdb/files/kgdb/fbsd-kvm.c b/devel/gdb/files/kgdb/fbsd-kvm.c index bd4f71fecddd..12c1b3cb324c 100644 --- a/devel/gdb/files/kgdb/fbsd-kvm.c +++ b/devel/gdb/files/kgdb/fbsd-kvm.c @@ -102,6 +102,7 @@ fbsd_vmcore_set_cpu_pcb_addr (struct gdbarch *gdbarch, static CORE_ADDR kernstart; static kvm_t *kvm; int kgdb_quiet; +int kgdb_osreldate; static ptid_t fbsd_vmcore_ptid(int tid) @@ -279,7 +280,6 @@ fbsd_kvm_target_open (const char *args, int from_tty) kvm_t *nkvm; const char *kernel; std::string filename; - int osreldate; bool writeable; if (ops == NULL || ops->supply_pcb == NULL || ops->cpu_pcb_addr == NULL) @@ -364,7 +364,7 @@ fbsd_kvm_target_open (const char *args, int from_tty) try { CORE_ADDR osreldatesym = kgdb_lookup("osreldate"); - osreldate = read_memory_unsigned_integer(osreldatesym, 4, + kgdb_osreldate = read_memory_unsigned_integer(osreldatesym, 4, gdbarch_byte_order (target_gdbarch ())); } catch (const gdb_exception_error &e) { error ("Failed to look up osreldate"); @@ -375,7 +375,7 @@ fbsd_kvm_target_open (const char *args, int from_tty) * fail if they aren't present. */ stoppcbs = kgdb_lookup("stoppcbs"); - if (osreldate > 1400088) { + if (kgdb_osreldate > 1400088) { /* stoppcbs is now a pointer rather than an array. */ try { stoppcbs = read_memory_typed_address(stoppcbs, diff --git a/devel/gdb/files/kgdb/kgdb.h b/devel/gdb/files/kgdb/kgdb.h index 772e33d4daf5..0ccb6f91f874 100644 --- a/devel/gdb/files/kgdb/kgdb.h +++ b/devel/gdb/files/kgdb/kgdb.h @@ -40,6 +40,7 @@ struct kthr { extern struct kthr *curkthr; extern struct target_so_ops kld_so_ops; extern int kgdb_quiet; +extern int kgdb_osreldate; CORE_ADDR kgdb_trgt_stop_pcb(u_int);