diff options
author | jhb <jhb@FreeBSD.org> | 2020-02-27 09:01:03 +0800 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2020-02-27 09:01:03 +0800 |
commit | 35852d66e1cd558966749f4456f4740710a6d0cd (patch) | |
tree | d14f7405d1026d0bb5a1084716cf4d9faa5c9dd4 | |
parent | eafaab526053a99e22ece3cc0268043c368f8d5d (diff) | |
download | freebsd-ports-gnome-35852d66e1cd558966749f4456f4740710a6d0cd.tar.gz freebsd-ports-gnome-35852d66e1cd558966749f4456f4740710a6d0cd.tar.zst freebsd-ports-gnome-35852d66e1cd558966749f4456f4740710a6d0cd.zip |
Bring in various kgdb fixes for powerpc.
This merges in several fixes for kgdb on powerpc including fixing
backtraces and cross-debugging support.
Submitted by: luporl
Reviewed by: pizzamig (maintainer)
Differential Revision: https://reviews.freebsd.org/D23844
-rw-r--r-- | devel/gdb/Makefile | 1 | ||||
-rw-r--r-- | devel/gdb/files/extrapatch-kgdb | 86 | ||||
-rw-r--r-- | devel/gdb/files/kgdb/arm-fbsd-kern.c | 2 | ||||
-rw-r--r-- | devel/gdb/files/kgdb/fbsd-kvm.c | 22 | ||||
-rw-r--r-- | devel/gdb/files/kgdb/ppcfbsd-kern.c | 88 |
5 files changed, 151 insertions, 48 deletions
diff --git a/devel/gdb/Makefile b/devel/gdb/Makefile index 8e18462b8f3c..3ba51ee421d6 100644 --- a/devel/gdb/Makefile +++ b/devel/gdb/Makefile @@ -3,6 +3,7 @@ PORTNAME= gdb PORTVERSION= 8.3.1 +PORTREVISION= 1 CATEGORIES= devel MASTER_SITES= GNU diff --git a/devel/gdb/files/extrapatch-kgdb b/devel/gdb/files/extrapatch-kgdb index 5ce135790aba..b759b8c86298 100644 --- a/devel/gdb/files/extrapatch-kgdb +++ b/devel/gdb/files/extrapatch-kgdb @@ -199,13 +199,16 @@ index 5614cc3386..b9acc63c3f 100644 # All the .deps files to include. diff --git gdb/config.in gdb/config.in -index ea907d2b56..ee9146fd4e 100644 +index ea907d2b56..1019e448c5 100644 --- gdb/config.in +++ gdb/config.in -@@ -219,6 +219,9 @@ +@@ -219,6 +219,12 @@ /* Define to 1 if your system has the kinfo_getvmmap function. */ #undef HAVE_KINFO_GETVMMAP ++/* Define to 1 if your system has the kvm_kerndisp function. */ ++#undef HAVE_KVM_DISP ++ +/* Define to 1 if your system has the kvm_open2 function. */ +#undef HAVE_KVM_OPEN2 + @@ -213,17 +216,17 @@ index ea907d2b56..ee9146fd4e 100644 #undef HAVE_LANGINFO_CODESET diff --git gdb/configure gdb/configure -index 854837c50a..1f2da364cf 100755 +index 854837c50a..df64effa90 100755 --- gdb/configure +++ gdb/configure -@@ -8107,6 +8107,66 @@ $as_echo "#define HAVE_KINFO_GETFILE 1" >>confdefs.h +@@ -8107,6 +8107,126 @@ $as_echo "#define HAVE_KINFO_GETFILE 1" >>confdefs.h fi +# kgdb needs kvm_open2 for cross-debugging +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_open2" >&5 +$as_echo_n "checking for library containing kvm_open2... " >&6; } -+if test "${ac_cv_search_kvm_open2+set}" = set; then : ++if ${ac_cv_search_kvm_open2+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS @@ -257,11 +260,11 @@ index 854837c50a..1f2da364cf 100755 +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext -+ if test "${ac_cv_search_kvm_open2+set}" = set; then : ++ if ${ac_cv_search_kvm_open2+:} false; then : + break +fi +done -+if test "${ac_cv_search_kvm_open2+set}" = set; then : ++if ${ac_cv_search_kvm_open2+:} false; then : + +else + ac_cv_search_kvm_open2=no @@ -280,14 +283,74 @@ index 854837c50a..1f2da364cf 100755 +fi + + ++# kgdb needs kvm_kerndisp for relocatable kernels ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kvm_kerndisp" >&5 ++$as_echo_n "checking for library containing kvm_kerndisp... " >&6; } ++if ${ac_cv_search_kvm_kerndisp+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_func_search_save_LIBS=$LIBS ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char kvm_kerndisp (); ++int ++main () ++{ ++return kvm_kerndisp (); ++ ; ++ return 0; ++} ++_ACEOF ++for ac_lib in '' kvm; do ++ if test -z "$ac_lib"; then ++ ac_res="none required" ++ else ++ ac_res=-l$ac_lib ++ LIBS="-l$ac_lib $ac_func_search_save_LIBS" ++ fi ++ if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_search_kvm_kerndisp=$ac_res ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext ++ if ${ac_cv_search_kvm_kerndisp+:} false; then : ++ break ++fi ++done ++if ${ac_cv_search_kvm_kerndisp+:} false; then : ++ ++else ++ ac_cv_search_kvm_kerndisp=no ++fi ++rm conftest.$ac_ext ++LIBS=$ac_func_search_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kvm_kerndisp" >&5 ++$as_echo "$ac_cv_search_kvm_kerndisp" >&6; } ++ac_res=$ac_cv_search_kvm_kerndisp ++if test "$ac_res" != no; then : ++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ++ ++$as_echo "#define HAVE_KVM_DISP 1" >>confdefs.h ++ ++fi ++ ++ if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" diff --git gdb/configure.ac gdb/configure.ac -index 1527585839..37e8ce54b0 100644 +index 1527585839..7ff0361e69 100644 --- gdb/configure.ac +++ gdb/configure.ac -@@ -511,6 +511,11 @@ AC_SEARCH_LIBS(kinfo_getfile, util util-freebsd, +@@ -511,6 +511,16 @@ AC_SEARCH_LIBS(kinfo_getfile, util util-freebsd, [AC_DEFINE(HAVE_KINFO_GETFILE, 1, [Define to 1 if your system has the kinfo_getfile function. ])]) @@ -296,6 +359,11 @@ index 1527585839..37e8ce54b0 100644 + [AC_DEFINE(HAVE_KVM_OPEN2, 1, + [Define to 1 if your system has the kvm_open2 function. ])]) + ++# kgdb needs kvm_kerndisp for relocatable kernels ++AC_SEARCH_LIBS(kvm_kerndisp, kvm, ++ [AC_DEFINE(HAVE_KVM_DISP, 1, ++ [Define to 1 if your system has the kvm_kerndisp function. ])]) ++ AM_ICONV # GDB may fork/exec the iconv program to get the list of supported character diff --git a/devel/gdb/files/kgdb/arm-fbsd-kern.c b/devel/gdb/files/kgdb/arm-fbsd-kern.c index dd68c7a90d84..560aee0bfada 100644 --- a/devel/gdb/files/kgdb/arm-fbsd-kern.c +++ b/devel/gdb/files/kgdb/arm-fbsd-kern.c @@ -79,7 +79,7 @@ arm_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; - CORE_ADDR addr, func, pc, sp; + CORE_ADDR func, pc, sp; const char *name; int i; diff --git a/devel/gdb/files/kgdb/fbsd-kvm.c b/devel/gdb/files/kgdb/fbsd-kvm.c index 507e09bc26ec..4d58c8683847 100644 --- a/devel/gdb/files/kgdb/fbsd-kvm.c +++ b/devel/gdb/files/kgdb/fbsd-kvm.c @@ -331,6 +331,28 @@ fbsd_kvm_target_open (const char *args, int from_tty) discard_cleanups(old_chain); unpush_target(&fbsd_kvm_ops); +#ifdef HAVE_KVM_DISP + /* Relocate kernel objfile if needed. */ + if (symfile_objfile && + (bfd_get_file_flags(symfile_objfile->obfd) & + (EXEC_P | DYNAMIC)) != 0) { + struct section_offsets *new_offsets; + int i; + CORE_ADDR displacement; + + displacement = kvm_kerndisp(nkvm); + if (displacement != 0) { + new_offsets = XALLOCAVEC (struct section_offsets, + symfile_objfile->num_sections); + + for (i = 0; i < symfile_objfile->num_sections; i++) + new_offsets->offsets[i] = displacement; + + objfile_relocate(symfile_objfile, new_offsets); + } + } +#endif + /* * Determine the first address in KVA. Newer kernels export * VM_MAXUSER_ADDRESS and the first kernel address can be diff --git a/devel/gdb/files/kgdb/ppcfbsd-kern.c b/devel/gdb/files/kgdb/ppcfbsd-kern.c index 35d99d3b25d7..43481edf99f8 100644 --- a/devel/gdb/files/kgdb/ppcfbsd-kern.c +++ b/devel/gdb/files/kgdb/ppcfbsd-kern.c @@ -45,39 +45,55 @@ __FBSDID("$FreeBSD$"); #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__ +_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 ppcfbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { - struct pcb pcb; - struct gdbarch_tdep *tdep; - int i; - - tdep = gdbarch_tdep (regcache->arch ()); - - if (target_read_memory(pcb_addr, (gdb_byte *)&pcb, sizeof(pcb)) != 0) - memset(&pcb, 0, sizeof(pcb)); - - /* - * 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 */ - regcache->raw_supply(tdep->ppc_gp0_regnum + 1, - (char *)&pcb.pcb_sp); - if (tdep->wordsize == 8) - /* r2 is saved in the toc field */ - regcache->raw_supply(tdep->ppc_gp0_regnum + 2, - (char *)&pcb.pcb_toc); - - regcache->raw_supply(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); - regcache->raw_supply(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); + struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ()); + gdb_byte buf[24 * tdep->wordsize]; + int i; + + /* 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; + + /* r12 - r31 */ + for (i = 0; i < 20; i++) + regcache->raw_supply (tdep->ppc_gp0_regnum + 12 + i, + buf + tdep->wordsize * i); + + /* r1 is saved in the sp field */ + regcache->raw_supply (tdep->ppc_gp0_regnum + 1, + buf + tdep->wordsize * PCB_OFF_SP); + + if (tdep->wordsize == 8) + /* r2 is saved in the toc field */ + regcache->raw_supply (tdep->ppc_gp0_regnum + 2, + buf + tdep->wordsize * PCB_OFF_TOC); + + regcache->raw_supply (tdep->ppc_lr_regnum, buf + tdep->wordsize * PCB_OFF_LR); + 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_LR 32 @@ -142,7 +158,7 @@ ppcfbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, get_frame_func (this_frame))); - + return cache; } @@ -176,8 +192,9 @@ ppcfbsd_trapframe_sniffer (const struct frame_unwind *self, pc = get_frame_func (this_frame); find_pc_partial_function (pc, &name, NULL, NULL); - if (name && (strcmp(name, "asttrapexit") == 0 - || strcmp(name, "trapexit") == 0)) + if (name && (strcmp(name, "trapagain") == 0 + || strcmp(name, "trapexit") == 0 + || strcmp(name, "dbtrap") == 0)) return 1; return 0; @@ -202,13 +219,8 @@ ppcfbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) 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_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); - } -#endif + fbsd_vmcore_set_supply_pcb(gdbarch, ppcfbsd_supply_pcb); + fbsd_vmcore_set_cpu_pcb_addr(gdbarch, kgdb_trgt_stop_pcb); /* FreeBSD doesn't support the 128-bit `long double' from the psABI. */ set_gdbarch_long_double_bit (gdbarch, 64); |