git: 5dd228e81c1b - main - devel/gdb: kgdb: fixup aarch64 pcb/trapframe layout
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 05 Sep 2023 18:24:18 UTC
The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/ports/commit/?id=5dd228e81c1bcb49e0a7c5eca3927df24a607a15 commit 5dd228e81c1bcb49e0a7c5eca3927df24a607a15 Author: Kyle Evans <kevans@FreeBSD.org> AuthorDate: 2023-09-05 18:16:59 +0000 Commit: Kyle Evans <kevans@FreeBSD.org> CommitDate: 2023-09-05 18:23:36 +0000 devel/gdb: kgdb: fixup aarch64 pcb/trapframe layout base 1c1f31a5e5 and 2ecbbcc7cab altered the pcb and trapframe layouts in osreldate 1400084. This version of the patch is effectively extracted from work done by @jhb in CheriBSD's gdb fork, then ported forward to work with the gdb 13.x program_space_data equivalent. With this + D39951, I can again get a solid backtrace in recent main. While we're here, remove some special handling for kthreads not yet run, as the stack pointer is in-fact stored in pcb_sp in cpu_copy_thread and cpu_fork. This silences the following exception: Python Exception <class 'gdb.error'>: Register 2 is not available but there's not really any effect on the end result, since the thread hasn't been scheduled yet. Reviewed by: jhb Approved by: jhb (maintainer) MFH: 2023Q3 Differential Revision: https://reviews.freebsd.org/D41684 --- devel/gdb/Makefile | 2 +- devel/gdb/files/kgdb/aarch64-fbsd-kern.c | 123 ++++++++++++++++++++++++++----- 2 files changed, 105 insertions(+), 20 deletions(-) diff --git a/devel/gdb/Makefile b/devel/gdb/Makefile index 378ed1e197ca..921a14b566de 100644 --- a/devel/gdb/Makefile +++ b/devel/gdb/Makefile @@ -1,6 +1,6 @@ PORTNAME= gdb DISTVERSION= 13.1 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= devel MASTER_SITES= GNU diff --git a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c index f2d8f6511ff7..4d813c786b52 100644 --- a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c +++ b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c @@ -41,11 +41,44 @@ #include "kgdb.h" +struct aarch64fbsd_info +{ + int osreldate; +}; + +/* Per-program-space data key. */ +static const registry<program_space>::key<aarch64fbsd_info> aarch64fbsd_pspace_data; + +static void +aarch64fbsd_pspace_data_cleanup (struct program_space *pspace, void *arg) +{ + struct aarch64fbsd_info *info = (struct aarch64fbsd_info *)arg; + + xfree (info); +} + +/* Get the current aarch64_fbsd data. If none is found yet, add it + now. This function always returns a valid object. */ + +static struct aarch64fbsd_info * +get_aarch64fbsd_info (void) +{ + struct aarch64fbsd_info *info; + + info = aarch64fbsd_pspace_data.get (current_program_space); + if (info != nullptr) + return info; + + info = aarch64fbsd_pspace_data.emplace (current_program_space); + + info->osreldate = parse_and_eval_long ("osreldate"); + return info; +} + static const struct regcache_map_entry aarch64_fbsd_pcbmap[] = { - { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ + { 11, AARCH64_X0_REGNUM + 19, 8 }, /* x19 ... x29 */ { 1, AARCH64_PC_REGNUM, 8 }, - { 1, REGCACHE_MAP_SKIP, 8 }, { 1, AARCH64_SP_REGNUM, 8 }, { 0 } }; @@ -56,29 +89,92 @@ static const struct regset aarch64_fbsd_pcbregset = regcache_supply_regset, regcache_collect_regset }; +/* In kernels prior to __FreeBSD_version 1400084, struct pcb used an + alternate layout. */ + +static const struct regcache_map_entry aarch64_fbsd13_pcbmap[] = + { + { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ + { 1, AARCH64_PC_REGNUM, 8 }, + { 1, REGCACHE_MAP_SKIP, 8 }, + { 1, AARCH64_SP_REGNUM, 8 }, + { 0 } + }; + +static const struct regset aarch64_fbsd13_pcbregset = + { + aarch64_fbsd13_pcbmap, + regcache_supply_regset, regcache_collect_regset + }; + static void aarch64_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { + const struct regset *pcbregset; + struct aarch64fbsd_info *info = get_aarch64fbsd_info(); gdb_byte buf[8 * 33]; + if (info->osreldate >= 1400084) + pcbregset = &aarch64_fbsd_pcbregset; + else + pcbregset = &aarch64_fbsd13_pcbregset; + if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) - regcache_supply_regset (&aarch64_fbsd_pcbregset, regcache, -1, buf, + regcache_supply_regset (pcbregset, regcache, -1, buf, sizeof (buf)); } +static const struct regcache_map_entry aarch64_fbsd_trapframe_map[] = + { + { 1, AARCH64_SP_REGNUM, 0 }, + { 1, AARCH64_LR_REGNUM, 0 }, + { 1, AARCH64_PC_REGNUM, 0 }, + { 1, AARCH64_CPSR_REGNUM, 0 }, + { 1, REGCACHE_MAP_SKIP, 8 }, /* esr */ + { 1, REGCACHE_MAP_SKIP, 8 }, /* far */ + { 30, AARCH64_X0_REGNUM, 0 }, /* x0 ... x29 */ + { 0 }, + }; + +/* In kernels prior to __FreeBSD_version 1400084, struct trapframe + used an alternate layout. */ + +static const struct regcache_map_entry aarch64_fbsd13_trapframe_map[] = + { + { 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 }, /* esr */ + { 30, AARCH64_X0_REGNUM, 0 }, /* x0 ... x29 */ + { 0 }, + }; + static struct trad_frame_cache * aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + struct aarch64fbsd_info *info = get_aarch64fbsd_info(); struct trad_frame_cache *cache; CORE_ADDR func, pc, sp; const char *name; - int i; + int i, tf_size; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); + const struct regcache_map_entry *trapframe_map; + + if (info->osreldate >= 1400084) + { + trapframe_map = aarch64_fbsd_trapframe_map; + } + else + { + trapframe_map = aarch64_fbsd13_trapframe_map; + } + cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; @@ -86,23 +182,12 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache) sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); - if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func) - { - /* fork_exit hasn't been called (kthread has never run), so SP - hasn't been initialized yet. The stack pointer is stored in - the X2 in the pcb. */ - 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); + tf_size = regcache_map_entry_size (trapframe_map); + trad_frame_set_reg_regmap (cache, trapframe_map, sp, tf_size); /* Read $PC from trap frame. */ - pc = read_memory_unsigned_integer (sp + 16, 8, byte_order); + pc = read_memory_unsigned_integer (sp + 2 * 8, 8, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { @@ -112,7 +197,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 + tf_size, func)); } return cache;