Changeset View
Changeset View
Standalone View
Standalone View
lib/libpmcstat/libpmcstat_image.c
Show All 26 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/cpuset.h> | #include <sys/cpuset.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/pmc.h> | #include <sys/pmc.h> | ||||
#include <sys/sysctl.h> | |||||
#include <sys/imgact_aout.h> | #include <sys/imgact_aout.h> | ||||
#include <sys/imgact_elf.h> | #include <sys/imgact_elf.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
void | void | ||||
pmcstat_image_link(struct pmcstat_process *pp, struct pmcstat_image *image, | pmcstat_image_link(struct pmcstat_process *pp, struct pmcstat_image *image, | ||||
uintfptr_t start) | uintfptr_t start) | ||||
{ | { | ||||
struct pmcstat_pcmap *pcm, *pcmnew; | struct pmcstat_pcmap *pcm, *pcmnew; | ||||
uintfptr_t offset; | uintfptr_t offset; | ||||
#ifdef __powerpc__ | |||||
jhibbits: This probably affects all powerpc platforms, not just powerpc64. They're all ET_DYN, and I… | |||||
unsigned long kernbase; | |||||
size_t kernbase_len; | |||||
#endif | |||||
assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN && | assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN && | ||||
image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE); | image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE); | ||||
if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL) | if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL) | ||||
err(EX_OSERR, "ERROR: Cannot create a map entry"); | 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__ | |||||
Done Inline ActionsSame down here. jhibbits: Same down here. | |||||
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 | * Adjust the map entry to only cover the text portion | ||||
* of the object. | * of the object. | ||||
*/ | */ | ||||
offset = start - image->pi_vaddr; | offset = start - image->pi_vaddr; | ||||
pcmnew->ppm_lowpc = image->pi_start + offset; | pcmnew->ppm_lowpc = image->pi_start + offset; | ||||
▲ Show 20 Lines • Show All 335 Lines • Show Last 20 Lines |
This probably affects all powerpc platforms, not just powerpc64. They're all ET_DYN, and I know on Book-E 32-bit does get relocated.