From b5bca4807d0ab467f047e5110bcf1c37d6ec9d07 Mon Sep 17 00:00:00 2001 From: marcel Date: Thu, 15 Sep 2005 05:32:11 +0000 Subject: [PATCH] Mega-MFC: o Manpage type fix: kgdb/kgdb.1: 1.8 o Unwind across trapframes: kgdb/kgdb.h: 1.3 kgdb/kthr.c: 1.3 kgdb/main.c: 1.9 kgdb/trgt.c: 1.4 kgdb/trgt_alpha.c: 1.3, 1.4 kgdb/trgt_amd64.c: 1.3, 1.4, 1.5 kgdb/trgt_i386.c: 1.3, 1.4, 1.5 kgdb/trgt_ia64.c: 1.3, 1.4 kgdb/trgt_sparc64.c: 1.4, 1.5, 1.6 libgdb/Makefile: 1.10 libgdb/frame-unwind.diff: 1.1 Approved by: re (scottl) --- gnu/usr.bin/gdb/kgdb/kgdb.1 | 2 +- gnu/usr.bin/gdb/kgdb/kgdb.h | 4 +- gnu/usr.bin/gdb/kgdb/kthr.c | 1 + gnu/usr.bin/gdb/kgdb/main.c | 5 + gnu/usr.bin/gdb/kgdb/trgt.c | 1 + gnu/usr.bin/gdb/kgdb/trgt_alpha.c | 134 ++++++++++++-- gnu/usr.bin/gdb/kgdb/trgt_amd64.c | 140 ++++++++++++-- gnu/usr.bin/gdb/kgdb/trgt_i386.c | 128 ++++++++++++- gnu/usr.bin/gdb/kgdb/trgt_ia64.c | 277 +++++++++++++++++++++++----- gnu/usr.bin/gdb/kgdb/trgt_sparc64.c | 126 ++++++++++++- gnu/usr.bin/gdb/libgdb/Makefile | 8 +- 11 files changed, 741 insertions(+), 85 deletions(-) diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.1 b/gnu/usr.bin/gdb/kgdb/kgdb.1 index 46895251b1f..ba47fce3330 100644 --- a/gnu/usr.bin/gdb/kgdb/kgdb.1 +++ b/gnu/usr.bin/gdb/kgdb/kgdb.1 @@ -108,7 +108,7 @@ used. If no core dump file has been specified through either of the options or the last command-line argument, .Pa /dev/mem -will be opened to allow debugging the currenlty running +will be opened to allow debugging the currently running kernel. .Sh FILES .Bl -tag -width ".Pa /var/crash" diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.h b/gnu/usr.bin/gdb/kgdb/kgdb.h index b545ebbe03c..2103acdb082 100644 --- a/gnu/usr.bin/gdb/kgdb/kgdb.h +++ b/gnu/usr.bin/gdb/kgdb/kgdb.h @@ -29,7 +29,7 @@ #ifndef _KGDB_H_ #define _KGDB_H_ -struct thread_info; +struct thread_info; extern kvm_t *kvm; extern int verbose; @@ -50,6 +50,8 @@ void kgdb_target(void); void kgdb_trgt_fetch_registers(int); void kgdb_trgt_store_registers(int); +frame_unwind_sniffer_ftype kgdb_trgt_trapframe_sniffer; + struct kthr *kgdb_thr_first(void); struct kthr *kgdb_thr_init(void); struct kthr *kgdb_thr_lookup_tid(int); diff --git a/gnu/usr.bin/gdb/kgdb/kthr.c b/gnu/usr.bin/gdb/kgdb/kthr.c index 505605d406a..9156f1a9cf6 100644 --- a/gnu/usr.bin/gdb/kgdb/kthr.c +++ b/gnu/usr.bin/gdb/kgdb/kthr.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include "kgdb.h" diff --git a/gnu/usr.bin/gdb/kgdb/main.c b/gnu/usr.bin/gdb/kgdb/main.c index 856cb93411f..b07328cf8e9 100644 --- a/gnu/usr.bin/gdb/kgdb/main.c +++ b/gnu/usr.bin/gdb/kgdb/main.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); /* libgdb stuff. */ #include #include +#include #include #include #include @@ -61,6 +62,8 @@ __FBSDID("$FreeBSD$"); extern void (*init_ui_hook)(char *); +extern frame_unwind_sniffer_ftype *kgdb_sniffer_kluge; + extern void symbol_file_add_main (char *args, int from_tty); #include "kgdb.h" @@ -478,5 +481,7 @@ main(int argc, char *argv[]) init_ui_hook = kgdb_init; + kgdb_sniffer_kluge = kgdb_trgt_trapframe_sniffer; + return (gdb_main(&args)); } diff --git a/gnu/usr.bin/gdb/kgdb/trgt.c b/gnu/usr.bin/gdb/kgdb/trgt.c index 493c45063b0..d365f6b1732 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt.c +++ b/gnu/usr.bin/gdb/kgdb/trgt.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include diff --git a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c index 336970ba2be..99e8df64d67 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c @@ -29,17 +29,20 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include -#include "kgdb.h" - #include #include #include #include #include +#include +#include + +#include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) @@ -54,16 +57,17 @@ kgdb_trgt_fetch_registers(int regno __unused) warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } - - supply_register(9, (char *)&pcb.pcb_context[0]); - supply_register(10, (char *)&pcb.pcb_context[1]); - supply_register(11, (char *)&pcb.pcb_context[2]); - supply_register(12, (char *)&pcb.pcb_context[3]); - supply_register(13, (char *)&pcb.pcb_context[4]); - supply_register(14, (char *)&pcb.pcb_context[5]); - supply_register(15, (char *)&pcb.pcb_context[6]); - supply_register(30, (char *)&pcb.pcb_hw.apcb_ksp); - supply_register(64, (char *)&pcb.pcb_context[7]); +#define ALPHA_S0_REGNUM ALPHA_T7_REGNUM + 1 + supply_register(ALPHA_S0_REGNUM + 0, (char *)&pcb.pcb_context[0]); + supply_register(ALPHA_S0_REGNUM + 1, (char *)&pcb.pcb_context[1]); + supply_register(ALPHA_S0_REGNUM + 2, (char *)&pcb.pcb_context[2]); + supply_register(ALPHA_S0_REGNUM + 3, (char *)&pcb.pcb_context[3]); + supply_register(ALPHA_S0_REGNUM + 4, (char *)&pcb.pcb_context[4]); + supply_register(ALPHA_S0_REGNUM + 5, (char *)&pcb.pcb_context[5]); + supply_register(ALPHA_S0_REGNUM + 6, (char *)&pcb.pcb_context[6]); + supply_register(ALPHA_SP_REGNUM, (char *)&pcb.pcb_hw.apcb_ksp); + supply_register(ALPHA_PC_REGNUM, (char *)&pcb.pcb_context[7]); +#undef ALPHA_S0_REGNUM } void @@ -71,3 +75,109 @@ kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } + +struct kgdb_frame_cache { + CORE_ADDR pc; + CORE_ADDR sp; +}; + +static int kgdb_trgt_frame_offset[65] = { + FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2, + FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6, + FRAME_T7, FRAME_S0, FRAME_S1, FRAME_S2, + FRAME_S3, FRAME_S4, FRAME_S5, FRAME_S6, + FRAME_A0, FRAME_A1, FRAME_A2, FRAME_A3, + FRAME_A4, FRAME_A5, FRAME_T8, FRAME_T9, + FRAME_T10, FRAME_T11, FRAME_RA, FRAME_T12, + -1, FRAME_GP, FRAME_SP, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + FRAME_PC +}; + +static struct kgdb_frame_cache * +kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) +{ + char buf[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + + cache = *this_cache; + if (cache == NULL) { + cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); + *this_cache = cache; + cache->pc = frame_func_unwind(next_frame); + frame_unwind_register(next_frame, SP_REGNUM, buf); + cache->sp = extract_unsigned_integer(buf, + register_size(current_gdbarch, SP_REGNUM)); + } + return (cache); +} + +static void +kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct kgdb_frame_cache *cache; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + *this_id = frame_id_build(cache->sp, cache->pc); +} + +static void +kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, + void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *valuep) +{ + char dummy_valuep[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + int ofs, regsz; + + regsz = register_size(current_gdbarch, regnum); + + if (valuep == NULL) + valuep = dummy_valuep; + memset(valuep, 0, regsz); + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; + + ofs = (regnum >= 0 && regnum <= ALPHA_PC_REGNUM) + ? kgdb_trgt_frame_offset[regnum] : -1; + if (ofs == -1) + return; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + *addrp = cache->sp + ofs * 8; + *lvalp = lval_memory; + target_read_memory(*addrp, valuep, regsz); +} + +static const struct frame_unwind kgdb_trgt_trapframe_unwind = { + UNKNOWN_FRAME, + &kgdb_trgt_trapframe_this_id, + &kgdb_trgt_trapframe_prev_register +}; + +const struct frame_unwind * +kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) +{ + char *pname; + CORE_ADDR pc; + + pc = frame_func_unwind(next_frame); + pname = NULL; + find_pc_partial_function(pc, &pname, NULL, NULL); + if (pname == NULL) + return (NULL); + if (strncmp(pname, "Xent", 4) == 0) + return (&kgdb_trgt_trapframe_unwind); + /* printf("%s: %lx =%s\n", __func__, pc, pname); */ + return (NULL); +} diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c index 0907d0db567..c3596fb14bd 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c @@ -29,17 +29,20 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include -#include "kgdb.h" - #include #include #include #include #include +#include +#include + +#include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) @@ -55,15 +58,15 @@ kgdb_trgt_fetch_registers(int regno __unused) memset(&pcb, 0, sizeof(pcb)); } - supply_register(1, (char *)&pcb.pcb_rbx); - supply_register(6, (char *)&pcb.pcb_rbp); - supply_register(7, (char *)&pcb.pcb_rsp); - supply_register(12, (char *)&pcb.pcb_r12); - supply_register(13, (char *)&pcb.pcb_r13); - supply_register(14, (char *)&pcb.pcb_r14); - supply_register(15, (char *)&pcb.pcb_r15); - supply_register(16, (char *)&pcb.pcb_rip); - supply_register(17, (char *)&pcb.pcb_rflags); + supply_register(AMD64_RBX_REGNUM, (char *)&pcb.pcb_rbx); + supply_register(AMD64_RBP_REGNUM, (char *)&pcb.pcb_rbp); + supply_register(AMD64_RSP_REGNUM, (char *)&pcb.pcb_rsp); + supply_register(AMD64_R8_REGNUM + 4, (char *)&pcb.pcb_r12); + supply_register(AMD64_R8_REGNUM + 5, (char *)&pcb.pcb_r13); + supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); + supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); + supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); + supply_register(AMD64_EFLAGS_REGNUM, (char *)&pcb.pcb_rflags); } void @@ -71,3 +74,118 @@ kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } + +struct kgdb_frame_cache { + CORE_ADDR pc; + CORE_ADDR sp; +}; + +static int kgdb_trgt_frame_offset[20] = { + offsetof(struct trapframe, tf_rax), + offsetof(struct trapframe, tf_rbx), + offsetof(struct trapframe, tf_rcx), + offsetof(struct trapframe, tf_rdx), + offsetof(struct trapframe, tf_rsi), + offsetof(struct trapframe, tf_rdi), + offsetof(struct trapframe, tf_rbp), + offsetof(struct trapframe, tf_rsp), + offsetof(struct trapframe, tf_r8), + offsetof(struct trapframe, tf_r9), + offsetof(struct trapframe, tf_r10), + offsetof(struct trapframe, tf_r11), + offsetof(struct trapframe, tf_r12), + offsetof(struct trapframe, tf_r13), + offsetof(struct trapframe, tf_r14), + offsetof(struct trapframe, tf_r15), + offsetof(struct trapframe, tf_rip), + offsetof(struct trapframe, tf_rflags), + offsetof(struct trapframe, tf_cs), + offsetof(struct trapframe, tf_ss) +}; + +static struct kgdb_frame_cache * +kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) +{ + char buf[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + + cache = *this_cache; + if (cache == NULL) { + cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); + *this_cache = cache; + cache->pc = frame_func_unwind(next_frame); + frame_unwind_register(next_frame, SP_REGNUM, buf); + cache->sp = extract_unsigned_integer(buf, + register_size(current_gdbarch, SP_REGNUM)); + } + return (cache); +} + +static void +kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct kgdb_frame_cache *cache; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + *this_id = frame_id_build(cache->sp, cache->pc); +} + +static void +kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, + void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *valuep) +{ + char dummy_valuep[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + int ofs, regsz; + + regsz = register_size(current_gdbarch, regnum); + + if (valuep == NULL) + valuep = dummy_valuep; + memset(valuep, 0, regsz); + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + if (cache->pc == 0) + return; + + ofs = (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_EFLAGS_REGNUM + 2) + ? kgdb_trgt_frame_offset[regnum] : -1; + if (ofs == -1) + return; + + *addrp = cache->sp + ofs; + *lvalp = lval_memory; + target_read_memory(*addrp, valuep, regsz); +} + +static const struct frame_unwind kgdb_trgt_trapframe_unwind = { + UNKNOWN_FRAME, + &kgdb_trgt_trapframe_this_id, + &kgdb_trgt_trapframe_prev_register +}; + +const struct frame_unwind * +kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) +{ + char *pname; + CORE_ADDR pc; + + pc = frame_pc_unwind(next_frame); + if (pc == 0) + return (&kgdb_trgt_trapframe_unwind); + pname = NULL; + find_pc_partial_function(pc, &pname, NULL, NULL); + if (pname == NULL) + return (NULL); + if (strcmp(pname, "calltrap") == 0 || + (pname[0] == 'X' && pname[1] != '_')) + return (&kgdb_trgt_trapframe_unwind); + /* printf("%s: %lx =%s\n", __func__, pc, pname); */ + return (NULL); +} diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c index 96dad51fcff..73d02d4a3e2 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c @@ -29,17 +29,20 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include -#include "kgdb.h" - #include #include #include #include #include +#include +#include + +#include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) @@ -54,12 +57,12 @@ kgdb_trgt_fetch_registers(int regno __unused) warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } - supply_register(3, (char *)&pcb.pcb_ebx); - supply_register(4, (char *)&pcb.pcb_esp); - supply_register(5, (char *)&pcb.pcb_ebp); - supply_register(6, (char *)&pcb.pcb_esi); - supply_register(7, (char *)&pcb.pcb_edi); - supply_register(8, (char *)&pcb.pcb_eip); + supply_register(I386_EBX_REGNUM, (char *)&pcb.pcb_ebx); + supply_register(I386_ESP_REGNUM, (char *)&pcb.pcb_esp); + supply_register(I386_EBP_REGNUM, (char *)&pcb.pcb_ebp); + supply_register(I386_ESI_REGNUM, (char *)&pcb.pcb_esi); + supply_register(I386_EDI_REGNUM, (char *)&pcb.pcb_edi); + supply_register(I386_EIP_REGNUM, (char *)&pcb.pcb_eip); } void @@ -67,3 +70,112 @@ kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } + +struct kgdb_frame_cache { + int intrframe; + CORE_ADDR pc; + CORE_ADDR sp; +}; + +static int kgdb_trgt_frame_offset[15] = { + offsetof(struct trapframe, tf_eax), + offsetof(struct trapframe, tf_ecx), + offsetof(struct trapframe, tf_edx), + offsetof(struct trapframe, tf_ebx), + offsetof(struct trapframe, tf_esp), + offsetof(struct trapframe, tf_ebp), + offsetof(struct trapframe, tf_esi), + offsetof(struct trapframe, tf_edi), + offsetof(struct trapframe, tf_eip), + offsetof(struct trapframe, tf_eflags), + offsetof(struct trapframe, tf_cs), + offsetof(struct trapframe, tf_ss), + offsetof(struct trapframe, tf_ds), + offsetof(struct trapframe, tf_es), + offsetof(struct trapframe, tf_fs) +}; + +static struct kgdb_frame_cache * +kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) +{ + char buf[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + char *pname; + + cache = *this_cache; + if (cache == NULL) { + cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); + *this_cache = cache; + cache->pc = frame_func_unwind(next_frame); + find_pc_partial_function(cache->pc, &pname, NULL, NULL); + cache->intrframe = (pname[0] == 'X') ? 1 : 0; + frame_unwind_register(next_frame, SP_REGNUM, buf); + cache->sp = extract_unsigned_integer(buf, + register_size(current_gdbarch, SP_REGNUM)); + } + return (cache); +} + +static void +kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct kgdb_frame_cache *cache; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + *this_id = frame_id_build(cache->sp, cache->pc); +} + +static void +kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, + void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *valuep) +{ + char dummy_valuep[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + int ofs, regsz; + + regsz = register_size(current_gdbarch, regnum); + + if (valuep == NULL) + valuep = dummy_valuep; + memset(valuep, 0, regsz); + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; + + ofs = (regnum >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM) + ? kgdb_trgt_frame_offset[regnum] : -1; + if (ofs == -1) + return; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + *addrp = cache->sp + ofs + (cache->intrframe ? 4 : 0); + *lvalp = lval_memory; + target_read_memory(*addrp, valuep, regsz); +} + +static const struct frame_unwind kgdb_trgt_trapframe_unwind = { + UNKNOWN_FRAME, + &kgdb_trgt_trapframe_this_id, + &kgdb_trgt_trapframe_prev_register +}; + +const struct frame_unwind * +kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) +{ + char *pname; + CORE_ADDR pc; + + pc = frame_pc_unwind(next_frame); + pname = NULL; + find_pc_partial_function(pc, &pname, NULL, NULL); + if (pname == NULL) + return (NULL); + if (strcmp(pname, "calltrap") == 0 || + (pname[0] == 'X' && pname[1] != '_')) + return (&kgdb_trgt_trapframe_unwind); + /* printf("%s: %llx =%s\n", __func__, pc, pname); */ + return (NULL); +} diff --git a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c index bfceba4cd0a..86d83fc2fce 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c @@ -28,19 +28,22 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include #include #include -#include "kgdb.h" - #include #include #include #include #include +#include +#include + +#include "kgdb.h" void kgdb_trgt_fetch_registers(int regno __unused) @@ -58,72 +61,72 @@ kgdb_trgt_fetch_registers(int regno __unused) } /* Registers 0-127: general registers. */ - supply_register(1, (char *)&pcb.pcb_special.gp); - supply_register(4, (char *)&pcb.pcb_preserved.gr4); - supply_register(5, (char *)&pcb.pcb_preserved.gr5); - supply_register(6, (char *)&pcb.pcb_preserved.gr6); - supply_register(7, (char *)&pcb.pcb_preserved.gr7); - supply_register(12, (char *)&pcb.pcb_special.sp); - supply_register(13, (char *)&pcb.pcb_special.tp); + supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp); + supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4); + supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5); + supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6); + supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7); + supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp); + supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp); /* Registers 128-255: floating-point registers. */ - supply_register(130, (char *)&pcb.pcb_preserved_fp.fr2); - supply_register(131, (char *)&pcb.pcb_preserved_fp.fr3); - supply_register(132, (char *)&pcb.pcb_preserved_fp.fr4); - supply_register(133, (char *)&pcb.pcb_preserved_fp.fr5); - supply_register(144, (char *)&pcb.pcb_preserved_fp.fr16); - supply_register(145, (char *)&pcb.pcb_preserved_fp.fr17); - supply_register(146, (char *)&pcb.pcb_preserved_fp.fr18); - supply_register(147, (char *)&pcb.pcb_preserved_fp.fr19); - supply_register(148, (char *)&pcb.pcb_preserved_fp.fr20); - supply_register(149, (char *)&pcb.pcb_preserved_fp.fr21); - supply_register(150, (char *)&pcb.pcb_preserved_fp.fr22); - supply_register(151, (char *)&pcb.pcb_preserved_fp.fr23); - supply_register(152, (char *)&pcb.pcb_preserved_fp.fr24); - supply_register(153, (char *)&pcb.pcb_preserved_fp.fr25); - supply_register(154, (char *)&pcb.pcb_preserved_fp.fr26); - supply_register(155, (char *)&pcb.pcb_preserved_fp.fr27); - supply_register(156, (char *)&pcb.pcb_preserved_fp.fr28); - supply_register(157, (char *)&pcb.pcb_preserved_fp.fr29); - supply_register(158, (char *)&pcb.pcb_preserved_fp.fr30); - supply_register(159, (char *)&pcb.pcb_preserved_fp.fr31); + supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2); + supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3); + supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4); + supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5); + supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16); + supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17); + supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18); + supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19); + supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20); + supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21); + supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22); + supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23); + supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24); + supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25); + supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26); + supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27); + supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28); + supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29); + supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30); + supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31); /* Registers 320-327: branch registers. */ if (pcb.pcb_special.__spare == ~0UL) - supply_register(320, (char *)&pcb.pcb_special.rp); - supply_register(321, (char *)&pcb.pcb_preserved.br1); - supply_register(322, (char *)&pcb.pcb_preserved.br2); - supply_register(323, (char *)&pcb.pcb_preserved.br3); - supply_register(324, (char *)&pcb.pcb_preserved.br4); - supply_register(325, (char *)&pcb.pcb_preserved.br5); + supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp); + supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1); + supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2); + supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3); + supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4); + supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5); /* Registers 328-333: misc. other registers. */ - supply_register(330, (char *)&pcb.pcb_special.pr); + supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr); if (pcb.pcb_special.__spare == ~0UL) { r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3); - supply_register(331, (char *)&r); - supply_register(333, (char *)&pcb.pcb_special.cfm); + supply_register(IA64_IP_REGNUM, (char *)&r); + supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm); } else { - supply_register(331, (char *)&pcb.pcb_special.rp); - supply_register(333, (char *)&pcb.pcb_special.pfs); + supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp); + supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs); } /* Registers 334-461: application registers. */ - supply_register(350, (char *)&pcb.pcb_special.rsc); + supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc); r = pcb.pcb_special.bspstore; if (pcb.pcb_special.__spare == ~0UL) r += pcb.pcb_special.ndirty; else r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) - IA64_CFM_SOL(pcb.pcb_special.pfs)); - supply_register(351, (char *)&r); /* bsp */ - supply_register(352, (char *)&r); /* bspstore */ - supply_register(353, (char *)&pcb.pcb_special.rnat); - supply_register(370, (char *)&pcb.pcb_special.unat); - supply_register(374, (char *)&pcb.pcb_special.fpsr); + supply_register(IA64_BSP_REGNUM, (char *)&r); + supply_register(IA64_BSPSTORE_REGNUM, (char *)&r); + supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat); + supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat); + supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr); if (pcb.pcb_special.__spare == ~0UL) - supply_register(398, (char *)&pcb.pcb_special.pfs); - supply_register(399, (char *)&pcb.pcb_preserved.lc); + supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs); + supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc); } void @@ -131,3 +134,181 @@ kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } + +struct kgdb_frame_cache { + CORE_ADDR bsp; + CORE_ADDR ip; + CORE_ADDR sp; + CORE_ADDR saved_bsp; +}; + +#define SPECIAL(x) offsetof(struct trapframe, tf_special) \ + + offsetof(struct _special, x) +#define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \ + + offsetof(struct _caller_saved, x) +#define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \ + + offsetof(struct _caller_saved_fp, x) + +static int kgdb_trgt_frame_ofs_gr[32] = { + -1, /* gr0 */ + SPECIAL(gp), + SCRATCH(gr2), SCRATCH(gr3), + -1, -1, -1, -1, /* gr4-gr7 */ + SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11), + SPECIAL(sp), SPECIAL(tp), + SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17), + SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21), + SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25), + SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29), + SCRATCH(gr30), SCRATCH(gr31) +}; + +static int kgdb_trgt_frame_ofs_fr[32] = { + -1, /* fr0: constant 0.0 */ + -1, /* fr1: constant 1.0 */ + -1, -1, -1, -1, /* fr2-fr5 */ + SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9), + SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13), + SCRATCH_FP(fr14), SCRATCH_FP(fr15) +}; + +static int kgdb_trgt_frame_ofs_br[8] = { + SPECIAL(rp), + -1, -1, -1, -1, -1, /* br1-br5 */ + SCRATCH(br6), SCRATCH(br7) +}; + +static int kgdb_trgt_frame_ofs_ar[49] = { + /* ar0-ar15 */ + SPECIAL(rsc), + -1, /* ar.bsp */ + SPECIAL(bspstore), SPECIAL(rnat), + -1, -1, -1, -1, -1, /* ar20-ar24 */ + SCRATCH(csd), SCRATCH(ssd), + -1, -1, -1, -1, -1, /* ar27-ar31 */ + SCRATCH(ccv), + -1, -1, -1, /* ar33-ar35 */ + SPECIAL(unat), + -1, -1, -1, /* ar37-ar39 */ + SPECIAL(fpsr), + -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */ + SPECIAL(pfs) +}; + +static struct kgdb_frame_cache * +kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) +{ + char buf[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + + cache = *this_cache; + if (cache == NULL) { + cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); + *this_cache = cache; + frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf); + cache->bsp = extract_unsigned_integer(buf, + register_size(current_gdbarch, IA64_BSP_REGNUM)); + cache->ip = frame_func_unwind(next_frame); + frame_unwind_register(next_frame, SP_REGNUM, buf); + cache->sp = extract_unsigned_integer(buf, + register_size(current_gdbarch, SP_REGNUM)); + } + return (cache); +} + +static void +kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct kgdb_frame_cache *cache; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp); +} + +static void +kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, + void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *valuep) +{ + char buf[MAX_REGISTER_SIZE]; + char dummy_valuep[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + CORE_ADDR bsp; + int ofs, regsz; + + regsz = register_size(current_gdbarch, regnum); + + if (valuep == NULL) + valuep = dummy_valuep; + memset(valuep, 0, regsz); + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + + if (regnum == IA64_BSP_REGNUM) { + if (cache->saved_bsp == 0) { + target_read_memory(cache->sp + 16 + SPECIAL(bspstore), + buf, regsz); + bsp = extract_unsigned_integer(buf, regsz); + target_read_memory(cache->sp + 16 + SPECIAL(ndirty), + buf, regsz); + bsp += extract_unsigned_integer(buf, regsz); + cache->saved_bsp = bsp; + } + store_unsigned_integer(valuep, regsz, cache->saved_bsp); + return; + } + if (regnum == IA64_PR_REGNUM) + ofs = SPECIAL(pr); + else if (regnum == IA64_IP_REGNUM) + ofs = SPECIAL(iip); + else if (regnum == IA64_PSR_REGNUM) + ofs = SPECIAL(psr); + else if (regnum == IA64_CFM_REGNUM) + ofs = SPECIAL(cfm); + else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM) + ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM]; + else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM) + ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM]; + else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM) + ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM]; + else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM) + ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM]; + else + ofs = -1; + if (ofs == -1) + return; + + *addrp = cache->sp + 16 + ofs; + *lvalp = lval_memory; + target_read_memory(*addrp, valuep, regsz); +} + +static const struct frame_unwind kgdb_trgt_trapframe_unwind = { + UNKNOWN_FRAME, + &kgdb_trgt_trapframe_this_id, + &kgdb_trgt_trapframe_prev_register +}; + +const struct frame_unwind * +kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) +{ + char *pname; + CORE_ADDR ip; + + ip = frame_func_unwind(next_frame); + pname = NULL; + find_pc_partial_function(ip, &pname, NULL, NULL); + if (pname == NULL) + return (NULL); + if (strncmp(pname, "ivt_", 4) == 0) + return (&kgdb_trgt_trapframe_unwind); + /* printf("%s: %lx =%s\n", __func__, ip, pname); */ + return (NULL); +} diff --git a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c index 17d8135fa7a..3e4a41abb4d 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c @@ -30,20 +30,22 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include -#include "kgdb.h" - #include #include #include #include #include +#include #include #include +#include "kgdb.h" + void kgdb_trgt_fetch_registers(int regno __unused) { @@ -70,3 +72,123 @@ kgdb_trgt_store_registers(int regno __unused) { fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); } + +struct kgdb_frame_cache { + CORE_ADDR pc; + CORE_ADDR sp; + CORE_ADDR fp; +}; + +static struct kgdb_frame_cache * +kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) +{ + char buf[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + + cache = *this_cache; + if (cache == NULL) { + cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); + *this_cache = cache; + cache->pc = frame_func_unwind(next_frame); + frame_unwind_register(next_frame, SPARC_SP_REGNUM, buf); + cache->sp = extract_unsigned_integer(buf, + register_size(current_gdbarch, SPARC_SP_REGNUM)); + frame_unwind_register(next_frame, SPARC_FP_REGNUM, buf); + cache->fp = extract_unsigned_integer(buf, + register_size(current_gdbarch, SPARC_FP_REGNUM)); + cache->fp += BIAS - sizeof(struct trapframe); + } + return (cache); +} + +static void +kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) +{ + struct kgdb_frame_cache *cache; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + *this_id = frame_id_build(cache->sp, cache->pc); +} + +static void +kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, + void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, + CORE_ADDR *addrp, int *realnump, void *valuep) +{ + char dummy_valuep[MAX_REGISTER_SIZE]; + struct kgdb_frame_cache *cache; + int ofs, regsz; + + regsz = register_size(current_gdbarch, regnum); + + if (valuep == NULL) + valuep = dummy_valuep; + memset(valuep, 0, regsz); + *optimizedp = 0; + *addrp = 0; + *lvalp = not_lval; + *realnump = -1; + + cache = kgdb_trgt_frame_cache(next_frame, this_cache); + + switch (regnum) { + case SPARC_SP_REGNUM: + ofs = offsetof(struct trapframe, tf_sp); + break; + case SPARC64_PC_REGNUM: + ofs = offsetof(struct trapframe, tf_tpc); + break; + case SPARC64_NPC_REGNUM: + ofs = offsetof(struct trapframe, tf_tnpc); + break; + case SPARC_O0_REGNUM: + case SPARC_O1_REGNUM: + case SPARC_O2_REGNUM: + case SPARC_O3_REGNUM: + case SPARC_O4_REGNUM: + case SPARC_O5_REGNUM: + case SPARC_O7_REGNUM: + ofs = offsetof(struct trapframe, tf_out) + + (regnum - SPARC_O0_REGNUM) * 8; + break; + default: + if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) { + ofs = (regnum - SPARC_L0_REGNUM) * 8; + *addrp = cache->sp + BIAS + ofs; + *lvalp = lval_memory; + target_read_memory(*addrp, valuep, regsz); + } + return; + } + + *addrp = cache->fp + ofs; + *lvalp = lval_memory; + target_read_memory(*addrp, valuep, regsz); +} + +static const struct frame_unwind kgdb_trgt_trapframe_unwind = { + UNKNOWN_FRAME, + &kgdb_trgt_trapframe_this_id, + &kgdb_trgt_trapframe_prev_register +}; + +const struct frame_unwind * +kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) +{ + char *pname; + CORE_ADDR pc; + + pc = frame_func_unwind(next_frame); + pname = NULL; + find_pc_partial_function(pc, &pname, NULL, NULL); + if (pname == NULL) + return (NULL); + if (strcmp(pname, "tl0_intr") == 0 || + strcmp(pname, "tl0_trap") == 0 || + strcmp(pname, "tl1_intr") == 0 || + strcmp(pname, "tl1_trap") == 0) + return (&kgdb_trgt_trapframe_unwind); + /* printf("%s: %lx =%s\n", __func__, pc, pname); */ + return (NULL); +} diff --git a/gnu/usr.bin/gdb/libgdb/Makefile b/gnu/usr.bin/gdb/libgdb/Makefile index e9e92cac200..29598d3c230 100644 --- a/gnu/usr.bin/gdb/libgdb/Makefile +++ b/gnu/usr.bin/gdb/libgdb/Makefile @@ -18,7 +18,7 @@ SRCS= annotate.c arch-utils.c auxv.c ax-gdb.c ax-general.c \ elfread.c environ.c eval.c event-loop.c event-top.c exec.c \ expprint.c \ f-exp.y f-lang.c f-typeprint.c f-valprint.c findvar.c \ - ${_fork_child} frame-base.c frame-unwind.c frame.c \ + ${_fork_child} frame-base.c frame-unwind-kluge.c frame.c \ gdb-events.c gdbarch.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \ hpacc-abi.c \ inf-loop.c infcall.c infcmd.c inflow.c ${_infptrace} infrun.c \ @@ -59,7 +59,11 @@ _infptrace= infptrace.c _inftarg= inftarg.c .endif -GENSRCS= version.c +GENSRCS= frame-unwind-kluge.c version.c + +frame-unwind-kluge.c: frame-unwind.diff + cat ${CNTRB_GDB}/gdb/frame-unwind.c > ${.TARGET} + patch ${.TARGET} ${.ALLSRC} version.c: echo '#include "version.h"' > ${.TARGET} -- 2.45.0