[llvm] [llvm-profgen] Handle perf mmaps with page sizes larger than 4 KiB (PR #217887)

Jinjie Huang via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 11:48:42 PDT 2026


================
@@ -362,10 +362,11 @@ template <class ELFT>
 void ProfiledBinary::setPreferredTextSegmentAddresses(const ELFFile<ELFT> &Obj,
                                                       StringRef FileName) {
   const auto &PhdrRange = unwrapOrError(Obj.program_headers(), FileName);
-  // FIXME: This should be the page size of the system running profiling.
-  // However such info isn't available at post-processing time, assuming
-  // 4K page now. Note that we don't use EXEC_PAGESIZE from <linux/param.h>
-  // because we may build the tools on non-linux.
+  // The page size of the profiling system cannot be determined from the ELF
+  // binary alone, and using the page size of the post-processing system would
+  // be incorrect. Use 4 KiB as the binary-side baseline. PerfScriptReader
+  // reconciles executable mmap events whose mappings cover the segment start
+  // due to a larger runtime page size.
   uint64_t PageSize = 0x1000;
----------------
Jinjie-Huang wrote:

Thanks for the review! This is actually not safe enough because p_align is merely a layout promise made by the linker (vaddr % p_align == offset % p_align). In practice, the kernel still enforces alignment based on its own configuration or architectural requirements. For example, if p_align is 16 KiB but the actual OS page size is 64 KiB, the kernel will round down the mapping, making the offset reported by perf mmap smaller than the segment's actual file offset.

Therefore, the core solution here is to determine exactly how far the kernel rounded down the offset for alignment, and add this distance to the mmap's base address to calculate the true runtime load address.

https://github.com/llvm/llvm-project/pull/217887


More information about the llvm-commits mailing list