[llvm-profgen] Fix alignment in preferred based calculation
authorWenlei He <aktoon@gmail.com>
Thu, 30 Sep 2021 00:41:11 +0000 (17:41 -0700)
committerWenlei He <aktoon@gmail.com>
Thu, 30 Sep 2021 06:01:10 +0000 (23:01 -0700)
We used the segment alignment in elf header to assume the loader alignment. However this is incorrect because loader alignment is always the same as page size. If segment needs to be aligned at load time, linker will set aligned address as virtual address in elf header.

Differential Revision: https://reviews.llvm.org/D110795

llvm/tools/llvm-profgen/ProfiledBinary.cpp

index 2d1f68f..aa96f94 100644 (file)
@@ -233,11 +233,17 @@ ProfiledBinary::getExpandedContext(const SmallVectorImpl<uint64_t> &Stack,
 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.
+  uint32_t PageSize = 0x1000;
   for (const typename ELFT::Phdr &Phdr : PhdrRange) {
     if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_flags & ELF::PF_X)) {
         // Segments will always be loaded at a page boundary.
-        PreferredTextSegmentAddresses.push_back(Phdr.p_vaddr & ~(Phdr.p_align - 1U));
-        TextSegmentOffsets.push_back(Phdr.p_offset & ~(Phdr.p_align - 1U));
+        PreferredTextSegmentAddresses.push_back(Phdr.p_vaddr &
+                                                ~(PageSize - 1U));
+        TextSegmentOffsets.push_back(Phdr.p_offset & ~(PageSize - 1U));
       }
   }