diff --git a/lib/libpmc/libpmc_json.cc b/lib/libpmc/libpmc_json.cc --- a/lib/libpmc/libpmc_json.cc +++ b/lib/libpmc/libpmc_json.cc @@ -163,9 +163,12 @@ startent = startentry(ev); snprintf(eventbuf, sizeof(eventbuf), "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", " - "\"start\": \"0x%016jx\", \"pathname\": \"%s\"}\n", + "\"base\": \"0x%016jx\", \"dyn\": \"0x%016jx\", " + "\"pathname\": \"%s\"}\n", startent.c_str(), ev->pl_u.pl_x.pl_pmcid, ev->pl_u.pl_x.pl_pid, - (uintmax_t)ev->pl_u.pl_x.pl_entryaddr, ev->pl_u.pl_x.pl_pathname); + (uintmax_t)ev->pl_u.pl_x.pl_baseaddr, + (uintmax_t)ev->pl_u.pl_x.pl_dynaddr, + ev->pl_u.pl_x.pl_pathname); return string(eventbuf); } diff --git a/lib/libpmc/pmclog.h b/lib/libpmc/pmclog.h --- a/lib/libpmc/pmclog.h +++ b/lib/libpmc/pmclog.h @@ -132,7 +132,8 @@ struct pmclog_ev_procexec { pid_t pl_pid; pmc_id_t pl_pmcid; - uintfptr_t pl_entryaddr; + uintptr_t pl_baseaddr; + uintptr_t pl_dynaddr; char pl_pathname[PATH_MAX]; }; diff --git a/lib/libpmc/pmclog.c b/lib/libpmc/pmclog.c --- a/lib/libpmc/pmclog.c +++ b/lib/libpmc/pmclog.c @@ -393,7 +393,8 @@ PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_procexec); PMCLOG_READ32(le,ev->pl_u.pl_x.pl_pid); PMCLOG_READ32(le,ev->pl_u.pl_x.pl_pmcid); - PMCLOG_READADDR(le,ev->pl_u.pl_x.pl_entryaddr); + PMCLOG_READADDR(le,ev->pl_u.pl_x.pl_baseaddr); + PMCLOG_READADDR(le,ev->pl_u.pl_x.pl_dynaddr); PMCLOG_READSTRING(le,ev->pl_u.pl_x.pl_pathname,pathlen); break; case PMCLOG_TYPE_PROCEXIT: diff --git a/lib/libpmcstat/libpmcstat.h b/lib/libpmcstat/libpmcstat.h --- a/lib/libpmcstat/libpmcstat.h +++ b/lib/libpmcstat/libpmcstat.h @@ -336,7 +336,7 @@ int pmcstat_string_lookup_hash(pmcstat_interned_string _is); void pmcstat_process_elf_exec(struct pmcstat_process *_pp, - struct pmcstat_image *_image, uintfptr_t _entryaddr, + struct pmcstat_image *_image, uintptr_t _baseaddr, uintptr_t _dynaddr, struct pmcstat_args *args, struct pmc_plugins *plugins, struct pmcstat_stats *pmcstat_stats); @@ -344,9 +344,9 @@ struct pmcstat_image *_i, uintfptr_t _lpc); void pmcstat_process_aout_exec(struct pmcstat_process *_pp, - struct pmcstat_image *_image, uintfptr_t _entryaddr); + struct pmcstat_image *_image, uintptr_t _baseaddr); void pmcstat_process_exec(struct pmcstat_process *_pp, - pmcstat_interned_string _path, uintfptr_t _entryaddr, + pmcstat_interned_string _path, uintptr_t _baseaddr, uintptr_t _dynaddr, struct pmcstat_args *args, struct pmc_plugins *plugins, struct pmcstat_stats *pmcstat_stats); void pmcstat_image_determine_type(struct pmcstat_image *_image, struct pmcstat_args *args); diff --git a/lib/libpmcstat/libpmcstat_logging.c b/lib/libpmcstat/libpmcstat_logging.c --- a/lib/libpmcstat/libpmcstat_logging.c +++ b/lib/libpmcstat/libpmcstat_logging.c @@ -353,8 +353,8 @@ ev.pl_u.pl_x.pl_pathname); assert(image_path != NULL); pmcstat_process_exec(pp, image_path, - ev.pl_u.pl_x.pl_entryaddr, args, - plugins, pmcstat_stats); + ev.pl_u.pl_x.pl_baseaddr, ev.pl_u.pl_x.pl_dynaddr, + args, plugins, pmcstat_stats); break; case PMCLOG_TYPE_PROCEXIT: diff --git a/lib/libpmcstat/libpmcstat_process.c b/lib/libpmcstat/libpmcstat_process.c --- a/lib/libpmcstat/libpmcstat_process.c +++ b/lib/libpmcstat/libpmcstat_process.c @@ -61,11 +61,11 @@ void pmcstat_process_aout_exec(struct pmcstat_process *pp, - struct pmcstat_image *image, uintfptr_t entryaddr) + struct pmcstat_image *image, uintptr_t baseaddr) { (void) pp; (void) image; - (void) entryaddr; + (void) baseaddr; /* TODO Implement a.out handling */ } @@ -75,18 +75,21 @@ void pmcstat_process_elf_exec(struct pmcstat_process *pp, - struct pmcstat_image *image, uintfptr_t entryaddr, + struct pmcstat_image *image, uintptr_t baseaddr, uintptr_t dynaddr, struct pmcstat_args *args, struct pmc_plugins *plugins, struct pmcstat_stats *pmcstat_stats) { - uintmax_t libstart; struct pmcstat_image *rtldimage; assert(image->pi_type == PMCSTAT_IMAGE_ELF32 || image->pi_type == PMCSTAT_IMAGE_ELF64); - /* Create a map entry for the base executable. */ - pmcstat_image_link(pp, image, image->pi_vaddr); + /* + * The exact address where the executable gets mapped in will vary for + * PIEs. The dynamic address recorded at process exec time corresponds + * to the address where the executable's file object had been mapped to. + */ + pmcstat_image_link(pp, image, image->pi_vaddr + dynaddr); /* * For dynamically linked executables we need to determine @@ -105,16 +108,14 @@ * [ TEXT DATA BSS HEAP -->*RTLD SHLIBS <--STACK] * ^ ^ * 0 VM_MAXUSER_ADDRESS - * * The exact address where the loader gets mapped in * will vary according to the size of the executable * and the limits on the size of the process'es data - * segment at the time of exec(). The entry address + * segment at the time of exec(). The base address * recorded at process exec time corresponds to the - * 'start' address inside the dynamic linker. From - * this we can figure out the address where the - * runtime loader's file object had been mapped to. + * address where the runtime loader's file object had + * been mapped to. */ rtldimage = pmcstat_image_from_path(image->pi_dynlinkerpath, 0, args, plugins); @@ -135,8 +136,7 @@ return; } - libstart = entryaddr - rtldimage->pi_entry; - pmcstat_image_link(pp, rtldimage, libstart); + pmcstat_image_link(pp, rtldimage, baseaddr); } } @@ -146,7 +146,7 @@ void pmcstat_process_exec(struct pmcstat_process *pp, - pmcstat_interned_string path, uintfptr_t entryaddr, + pmcstat_interned_string path, uintptr_t baseaddr, uintptr_t dynaddr, struct pmcstat_args *args, struct pmc_plugins *plugins, struct pmcstat_stats *pmcstat_stats) { @@ -167,13 +167,13 @@ case PMCSTAT_IMAGE_ELF32: case PMCSTAT_IMAGE_ELF64: pmcstat_stats->ps_exec_elf++; - pmcstat_process_elf_exec(pp, image, entryaddr, + pmcstat_process_elf_exec(pp, image, baseaddr, dynaddr, args, plugins, pmcstat_stats); break; case PMCSTAT_IMAGE_AOUT: pmcstat_stats->ps_exec_aout++; - pmcstat_process_aout_exec(pp, image, entryaddr); + pmcstat_process_aout_exec(pp, image, baseaddr); break; case PMCSTAT_IMAGE_INDETERMINABLE: diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -198,9 +198,9 @@ CTASSERT(sizeof(struct pmclog_pmcdetach) == 5*4 + TSDELTA); CTASSERT(sizeof(struct pmclog_proccsw) == 7*4 + 8 + TSDELTA); CTASSERT(sizeof(struct pmclog_procexec) == 5*4 + PATH_MAX + - sizeof(uintfptr_t) + TSDELTA); + 2*sizeof(uintptr_t) + TSDELTA); CTASSERT(offsetof(struct pmclog_procexec,pl_pathname) == 5*4 + TSDELTA + - sizeof(uintfptr_t)); + 2*sizeof(uintptr_t)); CTASSERT(sizeof(struct pmclog_procexit) == 5*4 + 8 + TSDELTA); CTASSERT(sizeof(struct pmclog_procfork) == 5*4 + TSDELTA); CTASSERT(sizeof(struct pmclog_sysexit) == 6*4); @@ -1096,7 +1096,7 @@ void pmclog_process_procexec(struct pmc_owner *po, pmc_id_t pmid, pid_t pid, - uintfptr_t startaddr, char *path) + uintptr_t baseaddr, uintptr_t dynaddr, char *path) { int pathlen, recordlen; @@ -1107,7 +1107,8 @@ PMCLOG_RESERVE(po, PMCLOG_TYPE_PROCEXEC, recordlen); PMCLOG_EMIT32(pid); PMCLOG_EMIT32(pmid); - PMCLOG_EMITADDR(startaddr); + PMCLOG_EMITADDR(baseaddr); + PMCLOG_EMITADDR(dynaddr); PMCLOG_EMITSTRING(path,pathlen); PMCLOG_DESPATCH_SYNC(po); } diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -2126,7 +2126,8 @@ CK_LIST_FOREACH(po, &pmc_ss_owners, po_ssnext) if (po->po_flags & PMC_PO_OWNS_LOGFILE) pmclog_process_procexec(po, PMC_ID_INVALID, - p->p_pid, pk->pm_entryaddr, fullpath); + p->p_pid, pk->pm_baseaddr, pk->pm_dynaddr, + fullpath); PMC_EPOCH_EXIT(); PROC_LOCK(p); @@ -2170,8 +2171,8 @@ if (po->po_sscount == 0 && po->po_flags & PMC_PO_OWNS_LOGFILE) pmclog_process_procexec(po, pm->pm_id, - p->p_pid, pk->pm_entryaddr, - fullpath); + p->p_pid, pk->pm_baseaddr, + pk->pm_dynaddr, fullpath); } if (freepath) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -919,7 +919,8 @@ if (PMC_SYSTEM_SAMPLING_ACTIVE() || PMC_PROC_IS_USING_PMCS(p)) { VOP_UNLOCK(imgp->vp); pe.pm_credentialschanged = credential_changing; - pe.pm_entryaddr = imgp->entry_addr; + pe.pm_baseaddr = imgp->reloc_base; + pe.pm_dynaddr = imgp->et_dyn_addr; PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, (void *) &pe); vn_lock(imgp->vp, LK_SHARED | LK_RETRY); diff --git a/sys/sys/pmckern.h b/sys/sys/pmckern.h --- a/sys/sys/pmckern.h +++ b/sys/sys/pmckern.h @@ -76,7 +76,8 @@ struct pmckern_procexec { int pm_credentialschanged; - uintfptr_t pm_entryaddr; + uintptr_t pm_baseaddr; + uintptr_t pm_dynaddr; }; struct pmckern_map_in { diff --git a/sys/sys/pmclog.h b/sys/sys/pmclog.h --- a/sys/sys/pmclog.h +++ b/sys/sys/pmclog.h @@ -202,7 +202,10 @@ PMCLOG_ENTRY_HEADER uint32_t pl_pid; uint32_t pl_pmcid; - uintfptr_t pl_start; /* keep 8 byte aligned */ + /* keep 8 byte aligned */ + uintptr_t pl_base; /* AT_BASE */ + /* keep 8 byte aligned */ + uintptr_t pl_dyn; /* PIE load base */ char pl_pathname[PATH_MAX]; } __packed; @@ -314,7 +317,7 @@ void pmclog_process_proccsw(struct pmc *_pm, struct pmc_process *_pp, pmc_value_t _v, struct thread *); void pmclog_process_procexec(struct pmc_owner *_po, pmc_id_t _pmid, pid_t _pid, - uintfptr_t _startaddr, char *_path); + uintfptr_t _baseaddr, uintptr_t _dynaddr, char *_path); void pmclog_process_procexit(struct pmc *_pm, struct pmc_process *_pp); void pmclog_process_procfork(struct pmc_owner *_po, pid_t _oldpid, pid_t _newpid); void pmclog_process_sysexit(struct pmc_owner *_po, pid_t _pid); diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -459,10 +459,11 @@ ev.pl_u.pl_pc.pl_pcomm); break; case PMCLOG_TYPE_PROCEXEC: - PMCSTAT_PRINT_ENTRY("exec","0x%x %d %p \"%s\"", + PMCSTAT_PRINT_ENTRY("exec","0x%x %d %p %p \"%s\"", ev.pl_u.pl_x.pl_pmcid, ev.pl_u.pl_x.pl_pid, - (void *) ev.pl_u.pl_x.pl_entryaddr, + (void *)ev.pl_u.pl_x.pl_baseaddr, + (void *)ev.pl_u.pl_x.pl_dynaddr, ev.pl_u.pl_x.pl_pathname); break; case PMCLOG_TYPE_PROCEXIT: