diff --git a/bolt/src/BinaryContext.h b/bolt/src/BinaryContext.h index 990c89405bde..a89fbebd7257 100644 --- a/bolt/src/BinaryContext.h +++ b/bolt/src/BinaryContext.h @@ -63,6 +63,7 @@ namespace bolt { class BinaryFunction; class BinaryBasicBlock; class DataReader; +class ExecutableFileMemoryManager; enum class MemoryContentsType : char { UNKNOWN = 0, /// Unknown contents. @@ -196,6 +197,10 @@ public: FilterIterator; using FilteredBinaryDataIterator = FilterIterator; + /// Memory manager for sections and segments. Used to communicate with ORC + /// among other things. + std::shared_ptr EFMM; + /// Return BinaryFunction containing a given \p Address or nullptr if /// no registered function has it. /// diff --git a/bolt/src/DataAggregator.cpp b/bolt/src/DataAggregator.cpp index acb05c8e6ade..8f7e1e6e02a1 100644 --- a/bolt/src/DataAggregator.cpp +++ b/bolt/src/DataAggregator.cpp @@ -16,6 +16,7 @@ #include "BinaryFunction.h" #include "BoltAddressTranslation.h" #include "DataAggregator.h" +#include "ExecutableFileMemoryManager.h" #include "Heatmap.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" @@ -1857,11 +1858,22 @@ std::error_code DataAggregator::parseMMapEvents() { auto Range = GlobalMMapInfo.equal_range(NameToUse); for (auto I = Range.first; I != Range.second; ++I) { - if (BC->HasFixedLoadAddress && I->second.BaseAddress && - I->second.BaseAddress != BC->FirstAllocAddress) { - errs() << "PERF2BOLT-WARNING: ignoring mapping of " << NameToUse - << " at 0x" << Twine::utohexstr(I->second.BaseAddress) << '\n'; - continue; + if (BC->HasFixedLoadAddress && I->second.BaseAddress) { + // Check that the binary mapping matches one of the segments. + bool MatchFound{false}; + for (auto &KV : BC->EFMM->SegmentMapInfo) { + auto &SegInfo = KV.second; + const auto MapAddress = alignDown(SegInfo.Address, SegInfo.Alignment); + if (I->second.BaseAddress == MapAddress) { + MatchFound = true; + break; + } + } + if (!MatchFound) { + errs() << "PERF2BOLT-WARNING: ignoring mapping of " << NameToUse + << " at 0x" << Twine::utohexstr(I->second.BaseAddress) << '\n'; + continue; + } } BinaryMMapInfo.insert(std::make_pair(I->second.PID, I->second)); diff --git a/bolt/src/ExecutableFileMemoryManager.h b/bolt/src/ExecutableFileMemoryManager.h index fced00ef7765..f8dc4ad0d5b7 100644 --- a/bolt/src/ExecutableFileMemoryManager.h +++ b/bolt/src/ExecutableFileMemoryManager.h @@ -27,13 +27,15 @@ struct SegmentInfo { uint64_t Size; /// Size of the segment in memory. uint64_t FileOffset; /// Offset in the file. uint64_t FileSize; /// Size in file. + uint64_t Alignment; /// Alignment of the segment. void print(raw_ostream &OS) const { OS << "SegmentInfo { Address: 0x" << Twine::utohexstr(Address) << ", Size: 0x" << Twine::utohexstr(Size) << ", FileOffset: 0x" << Twine::utohexstr(FileOffset) << ", FileSize: 0x" - << Twine::utohexstr(FileSize) << "}"; + << Twine::utohexstr(FileSize) << ", Alignment: 0x" + << Twine::utohexstr(Alignment) << "}"; }; }; diff --git a/bolt/src/RewriteInstance.cpp b/bolt/src/RewriteInstance.cpp index f4ea022104af..555a600d1f71 100644 --- a/bolt/src/RewriteInstance.cpp +++ b/bolt/src/RewriteInstance.cpp @@ -780,7 +780,7 @@ void RewriteInstance::discoverStorage() { // sections accounting for stubs when we need those sections to match the // same size seen in the input binary, in case this section is a copy // of the original one seen in the binary. - EFMM.reset(new ExecutableFileMemoryManager(*BC, /*AllowStubs*/ false)); + BC->EFMM.reset(new ExecutableFileMemoryManager(*BC, /*AllowStubs*/ false)); auto ELF64LEFile = dyn_cast(InputFile); if (!ELF64LEFile) { @@ -808,10 +808,11 @@ void RewriteInstance::discoverStorage() { NextAvailableOffset = std::max(NextAvailableOffset, Phdr.p_offset + Phdr.p_filesz); - EFMM->SegmentMapInfo[Phdr.p_vaddr] = SegmentInfo{Phdr.p_vaddr, - Phdr.p_memsz, - Phdr.p_offset, - Phdr.p_filesz}; + BC->EFMM->SegmentMapInfo[Phdr.p_vaddr] = SegmentInfo{Phdr.p_vaddr, + Phdr.p_memsz, + Phdr.p_offset, + Phdr.p_filesz, + Phdr.p_align}; } } @@ -2969,7 +2970,7 @@ void RewriteInstance::emitAndLink() { auto Resolver = orc::createLegacyLookupResolver( [&](const std::string &Name) -> JITSymbol { DEBUG(dbgs() << "BOLT: looking for " << Name << "\n"); - if (EFMM->ObjectsLoaded) { + if (BC->EFMM->ObjectsLoaded) { auto Result = OLT->findSymbol(Name, false); if (cantFail(Result.getAddress()) == 0) { // Resolve to a PLT entry if possible @@ -3008,7 +3009,7 @@ void RewriteInstance::emitAndLink() { *ES, [this, &Resolver](orc::VModuleKey Key) { orc::RTDyldObjectLinkingLayer::Resources R; - R.MemMgr = EFMM; + R.MemMgr = BC->EFMM; R.Resolver = Resolver; // Get memory manager return R; @@ -4934,8 +4935,8 @@ uint64_t RewriteInstance::getFileOffsetForAddress(uint64_t Address) const { } // Find an existing segment that matches the address. - const auto SegmentInfoI = EFMM->SegmentMapInfo.upper_bound(Address); - if (SegmentInfoI == EFMM->SegmentMapInfo.begin()) + const auto SegmentInfoI = BC->EFMM->SegmentMapInfo.upper_bound(Address); + if (SegmentInfoI == BC->EFMM->SegmentMapInfo.begin()) return 0; const auto &SegmentInfo = std::prev(SegmentInfoI)->second; diff --git a/bolt/src/RewriteInstance.h b/bolt/src/RewriteInstance.h index 7f1d3c27ab15..9f7ab5ec7fe3 100644 --- a/bolt/src/RewriteInstance.h +++ b/bolt/src/RewriteInstance.h @@ -343,10 +343,6 @@ private: std::unique_ptr BC; std::unique_ptr CFIRdWrt; - /// Memory manager for sections and segments. Used to communicate with ORC - /// among other things. - std::shared_ptr EFMM; - std::unique_ptr SSP; std::unique_ptr ES;