aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2020-02-27 09:01:03 +0800
committerjhb <jhb@FreeBSD.org>2020-02-27 09:01:03 +0800
commit35852d66e1cd558966749f4456f4740710a6d0cd (patch)
treed14f7405d1026d0bb5a1084716cf4d9faa5c9dd4
parenteafaab526053a99e22ece3cc0268043c368f8d5d (diff)
downloadfreebsd-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/Makefile1
-rw-r--r--devel/gdb/files/extrapatch-kgdb86
-rw-r--r--devel/gdb/files/kgdb/arm-fbsd-kern.c2
-rw-r--r--devel/gdb/files/kgdb/fbsd-kvm.c22
-rw-r--r--devel/gdb/files/kgdb/ppcfbsd-kern.c88
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);