Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Nov 2020 16:47:24 +0000 (UTC)
From:      Leandro Lupori <luporl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r367392 - head/lib/libpmcstat
Message-ID:  <202011051647.0A5GlOrA097877@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luporl
Date: Thu Nov  5 16:47:23 2020
New Revision: 367392
URL: https://svnweb.freebsd.org/changeset/base/367392

Log:
  pmcstat: fix PPC kernel symbol resolution
  
  PowerPC kernel is of DYN type and it has a base address where it is
  initially loaded, before being relocated. As the start address passed to
  pmcstat_image_link() is where the kernel was relocated to, but the symbols
  always use the original base address, we need to subtract it to get the
  correct offset.
  
  Reviewed by:	jhibbits
  Sponsored by:	Eldorado Research Institute (eldorado.org.br)
  Differential Revision:	https://reviews.freebsd.org/D26114

Modified:
  head/lib/libpmcstat/libpmcstat_image.c

Modified: head/lib/libpmcstat/libpmcstat_image.c
==============================================================================
--- head/lib/libpmcstat/libpmcstat_image.c	Thu Nov  5 16:41:28 2020	(r367391)
+++ head/lib/libpmcstat/libpmcstat_image.c	Thu Nov  5 16:47:23 2020	(r367392)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/endian.h>
 #include <sys/pmc.h>
+#include <sys/sysctl.h>
 #include <sys/imgact_aout.h>
 #include <sys/imgact_elf.h>
 
@@ -176,12 +177,36 @@ pmcstat_image_link(struct pmcstat_process *pp, struct 
 {
 	struct pmcstat_pcmap *pcm, *pcmnew;
 	uintfptr_t offset;
+#ifdef __powerpc__
+	unsigned long kernbase;
+	size_t kernbase_len;
+#endif
 
 	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN &&
 	    image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE);
 
 	if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL)
 		err(EX_OSERR, "ERROR: Cannot create a map entry");
+
+	/*
+	 * PowerPC kernel is of DYN type and it has a base address
+	 * where it is initially loaded, before being relocated.
+	 * As the address in 'start' is where the kernel was relocated to,
+	 * but the symbols always use the original base address, we need to
+	 * subtract it to get the correct offset.
+	 */
+#ifdef __powerpc__
+	if (pp->pp_pid == -1) {
+		kernbase = 0;
+		kernbase_len = sizeof(kernbase);
+		if (sysctlbyname("kern.base_address", &kernbase, &kernbase_len,
+		    NULL, 0) == -1)
+			warnx(
+			    "WARNING: Could not retrieve kernel base address");
+		else
+			start -= kernbase;
+	}
+#endif
 
 	/*
 	 * Adjust the map entry to only cover the text portion



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