Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Feb 2020 01:01:03 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r527234 - in head/devel/gdb: . files files/kgdb
Message-ID:  <202002270101.01R113w8066348@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb (src,doc committer)
Date: Thu Feb 27 01:01:03 2020
New Revision: 527234
URL: https://svnweb.freebsd.org/changeset/ports/527234

Log:
  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

Modified:
  head/devel/gdb/Makefile
  head/devel/gdb/files/extrapatch-kgdb
  head/devel/gdb/files/kgdb/arm-fbsd-kern.c
  head/devel/gdb/files/kgdb/fbsd-kvm.c
  head/devel/gdb/files/kgdb/ppcfbsd-kern.c

Modified: head/devel/gdb/Makefile
==============================================================================
--- head/devel/gdb/Makefile	Thu Feb 27 00:53:47 2020	(r527233)
+++ head/devel/gdb/Makefile	Thu Feb 27 01:01:03 2020	(r527234)
@@ -3,6 +3,7 @@
 
 PORTNAME=	gdb
 PORTVERSION=	8.3.1
+PORTREVISION=	1
 CATEGORIES=	devel
 MASTER_SITES=	GNU
 

Modified: head/devel/gdb/files/extrapatch-kgdb
==============================================================================
--- head/devel/gdb/files/extrapatch-kgdb	Thu Feb 27 00:53:47 2020	(r527233)
+++ head/devel/gdb/files/extrapatch-kgdb	Thu Feb 27 01:01:03 2020	(r527234)
@@ -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. ])])
  
@@ -295,6 +358,11 @@ index 1527585839..37e8ce54b0 100644
 +AC_SEARCH_LIBS(kvm_open2, kvm,
 +  [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
  

Modified: head/devel/gdb/files/kgdb/arm-fbsd-kern.c
==============================================================================
--- head/devel/gdb/files/kgdb/arm-fbsd-kern.c	Thu Feb 27 00:53:47 2020	(r527233)
+++ head/devel/gdb/files/kgdb/arm-fbsd-kern.c	Thu Feb 27 01:01:03 2020	(r527234)
@@ -79,7 +79,7 @@ arm_fbsd_trapframe_cache (struct frame_info *this_fram
   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;
 

Modified: head/devel/gdb/files/kgdb/fbsd-kvm.c
==============================================================================
--- head/devel/gdb/files/kgdb/fbsd-kvm.c	Thu Feb 27 00:53:47 2020	(r527233)
+++ head/devel/gdb/files/kgdb/fbsd-kvm.c	Thu Feb 27 01:01:03 2020	(r527234)
@@ -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

Modified: head/devel/gdb/files/kgdb/ppcfbsd-kern.c
==============================================================================
--- head/devel/gdb/files/kgdb/ppcfbsd-kern.c	Thu Feb 27 00:53:47 2020	(r527233)
+++ head/devel/gdb/files/kgdb/ppcfbsd-kern.c	Thu Feb 27 01:01:03 2020	(r527234)
@@ -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;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+  gdb_byte buf[24 * tdep->wordsize];
+  int i;
 
-	tdep = gdbarch_tdep (regcache->arch ());
+  /* 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;
 
-	if (target_read_memory(pcb_addr, (gdb_byte *)&pcb, sizeof(pcb)) != 0)
-		memset(&pcb, 0, sizeof(pcb));
+  /* r12 - r31 */
+  for (i = 0; i < 20; i++)
+    regcache->raw_supply (tdep->ppc_gp0_regnum + 12 + i,
+			  buf + tdep->wordsize * i);
 
-	/*
-	 * 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,
+			buf + tdep->wordsize * PCB_OFF_SP);
 
-	/* 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);
+  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, (char *)&pcb.pcb_lr);
-	regcache->raw_supply(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr);
+  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
 
   /* 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 *
 
   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, stru
 
   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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002270101.01R113w8066348>