From nobody Wed Dec 15 13:43:58 2021 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id ED19318E13C9; Wed, 15 Dec 2021 13:43:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JDc0Z4vzqz3mnS; Wed, 15 Dec 2021 13:43:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8804D1D1AB; Wed, 15 Dec 2021 13:43:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1BFDhwOB083322; Wed, 15 Dec 2021 13:43:58 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1BFDhwer083321; Wed, 15 Dec 2021 13:43:58 GMT (envelope-from git) Date: Wed, 15 Dec 2021 13:43:58 GMT Message-Id: <202112151343.1BFDhwer083321@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Gallatin Subject: git: 517a7adb1160 - main - Make hwpmc work for userspace binaries again List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: gallatin X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 517a7adb1160850746227e4cc30d4bcc3ff04d7d Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1639575838; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=iRSLAR+aOdE/gfcQIMmQdV3n0H27mdYaKT66ZyWbz+U=; b=e0YGX1ZLUicwuSYTBD1U9zsaKNmfnTkgfg5ozr8fG4nIo0Vqta79BB3o3o47SbScthydYV VFRPVmipvIX3hG4ZwTriRxur31L2xjfo2oE4lLZZ9a7E9LOzkzcU+Bl2FPbLWP0ViYJxV9 /RTy+B5RbD2Y33d/PQFvIKpML1y9J3fdRL7/WBVdKsZzzZ18Hgj3YnNtOikwC9UEgj+47m mP3cS+Cfgs2QrHyqqy3VUBPfywhLD9ixeFFsWXl29AuDQs7z2GhRw+8T01T5l6iysQY+Bb OzS3JTSyHA1cO50Etd+LZKRq7G9cK+mSHCrtlmESG+PjqIxmC3ZeRX9djh5EJw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1639575838; a=rsa-sha256; cv=none; b=KtOP0EnRtFaYdgRfsaARojaJnEcFioclSEtyQXIzNGHXp5+6AxxnvqGyQitBMm6k+cxvD2 pdP0CVo8Z+CSivZ3jPIRRwnflWP0FGglbh1Rhmp32z7fvPueyETluSID79CmvIbFfZwCHO YAQUQR/8Gk5w88/YRLdu6JOB3gSixY8psMiDoGhccpF34WAbc1eaOOEivL1RrgvRVeWwFd ShSfDOopPeooBsHOtW4Xqg7LnnEa96BtnrRnsnoif0j+J2c2UGqZASUP6wA4a+o08BJNoL N3v+wkchG7C56fjjvHEjhXylKKCnacFh7KhZ4IX73vOAMsDIhxRq+uUTUI91Og== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by gallatin: URL: https://cgit.FreeBSD.org/src/commit/?id=517a7adb1160850746227e4cc30d4bcc3ff04d7d commit 517a7adb1160850746227e4cc30d4bcc3ff04d7d Author: Andrew Gallatin AuthorDate: 2021-12-15 13:38:36 +0000 Commit: Andrew Gallatin CommitDate: 2021-12-15 13:38:36 +0000 Make hwpmc work for userspace binaries again hwpmc has been utterly broken for userspace binaries, and has been labeling all samples from userspace binaries as dubious frames. The issues are that: -The check for ph.p_offset & (-ph.p_align) == 0 was mostly bogus. The intent was to ignore all executable segments other than the first, which when using BFD appeared in the first page, but with current LLD a read-only data segment appears before the executable segment, pushing the latter into the second page or later. This meant no executable segment was ever found, and thus pi_vaddr remained 0. Instead of relying on BFD's layout, track whether we've seen an executable segment explicitly with a local bool. -Shared libraries were not parsing the segments to calculate pi_vaddr, resulting in it always being 0. Again, when using BFD, the executable segment started at the first page, and so pi_vaddr was genuinely meant to be 0, but not with LLD's current layout. This meant that pmcstat_image_link's offset calculation gave the base address of the segment in memory, rather than the base address of the whole library in memory, and so when adding that to pi_start/pi_end to get the range of the executable sections in memory it double-counted the offset of the first executable segment within the library. Thus we need to do the exact same parsing for ET_DYN as we do for ET_EXEC, which is simpler to write as special-casing ET_REL to not look for segments. Note that, whilst PT_INTERP isn't needed for shared libraries, it will be for PIEs, which pmcstat still fails to handle due to not knowing the base address of the PIE; we get the base address for libraries by MAP_IN events, and for rtld by virtue of the process's entry address being rtld's, but have no equivalent for the executable. Fixes courtesy of jrtc27@. Reviewed by: jrtc27, jhb (earlier version) Differential Revision: https://reviews.freebsd.org/D33055 Sponsored by: Netflix --- lib/libpmcstat/libpmcstat_image.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/libpmcstat/libpmcstat_image.c b/lib/libpmcstat/libpmcstat_image.c index 9ee7097e95ec..97109f203806 100644 --- a/lib/libpmcstat/libpmcstat_image.c +++ b/lib/libpmcstat/libpmcstat_image.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -295,6 +296,7 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image, size_t i, nph, nsh; const char *path, *elfbase; char *p, *endp; + bool first_exec_segment; uintfptr_t minva, maxva; Elf *e; Elf_Scn *scn; @@ -384,7 +386,7 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image, * loaded. Additionally, for dynamically linked executables, * save the pathname to the runtime linker. */ - if (eh.e_type == ET_EXEC) { + if (eh.e_type != ET_REL) { if (elf_getphnum(e, &nph) == 0) { warnx( "WARNING: Could not determine the number of program headers in \"%s\": %s.", @@ -392,6 +394,7 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image, elf_errmsg(-1)); goto done; } + first_exec_segment = true; for (i = 0; i < eh.e_phnum; i++) { if (gelf_getphdr(e, i, &ph) != &ph) { warnx( @@ -416,8 +419,10 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image, break; case PT_LOAD: if ((ph.p_flags & PF_X) != 0 && - (ph.p_offset & (-ph.p_align)) == 0) + first_exec_segment) { image->pi_vaddr = ph.p_vaddr & (-ph.p_align); + first_exec_segment = false; + } break; } }