diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -1191,7 +1191,7 @@ if (!Islands->FunctionConstantIslandLabel) { Islands->FunctionConstantIslandLabel = - BC.Ctx->createNamedTempSymbol("func_const_island"); + BC.Ctx->getOrCreateSymbol("func_const_island@" + getOneName()); } return Islands->FunctionConstantIslandLabel; } @@ -1201,7 +1201,7 @@ if (!Islands->FunctionColdConstantIslandLabel) { Islands->FunctionColdConstantIslandLabel = - BC.Ctx->createNamedTempSymbol("func_cold_const_island"); + BC.Ctx->getOrCreateSymbol("func_cold_const_island@" + getOneName()); } return Islands->FunctionColdConstantIslandLabel; } @@ -1221,7 +1221,7 @@ } /// Update output values of the function based on the final \p Layout. - void updateOutputValues(const MCAsmLayout &Layout); + void updateOutputValues(const BOLTLinker &Linker); /// Register relocation type \p RelType at a given \p Address in the function /// against \p Symbol. diff --git a/bolt/include/bolt/Core/Linker.h b/bolt/include/bolt/Core/Linker.h --- a/bolt/include/bolt/Core/Linker.h +++ b/bolt/include/bolt/Core/Linker.h @@ -31,6 +31,11 @@ std::function; using SectionsMapper = std::function; + struct SymbolInfo { + uint64_t Address; + uint64_t Size; + }; + virtual ~BOLTLinker() = default; /// Load and link \p Obj. \p MapSections will be called before the object is @@ -38,8 +43,16 @@ /// of a section can be changed by calling the passed SectionMapper. virtual void loadObject(MemoryBufferRef Obj, SectionsMapper MapSections) = 0; + /// Return the address and size of a symbol or std::nullopt if it cannot be + /// found. + virtual std::optional lookupSymbolInfo(StringRef Name) const = 0; + /// Return the address of a symbol or std::nullopt if it cannot be found. - virtual std::optional lookupSymbol(StringRef Name) const = 0; + std::optional lookupSymbol(StringRef Name) const { + if (const auto Info = lookupSymbolInfo(Name)) + return Info->Address; + return std::nullopt; + } }; } // namespace bolt diff --git a/bolt/include/bolt/Rewrite/JITLinkLinker.h b/bolt/include/bolt/Rewrite/JITLinkLinker.h --- a/bolt/include/bolt/Rewrite/JITLinkLinker.h +++ b/bolt/include/bolt/Rewrite/JITLinkLinker.h @@ -17,7 +17,6 @@ #include "bolt/Rewrite/ExecutableFileMemoryManager.h" #include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h" -#include #include #include @@ -35,7 +34,7 @@ std::unique_ptr MM; jitlink::JITLinkDylib Dylib{"main"}; std::vector Allocs; - std::map Symtab; + StringMap Symtab; public: JITLinkLinker(BinaryContext &BC, @@ -43,7 +42,7 @@ ~JITLinkLinker(); void loadObject(MemoryBufferRef Obj, SectionsMapper MapSections) override; - std::optional lookupSymbol(StringRef Name) const override; + std::optional lookupSymbolInfo(StringRef Name) const override; static SmallVector orderedBlocks(const jitlink::Section &Section); diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h --- a/bolt/include/bolt/Rewrite/RewriteInstance.h +++ b/bolt/include/bolt/Rewrite/RewriteInstance.h @@ -190,7 +190,7 @@ void mapAllocatableSections(BOLTLinker::SectionMapper MapSection); /// Update output object's values based on the final \p Layout. - void updateOutputValues(const MCAsmLayout &Layout); + void updateOutputValues(const BOLTLinker &Linker); /// Rewrite back all functions (hopefully optimized) that fit in the original /// memory footprint for that function. If the function is now larger and does diff --git a/bolt/lib/Core/BinaryBasicBlock.cpp b/bolt/lib/Core/BinaryBasicBlock.cpp --- a/bolt/lib/Core/BinaryBasicBlock.cpp +++ b/bolt/lib/Core/BinaryBasicBlock.cpp @@ -14,7 +14,6 @@ #include "bolt/Core/BinaryContext.h" #include "bolt/Core/BinaryFunction.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCInst.h" #include "llvm/Support/Errc.h" diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -25,7 +25,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCExpr.h" @@ -4030,7 +4029,7 @@ } } -void BinaryFunction::updateOutputValues(const MCAsmLayout &Layout) { +void BinaryFunction::updateOutputValues(const BOLTLinker &Linker) { if (!isEmitted()) { assert(!isInjected() && "injected function should be emitted"); setOutputAddress(getAddress()); @@ -4038,16 +4037,17 @@ return; } - const uint64_t BaseAddress = getCodeSection()->getOutputAddress(); + const auto SymbolInfo = Linker.lookupSymbolInfo(getSymbol()->getName()); + assert(SymbolInfo && "Cannot find function entry symbol"); + setOutputAddress(SymbolInfo->Address); + setOutputSize(SymbolInfo->Size); + if (BC.HasRelocations || isInjected()) { - const uint64_t StartOffset = Layout.getSymbolOffset(*getSymbol()); - const uint64_t EndOffset = Layout.getSymbolOffset(*getFunctionEndLabel()); - setOutputAddress(BaseAddress + StartOffset); - setOutputSize(EndOffset - StartOffset); if (hasConstantIsland()) { - const uint64_t DataOffset = - Layout.getSymbolOffset(*getFunctionConstantIslandLabel()); - setOutputDataAddress(BaseAddress + DataOffset); + const auto DataAddress = + Linker.lookupSymbol(getFunctionConstantIslandLabel()->getName()); + assert(DataAddress && "Cannot find function CI symbol"); + setOutputDataAddress(*DataAddress); for (auto It : Islands->Offsets) { const uint64_t OldOffset = It.first; BinaryData *BD = BC.getBinaryDataAtAddress(getAddress() + OldOffset); @@ -4055,8 +4055,11 @@ continue; MCSymbol *Symbol = It.second; - const uint64_t NewOffset = Layout.getSymbolOffset(*Symbol); - BD->setOutputLocation(*getCodeSection(), NewOffset); + const auto NewAddress = Linker.lookupSymbol(Symbol->getName()); + assert(NewAddress && "Cannot find CI symbol"); + auto &Section = *getCodeSection(); + const auto NewOffset = *NewAddress - Section.getOutputAddress(); + BD->setOutputLocation(Section, NewOffset); } } if (isSplit()) { @@ -4066,7 +4069,6 @@ // If fragment is empty, cold section might not exist if (FF.empty() && ColdSection.getError()) continue; - const uint64_t ColdBaseAddress = ColdSection->getOutputAddress(); const MCSymbol *ColdStartSymbol = getSymbol(FF.getFragmentNum()); // If fragment is empty, symbol might have not been emitted @@ -4075,31 +4077,24 @@ continue; assert(ColdStartSymbol && ColdStartSymbol->isDefined() && "split function should have defined cold symbol"); - const MCSymbol *ColdEndSymbol = - getFunctionEndLabel(FF.getFragmentNum()); - assert(ColdEndSymbol && ColdEndSymbol->isDefined() && - "split function should have defined cold end symbol"); - const uint64_t ColdStartOffset = - Layout.getSymbolOffset(*ColdStartSymbol); - const uint64_t ColdEndOffset = Layout.getSymbolOffset(*ColdEndSymbol); - FF.setAddress(ColdBaseAddress + ColdStartOffset); - FF.setImageSize(ColdEndOffset - ColdStartOffset); + const auto ColdStartSymbolInfo = + Linker.lookupSymbolInfo(ColdStartSymbol->getName()); + assert(ColdStartSymbolInfo && "Cannot find cold start symbol"); + FF.setAddress(ColdStartSymbolInfo->Address); + FF.setImageSize(ColdStartSymbolInfo->Size); if (hasConstantIsland()) { - const uint64_t DataOffset = - Layout.getSymbolOffset(*getFunctionColdConstantIslandLabel()); - setOutputColdDataAddress(ColdBaseAddress + DataOffset); + const auto DataAddress = Linker.lookupSymbol( + getFunctionColdConstantIslandLabel()->getName()); + assert(DataAddress && "Cannot find cold CI symbol"); + setOutputColdDataAddress(*DataAddress); } } } - } else { - setOutputAddress(getAddress()); - setOutputSize(Layout.getSymbolOffset(*getFunctionEndLabel())); } // Update basic block output ranges for the debug info, if we have // secondary entry points in the symbol table to update or if writing BAT. - if (!opts::UpdateDebugSections && !isMultiEntry() && - !requiresAddressTranslation()) + if (!requiresAddressMap()) return; // Output ranges should match the input if the body hasn't changed. diff --git a/bolt/lib/Rewrite/JITLinkLinker.cpp b/bolt/lib/Rewrite/JITLinkLinker.cpp --- a/bolt/lib/Rewrite/JITLinkLinker.cpp +++ b/bolt/lib/Rewrite/JITLinkLinker.cpp @@ -142,8 +142,8 @@ }); for (auto *Symbol : G.defined_symbols()) { - Linker.Symtab.insert( - {Symbol->getName().str(), Symbol->getAddress().getValue()}); + SymbolInfo Info{Symbol->getAddress().getValue(), Symbol->getSize()}; + Linker.Symtab.insert({Symbol->getName().str(), Info}); } return Error::success(); @@ -174,7 +174,8 @@ jitlink::link(std::move(*LG), std::move(Ctx)); } -std::optional JITLinkLinker::lookupSymbol(StringRef Name) const { +std::optional +JITLinkLinker::lookupSymbolInfo(StringRef Name) const { auto It = Symtab.find(Name.data()); if (It == Symtab.end()) return std::nullopt; diff --git a/bolt/lib/Rewrite/MachORewriteInstance.cpp b/bolt/lib/Rewrite/MachORewriteInstance.cpp --- a/bolt/lib/Rewrite/MachORewriteInstance.cpp +++ b/bolt/lib/Rewrite/MachORewriteInstance.cpp @@ -20,7 +20,6 @@ #include "bolt/Rewrite/JITLinkLinker.h" #include "bolt/RuntimeLibs/InstrumentationRuntimeLibrary.h" #include "bolt/Utils/Utils.h" -#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCObjectStreamer.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileSystem.h" @@ -476,9 +475,6 @@ "error creating in-memory object"); assert(Obj && "createObjectFile cannot return nullptr"); - MCAsmLayout FinalLayout( - static_cast(Streamer.get())->getAssembler()); - auto EFMM = std::make_unique(*BC); EFMM->setNewSecPrefix(getNewSecPrefix()); EFMM->setOrgSecPrefix(getOrgSecPrefix()); diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -3241,15 +3241,15 @@ Linker->loadObject(ObjectMemBuffer->getMemBufferRef(), [this](auto MapSection) { mapFileSections(MapSection); }); - MCAsmLayout FinalLayout( - static_cast(Streamer.get())->getAssembler()); - // Update output addresses based on the new section map and // layout. Only do this for the object created by ourselves. - updateOutputValues(FinalLayout); + updateOutputValues(*Linker); - if (opts::UpdateDebugSections) + if (opts::UpdateDebugSections) { + MCAsmLayout FinalLayout( + static_cast(Streamer.get())->getAssembler()); DebugInfoRewriter->updateLineTableOffsets(FinalLayout); + } if (RuntimeLibrary *RtLibrary = BC->getRuntimeLibrary()) RtLibrary->link(*BC, ToolPath, *Linker, [this](auto MapSection) { @@ -3644,7 +3644,7 @@ } } -void RewriteInstance::updateOutputValues(const MCAsmLayout &Layout) { +void RewriteInstance::updateOutputValues(const BOLTLinker &Linker) { if (auto MapSection = BC->getUniqueSectionByName(AddressMap::SectionName)) { auto Map = AddressMap::parse(MapSection->getOutputContents(), *BC); BC->setIOAddressMap(std::move(Map)); @@ -3652,7 +3652,7 @@ } for (BinaryFunction *Function : BC->getAllBinaryFunctions()) - Function->updateOutputValues(Layout); + Function->updateOutputValues(Linker); } void RewriteInstance::patchELFPHDRTable() {