517a7adb11
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 |
||
---|---|---|
.. | ||
libpmcstat_event.c | ||
libpmcstat_image.c | ||
libpmcstat_logging.c | ||
libpmcstat_process.c | ||
libpmcstat_string.c | ||
libpmcstat_symbol.c | ||
libpmcstat.h | ||
Makefile | ||
Makefile.depend |