0
0
mirror of https://github.com/llvm/llvm-project.git synced 2025-04-22 01:56:52 +00:00

[JITLink] Switch to SymbolStringPtr for Symbol names ()

Use SymbolStringPtr for Symbol names in LinkGraph. This reduces string interning
on the boundary between JITLink and ORC, and allows pointer comparisons (rather
than string comparisons) between Symbol names. This should improve the
performance and readability of code that bridges between JITLink and ORC (e.g.
ObjectLinkingLayer and ObjectLinkingLayer::Plugins).

To enable use of SymbolStringPtr a std::shared_ptr<SymbolStringPool> is added to
LinkGraph and threaded through to its construction sites in LLVM and Bolt. All
LinkGraphs that are to have symbol names compared by pointer equality must point
to the same SymbolStringPool instance, which in ORC sessions should be the pool
attached to the ExecutionSession.
---------

Co-authored-by: Lang Hames <lhames@gmail.com>
This commit is contained in:
Jared Wyles 2024-12-06 10:22:09 +11:00 committed by GitHub
parent e6cf5d2863
commit 2ccf7ed277
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
81 changed files with 667 additions and 494 deletions
.gitignore
bolt
llvm

2
.gitignore vendored

@ -59,6 +59,8 @@ autoconf/autom4te.cache
# VS2017 and VSCode config files.
.vscode
.vs
#zed config files
.zed
# pythonenv for github Codespaces
pythonenv*
# clangd index. (".clangd" is a config file now, thus trailing slash)

@ -28,6 +28,7 @@
#include "llvm/ADT/iterator.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@ -276,11 +277,10 @@ class BinaryContext {
void deregisterSectionName(const BinarySection &Section);
public:
static Expected<std::unique_ptr<BinaryContext>>
createBinaryContext(Triple TheTriple, StringRef InputFileName,
SubtargetFeatures *Features, bool IsPIC,
std::unique_ptr<DWARFContext> DwCtx,
JournalingStreams Logger);
static Expected<std::unique_ptr<BinaryContext>> createBinaryContext(
Triple TheTriple, std::shared_ptr<orc::SymbolStringPool> SSP,
StringRef InputFileName, SubtargetFeatures *Features, bool IsPIC,
std::unique_ptr<DWARFContext> DwCtx, JournalingStreams Logger);
/// Superset of compiler units that will contain overwritten code that needs
/// new debug info. In a few cases, functions may end up not being
@ -372,6 +372,7 @@ public:
bool hasSymbolsWithFileName() const { return HasSymbolsWithFileName; }
void setHasSymbolsWithFileName(bool Value) { HasSymbolsWithFileName = Value; }
std::shared_ptr<orc::SymbolStringPool> getSymbolStringPool() { return SSP; }
/// Return true if relocations against symbol with a given name
/// must be created.
bool forceSymbolRelocations(StringRef SymbolName) const;
@ -631,6 +632,8 @@ public:
std::unique_ptr<Triple> TheTriple;
std::shared_ptr<orc::SymbolStringPool> SSP;
const Target *TheTarget;
std::string TripleName;
@ -807,8 +810,10 @@ public:
BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<DWARFContext> DwCtx,
std::unique_ptr<Triple> TheTriple, const Target *TheTarget,
std::string TripleName, std::unique_ptr<MCCodeEmitter> MCE,
std::unique_ptr<Triple> TheTriple,
std::shared_ptr<orc::SymbolStringPool> SSP,
const Target *TheTarget, std::string TripleName,
std::unique_ptr<MCCodeEmitter> MCE,
std::unique_ptr<MCObjectFileInfo> MOFI,
std::unique_ptr<const MCAsmInfo> AsmInfo,
std::unique_ptr<const MCInstrInfo> MII,

@ -123,6 +123,7 @@ void BinaryContext::logBOLTErrorsAndQuitOnFatal(Error E) {
BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<DWARFContext> DwCtx,
std::unique_ptr<Triple> TheTriple,
std::shared_ptr<orc::SymbolStringPool> SSP,
const Target *TheTarget, std::string TripleName,
std::unique_ptr<MCCodeEmitter> MCE,
std::unique_ptr<MCObjectFileInfo> MOFI,
@ -136,12 +137,12 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
std::unique_ptr<MCDisassembler> DisAsm,
JournalingStreams Logger)
: Ctx(std::move(Ctx)), DwCtx(std::move(DwCtx)),
TheTriple(std::move(TheTriple)), TheTarget(TheTarget),
TripleName(TripleName), MCE(std::move(MCE)), MOFI(std::move(MOFI)),
AsmInfo(std::move(AsmInfo)), MII(std::move(MII)), STI(std::move(STI)),
InstPrinter(std::move(InstPrinter)), MIA(std::move(MIA)),
MIB(std::move(MIB)), MRI(std::move(MRI)), DisAsm(std::move(DisAsm)),
Logger(Logger), InitialDynoStats(isAArch64()) {
TheTriple(std::move(TheTriple)), SSP(std::move(SSP)),
TheTarget(TheTarget), TripleName(TripleName), MCE(std::move(MCE)),
MOFI(std::move(MOFI)), AsmInfo(std::move(AsmInfo)), MII(std::move(MII)),
STI(std::move(STI)), InstPrinter(std::move(InstPrinter)),
MIA(std::move(MIA)), MIB(std::move(MIB)), MRI(std::move(MRI)),
DisAsm(std::move(DisAsm)), Logger(Logger), InitialDynoStats(isAArch64()) {
RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86;
PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize;
}
@ -159,8 +160,9 @@ BinaryContext::~BinaryContext() {
/// Create BinaryContext for a given architecture \p ArchName and
/// triple \p TripleName.
Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
Triple TheTriple, StringRef InputFileName, SubtargetFeatures *Features,
bool IsPIC, std::unique_ptr<DWARFContext> DwCtx, JournalingStreams Logger) {
Triple TheTriple, std::shared_ptr<orc::SymbolStringPool> SSP,
StringRef InputFileName, SubtargetFeatures *Features, bool IsPIC,
std::unique_ptr<DWARFContext> DwCtx, JournalingStreams Logger) {
StringRef ArchName = "";
std::string FeaturesStr = "";
switch (TheTriple.getArch()) {
@ -283,8 +285,8 @@ Expected<std::unique_ptr<BinaryContext>> BinaryContext::createBinaryContext(
auto BC = std::make_unique<BinaryContext>(
std::move(Ctx), std::move(DwCtx), std::make_unique<Triple>(TheTriple),
TheTarget, std::string(TripleName), std::move(MCE), std::move(MOFI),
std::move(AsmInfo), std::move(MII), std::move(STI),
std::move(SSP), TheTarget, std::string(TripleName), std::move(MCE),
std::move(MOFI), std::move(AsmInfo), std::move(MII), std::move(STI),
std::move(InstructionPrinter), std::move(MIA), nullptr, std::move(MRI),
std::move(DisAsm), Logger);

@ -1691,7 +1691,8 @@ namespace {
std::unique_ptr<BinaryContext>
createDwarfOnlyBC(const object::ObjectFile &File) {
return cantFail(BinaryContext::createBinaryContext(
File.makeTriple(), File.getFileName(), nullptr, false,
File.makeTriple(), std::make_shared<orc::SymbolStringPool>(),
File.getFileName(), nullptr, false,
DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore,
nullptr, "", WithColor::defaultErrorHandler,
WithColor::defaultWarningHandler),

@ -122,7 +122,7 @@ struct JITLinkLinker::Context : jitlink::JITLinkContext {
jitlink::AsyncLookupResult AllResults;
for (const auto &Symbol : Symbols) {
std::string SymName = Symbol.first.str();
std::string SymName = (*Symbol.first).str();
LLVM_DEBUG(dbgs() << "BOLT: looking for " << SymName << "\n");
if (auto Address = Linker.lookupSymbol(SymName)) {
@ -167,7 +167,9 @@ struct JITLinkLinker::Context : jitlink::JITLinkContext {
Error notifyResolved(jitlink::LinkGraph &G) override {
for (auto *Symbol : G.defined_symbols()) {
SymbolInfo Info{Symbol->getAddress().getValue(), Symbol->getSize()};
Linker.Symtab.insert({Symbol->getName().str(), Info});
auto Name =
Symbol->hasName() ? (*Symbol->getName()).str() : std::string();
Linker.Symtab.insert({std::move(Name), Info});
}
return Error::success();
@ -189,7 +191,7 @@ JITLinkLinker::~JITLinkLinker() { cantFail(MM->deallocate(std::move(Allocs))); }
void JITLinkLinker::loadObject(MemoryBufferRef Obj,
SectionsMapper MapSections) {
auto LG = jitlink::createLinkGraphFromObject(Obj);
auto LG = jitlink::createLinkGraphFromObject(Obj, BC.getSymbolStringPool());
if (auto E = LG.takeError()) {
errs() << "BOLT-ERROR: JITLink failed: " << E << '\n';
exit(1);

@ -74,7 +74,8 @@ MachORewriteInstance::MachORewriteInstance(object::MachOObjectFile *InputFile,
ErrorAsOutParameter EAO(&Err);
Relocation::Arch = InputFile->makeTriple().getArch();
auto BCOrErr = BinaryContext::createBinaryContext(
InputFile->makeTriple(), InputFile->getFileName(), nullptr,
InputFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
InputFile->getFileName(), nullptr,
/* IsPIC */ true, DWARFContext::create(*InputFile),
{llvm::outs(), llvm::errs()});
if (Error E = BCOrErr.takeError()) {

@ -356,7 +356,8 @@ RewriteInstance::RewriteInstance(ELFObjectFileBase *File, const int Argc,
Relocation::Arch = TheTriple.getArch();
auto BCOrErr = BinaryContext::createBinaryContext(
TheTriple, File->getFileName(), Features.get(), IsPIC,
TheTriple, std::make_shared<orc::SymbolStringPool>(), File->getFileName(),
Features.get(), IsPIC,
DWARFContext::create(*File, DWARFContext::ProcessDebugRelocations::Ignore,
nullptr, opts::DWPPathName,
WithColor::defaultErrorHandler,

@ -48,7 +48,8 @@ protected:
void initializeBOLT() {
Relocation::Arch = ObjFile->makeTriple().getArch();
BC = cantFail(BinaryContext::createBinaryContext(
ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true,
ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
ObjFile->getFileName(), nullptr, true,
DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()}));
ASSERT_FALSE(!BC);
}
@ -216,4 +217,4 @@ TEST_P(BinaryContextTester, BaseAddressSegmentsSmallerThanAlignment) {
BC->getBaseAddressForMapping(0xaaaaaaab1000, 0x1000);
ASSERT_TRUE(BaseAddress.has_value());
ASSERT_EQ(*BaseAddress, 0xaaaaaaaa0000ULL);
}
}

@ -58,7 +58,8 @@ protected:
void initializeBolt() {
Relocation::Arch = ObjFile->makeTriple().getArch();
BC = cantFail(BinaryContext::createBinaryContext(
ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true,
ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
ObjFile->getFileName(), nullptr, true,
DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()}));
ASSERT_FALSE(!BC);
BC->initializeTarget(std::unique_ptr<MCPlusBuilder>(

@ -59,7 +59,8 @@ protected:
void initializeBOLT() {
Relocation::Arch = ObjFile->makeTriple().getArch();
BC = cantFail(BinaryContext::createBinaryContext(
ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true,
ObjFile->makeTriple(), std::make_shared<orc::SymbolStringPool>(),
ObjFile->getFileName(), nullptr, true,
DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()}));
ASSERT_FALSE(!BC);
}

@ -24,7 +24,8 @@ namespace jitlink {
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer);
createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// Link the given graph.
///

@ -23,8 +23,8 @@ namespace jitlink {
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer);
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromCOFFObject_x86_64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be a COFF x86-64 object file.
void link_COFF_x86_64(std::unique_ptr<LinkGraph> G,

@ -24,7 +24,8 @@ namespace jitlink {
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer);
createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// Link the given graph.
///

@ -24,8 +24,8 @@ namespace jitlink {
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer);
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch32(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be an ELF arm/thumb object
/// file.

@ -25,8 +25,8 @@ namespace jitlink {
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer);
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be a ELF aarch64 relocatable
/// object file.

@ -26,7 +26,8 @@ namespace jitlink {
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer);
createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be a ELF i386 relocatable
/// object file.

@ -25,8 +25,8 @@ namespace jitlink {
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer);
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_loongarch(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be an ELF loongarch object
/// file.

@ -25,15 +25,16 @@ namespace llvm::jitlink {
///
/// WARNING: The big-endian backend has not been tested yet.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer);
createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// Create a LinkGraph from an ELF/ppc64le relocatable object.
///
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_ppc64le(MemoryBufferRef ObjectBuffer);
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_ppc64le(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be a ELF ppc64le object file.
///

@ -26,7 +26,8 @@ namespace jitlink {
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer);
createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be a ELF riscv object file.
void link_ELF_riscv(std::unique_ptr<LinkGraph> G,

@ -24,7 +24,8 @@ namespace jitlink {
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer);
createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be a ELF x86-64 object file.
void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,

@ -23,6 +23,7 @@
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
@ -396,12 +397,7 @@ const char *getLinkageName(Linkage L);
/// SideEffectsOnly -- Like hidden, but symbol can only be looked up once
/// to trigger materialization of the containing graph.
/// Local -- Visible only within the LinkGraph.
enum class Scope : uint8_t {
Default,
Hidden,
SideEffectsOnly,
Local
};
enum class Scope : uint8_t { Default, Hidden, SideEffectsOnly, Local };
/// For debugging output.
const char *getScopeName(Scope S);
@ -425,10 +421,11 @@ class Symbol {
friend class LinkGraph;
private:
Symbol(Addressable &Base, orc::ExecutorAddrDiff Offset, StringRef Name,
orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive,
bool IsCallable)
: Name(Name), Base(&Base), Offset(Offset), WeakRef(0), Size(Size) {
Symbol(Addressable &Base, orc::ExecutorAddrDiff Offset,
orc::SymbolStringPtr &&Name, orc::ExecutorAddrDiff Size, Linkage L,
Scope S, bool IsLive, bool IsCallable)
: Name(std::move(Name)), Base(&Base), Offset(Offset), WeakRef(0),
Size(Size) {
assert(Offset <= MaxOffset && "Offset out of range");
setLinkage(L);
setScope(S);
@ -438,26 +435,29 @@ private:
}
static Symbol &constructExternal(BumpPtrAllocator &Allocator,
Addressable &Base, StringRef Name,
Addressable &Base,
orc::SymbolStringPtr &&Name,
orc::ExecutorAddrDiff Size, Linkage L,
bool WeaklyReferenced) {
assert(!Base.isDefined() &&
"Cannot create external symbol from defined block");
assert(!Name.empty() && "External symbol name cannot be empty");
assert(Name && "External symbol name cannot be empty");
auto *Sym = Allocator.Allocate<Symbol>();
new (Sym) Symbol(Base, 0, Name, Size, L, Scope::Default, false, false);
new (Sym)
Symbol(Base, 0, std::move(Name), Size, L, Scope::Default, false, false);
Sym->setWeaklyReferenced(WeaklyReferenced);
return *Sym;
}
static Symbol &constructAbsolute(BumpPtrAllocator &Allocator,
Addressable &Base, StringRef Name,
Addressable &Base,
orc::SymbolStringPtr &&Name,
orc::ExecutorAddrDiff Size, Linkage L,
Scope S, bool IsLive) {
assert(!Base.isDefined() &&
"Cannot create absolute symbol from a defined block");
auto *Sym = Allocator.Allocate<Symbol>();
new (Sym) Symbol(Base, 0, Name, Size, L, S, IsLive, false);
new (Sym) Symbol(Base, 0, std::move(Name), Size, L, S, IsLive, false);
return *Sym;
}
@ -468,20 +468,22 @@ private:
assert((Offset + Size) <= Base.getSize() &&
"Symbol extends past end of block");
auto *Sym = Allocator.Allocate<Symbol>();
new (Sym) Symbol(Base, Offset, StringRef(), Size, Linkage::Strong,
Scope::Local, IsLive, IsCallable);
new (Sym) Symbol(Base, Offset, nullptr, Size, Linkage::Strong, Scope::Local,
IsLive, IsCallable);
return *Sym;
}
static Symbol &constructNamedDef(BumpPtrAllocator &Allocator, Block &Base,
orc::ExecutorAddrDiff Offset, StringRef Name,
orc::ExecutorAddrDiff Offset,
orc::SymbolStringPtr Name,
orc::ExecutorAddrDiff Size, Linkage L,
Scope S, bool IsLive, bool IsCallable) {
assert((Offset + Size) <= Base.getSize() &&
"Symbol extends past end of block");
assert(!Name.empty() && "Name cannot be empty");
assert(Name && "Name cannot be empty");
auto *Sym = Allocator.Allocate<Symbol>();
new (Sym) Symbol(Base, Offset, Name, Size, L, S, IsLive, IsCallable);
new (Sym)
Symbol(Base, Offset, std::move(Name), Size, L, S, IsLive, IsCallable);
return *Sym;
}
@ -498,18 +500,19 @@ public:
Symbol &operator=(Symbol &&) = delete;
/// Returns true if this symbol has a name.
bool hasName() const { return !Name.empty(); }
bool hasName() const { return Name != nullptr; }
/// Returns the name of this symbol (empty if the symbol is anonymous).
StringRef getName() const {
assert((!Name.empty() || getScope() == Scope::Local) &&
const orc::SymbolStringPtr &getName() const {
assert((hasName() || getScope() == Scope::Local) &&
"Anonymous symbol has non-local scope");
return Name;
}
/// Rename this symbol. The client is responsible for updating scope and
/// linkage if this name-change requires it.
void setName(StringRef Name) { this->Name = Name; }
void setName(const orc::SymbolStringPtr Name) { this->Name = Name; }
/// Returns true if this Symbol has content (potentially) defined within this
/// object file (i.e. is anything but an external or absolute symbol).
@ -616,7 +619,7 @@ public:
/// Set the linkage for this Symbol.
void setLinkage(Linkage L) {
assert((L == Linkage::Strong || (!Base->isAbsolute() && !Name.empty())) &&
assert((L == Linkage::Strong || (!Base->isAbsolute() && Name)) &&
"Linkage can only be applied to defined named symbols");
this->L = static_cast<uint8_t>(L);
}
@ -626,7 +629,7 @@ public:
/// Set the visibility for this Symbol.
void setScope(Scope S) {
assert((!Name.empty() || S == Scope::Local) &&
assert((hasName() || S == Scope::Local) &&
"Can not set anonymous symbol to non-local scope");
assert((S != Scope::Local || Base->isDefined() || Base->isAbsolute()) &&
"Invalid visibility for symbol type");
@ -678,8 +681,7 @@ private:
static constexpr uint64_t MaxOffset = (1ULL << 59) - 1;
// FIXME: A char* or SymbolStringPtr may pack better.
StringRef Name;
orc::SymbolStringPtr Name = nullptr;
Addressable *Base = nullptr;
uint64_t Offset : 57;
uint64_t L : 1;
@ -1004,22 +1006,23 @@ public:
using GetEdgeKindNameFunction = const char *(*)(Edge::Kind);
LinkGraph(std::string Name, const Triple &TT, SubtargetFeatures Features,
unsigned PointerSize, llvm::endianness Endianness,
GetEdgeKindNameFunction GetEdgeKindName)
: Name(std::move(Name)), TT(TT), Features(std::move(Features)),
PointerSize(PointerSize), Endianness(Endianness),
GetEdgeKindName(std::move(GetEdgeKindName)) {}
LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize,
LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
const Triple &TT, SubtargetFeatures Features, unsigned PointerSize,
llvm::endianness Endianness,
GetEdgeKindNameFunction GetEdgeKindName)
: LinkGraph(std::move(Name), TT, SubtargetFeatures(), PointerSize,
Endianness, GetEdgeKindName) {}
: Name(std::move(Name)), SSP(std::move(SSP)), TT(TT),
Features(std::move(Features)), PointerSize(PointerSize),
Endianness(Endianness), GetEdgeKindName(std::move(GetEdgeKindName)) {}
LinkGraph(std::string Name, const Triple &TT,
LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
const Triple &TT, unsigned PointerSize, llvm::endianness Endianness,
GetEdgeKindNameFunction GetEdgeKindName)
: LinkGraph(std::move(Name), TT, SubtargetFeatures(),
: LinkGraph(std::move(Name), std::move(SSP), TT, SubtargetFeatures(),
PointerSize, Endianness, GetEdgeKindName) {}
LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
const Triple &TT, GetEdgeKindNameFunction GetEdgeKindName)
: LinkGraph(std::move(Name), std::move(SSP), TT, SubtargetFeatures(),
Triple::getArchPointerBitWidth(TT.getArch()) / 8,
TT.isLittleEndian() ? endianness::little : endianness::big,
GetEdgeKindName) {
@ -1031,6 +1034,7 @@ public:
LinkGraph &operator=(const LinkGraph &) = delete;
LinkGraph(LinkGraph &&) = delete;
LinkGraph &operator=(LinkGraph &&) = delete;
~LinkGraph();
/// Returns the name of this graph (usually the name of the original
/// underlying MemoryBuffer).
@ -1050,6 +1054,8 @@ public:
const char *getEdgeKindName(Edge::Kind K) const { return GetEdgeKindName(K); }
std::shared_ptr<orc::SymbolStringPool> getSymbolStringPool() { return SSP; }
/// Allocate a mutable buffer of the given size using the LinkGraph's
/// allocator.
MutableArrayRef<char> allocateBuffer(size_t Size) {
@ -1263,6 +1269,10 @@ public:
return splitBlockImpl(std::move(Blocks), Cache);
}
//
orc::SymbolStringPtr intern(StringRef SymbolName) {
return SSP->intern(SymbolName);
}
/// Add an external symbol.
/// Some formats (e.g. ELF) allow Symbols to have sizes. For Symbols whose
/// size is not known, you should substitute '0'.
@ -1271,18 +1281,25 @@ public:
/// found or an error will be emitted. Externals that are weakly referenced
/// are permitted to be undefined, in which case they are assigned an address
/// of 0.
Symbol &addExternalSymbol(StringRef Name, orc::ExecutorAddrDiff Size,
Symbol &addExternalSymbol(orc::SymbolStringPtr Name,
orc::ExecutorAddrDiff Size,
bool IsWeaklyReferenced) {
assert(!ExternalSymbols.contains(Name) && "Duplicate external symbol");
assert(!ExternalSymbols.contains(*Name) && "Duplicate external symbol");
auto &Sym = Symbol::constructExternal(
Allocator, createAddressable(orc::ExecutorAddr(), false), Name, Size,
Linkage::Strong, IsWeaklyReferenced);
ExternalSymbols.insert({Sym.getName(), &Sym});
Allocator, createAddressable(orc::ExecutorAddr(), false),
std::move(Name), Size, Linkage::Strong, IsWeaklyReferenced);
ExternalSymbols.insert({*Sym.getName(), &Sym});
return Sym;
}
Symbol &addExternalSymbol(StringRef Name, orc::ExecutorAddrDiff Size,
bool IsWeaklyReferenced) {
return addExternalSymbol(SSP->intern(Name), Size, IsWeaklyReferenced);
}
/// Add an absolute symbol.
Symbol &addAbsoluteSymbol(StringRef Name, orc::ExecutorAddr Address,
Symbol &addAbsoluteSymbol(orc::SymbolStringPtr Name,
orc::ExecutorAddr Address,
orc::ExecutorAddrDiff Size, Linkage L, Scope S,
bool IsLive) {
assert((S == Scope::Local || llvm::count_if(AbsoluteSymbols,
@ -1291,11 +1308,18 @@ public:
}) == 0) &&
"Duplicate absolute symbol");
auto &Sym = Symbol::constructAbsolute(Allocator, createAddressable(Address),
Name, Size, L, S, IsLive);
std::move(Name), Size, L, S, IsLive);
AbsoluteSymbols.insert(&Sym);
return Sym;
}
Symbol &addAbsoluteSymbol(StringRef Name, orc::ExecutorAddr Address,
orc::ExecutorAddrDiff Size, Linkage L, Scope S,
bool IsLive) {
return addAbsoluteSymbol(SSP->intern(Name), Address, Size, L, S, IsLive);
}
/// Add an anonymous symbol.
Symbol &addAnonymousSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
orc::ExecutorAddrDiff Size, bool IsCallable,
@ -1310,13 +1334,22 @@ public:
Symbol &addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
StringRef Name, orc::ExecutorAddrDiff Size,
Linkage L, Scope S, bool IsCallable, bool IsLive) {
return addDefinedSymbol(Content, Offset, SSP->intern(Name), Size, L, S,
IsCallable, IsLive);
}
Symbol &addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
orc::SymbolStringPtr Name,
orc::ExecutorAddrDiff Size, Linkage L, Scope S,
bool IsCallable, bool IsLive) {
assert((S == Scope::Local || llvm::count_if(defined_symbols(),
[&](const Symbol *Sym) {
return Sym->getName() == Name;
}) == 0) &&
"Duplicate defined symbol");
auto &Sym = Symbol::constructNamedDef(Allocator, Content, Offset, Name,
Size, L, S, IsLive, IsCallable);
auto &Sym =
Symbol::constructNamedDef(Allocator, Content, Offset, std::move(Name),
Size, L, S, IsLive, IsCallable);
Content.getSection().addSymbol(Sym);
return Sym;
}
@ -1401,7 +1434,7 @@ public:
Sec.removeSymbol(Sym);
Sym.makeExternal(createAddressable(orc::ExecutorAddr(), false));
}
ExternalSymbols.insert({Sym.getName(), &Sym});
ExternalSymbols.insert({*Sym.getName(), &Sym});
}
/// Make the given symbol an absolute with the given address (must not already
@ -1415,10 +1448,10 @@ public:
void makeAbsolute(Symbol &Sym, orc::ExecutorAddr Address) {
assert(!Sym.isAbsolute() && "Symbol is already absolute");
if (Sym.isExternal()) {
assert(ExternalSymbols.contains(Sym.getName()) &&
assert(ExternalSymbols.contains(*Sym.getName()) &&
"Sym is not in the absolute symbols set");
assert(Sym.getOffset() == 0 && "External is not at offset 0");
ExternalSymbols.erase(Sym.getName());
ExternalSymbols.erase(*Sym.getName());
auto &A = Sym.getAddressable();
A.setAbsolute(true);
A.setAddress(Address);
@ -1443,9 +1476,9 @@ public:
"Symbol is not in the absolutes set");
AbsoluteSymbols.erase(&Sym);
} else {
assert(ExternalSymbols.contains(Sym.getName()) &&
assert(ExternalSymbols.contains(*Sym.getName()) &&
"Symbol is not in the externals set");
ExternalSymbols.erase(Sym.getName());
ExternalSymbols.erase(*Sym.getName());
}
Addressable &OldBase = *Sym.Base;
Sym.setBlock(Content);
@ -1530,9 +1563,9 @@ public:
void removeExternalSymbol(Symbol &Sym) {
assert(!Sym.isDefined() && !Sym.isAbsolute() &&
"Sym is not an external symbol");
assert(ExternalSymbols.contains(Sym.getName()) &&
assert(ExternalSymbols.contains(*Sym.getName()) &&
"Symbol is not in the externals set");
ExternalSymbols.erase(Sym.getName());
ExternalSymbols.erase(*Sym.getName());
Addressable &Base = *Sym.Base;
assert(llvm::none_of(external_symbols(),
[&](Symbol *AS) { return AS->Base == &Base; }) &&
@ -1603,12 +1636,14 @@ private:
BumpPtrAllocator Allocator;
std::string Name;
std::shared_ptr<orc::SymbolStringPool> SSP;
Triple TT;
SubtargetFeatures Features;
unsigned PointerSize;
llvm::endianness Endianness;
GetEdgeKindNameFunction GetEdgeKindName = nullptr;
DenseMap<StringRef, std::unique_ptr<Section>> Sections;
// FIXME(jared): these should become dense maps
ExternalSymbolMap ExternalSymbols;
AbsoluteSymbolSet AbsoluteSymbols;
orc::shared::AllocActions AAs;
@ -1831,7 +1866,8 @@ enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol };
raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF);
/// A map of symbol names to resolved addresses.
using AsyncLookupResult = DenseMap<StringRef, orc::ExecutorSymbolDef>;
using AsyncLookupResult =
DenseMap<orc::SymbolStringPtr, orc::ExecutorSymbolDef>;
/// A function object to call with a resolved symbol map (See AsyncLookupResult)
/// or an error if resolution failed.
@ -1864,7 +1900,7 @@ createLookupContinuation(Continuation Cont) {
/// Holds context for a single jitLink invocation.
class JITLinkContext {
public:
using LookupMap = DenseMap<StringRef, SymbolLookupFlags>;
using LookupMap = DenseMap<orc::SymbolStringPtr, SymbolLookupFlags>;
/// Create a JITLinkContext.
JITLinkContext(const JITLinkDylib *JD) : JD(JD) {}
@ -1997,11 +2033,14 @@ void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs) {
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromObject(MemoryBufferRef ObjectBuffer);
createLinkGraphFromObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// Create a \c LinkGraph defining the given absolute symbols.
std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT,
orc::SymbolMap Symbols);
std::unique_ptr<LinkGraph>
absoluteSymbolsLinkGraph(const Triple &TT,
std::shared_ptr<orc::SymbolStringPool> SSP,
orc::SymbolMap Symbols);
/// Link the given graph.
void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx);

@ -19,6 +19,7 @@
#include "llvm/ExecutionEngine/Orc/Shared/AllocationActions.h"
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
@ -320,12 +321,15 @@ public:
using OnFinalizedFunction =
JITLinkMemoryManager::InFlightAlloc::OnFinalizedFunction;
static void Create(JITLinkMemoryManager &MemMgr, const JITLinkDylib *JD,
SegmentMap Segments, OnCreatedFunction OnCreated);
static void Create(JITLinkMemoryManager &MemMgr,
std::shared_ptr<orc::SymbolStringPool> SSP,
const JITLinkDylib *JD, SegmentMap Segments,
OnCreatedFunction OnCreated);
static Expected<SimpleSegmentAlloc> Create(JITLinkMemoryManager &MemMgr,
const JITLinkDylib *JD,
SegmentMap Segments);
static Expected<SimpleSegmentAlloc>
Create(JITLinkMemoryManager &MemMgr,
std::shared_ptr<orc::SymbolStringPool> SSP, const JITLinkDylib *JD,
SegmentMap Segments);
SimpleSegmentAlloc(SimpleSegmentAlloc &&);
SimpleSegmentAlloc &operator=(SimpleSegmentAlloc &&);

@ -25,7 +25,8 @@ namespace jitlink {
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer);
createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given ObjBuffer, which must be a MachO object file.
///

@ -23,8 +23,8 @@ namespace jitlink {
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer);
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_arm64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given object buffer, which must be a MachO arm64 object file.
///

@ -23,8 +23,8 @@ namespace jitlink {
/// Note: The graph does not take ownership of the underlying buffer, nor copy
/// its contents. The caller is responsible for ensuring that the object buffer
/// outlives the graph.
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer);
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_x86_64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);
/// jit-link the given LinkGraph.
///

@ -69,7 +69,7 @@ public:
private:
TableManagerImplT &impl() { return static_cast<TableManagerImplT &>(*this); }
DenseMap<StringRef, Symbol *> Entries;
DenseMap<orc::SymbolStringPtr, Symbol *> Entries;
};
} // namespace jitlink

@ -181,7 +181,7 @@ public:
ExecutorProcessControl(std::shared_ptr<SymbolStringPool> SSP,
std::unique_ptr<TaskDispatcher> D)
: SSP(std::move(SSP)), D(std::move(D)) {}
: SSP(std::move(SSP)), D(std::move(D)) {}
virtual ~ExecutorProcessControl();

@ -10,6 +10,7 @@
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Support/Endian.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"

@ -40,7 +40,8 @@ static StringRef getMachineName(uint16_t Machine) {
}
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
StringRef Data = ObjectBuffer.getBuffer();
// Check magic
@ -108,7 +109,7 @@ createLinkGraphFromCOFFObject(MemoryBufferRef ObjectBuffer) {
switch (Machine) {
case COFF::IMAGE_FILE_MACHINE_AMD64:
return createLinkGraphFromCOFFObject_x86_64(ObjectBuffer);
return createLinkGraphFromCOFFObject_x86_64(ObjectBuffer, std::move(SSP));
default:
return make_error<JITLinkError>(
"Unsupported target machine architecture in COFF object " +

@ -11,6 +11,8 @@
//===----------------------------------------------------------------------===//
#include "COFFLinkGraphBuilder.h"
#include <memory>
#define DEBUG_TYPE "jitlink"
static const char *CommonSectionName = "__common";
@ -24,12 +26,16 @@ static Triple createTripleWithCOFFFormat(Triple T) {
}
COFFLinkGraphBuilder::COFFLinkGraphBuilder(
const object::COFFObjectFile &Obj, Triple TT, SubtargetFeatures Features,
const object::COFFObjectFile &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
SubtargetFeatures Features,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
: Obj(Obj), G(std::make_unique<LinkGraph>(
Obj.getFileName().str(), createTripleWithCOFFFormat(TT),
std::move(Features), getPointerSize(Obj),
getEndianness(Obj), std::move(GetEdgeKindName))) {
: Obj(Obj),
G(std::make_unique<LinkGraph>(Obj.getFileName().str(), std::move(SSP),
createTripleWithCOFFFormat(TT),
std::move(Features), getPointerSize(Obj),
getEndianness(Obj),
std::move(GetEdgeKindName))) {
LLVM_DEBUG({
dbgs() << "Created COFFLinkGraphBuilder for \"" << Obj.getFileName()
<< "\"\n";
@ -226,18 +232,19 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
" (" + toString(SecOrErr.takeError()) + ")");
Sec = *SecOrErr;
}
auto InternedSymbolName = G->intern(std::move(SymbolName));
// Create jitlink symbol
jitlink::Symbol *GSym = nullptr;
if (Sym->isFileRecord())
LLVM_DEBUG({
dbgs() << " " << SymIndex << ": Skipping FileRecord symbol \""
<< SymbolName << "\" in "
<< InternedSymbolName << "\" in "
<< getCOFFSectionName(SectionIndex, Sec, *Sym)
<< " (index: " << SectionIndex << ") \n";
});
else if (Sym->isUndefined()) {
GSym = createExternalSymbol(SymIndex, SymbolName, *Sym, Sec);
GSym = createExternalSymbol(SymIndex, InternedSymbolName, *Sym, Sec);
} else if (Sym->isWeakExternal()) {
auto *WeakExternal = Sym->getAux<object::coff_aux_weak_external>();
COFFSymbolIndex TagIndex = WeakExternal->TagIndex;
@ -246,7 +253,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
{SymIndex, TagIndex, Characteristics, SymbolName});
} else {
Expected<jitlink::Symbol *> NewGSym =
createDefinedSymbol(SymIndex, SymbolName, *Sym, Sec);
createDefinedSymbol(SymIndex, InternedSymbolName, *Sym, Sec);
if (!NewGSym)
return NewGSym.takeError();
GSym = *NewGSym;
@ -254,7 +261,7 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
LLVM_DEBUG({
dbgs() << " " << SymIndex
<< ": Creating defined graph symbol for COFF symbol \""
<< SymbolName << "\" in "
<< InternedSymbolName << "\" in "
<< getCOFFSectionName(SectionIndex, Sec, *Sym)
<< " (index: " << SectionIndex << ") \n";
dbgs() << " " << *GSym << "\n";
@ -293,14 +300,13 @@ Error COFFLinkGraphBuilder::handleDirectiveSection(StringRef Str) {
if (From.empty() || To.empty())
return make_error<JITLinkError>(
"Invalid COFF /alternatename directive");
AlternateNames[From] = To;
AlternateNames[G->intern(From)] = G->intern(To);
break;
}
case COFF_OPT_incl: {
auto DataCopy = G->allocateContent(S);
StringRef StrCopy(DataCopy.data(), DataCopy.size());
ExternalSymbols[StrCopy] = &G->addExternalSymbol(StrCopy, 0, false);
ExternalSymbols[StrCopy]->setLive(true);
auto Symbol = &G->addExternalSymbol(S, 0, false);
Symbol->setLive(true);
ExternalSymbols[Symbol->getName()] = Symbol;
break;
}
case COFF_OPT_export:
@ -332,8 +338,8 @@ Error COFFLinkGraphBuilder::flushWeakAliasRequests() {
? Scope::Default
: Scope::Local;
auto NewSymbol =
createAliasSymbol(WeakExternal.SymbolName, Linkage::Weak, S, *Target);
auto NewSymbol = createAliasSymbol(G->intern(WeakExternal.SymbolName),
Linkage::Weak, S, *Target);
if (!NewSymbol)
return NewSymbol.takeError();
setGraphSymbol(AliasSymbol->getSectionNumber(), WeakExternal.Alias,
@ -354,37 +360,44 @@ Error COFFLinkGraphBuilder::flushWeakAliasRequests() {
}
Error COFFLinkGraphBuilder::handleAlternateNames() {
for (auto &KeyValue : AlternateNames)
if (DefinedSymbols.count(KeyValue.second) &&
ExternalSymbols.count(KeyValue.first)) {
auto *Target = DefinedSymbols[KeyValue.second];
auto *Alias = ExternalSymbols[KeyValue.first];
for (auto &KeyValue : AlternateNames) {
auto DefinedSymbolName = KeyValue.second;
auto ExternalSymbolsName = KeyValue.first;
if (DefinedSymbols.count(DefinedSymbolName) &&
ExternalSymbols.count(ExternalSymbolsName)) {
auto *Target = DefinedSymbols[DefinedSymbolName];
auto *Alias = ExternalSymbols[ExternalSymbolsName];
G->makeDefined(*Alias, Target->getBlock(), Target->getOffset(),
Target->getSize(), Linkage::Weak, Scope::Local, false);
}
}
return Error::success();
}
Symbol *COFFLinkGraphBuilder::createExternalSymbol(
COFFSymbolIndex SymIndex, StringRef SymbolName,
COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName,
object::COFFSymbolRef Symbol, const object::coff_section *Section) {
if (!ExternalSymbols.count(SymbolName))
ExternalSymbols[SymbolName] =
&G->addExternalSymbol(SymbolName, Symbol.getValue(), false);
llvm::jitlink::Symbol *Sym = nullptr;
if (!ExternalSymbols.count(SymbolName)) {
Sym = &G->addExternalSymbol(*SymbolName, Symbol.getValue(), false);
ExternalSymbols[Sym->getName()] = Sym;
} else {
Sym = ExternalSymbols[SymbolName];
}
LLVM_DEBUG({
dbgs() << " " << SymIndex
<< ": Creating external graph symbol for COFF symbol \""
<< SymbolName << "\" in "
<< Sym->getName() << "\" in "
<< getCOFFSectionName(Symbol.getSectionNumber(), Section, Symbol)
<< " (index: " << Symbol.getSectionNumber() << ") \n";
});
return ExternalSymbols[SymbolName];
return Sym;
}
Expected<Symbol *> COFFLinkGraphBuilder::createAliasSymbol(StringRef SymbolName,
Linkage L, Scope S,
Symbol &Target) {
Expected<Symbol *>
COFFLinkGraphBuilder::createAliasSymbol(orc::SymbolStringPtr SymbolName,
Linkage L, Scope S, Symbol &Target) {
if (!Target.isDefined()) {
// FIXME: Support this when there's a way to handle this.
return make_error<JITLinkError>("Weak external symbol with external "
@ -460,8 +473,9 @@ Error COFFLinkGraphBuilder::calculateImplicitSizeOfSymbols() {
}
Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
COFFSymbolIndex SymIndex, StringRef SymbolName,
COFFSymbolIndex SymIndex, orc::SymbolStringPtr SymbolName,
object::COFFSymbolRef Symbol, const object::coff_section *Section) {
if (Symbol.isCommon()) {
// FIXME: correct alignment
return &G->addDefinedSymbol(
@ -470,6 +484,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
0, SymbolName, Symbol.getValue(), Linkage::Weak, Scope::Default,
false, false);
}
if (Symbol.isAbsolute())
return &G->addAbsoluteSymbol(SymbolName,
orc::ExecutorAddr(Symbol.getValue()), 0,
@ -603,7 +618,7 @@ Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest(
// Process the second symbol of COMDAT sequence.
Expected<Symbol *>
COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
StringRef SymbolName,
orc::SymbolStringPtr SymbolName,
object::COFFSymbolRef Symbol) {
Block *B = getGraphBlock(Symbol.getSectionNumber());
auto &PendingComdatExport = PendingComdatExports[Symbol.getSectionNumber()];

@ -37,7 +37,8 @@ protected:
using COFFSectionIndex = int32_t;
using COFFSymbolIndex = int32_t;
COFFLinkGraphBuilder(const object::COFFObjectFile &Obj, Triple TT,
COFFLinkGraphBuilder(const object::COFFObjectFile &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
SubtargetFeatures Features,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
@ -134,20 +135,21 @@ private:
Section &getCommonSection();
Symbol *createExternalSymbol(COFFSymbolIndex SymIndex, StringRef SymbolName,
Symbol *createExternalSymbol(COFFSymbolIndex SymIndex,
orc::SymbolStringPtr SymbolName,
object::COFFSymbolRef Symbol,
const object::coff_section *Section);
Expected<Symbol *> createAliasSymbol(StringRef SymbolName, Linkage L, Scope S,
Symbol &Target);
Expected<Symbol *> createAliasSymbol(orc::SymbolStringPtr SymbolName,
Linkage L, Scope S, Symbol &Target);
Expected<Symbol *> createDefinedSymbol(COFFSymbolIndex SymIndex,
StringRef SymbolName,
orc::SymbolStringPtr SymbolName,
object::COFFSymbolRef Symbol,
const object::coff_section *Section);
Expected<Symbol *> createCOMDATExportRequest(
COFFSymbolIndex SymIndex, object::COFFSymbolRef Symbol,
const object::coff_aux_section_definition *Definition);
Expected<Symbol *> exportCOMDATSymbol(COFFSymbolIndex SymIndex,
StringRef SymbolName,
orc::SymbolStringPtr SymbolName,
object::COFFSymbolRef Symbol);
Error handleDirectiveSection(StringRef Str);
@ -176,9 +178,9 @@ private:
std::vector<Block *> GraphBlocks;
std::vector<Symbol *> GraphSymbols;
DenseMap<StringRef, StringRef> AlternateNames;
DenseMap<StringRef, Symbol *> ExternalSymbols;
DenseMap<StringRef, Symbol *> DefinedSymbols;
DenseMap<orc::SymbolStringPtr, orc::SymbolStringPtr> AlternateNames;
DenseMap<orc::SymbolStringPtr, Symbol *> ExternalSymbols;
DenseMap<orc::SymbolStringPtr, Symbol *> DefinedSymbols;
};
template <typename RelocHandlerFunction>

@ -148,6 +148,7 @@ private:
SectionIdx = getObject().getNumberOfSections() + 1;
else
SectionIdx = COFFSymbol.getSectionNumber();
auto *AbsSym = &getGraph().addAbsoluteSymbol(
"secidx", orc::ExecutorAddr(SectionIdx), 2, Linkage::Strong,
Scope::Local, false);
@ -181,14 +182,20 @@ private:
}
public:
COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj, const Triple T,
const SubtargetFeatures Features)
: COFFLinkGraphBuilder(Obj, std::move(T), std::move(Features),
COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
const Triple T, const SubtargetFeatures Features)
: COFFLinkGraphBuilder(Obj, std::move(SSP), std::move(T),
std::move(Features),
getCOFFX86RelocationKindName) {}
};
class COFFLinkGraphLowering_x86_64 {
public:
COFFLinkGraphLowering_x86_64(std::shared_ptr<orc::SymbolStringPool> SSP)
: SSP(std::move(SSP)) {
ImageBaseName = this->SSP->intern("__ImageBase");
}
// Lowers COFF x86_64 specific edges to generic x86_64 edges.
Error lowerCOFFRelocationEdges(LinkGraph &G, JITLinkContext &Ctx) {
for (auto *B : G.blocks()) {
@ -230,7 +237,9 @@ public:
}
private:
static StringRef getImageBaseSymbolName() { return "__ImageBase"; }
const orc::SymbolStringPtr &getImageBaseSymbolName() const {
return this->ImageBaseName;
}
orc::ExecutorAddr getSectionStart(Section &Sec) {
if (!SectionStartCache.count(&Sec)) {
@ -271,12 +280,13 @@ private:
DenseMap<Section *, orc::ExecutorAddr> SectionStartCache;
orc::ExecutorAddr ImageBase;
std::shared_ptr<orc::SymbolStringPool> SSP;
orc::SymbolStringPtr ImageBaseName = nullptr;
};
Error lowerEdges_COFF_x86_64(LinkGraph &G, JITLinkContext *Ctx) {
LLVM_DEBUG(dbgs() << "Lowering COFF x86_64 edges:\n");
COFFLinkGraphLowering_x86_64 GraphLowering;
COFFLinkGraphLowering_x86_64 GraphLowering(G.getSymbolStringPool());
if (auto Err = GraphLowering.lowerCOFFRelocationEdges(G, *Ctx))
return Err;
@ -305,8 +315,8 @@ const char *getCOFFX86RelocationKindName(Edge::Kind R) {
}
}
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromCOFFObject_x86_64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -320,7 +330,8 @@ createLinkGraphFromCOFFObject_x86_64(MemoryBufferRef ObjectBuffer) {
if (!Features)
return Features.takeError();
return COFFLinkGraphBuilder_x86_64(**COFFObj, (*COFFObj)->makeTriple(),
return COFFLinkGraphBuilder_x86_64(**COFFObj, std::move(SSP),
(*COFFObj)->makeTriple(),
std::move(*Features))
.buildGraph();
}

@ -112,13 +112,13 @@ identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym) {
constexpr StringRef EndSymbolPrefix = "__stop_";
auto SymName = Sym.getName();
if (SymName.starts_with(StartSymbolPrefix)) {
if (auto *Sec =
G.findSectionByName(SymName.drop_front(StartSymbolPrefix.size())))
if ((*SymName).starts_with(StartSymbolPrefix)) {
if (auto *Sec = G.findSectionByName(
(*SymName).drop_front(StartSymbolPrefix.size())))
return {*Sec, true};
} else if (SymName.starts_with(EndSymbolPrefix)) {
} else if ((*SymName).starts_with(EndSymbolPrefix)) {
if (auto *Sec =
G.findSectionByName(SymName.drop_front(EndSymbolPrefix.size())))
G.findSectionByName((*SymName).drop_front(EndSymbolPrefix.size())))
return {*Sec, false};
}
return {};
@ -131,15 +131,15 @@ identifyMachOSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym) {
constexpr StringRef EndSymbolPrefix = "section$end$";
auto SymName = Sym.getName();
if (SymName.starts_with(StartSymbolPrefix)) {
if ((*SymName).starts_with(StartSymbolPrefix)) {
auto [SegName, SecName] =
SymName.drop_front(StartSymbolPrefix.size()).split('$');
(*SymName).drop_front(StartSymbolPrefix.size()).split('$');
std::string SectionName = (SegName + "," + SecName).str();
if (auto *Sec = G.findSectionByName(SectionName))
return {*Sec, true};
} else if (SymName.starts_with(EndSymbolPrefix)) {
} else if ((*SymName).starts_with(EndSymbolPrefix)) {
auto [SegName, SecName] =
SymName.drop_front(EndSymbolPrefix.size()).split('$');
(*SymName).drop_front(EndSymbolPrefix.size()).split('$');
std::string SectionName = (SegName + "," + SecName).str();
if (auto *Sec = G.findSectionByName(SectionName))
return {*Sec, false};

@ -69,7 +69,8 @@ Expected<uint16_t> readTargetMachineArch(StringRef Buffer) {
}
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
StringRef Buffer = ObjectBuffer.getBuffer();
if (Buffer.size() < ELF::EI_NIDENT)
return make_error<JITLinkError>("Truncated ELF buffer");
@ -84,23 +85,23 @@ createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer) {
switch (*TargetMachineArch) {
case ELF::EM_AARCH64:
return createLinkGraphFromELFObject_aarch64(ObjectBuffer);
return createLinkGraphFromELFObject_aarch64(ObjectBuffer, std::move(SSP));
case ELF::EM_ARM:
return createLinkGraphFromELFObject_aarch32(ObjectBuffer);
case ELF::EM_LOONGARCH:
return createLinkGraphFromELFObject_loongarch(ObjectBuffer);
return createLinkGraphFromELFObject_aarch32(ObjectBuffer, std::move(SSP));
case ELF::EM_PPC64: {
if (DataEncoding == ELF::ELFDATA2LSB)
return createLinkGraphFromELFObject_ppc64le(ObjectBuffer);
return createLinkGraphFromELFObject_ppc64le(ObjectBuffer, std::move(SSP));
else
return createLinkGraphFromELFObject_ppc64(ObjectBuffer);
return createLinkGraphFromELFObject_ppc64(ObjectBuffer, std::move(SSP));
}
case ELF::EM_LOONGARCH:
return createLinkGraphFromELFObject_loongarch(ObjectBuffer, std::move(SSP));
case ELF::EM_RISCV:
return createLinkGraphFromELFObject_riscv(ObjectBuffer);
return createLinkGraphFromELFObject_riscv(ObjectBuffer, std::move(SSP));
case ELF::EM_X86_64:
return createLinkGraphFromELFObject_x86_64(ObjectBuffer);
return createLinkGraphFromELFObject_x86_64(ObjectBuffer, std::move(SSP));
case ELF::EM_386:
return createLinkGraphFromELFObject_i386(ObjectBuffer);
return createLinkGraphFromELFObject_i386(ObjectBuffer, std::move(SSP));
default:
return make_error<JITLinkError>(
"Unsupported target machine architecture in ELF object " +

@ -58,7 +58,8 @@ class ELFLinkGraphBuilder : public ELFLinkGraphBuilderBase {
using ELFFile = object::ELFFile<ELFT>;
public:
ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj, Triple TT,
ELFLinkGraphBuilder(const object::ELFFile<ELFT> &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
SubtargetFeatures Features, StringRef FileName,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
@ -189,12 +190,13 @@ protected:
template <typename ELFT>
ELFLinkGraphBuilder<ELFT>::ELFLinkGraphBuilder(
const ELFFile &Obj, Triple TT, SubtargetFeatures Features,
StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
const ELFFile &Obj, std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
SubtargetFeatures Features, StringRef FileName,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
: ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
FileName.str(), Triple(std::move(TT)), std::move(Features),
ELFT::Is64Bits ? 8 : 4, llvm::endianness(ELFT::Endianness),
std::move(GetEdgeKindName))),
FileName.str(), std::move(SSP), Triple(std::move(TT)),
std::move(Features), ELFT::Is64Bits ? 8 : 4,
llvm::endianness(ELFT::Endianness), std::move(GetEdgeKindName))),
Obj(Obj) {
LLVM_DEBUG(
{ dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });

@ -219,11 +219,13 @@ protected:
public:
ELFLinkGraphBuilder_aarch32(StringRef FileName,
const llvm::object::ELFFile<ELFT> &Obj, Triple TT,
SubtargetFeatures Features,
const llvm::object::ELFFile<ELFT> &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT, SubtargetFeatures Features,
aarch32::ArmConfig ArmCfg)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
FileName, getELFAArch32EdgeKindName),
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
std::move(Features), FileName,
getELFAArch32EdgeKindName),
ArmCfg(std::move(ArmCfg)) {}
};
@ -239,8 +241,8 @@ Error buildTables_ELF_aarch32(LinkGraph &G) {
return Error::success();
}
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch32(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -273,16 +275,16 @@ createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
case Triple::thumb: {
auto &ELFFile = cast<ELFObjectFile<ELF32LE>>(**ELFObj).getELFFile();
return ELFLinkGraphBuilder_aarch32<llvm::endianness::little>(
(*ELFObj)->getFileName(), ELFFile, TT, std::move(*Features),
ArmCfg)
(*ELFObj)->getFileName(), ELFFile, std::move(SSP), TT,
std::move(*Features), ArmCfg)
.buildGraph();
}
case Triple::armeb:
case Triple::thumbeb: {
auto &ELFFile = cast<ELFObjectFile<ELF32BE>>(**ELFObj).getELFFile();
return ELFLinkGraphBuilder_aarch32<llvm::endianness::big>(
(*ELFObj)->getFileName(), ELFFile, TT, std::move(*Features),
ArmCfg)
(*ELFObj)->getFileName(), ELFFile, std::move(SSP), TT,
std::move(*Features), ArmCfg)
.buildGraph();
}
default:

@ -52,10 +52,13 @@ private:
}
Error getOrCreateGOTSymbol(LinkGraph &G) {
auto InteredGOTSymbolName =
G.getSymbolStringPool()->intern(ELFGOTSymbolName);
auto DefineExternalGOTSymbolIfPresent =
createDefineExternalSectionStartAndEndSymbolsPass(
[&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
if (Sym.getName() == ELFGOTSymbolName)
if (*Sym.getName() == ELFGOTSymbolName)
if (auto *GOTSection = G.findSectionByName(
aarch64::GOTTableManager::getSectionName())) {
GOTSymbol = &Sym;
@ -81,7 +84,7 @@ private:
// Check for an existing defined symbol.
for (auto *Sym : GOTSection->symbols())
if (Sym->getName() == ELFGOTSymbolName) {
if (Sym->getName() == InteredGOTSymbolName) {
GOTSymbol = Sym;
return Error::success();
}
@ -90,11 +93,12 @@ private:
SectionRange SR(*GOTSection);
if (SR.empty())
GOTSymbol =
&G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,
// FIXME: we should only do this once
&G.addAbsoluteSymbol(InteredGOTSymbolName, orc::ExecutorAddr(), 0,
Linkage::Strong, Scope::Local, true);
else
GOTSymbol =
&G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
&G.addDefinedSymbol(*SR.getFirstBlock(), 0, InteredGOTSymbolName, 0,
Linkage::Strong, Scope::Local, false, true);
}
@ -103,7 +107,7 @@ private:
// we just need to point the GOT symbol at some address in this graph.
if (!GOTSymbol) {
for (auto *Sym : G.external_symbols()) {
if (Sym->getName() == ELFGOTSymbolName) {
if (*Sym->getName() == ELFGOTSymbolName) {
auto Blocks = G.blocks();
if (!Blocks.empty()) {
G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());
@ -525,10 +529,13 @@ private:
public:
ELFLinkGraphBuilder_aarch64(StringRef FileName,
const object::ELFFile<ELFT> &Obj, Triple TT,
SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
FileName, aarch64::getEdgeKindName) {}
const object::ELFFile<ELFT> &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT, SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
std::move(Features), FileName,
aarch64::getEdgeKindName) {}
};
// TLS Info Builder.
@ -665,8 +672,8 @@ Error buildTables_ELF_aarch64(LinkGraph &G) {
namespace llvm {
namespace jitlink {
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_aarch64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -685,7 +692,7 @@ createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) {
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
return ELFLinkGraphBuilder_aarch64<object::ELF64LE>(
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
(*ELFObj)->makeTriple(), std::move(*Features))
.buildGraph();
}

@ -56,7 +56,8 @@ private:
auto DefineExternalGOTSymbolIfPresent =
createDefineExternalSectionStartAndEndSymbolsPass(
[&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
if (Sym.getName() == ELFGOTSymbolName)
if (Sym.getName() != nullptr &&
*Sym.getName() == ELFGOTSymbolName)
if (auto *GOTSection = G.findSectionByName(
i386::GOTTableManager::getSectionName())) {
GOTSymbol = &Sym;
@ -82,7 +83,7 @@ private:
// Check for an existing defined symbol.
for (auto *Sym : GOTSection->symbols())
if (Sym->getName() == ELFGOTSymbolName) {
if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {
GOTSymbol = Sym;
return Error::success();
}
@ -224,13 +225,16 @@ private:
public:
ELFLinkGraphBuilder_i386(StringRef FileName, const object::ELFFile<ELFT> &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT, SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
FileName, i386::getEdgeKindName) {}
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
std::move(Features), FileName,
i386::getEdgeKindName) {}
};
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -248,8 +252,9 @@ createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer) {
"Only i386 (little endian) is supported for now");
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
return ELFLinkGraphBuilder_i386<object::ELF32LE>(
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
(*ELFObj)->makeTriple(), std::move(*Features))
.buildGraph();
}

@ -131,10 +131,12 @@ private:
public:
ELFLinkGraphBuilder_loongarch(StringRef FileName,
const object::ELFFile<ELFT> &Obj, Triple TT,
SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
FileName, loongarch::getEdgeKindName) {}
const object::ELFFile<ELFT> &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT, SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
std::move(Features), FileName,
loongarch::getEdgeKindName) {}
};
Error buildTables_ELF_loongarch(LinkGraph &G) {
@ -151,8 +153,8 @@ Error buildTables_ELF_loongarch(LinkGraph &G) {
namespace llvm {
namespace jitlink {
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_loongarch(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -170,7 +172,7 @@ createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
return ELFLinkGraphBuilder_loongarch<object::ELF64LE>(
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
(*ELFObj)->makeTriple(), std::move(*Features))
std::move(SSP), (*ELFObj)->makeTriple(), std::move(*Features))
.buildGraph();
}
@ -178,7 +180,7 @@ createLinkGraphFromELFObject_loongarch(MemoryBufferRef ObjectBuffer) {
"Invalid triple for LoongArch ELF object file");
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
return ELFLinkGraphBuilder_loongarch<object::ELF32LE>(
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
(*ELFObj)->makeTriple(), std::move(*Features))
.buildGraph();
}

@ -106,14 +106,14 @@ Symbol &createELFGOTHeader(LinkGraph &G,
Symbol *TOCSymbol = nullptr;
for (Symbol *Sym : G.defined_symbols())
if (LLVM_UNLIKELY(Sym->getName() == ELFTOCSymbolName)) {
if (LLVM_UNLIKELY(Sym->hasName() && *Sym->getName() == ELFTOCSymbolName)) {
TOCSymbol = Sym;
break;
}
if (LLVM_LIKELY(TOCSymbol == nullptr)) {
for (Symbol *Sym : G.external_symbols())
if (Sym->getName() == ELFTOCSymbolName) {
if (Sym->hasName() && *Sym->getName() == ELFTOCSymbolName) {
TOCSymbol = Sym;
break;
}
@ -393,10 +393,12 @@ private:
public:
ELFLinkGraphBuilder_ppc64(StringRef FileName,
const object::ELFFile<ELFT> &Obj, Triple TT,
SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
FileName, ppc64::getEdgeKindName) {}
const object::ELFFile<ELFT> &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT, SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
std::move(Features), FileName,
ppc64::getEdgeKindName) {}
};
template <llvm::endianness Endianness>
@ -417,7 +419,8 @@ private:
Error defineTOCBase(LinkGraph &G) {
for (Symbol *Sym : G.defined_symbols()) {
if (LLVM_UNLIKELY(Sym->getName() == ELFTOCSymbolName)) {
if (LLVM_UNLIKELY(Sym->hasName() &&
*Sym->getName() == ELFTOCSymbolName)) {
TOCSymbol = Sym;
return Error::success();
}
@ -427,7 +430,7 @@ private:
"TOCSymbol should not be defined at this point");
for (Symbol *Sym : G.external_symbols()) {
if (Sym->getName() == ELFTOCSymbolName) {
if (Sym->hasName() && *Sym->getName() == ELFTOCSymbolName) {
TOCSymbol = Sym;
break;
}
@ -463,7 +466,8 @@ private:
template <llvm::endianness Endianness>
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -480,7 +484,7 @@ createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer) {
using ELFT = object::ELFType<Endianness, true>;
auto &ELFObjFile = cast<object::ELFObjectFile<ELFT>>(**ELFObj);
return ELFLinkGraphBuilder_ppc64<Endianness>(
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),
(*ELFObj)->makeTriple(), std::move(*Features))
.buildGraph();
}
@ -517,15 +521,16 @@ void link_ELF_ppc64(std::unique_ptr<LinkGraph> G,
}
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromELFObject_ppc64(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
return createLinkGraphFromELFObject_ppc64<llvm::endianness::big>(
std::move(ObjectBuffer));
std::move(ObjectBuffer), std::move(SSP));
}
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_ppc64le(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_ppc64le(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
return createLinkGraphFromELFObject_ppc64<llvm::endianness::little>(
std::move(ObjectBuffer));
std::move(ObjectBuffer), std::move(SSP));
}
/// jit-link the given object buffer, which must be a ELF ppc64 object file.

@ -927,14 +927,17 @@ private:
public:
ELFLinkGraphBuilder_riscv(StringRef FileName,
const object::ELFFile<ELFT> &Obj, Triple TT,
SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(TT), std::move(Features),
FileName, riscv::getEdgeKindName) {}
const object::ELFFile<ELFT> &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
Triple TT, SubtargetFeatures Features)
: ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
std::move(Features), FileName,
riscv::getEdgeKindName) {}
};
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -952,7 +955,7 @@ createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer) {
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
return ELFLinkGraphBuilder_riscv<object::ELF64LE>(
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
(*ELFObj)->makeTriple(), std::move(*Features))
std::move(SSP), (*ELFObj)->makeTriple(), std::move(*Features))
.buildGraph();
} else {
assert((*ELFObj)->getArch() == Triple::riscv32 &&
@ -960,7 +963,7 @@ createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer) {
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
return ELFLinkGraphBuilder_riscv<object::ELF32LE>(
(*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
(*ELFObj)->makeTriple(), std::move(*Features))
std::move(SSP), (*ELFObj)->makeTriple(), std::move(*Features))
.buildGraph();
}
}

@ -238,9 +238,10 @@ private:
public:
ELFLinkGraphBuilder_x86_64(StringRef FileName,
std::shared_ptr<orc::SymbolStringPool> SSP,
const object::ELFFile<object::ELF64LE> &Obj,
SubtargetFeatures Features)
: ELFLinkGraphBuilder(Obj, Triple("x86_64-unknown-linux"),
: ELFLinkGraphBuilder(Obj, std::move(SSP), Triple("x86_64-unknown-linux"),
std::move(Features), FileName,
x86_64::getEdgeKindName) {}
};
@ -261,12 +262,12 @@ public:
private:
Symbol *GOTSymbol = nullptr;
Error getOrCreateGOTSymbol(LinkGraph &G) {
auto DefineExternalGOTSymbolIfPresent =
createDefineExternalSectionStartAndEndSymbolsPass(
[&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
if (Sym.getName() == ELFGOTSymbolName)
if (Sym.getName() != nullptr &&
*Sym.getName() == ELFGOTSymbolName)
if (auto *GOTSection = G.findSectionByName(
x86_64::GOTTableManager::getSectionName())) {
GOTSymbol = &Sym;
@ -292,7 +293,7 @@ private:
// Check for an existing defined symbol.
for (auto *Sym : GOTSection->symbols())
if (Sym->getName() == ELFGOTSymbolName) {
if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {
GOTSymbol = Sym;
return Error::success();
}
@ -314,7 +315,7 @@ private:
// we just need to point the GOT symbol at some address in this graph.
if (!GOTSymbol) {
for (auto *Sym : G.external_symbols()) {
if (Sym->getName() == ELFGOTSymbolName) {
if (*Sym->getName() == ELFGOTSymbolName) {
auto Blocks = G.blocks();
if (!Blocks.empty()) {
G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());
@ -333,8 +334,8 @@ private:
}
};
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromELFObject_x86_64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
LLVM_DEBUG({
dbgs() << "Building jitlink graph for new input "
<< ObjectBuffer.getBufferIdentifier() << "...\n";
@ -349,7 +350,7 @@ createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer) {
return Features.takeError();
auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(),
return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(), std::move(SSP),
ELFObjFile.getELFFile(),
std::move(*Features))
.buildGraph();

@ -125,7 +125,7 @@ raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) {
<< ", linkage: " << formatv("{0:6}", getLinkageName(Sym.getLinkage()))
<< ", scope: " << formatv("{0:8}", getScopeName(Sym.getScope())) << ", "
<< (Sym.isLive() ? "live" : "dead") << " - "
<< (Sym.hasName() ? Sym.getName() : "<anonymous symbol>");
<< (Sym.hasName() ? *Sym.getName() : "<anonymous symbol>");
return OS;
}
@ -167,6 +167,16 @@ Section::~Section() {
B->~Block();
}
LinkGraph::~LinkGraph() {
for (auto *Sym : AbsoluteSymbols) {
Sym->~Symbol();
}
for (auto *Sym : external_symbols()) {
Sym->~Symbol();
}
ExternalSymbols.clear();
}
std::vector<Block *> LinkGraph::splitBlockImpl(std::vector<Block *> Blocks,
SplitBlockCache *Cache) {
assert(!Blocks.empty() && "Blocks must at least contain the original block");
@ -481,22 +491,25 @@ PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT) {
}
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromObject(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
auto Magic = identify_magic(ObjectBuffer.getBuffer());
switch (Magic) {
case file_magic::macho_object:
return createLinkGraphFromMachOObject(ObjectBuffer);
return createLinkGraphFromMachOObject(ObjectBuffer, std::move(SSP));
case file_magic::elf_relocatable:
return createLinkGraphFromELFObject(ObjectBuffer);
return createLinkGraphFromELFObject(ObjectBuffer, std::move(SSP));
case file_magic::coff_object:
return createLinkGraphFromCOFFObject(ObjectBuffer);
return createLinkGraphFromCOFFObject(ObjectBuffer, std::move(SSP));
default:
return make_error<JITLinkError>("Unsupported file format");
};
}
std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT,
orc::SymbolMap Symbols) {
std::unique_ptr<LinkGraph>
absoluteSymbolsLinkGraph(const Triple &TT,
std::shared_ptr<orc::SymbolStringPool> SSP,
orc::SymbolMap Symbols) {
unsigned PointerSize;
endianness Endianness =
TT.isLittleEndian() ? endianness::little : endianness::big;
@ -518,8 +531,8 @@ std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT,
static std::atomic<uint64_t> Counter = {0};
auto Index = Counter.fetch_add(1, std::memory_order_relaxed);
auto G = std::make_unique<LinkGraph>(
"<Absolute Symbols " + std::to_string(Index) + ">", TT, PointerSize,
Endianness, /*GetEdgeKindName=*/nullptr);
"<Absolute Symbols " + std::to_string(Index) + ">", std::move(SSP), TT,
PointerSize, Endianness, /*GetEdgeKindName=*/nullptr);
for (auto &[Name, Def] : Symbols) {
auto &Sym =
G->addAbsoluteSymbol(*Name, Def.getAddress(), /*Size=*/0,

@ -211,8 +211,7 @@ JITLinkContext::LookupMap JITLinkerBase::getExternalSymbolNames() const {
for (auto *Sym : G->external_symbols()) {
assert(!Sym->getAddress() &&
"External has already been assigned an address");
assert(Sym->getName() != StringRef() && Sym->getName() != "" &&
"Externals must be named");
assert(Sym->hasName() && "Externals must be named");
SymbolLookupFlags LookupFlags =
Sym->isWeaklyReferenced() ? SymbolLookupFlags::WeaklyReferencedSymbol
: SymbolLookupFlags::RequiredSymbol;

@ -144,6 +144,7 @@ orc::shared::AllocActions &BasicLayout::graphAllocActions() {
}
void SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr,
std::shared_ptr<orc::SymbolStringPool> SSP,
const JITLinkDylib *JD, SegmentMap Segments,
OnCreatedFunction OnCreated) {
@ -155,7 +156,7 @@ void SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr,
"__---.finalize", "__R--.finalize", "__-W-.finalize", "__RW-.finalize",
"__--X.finalize", "__R-X.finalize", "__-WX.finalize", "__RWX.finalize"};
auto G = std::make_unique<LinkGraph>("", Triple(), 0,
auto G = std::make_unique<LinkGraph>("", std::move(SSP), Triple(), 0,
llvm::endianness::native, nullptr);
orc::AllocGroupSmallMap<Block *> ContentBlocks;
@ -201,11 +202,12 @@ void SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr,
}
Expected<SimpleSegmentAlloc>
SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr, const JITLinkDylib *JD,
SegmentMap Segments) {
SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr,
std::shared_ptr<orc::SymbolStringPool> SSP,
const JITLinkDylib *JD, SegmentMap Segments) {
std::promise<MSVCPExpected<SimpleSegmentAlloc>> AllocP;
auto AllocF = AllocP.get_future();
Create(MemMgr, JD, std::move(Segments),
Create(MemMgr, std::move(SSP), JD, std::move(Segments),
[&](Expected<SimpleSegmentAlloc> Result) {
AllocP.set_value(std::move(Result));
});

@ -25,7 +25,8 @@ namespace llvm {
namespace jitlink {
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer) {
createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer,
std::shared_ptr<orc::SymbolStringPool> SSP) {
StringRef Data = ObjectBuffer.getBuffer();
if (Data.size() < 4)
return make_error<JITLinkError>("Truncated MachO buffer \"" +
@ -61,9 +62,10 @@ createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer) {
switch (CPUType) {
case MachO::CPU_TYPE_ARM64:
return createLinkGraphFromMachOObject_arm64(ObjectBuffer);
return createLinkGraphFromMachOObject_arm64(ObjectBuffer, std::move(SSP));
case MachO::CPU_TYPE_X86_64:
return createLinkGraphFromMachOObject_x86_64(ObjectBuffer);
return createLinkGraphFromMachOObject_x86_64(ObjectBuffer,
std::move(SSP));
}
return make_error<JITLinkError>("MachO-64 CPU type not valid");
} else

@ -49,13 +49,14 @@ Expected<std::unique_ptr<LinkGraph>> MachOLinkGraphBuilder::buildGraph() {
}
MachOLinkGraphBuilder::MachOLinkGraphBuilder(
const object::MachOObjectFile &Obj, Triple TT, SubtargetFeatures Features,
const object::MachOObjectFile &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
SubtargetFeatures Features,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
: Obj(Obj),
G(std::make_unique<LinkGraph>(std::string(Obj.getFileName()),
std::move(TT), std::move(Features),
getPointerSize(Obj), getEndianness(Obj),
std::move(GetEdgeKindName))) {
: Obj(Obj), G(std::make_unique<LinkGraph>(
std::string(Obj.getFileName()), std::move(SSP),
std::move(TT), std::move(Features), getPointerSize(Obj),
getEndianness(Obj), std::move(GetEdgeKindName))) {
auto &MachHeader = Obj.getHeader64();
SubsectionsViaSymbols = MachHeader.flags & MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
}
@ -319,9 +320,8 @@ Error MachOLinkGraphBuilder::createNormalizedSymbols() {
}
}
IndexToSymbol[SymbolIndex] =
&createNormalizedSymbol(*Name, Value, Type, Sect, Desc,
getLinkage(Desc), getScope(*Name, Type));
IndexToSymbol[SymbolIndex] = &createNormalizedSymbol(
Name, Value, Type, Sect, Desc, getLinkage(Desc), getScope(*Name, Type));
}
return Error::success();
@ -587,7 +587,7 @@ Symbol &MachOLinkGraphBuilder::createStandardGraphSymbol(NormalizedSymbol &NSym,
if (!NSym.Name)
dbgs() << "<anonymous symbol>";
else
dbgs() << NSym.Name;
dbgs() << *NSym.Name;
if (IsText)
dbgs() << " [text]";
if (IsNoDeadStrip)
@ -726,7 +726,7 @@ Error MachOLinkGraphBuilder::graphifyCStringSection(
LLVM_DEBUG({
dbgs() << " Adding symbol for c-string block " << B.getRange()
<< ": "
<< (Sym.hasName() ? Sym.getName() : "<anonymous symbol>")
<< (Sym.hasName() ? *Sym.getName() : "<anonymous symbol>")
<< " at offset " << formatv("{0:x}", Sym.getOffset()) << "\n";
});
@ -826,7 +826,7 @@ Error CompactUnwindSplitter::operator()(LinkGraph &G) {
LLVM_DEBUG({
dbgs() << " Updating compact unwind record at "
<< CURec->getAddress() << " to point to "
<< (E.getTarget().hasName() ? E.getTarget().getName()
<< (E.getTarget().hasName() ? *E.getTarget().getName()
: StringRef())
<< " (at " << E.getTarget().getAddress() << ")\n";
});
@ -835,7 +835,7 @@ Error CompactUnwindSplitter::operator()(LinkGraph &G) {
return make_error<JITLinkError>(
"Error adding keep-alive edge for compact unwind record at " +
formatv("{0:x}", CURec->getAddress()) + ": target " +
E.getTarget().getName() + " is an external symbol");
*E.getTarget().getName() + " is an external symbol");
auto &TgtBlock = E.getTarget().getBlock();
auto &CURecSym =
G.addAnonymousSymbol(*CURec, 0, CURecordSize, false, false);

@ -83,10 +83,10 @@ protected:
using SectionParserFunction = std::function<Error(NormalizedSection &S)>;
MachOLinkGraphBuilder(const object::MachOObjectFile &Obj, Triple TT,
MachOLinkGraphBuilder(const object::MachOObjectFile &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
SubtargetFeatures Features,
LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
LinkGraph &getGraph() const { return *G; }
const object::MachOObjectFile &getObject() const { return Obj; }

@ -27,9 +27,10 @@ namespace {
class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder {
public:
MachOLinkGraphBuilder_arm64(const object::MachOObjectFile &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
SubtargetFeatures Features)
: MachOLinkGraphBuilder(Obj, getObjectTriple(Obj), std::move(Features),
aarch64::getEdgeKindName),
: MachOLinkGraphBuilder(Obj, std::move(SSP), getObjectTriple(Obj),
std::move(Features), aarch64::getEdgeKindName),
NumSymbols(Obj.getSymtabLoadCommand().nsyms) {}
private:
@ -580,8 +581,8 @@ private:
uint64_t NullValue = 0;
};
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_arm64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer);
if (!MachOObj)
return MachOObj.takeError();
@ -590,7 +591,8 @@ createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer) {
if (!Features)
return Features.takeError();
return MachOLinkGraphBuilder_arm64(**MachOObj, std::move(*Features))
return MachOLinkGraphBuilder_arm64(**MachOObj, std::move(SSP),
std::move(*Features))
.buildGraph();
}

@ -27,8 +27,10 @@ namespace {
class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder {
public:
MachOLinkGraphBuilder_x86_64(const object::MachOObjectFile &Obj,
std::shared_ptr<orc::SymbolStringPool> SSP,
SubtargetFeatures Features)
: MachOLinkGraphBuilder(Obj, Triple("x86_64-apple-darwin"),
: MachOLinkGraphBuilder(Obj, std::move(SSP),
Triple("x86_64-apple-darwin"),
std::move(Features), x86_64::getEdgeKindName) {}
private:
@ -483,8 +485,8 @@ private:
}
};
Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer) {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromMachOObject_x86_64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer);
if (!MachOObj)
return MachOObj.takeError();
@ -493,7 +495,8 @@ createLinkGraphFromMachOObject_x86_64(MemoryBufferRef ObjectBuffer) {
if (!Features)
return Features.takeError();
return MachOLinkGraphBuilder_x86_64(**MachOObj, std::move(*Features))
return MachOLinkGraphBuilder_x86_64(**MachOObj, std::move(SSP),
std::move(*Features))
.buildGraph();
}

@ -114,8 +114,8 @@ protected:
private:
BuilderImplT &impl() { return static_cast<BuilderImplT &>(*this); }
DenseMap<StringRef, Symbol *> GOTEntries;
DenseMap<StringRef, Symbol *> PLTStubs;
DenseMap<orc::SymbolStringPtr, Symbol *> GOTEntries;
DenseMap<orc::SymbolStringPtr, Symbol *> PLTStubs;
};
} // end namespace jitlink

@ -852,7 +852,7 @@ bool StubsManager_prev7::visitEdge(LinkGraph &G, Block *B, Edge &E) {
Symbol &Target = E.getTarget();
assert(Target.hasName() && "Edge cannot point to anonymous target");
auto [Slot, NewStub] = getStubMapSlot(Target.getName());
auto [Slot, NewStub] = getStubMapSlot(*Target.getName());
if (NewStub) {
if (!StubsSection)
@ -896,7 +896,7 @@ bool StubsManager_v7::visitEdge(LinkGraph &G, Block *B, Edge &E) {
Symbol &Target = E.getTarget();
assert(Target.hasName() && "Edge cannot point to anonymous target");
Symbol *&StubSymbol = getStubSymbolSlot(Target.getName(), MakeThumb);
Symbol *&StubSymbol = getStubSymbolSlot(*Target.getName(), MakeThumb);
if (!StubSymbol) {
if (!StubsSection)

@ -68,8 +68,8 @@ public:
}
auto G = std::make_unique<jitlink::LinkGraph>(
"<COFFHeaderMU>", TT, PointerSize, Endianness,
jitlink::getGenericEdgeKindName);
"<COFFHeaderMU>", CP.getExecutionSession().getSymbolStringPool(), TT,
PointerSize, Endianness, jitlink::getGenericEdgeKindName);
auto &HeaderSection = G->createSection("__header", MemProt::Read);
auto &HeaderBlock = createHeaderBlock(*G, HeaderSection);
@ -792,7 +792,7 @@ Error COFFPlatform::COFFPlatformPlugin::associateJITDylibHeaderSymbol(
jitlink::LinkGraph &G, MaterializationResponsibility &MR,
bool IsBootstraping) {
auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
return Sym->getName() == *CP.COFFHeaderStartSymbol;
return *Sym->getName() == *CP.COFFHeaderStartSymbol;
});
assert(I != G.defined_symbols().end() && "Missing COFF header start symbol");

@ -149,9 +149,9 @@ protected:
JITLinkMemoryManager &MemMgr;
const JITLinkDylib *JD = nullptr;
ExecutionSession &ES;
private:
ExecutionSession &ES;
DebugObjectFlags Flags;
FinalizedAlloc Alloc;
};
@ -331,8 +331,9 @@ Expected<SimpleSegmentAlloc> ELFDebugObject::finalizeWorkingMemory() {
size_t Size = Buffer->getBufferSize();
// Allocate working memory for debug object in read-only segment.
auto Alloc = SimpleSegmentAlloc::Create(
MemMgr, JD, {{MemProt::Read, {Size, Align(PageSize)}}});
auto Alloc =
SimpleSegmentAlloc::Create(MemMgr, ES.getSymbolStringPool(), JD,
{{MemProt::Read, {Size, Align(PageSize)}}});
if (!Alloc)
return Alloc;

@ -214,8 +214,8 @@ public:
Builder.addSymbol("", MachO::N_BNSYM, 1, 0, 0);
StabSymbols.push_back(
{*Sym, Builder.addSymbol(Sym->getName(), SymType, 1, 0, 0),
Builder.addSymbol(Sym->getName(), SymType, 0, 0, 0)});
{*Sym, Builder.addSymbol(*Sym->getName(), SymType, 1, 0, 0),
Builder.addSymbol(*Sym->getName(), SymType, 0, 0, 0)});
Builder.addSymbol("", MachO::N_ENSYM, 1, 0, 0);
}
}

@ -86,7 +86,7 @@ constexpr StringRef RegisterPerfImplSymbolName =
static PerfJITCodeLoadRecord
getCodeLoadRecord(const Symbol &Sym, std::atomic<uint64_t> &CodeIndex) {
PerfJITCodeLoadRecord Record;
auto Name = Sym.getName();
auto Name = *Sym.getName();
auto Addr = Sym.getAddress();
auto Size = Sym.getSize();
Record.Prefix.Id = PerfJITRecordType::JIT_CODE_LOAD;

@ -56,7 +56,7 @@ static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo) {
Method.ParentMI = 0;
Method.LoadAddr = Sym->getAddress();
Method.LoadSize = Sym->getSize();
Method.NameSI = GetStringIdx(Sym->getName());
Method.NameSI = GetStringIdx(*Sym->getName());
Method.ClassFileSI = 0;
Method.SourceFileSI = 0;

@ -65,9 +65,9 @@ std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(ELFNixPlatform &MOP,
llvm_unreachable("Unrecognized architecture");
}
return std::make_unique<jitlink::LinkGraph>(std::move(Name), TT, PointerSize,
Endianness,
jitlink::getGenericEdgeKindName);
return std::make_unique<jitlink::LinkGraph>(
std::move(Name), MOP.getExecutionSession().getSymbolStringPool(), TT,
PointerSize, Endianness, jitlink::getGenericEdgeKindName);
}
// Creates a Bootstrap-Complete LinkGraph to run deferred actions.
@ -188,8 +188,8 @@ public:
// void *__dso_handle = &__dso_handle;
auto G = std::make_unique<jitlink::LinkGraph>(
"<DSOHandleMU>", TT, PointerSize, Endianness,
jitlink::getGenericEdgeKindName);
"<DSOHandleMU>", ENP.getExecutionSession().getSymbolStringPool(), TT,
PointerSize, Endianness, jitlink::getGenericEdgeKindName);
auto &DSOHandleSection =
G->createSection(".data.__dso_handle", MemProt::Read);
auto &DSOHandleBlock = G->createContentBlock(
@ -663,14 +663,14 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::
for (auto *Sym : G.defined_symbols()) {
for (auto &RTSym : RuntimeSymbols) {
if (Sym->hasName() && Sym->getName() == RTSym.first) {
if (Sym->hasName() && *Sym->getName() == RTSym.first) {
if (*RTSym.second)
return make_error<StringError>(
"Duplicate " + RTSym.first +
" detected during ELFNixPlatform bootstrap",
inconvertibleErrorCode());
if (Sym->getName() == *MP.DSOHandleSymbol)
if (*Sym->getName() == *MP.DSOHandleSymbol)
RegisterELFNixHeader = true;
*RTSym.second = Sym->getAddress();
@ -798,7 +798,7 @@ void ELFNixPlatform::ELFNixPlatformPlugin::addDSOHandleSupportPasses(
Config.PostAllocationPasses.push_back([this, &JD = MR.getTargetJITDylib()](
jitlink::LinkGraph &G) -> Error {
auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
return Sym->getName() == *MP.DSOHandleSymbol;
return Sym->getName() == MP.DSOHandleSymbol;
});
assert(I != G.defined_symbols().end() && "Missing DSO handle symbol");
{
@ -997,12 +997,17 @@ Error ELFNixPlatform::ELFNixPlatformPlugin::registerInitSections(
Error ELFNixPlatform::ELFNixPlatformPlugin::fixTLVSectionsAndEdges(
jitlink::LinkGraph &G, JITDylib &JD) {
auto TLSGetAddrSymbolName = G.intern("__tls_get_addr");
auto TLSDescResolveSymbolName = G.intern("__tlsdesc_resolver");
for (auto *Sym : G.external_symbols()) {
if (Sym->getName() == "__tls_get_addr") {
Sym->setName("___orc_rt_elfnix_tls_get_addr");
} else if (Sym->getName() == "__tlsdesc_resolver") {
Sym->setName("___orc_rt_elfnix_tlsdesc_resolver");
if (Sym->getName() == TLSGetAddrSymbolName) {
auto TLSGetAddr =
MP.getExecutionSession().intern("___orc_rt_elfnix_tls_get_addr");
Sym->setName(std::move(TLSGetAddr));
} else if (Sym->getName() == TLSDescResolveSymbolName) {
auto TLSGetAddr =
MP.getExecutionSession().intern("___orc_rt_elfnix_tlsdesc_resolver");
Sym->setName(std::move(TLSGetAddr));
}
}

@ -110,7 +110,7 @@ Error EPCTrampolinePool::grow() {
auto &EPC = EPCIU.getExecutorProcessControl();
auto PageSize = EPC.getPageSize();
auto Alloc = SimpleSegmentAlloc::Create(
EPC.getMemMgr(), nullptr,
EPC.getMemMgr(), EPC.getSymbolStringPool(), nullptr,
{{MemProt::Read | MemProt::Exec, {PageSize, Align(PageSize)}}});
if (!Alloc)
return Alloc.takeError();
@ -294,10 +294,10 @@ EPCIndirectionUtils::writeResolverBlock(ExecutorAddr ReentryFnAddr,
assert(ABI && "ABI can not be null");
auto ResolverSize = ABI->getResolverCodeSize();
auto Alloc =
SimpleSegmentAlloc::Create(EPC.getMemMgr(), nullptr,
{{MemProt::Read | MemProt::Exec,
{ResolverSize, Align(EPC.getPageSize())}}});
auto Alloc = SimpleSegmentAlloc::Create(
EPC.getMemMgr(), EPC.getSymbolStringPool(), nullptr,
{{MemProt::Read | MemProt::Exec,
{ResolverSize, Align(EPC.getPageSize())}}});
if (!Alloc)
return Alloc.takeError();
@ -363,7 +363,7 @@ EPCIndirectionUtils::getIndirectStubs(unsigned NumStubs) {
auto PtrProt = MemProt::Read | MemProt::Write;
auto Alloc = SimpleSegmentAlloc::Create(
EPC.getMemMgr(), nullptr,
EPC.getMemMgr(), EPC.getSymbolStringPool(), nullptr,
{{StubProt, {static_cast<size_t>(StubBytes), Align(PageSize)}},
{PtrProt, {static_cast<size_t>(PtrBytes), Align(PageSize)}}});

@ -13,6 +13,7 @@
#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"
#include "llvm/ExecutionEngine/Orc/MachO.h"
#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
@ -559,8 +560,8 @@ DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) {
return Endianness.takeError();
auto G = std::make_unique<jitlink::LinkGraph>(
"<DLLIMPORT_STUBS>", TT, *PointerSize, *Endianness,
jitlink::getGenericEdgeKindName);
"<DLLIMPORT_STUBS>", ES.getSymbolStringPool(), TT, *PointerSize,
*Endianness, jitlink::getGenericEdgeKindName);
jitlink::Section &Sec =
G->createSection(getSectionName(), MemProt::Read | MemProt::Exec);
@ -572,9 +573,8 @@ DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) {
// Create __imp_ symbol
jitlink::Symbol &Ptr =
jitlink::x86_64::createAnonymousPointer(*G, Sec, &Target);
auto NameCopy = G->allocateContent(Twine(getImpPrefix()) + *KV.first);
StringRef NameCopyRef = StringRef(NameCopy.data(), NameCopy.size());
Ptr.setName(NameCopyRef);
auto name = getImpPrefix() + *KV.first;
Ptr.setName(G->intern((Twine(getImpPrefix()) + *KV.first).str()));
Ptr.setLinkage(jitlink::Linkage::Strong);
Ptr.setScope(jitlink::Scope::Default);

@ -27,8 +27,8 @@ void JITLinkRedirectableSymbolManager::emitRedirectableSymbols(
Triple TT = ES.getTargetTriple();
auto G = std::make_unique<jitlink::LinkGraph>(
("<indirect stubs graph #" + Twine(++StubGraphIdx) + ">").str(), TT,
TT.isArch64Bit() ? 8 : 4,
("<indirect stubs graph #" + Twine(++StubGraphIdx) + ">").str(),
ES.getSymbolStringPool(), TT, TT.isArch64Bit() ? 8 : 4,
TT.isLittleEndian() ? endianness::little : endianness::big,
jitlink::getGenericEdgeKindName);
auto &PointerSection =
@ -46,10 +46,10 @@ void JITLinkRedirectableSymbolManager::emitRedirectableSymbols(
auto PtrName = ES.intern((*Name + StubSuffix).str());
auto &Ptr = AnonymousPtrCreator(*G, PointerSection, TargetSym, 0);
Ptr.setName(*PtrName);
Ptr.setName(PtrName);
Ptr.setScope(jitlink::Scope::Hidden);
auto &Stub = PtrJumpStubCreator(*G, StubsSection, Ptr);
Stub.setName(*Name);
Stub.setName(Name);
Stub.setScope(jitlink::Scope::Default);
NewSymbols[std::move(PtrName)] = JITSymbolFlags();
}

@ -60,10 +60,10 @@ private:
for (auto *Sym : G.defined_symbols()) {
if (!Sym->hasName())
continue;
auto I = SymsToRename.find(Sym->getName());
auto I = SymsToRename.find(*Sym->getName());
if (I == SymsToRename.end())
continue;
Sym->setName(G.allocateName(*I->second));
Sym->setName(G.intern(G.allocateName(*I->second)));
}
return Error::success();

@ -108,9 +108,9 @@ std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(MachOPlatform &MOP,
llvm_unreachable("Unrecognized architecture");
}
return std::make_unique<jitlink::LinkGraph>(std::move(Name), TT, PointerSize,
Endianness,
jitlink::getGenericEdgeKindName);
return std::make_unique<jitlink::LinkGraph>(
std::move(Name), MOP.getExecutionSession().getSymbolStringPool(), TT,
PointerSize, Endianness, jitlink::getGenericEdgeKindName);
}
// Creates a Bootstrap-Complete LinkGraph to run deferred actions.
@ -893,14 +893,14 @@ Error MachOPlatform::MachOPlatformPlugin::
for (auto *Sym : G.defined_symbols()) {
for (auto &RTSym : RuntimeSymbols) {
if (Sym->hasName() && Sym->getName() == RTSym.first) {
if (Sym->hasName() && *Sym->getName() == RTSym.first) {
if (*RTSym.second)
return make_error<StringError>(
"Duplicate " + RTSym.first +
" detected during MachOPlatform bootstrap",
inconvertibleErrorCode());
if (Sym->getName() == *MP.MachOHeaderStartSymbol)
if (Sym->getName() == MP.MachOHeaderStartSymbol)
RegisterMachOHeader = true;
*RTSym.second = Sym->getAddress();
@ -936,7 +936,7 @@ Error MachOPlatform::MachOPlatformPlugin::bootstrapPipelineEnd(
Error MachOPlatform::MachOPlatformPlugin::associateJITDylibHeaderSymbol(
jitlink::LinkGraph &G, MaterializationResponsibility &MR) {
auto I = llvm::find_if(G.defined_symbols(), [this](jitlink::Symbol *Sym) {
return Sym->getName() == *MP.MachOHeaderStartSymbol;
return Sym->getName() == MP.MachOHeaderStartSymbol;
});
assert(I != G.defined_symbols().end() && "Missing MachO header start symbol");
@ -1175,11 +1175,13 @@ Error MachOPlatform::MachOPlatformPlugin::mergeImageInfoFlags(
Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
jitlink::LinkGraph &G, JITDylib &JD) {
auto TLVBootStrapSymbolName = G.intern("__tlv_bootstrap");
// Rename external references to __tlv_bootstrap to ___orc_rt_tlv_get_addr.
for (auto *Sym : G.external_symbols())
if (Sym->getName() == "__tlv_bootstrap") {
Sym->setName("___orc_rt_macho_tlv_get_addr");
if (Sym->getName() == TLVBootStrapSymbolName) {
auto TLSGetADDR =
MP.getExecutionSession().intern("___orc_rt_macho_tlv_get_addr");
Sym->setName(std::move(TLSGetADDR));
break;
}
@ -1499,19 +1501,19 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
// Look for an existing __objc_imageinfo symbol.
jitlink::Symbol *ObjCImageInfoSym = nullptr;
for (auto *Sym : G.external_symbols())
if (Sym->getName() == ObjCImageInfoSymbolName) {
if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
ObjCImageInfoSym = Sym;
break;
}
if (!ObjCImageInfoSym)
for (auto *Sym : G.absolute_symbols())
if (Sym->getName() == ObjCImageInfoSymbolName) {
if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
ObjCImageInfoSym = Sym;
break;
}
if (!ObjCImageInfoSym)
for (auto *Sym : G.defined_symbols())
if (Sym->hasName() && Sym->getName() == ObjCImageInfoSymbolName) {
if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
ObjCImageInfoSym = Sym;
std::optional<uint32_t> Flags;
{
@ -1652,11 +1654,11 @@ Error MachOPlatform::MachOPlatformPlugin::prepareSymbolTableRegistration(
if (!Sym->hasName())
continue;
auto I = ExistingStrings.find(Sym->getName());
auto I = ExistingStrings.find(*Sym->getName());
if (I == ExistingStrings.end()) {
auto &NameBlock = G.createMutableContentBlock(
*CStringSec, G.allocateCString(Sym->getName()), orc::ExecutorAddr(),
1, 0);
*CStringSec, G.allocateCString(*Sym->getName()),
orc::ExecutorAddr(), 1, 0);
auto &SymbolNameSym = G.addAnonymousSymbol(
NameBlock, 0, NameBlock.getSize(), false, true);
JITSymTabInfo.push_back({Sym, &SymbolNameSym});

@ -129,7 +129,7 @@ getELFObjectFileSymbolInfo(ExecutionSession &ES,
if (Sym.getBinding() == ELF::STB_GNU_UNIQUE)
*SymFlags |= JITSymbolFlags::Weak;
I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
I.SymbolFlags[ES.intern(std::move(*Name))] = std::move(*SymFlags);
}
SymbolStringPtr InitSymbol;

@ -100,8 +100,7 @@ private:
return;
assert(Sym->hasName() && "Anonymous non-local symbol?");
LGI.SymbolFlags[ES.intern(Sym->getName())] =
getJITSymbolFlagsForSymbol(*Sym);
LGI.SymbolFlags[Sym->getName()] = getJITSymbolFlagsForSymbol(*Sym);
};
for (auto *Sym : G.defined_symbols())
@ -129,7 +128,7 @@ private:
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
for (auto *Sym : G->defined_symbols())
if (Sym->getName() == *Name) {
if (Sym->getName() == Name) {
assert(Sym->getLinkage() == Linkage::Weak &&
"Discarding non-weak definition");
G->makeExternal(*Sym);
@ -204,7 +203,7 @@ public:
LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol;
break;
}
LookupSet.add(ES.intern(KV.first), LookupFlags);
LookupSet.add(KV.first, LookupFlags);
}
// OnResolve -- De-intern the symbols and pass the result to the linker.
@ -215,7 +214,7 @@ public:
else {
AsyncLookupResult LR;
for (auto &KV : *Result)
LR[*KV.first] = KV.second;
LR[KV.first] = KV.second;
LookupContinuation->run(std::move(LR));
}
};
@ -231,7 +230,6 @@ public:
}
Error notifyResolved(LinkGraph &G) override {
auto &ES = Layer.getExecutionSession();
SymbolFlagsMap ExtraSymbolsToClaim;
bool AutoClaim = Layer.AutoClaimObjectSymbols;
@ -239,27 +237,25 @@ public:
SymbolMap InternedResult;
for (auto *Sym : G.defined_symbols())
if (Sym->getScope() < Scope::SideEffectsOnly) {
auto InternedName = ES.intern(Sym->getName());
auto Ptr = getJITSymbolPtrForSymbol(*Sym, G.getTargetTriple());
auto Flags = getJITSymbolFlagsForSymbol(*Sym);
InternedResult[InternedName] = {Ptr, Flags};
if (AutoClaim && !MR->getSymbols().count(InternedName)) {
assert(!ExtraSymbolsToClaim.count(InternedName) &&
InternedResult[Sym->getName()] = {Ptr, Flags};
if (AutoClaim && !MR->getSymbols().count(Sym->getName())) {
assert(!ExtraSymbolsToClaim.count(Sym->getName()) &&
"Duplicate symbol to claim?");
ExtraSymbolsToClaim[InternedName] = Flags;
ExtraSymbolsToClaim[Sym->getName()] = Flags;
}
}
for (auto *Sym : G.absolute_symbols())
if (Sym->getScope() < Scope::SideEffectsOnly) {
auto InternedName = ES.intern(Sym->getName());
auto Ptr = getJITSymbolPtrForSymbol(*Sym, G.getTargetTriple());
auto Flags = getJITSymbolFlagsForSymbol(*Sym);
InternedResult[InternedName] = {Ptr, Flags};
if (AutoClaim && !MR->getSymbols().count(InternedName)) {
assert(!ExtraSymbolsToClaim.count(InternedName) &&
InternedResult[Sym->getName()] = {Ptr, Flags};
if (AutoClaim && !MR->getSymbols().count(Sym->getName())) {
assert(!ExtraSymbolsToClaim.count(Sym->getName()) &&
"Duplicate symbol to claim?");
ExtraSymbolsToClaim[InternedName] = Flags;
ExtraSymbolsToClaim[Sym->getName()] = Flags;
}
}
@ -379,19 +375,16 @@ public:
private:
Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) {
auto &ES = Layer.getExecutionSession();
SymbolFlagsMap NewSymbolsToClaim;
std::vector<std::pair<SymbolStringPtr, Symbol *>> NameToSym;
auto ProcessSymbol = [&](Symbol *Sym) {
if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak &&
Sym->getScope() != Scope::Local) {
auto Name = ES.intern(Sym->getName());
if (!MR->getSymbols().count(ES.intern(Sym->getName()))) {
NewSymbolsToClaim[Name] =
if (!MR->getSymbols().count(Sym->getName())) {
NewSymbolsToClaim[Sym->getName()] =
getJITSymbolFlagsForSymbol(*Sym) | JITSymbolFlags::Weak;
NameToSym.push_back(std::make_pair(std::move(Name), Sym));
NameToSym.push_back(std::make_pair(Sym->getName(), Sym));
}
}
};
@ -421,9 +414,8 @@ private:
}
Error markResponsibilitySymbolsLive(LinkGraph &G) const {
auto &ES = Layer.getExecutionSession();
for (auto *Sym : G.defined_symbols())
if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName())))
if (Sym->hasName() && MR->getSymbols().count(Sym->getName()))
Sym->setLive(true);
return Error::success();
}
@ -558,15 +550,6 @@ private:
// SymbolDependenceGroups (in the SymbolDepGroups member), ready for use in
// the upcoming notifyFinalized call.
auto &TargetJD = MR->getTargetJITDylib();
auto &ES = TargetJD.getExecutionSession();
DenseMap<Symbol *, SymbolStringPtr> InternedNames;
auto GetInternedName = [&](Symbol *S) {
auto &Name = InternedNames[S];
if (!Name)
Name = ES.intern(S->getName());
return Name;
};
for (auto &[B, BI] : BlockInfos) {
if (!BI.Defs.empty()) {
@ -574,10 +557,10 @@ private:
auto &SDG = SymbolDepGroups.back();
for (auto *Def : BI.Defs)
SDG.Symbols.insert(GetInternedName(Def));
SDG.Symbols.insert(Def->getName());
for (auto *Dep : BI.SymbolDeps) {
auto DepName = GetInternedName(Dep);
auto DepName = Dep->getName();
if (Dep->isDefined())
SDG.Dependencies[&TargetJD].insert(std::move(DepName));
else {
@ -643,8 +626,8 @@ void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>(
*this, std::move(R), std::move(O));
if (auto G = createLinkGraphFromObject(ObjBuffer)) {
if (auto G = createLinkGraphFromObject(
ObjBuffer, getExecutionSession().getSymbolStringPool())) {
Ctx->notifyMaterializing(**G);
link(std::move(*G), std::move(Ctx));
} else {

@ -18,6 +18,7 @@ void SectCreateMaterializationUnit::materialize(
std::unique_ptr<MaterializationResponsibility> R) {
auto G = std::make_unique<LinkGraph>(
"orc_sectcreate_" + SectName,
ObjLinkingLayer.getExecutionSession().getSymbolStringPool(),
ObjLinkingLayer.getExecutionSession().getTargetTriple(),
getGenericEdgeKindName);

@ -14,6 +14,7 @@
#include "Targets/RuntimeDyldELFMips.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Endian.h"

@ -15,6 +15,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"

@ -365,7 +365,7 @@ static raw_ostream &
operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
OS << "Symbols:\n";
for (auto &SKV : SIM)
OS << " \"" << SKV.first() << "\" " << SKV.second << "\n";
OS << " \"" << SKV.first << "\" " << SKV.second << "\n";
return OS;
}
@ -416,8 +416,8 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
continue;
if (Sym->getLinkage() == Linkage::Weak) {
if (!S.CanonicalWeakDefs.count(Sym->getName()) ||
S.CanonicalWeakDefs[Sym->getName()] != G.getName()) {
if (!S.CanonicalWeakDefs.count(*Sym->getName()) ||
S.CanonicalWeakDefs[*Sym->getName()] != G.getName()) {
LLVM_DEBUG({
dbgs() << " Externalizing weak symbol " << Sym->getName() << "\n";
});
@ -426,18 +426,18 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
LLVM_DEBUG({
dbgs() << " Making weak symbol " << Sym->getName() << " strong\n";
});
if (S.HarnessExternals.count(Sym->getName()))
if (S.HarnessExternals.count(*Sym->getName()))
Sym->setScope(Scope::Default);
else
Sym->setScope(Scope::Hidden);
Sym->setLinkage(Linkage::Strong);
}
} else if (S.HarnessExternals.count(Sym->getName())) {
} else if (S.HarnessExternals.count(*Sym->getName())) {
LLVM_DEBUG(dbgs() << " Promoting " << Sym->getName() << "\n");
Sym->setScope(Scope::Default);
Sym->setLive(true);
continue;
} else if (S.HarnessDefinitions.count(Sym->getName())) {
} else if (S.HarnessDefinitions.count(*Sym->getName())) {
LLVM_DEBUG(dbgs() << " Externalizing " << Sym->getName() << "\n");
DefinitionsToRemove.push_back(Sym);
}
@ -1306,9 +1306,9 @@ Error Session::FileInfo::registerGOTEntry(
auto TS = GetSymbolTarget(G, Sym.getBlock());
if (!TS)
return TS.takeError();
GOTEntryInfos[TS->getName()] = {Sym.getSymbolContent(),
Sym.getAddress().getValue(),
Sym.getTargetFlags()};
GOTEntryInfos[*TS->getName()] = {Sym.getSymbolContent(),
Sym.getAddress().getValue(),
Sym.getTargetFlags()};
return Error::success();
}
@ -1322,7 +1322,7 @@ Error Session::FileInfo::registerStubEntry(
if (!TS)
return TS.takeError();
SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[TS->getName()];
SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*TS->getName()];
Entry.insert(Entry.begin(),
{Sym.getSymbolContent(), Sym.getAddress().getValue(),
Sym.getTargetFlags()});
@ -1340,7 +1340,7 @@ Error Session::FileInfo::registerMultiStubEntry(
if (!Target)
return Target.takeError();
SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[Target->getName()];
SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*Target->getName()];
Entry.emplace_back(Sym.getSymbolContent(), Sym.getAddress().getValue(),
Sym.getTargetFlags());
@ -1485,15 +1485,16 @@ Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {
return GOTInfoItr->second;
}
bool Session::isSymbolRegistered(StringRef SymbolName) {
bool Session::isSymbolRegistered(const orc::SymbolStringPtr &SymbolName) {
return SymbolInfos.count(SymbolName);
}
Expected<Session::MemoryRegionInfo &>
Session::findSymbolInfo(StringRef SymbolName, Twine ErrorMsgStem) {
Session::findSymbolInfo(const orc::SymbolStringPtr &SymbolName,
Twine ErrorMsgStem) {
auto SymInfoItr = SymbolInfos.find(SymbolName);
if (SymInfoItr == SymbolInfos.end())
return make_error<StringError>(ErrorMsgStem + ": symbol " + SymbolName +
return make_error<StringError>(ErrorMsgStem + ": symbol " + *SymbolName +
" not found",
inconvertibleErrorCode());
return SymInfoItr->second;
@ -1719,12 +1720,13 @@ static Error addAbsoluteSymbols(Session &S,
AbsDefStmt + "\"",
inconvertibleErrorCode());
ExecutorSymbolDef AbsDef(ExecutorAddr(Addr), JITSymbolFlags::Exported);
if (auto Err = JD.define(absoluteSymbols({{S.ES.intern(Name), AbsDef}})))
auto InternedName = S.ES.intern(Name);
if (auto Err = JD.define(absoluteSymbols({{InternedName, AbsDef}})))
return Err;
// Register the absolute symbol with the session symbol infos.
S.SymbolInfos[Name] = {ArrayRef<char>(), Addr,
AbsDef.getFlags().getTargetFlags()};
S.SymbolInfos[InternedName] = {ArrayRef<char>(), Addr,
AbsDef.getFlags().getTargetFlags()};
}
return Error::success();
@ -2330,11 +2332,13 @@ static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
LLVM_DEBUG(dbgs() << "Running checks...\n");
auto IsSymbolValid = [&S](StringRef Symbol) {
return S.isSymbolRegistered(Symbol);
auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
return S.isSymbolRegistered(InternedSymbol);
};
auto GetSymbolInfo = [&S](StringRef Symbol) {
return S.findSymbolInfo(Symbol, "Can not get symbol info");
auto InternedSymbol = S.ES.getSymbolStringPool()->intern(Symbol);
return S.findSymbolInfo(InternedSymbol, "Can not get symbol info");
};
auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {

@ -78,7 +78,6 @@ struct Session {
using LinkGraph = jitlink::LinkGraph;
using GetSymbolTargetFunction =
unique_function<Expected<Symbol &>(LinkGraph &G, jitlink::Block &)>;
Error registerGOTEntry(LinkGraph &G, Symbol &Sym,
GetSymbolTargetFunction GetSymbolTarget);
Error registerStubEntry(LinkGraph &G, Symbol &Sym,
@ -88,7 +87,7 @@ struct Session {
};
using DynLibJDMap = std::map<std::string, orc::JITDylib *, std::less<>>;
using SymbolInfoMap = StringMap<MemoryRegionInfo>;
using SymbolInfoMap = DenseMap<orc::SymbolStringPtr, MemoryRegionInfo>;
using FileInfoMap = StringMap<FileInfo>;
Expected<orc::JITDylib *> getOrLoadDynamicLibrary(StringRef LibPath);
@ -111,8 +110,8 @@ struct Session {
Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName,
StringRef TargetName);
bool isSymbolRegistered(StringRef Name);
Expected<MemoryRegionInfo &> findSymbolInfo(StringRef SymbolName,
bool isSymbolRegistered(const orc::SymbolStringPtr &Name);
Expected<MemoryRegionInfo &> findSymbolInfo(const orc::SymbolStringPtr &Name,
Twine ErrorMsgStem);
DynLibJDMap DynLibJDs;

@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
#include <llvm/ExecutionEngine/JITLink/aarch32.h>
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
#include <llvm/ExecutionEngine/JITLink/aarch32.h>
using namespace llvm;
using namespace llvm::jitlink;
@ -18,9 +18,10 @@ using namespace llvm::support;
using namespace llvm::support::endian;
constexpr unsigned PointerSize = 4;
auto G = std::make_unique<LinkGraph>("foo", Triple("armv7-linux-gnueabi"),
PointerSize, endianness::little,
aarch32::getEdgeKindName);
auto G = std::make_unique<LinkGraph>(
"foo", std::make_shared<orc::SymbolStringPool>(),
Triple("armv7-linux-gnueabi"), PointerSize, endianness::little,
aarch32::getEdgeKindName);
auto &Sec =
G->createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -46,9 +47,10 @@ public:
static void SetUpTestCase() {}
void SetUp() override {
G = std::make_unique<LinkGraph>("foo", Triple("armv7-linux-gnueabi"),
PointerSize, endianness::little,
aarch32::getEdgeKindName);
G = std::make_unique<LinkGraph>(
"foo", std::make_shared<orc::SymbolStringPool>(),
Triple("armv7-linux-gnueabi"), PointerSize, endianness::little,
aarch32::getEdgeKindName);
S = &G->createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
}

@ -172,7 +172,8 @@ TEST(EHFrameCFIBlockInspector, BasicSuccessCase) {
// (3) Each FDE has an edge pointing to the CIE at the correct offset.
// (4) Each function has exactly one FDE pointing at it.
auto G = cantFail(createLinkGraphFromMachOObject_arm64(TestObject));
auto G = cantFail(createLinkGraphFromMachOObject_arm64(
TestObject, std::make_shared<orc::SymbolStringPool>()));
cantFail(createEHFrameSplitterPass_MachO_arm64()(*G));
cantFail(createEHFrameEdgeFixerPass_MachO_arm64()(*G));
@ -211,7 +212,7 @@ TEST(EHFrameCFIBlockInspector, BasicSuccessCase) {
ASSERT_TRUE(!!CFIBI.getPCBeginEdge());
auto &PCBeginTarget = CFIBI.getPCBeginEdge()->getTarget();
ASSERT_TRUE(PCBeginTarget.hasName());
Targets.insert(PCBeginTarget.getName());
Targets.insert(*PCBeginTarget.getName());
// If the FDE points at CIEs[0] (the CIE without a personality) then it
// should not have an LSDA. If it points to CIEs[1] then it should have
@ -232,11 +233,12 @@ TEST(EHFrameCFIBlockInspector, BasicSuccessCase) {
TEST(EHFrameCFIBlockInspector, ExternalPCBegin) {
// Check that we don't crash if we transform the target of an FDE into an
// external symbol before running edge-fixing.
auto G = cantFail(createLinkGraphFromMachOObject_arm64(TestObject));
auto G = cantFail(createLinkGraphFromMachOObject_arm64(
TestObject, std::make_shared<orc::SymbolStringPool>()));
// Make '_a' external.
for (auto *Sym : G->defined_symbols())
if (Sym->hasName() && Sym->getName() == "_a") {
if (Sym->hasName() && *Sym->getName() == "_a") {
G->makeExternal(*Sym);
break;
}

@ -92,9 +92,10 @@ void defaultCtxSetup(MockJITLinkContext &) {}
TEST(JITLinkMocks, SmokeTest) {
// Check that the testing infrastructure defaults can "link" a graph
// successfully.
auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little,
getGenericEdgeKindName);
auto G = std::make_unique<LinkGraph>(
"foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
ArrayRef<char> Content = "hello, world!";
auto &Sec =

@ -21,7 +21,8 @@ using namespace llvm::jitlink;
TEST(LinkGraphTest, Construction) {
// Check that LinkGraph construction works as expected.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
EXPECT_EQ(G.getName(), "foo");
EXPECT_EQ(G.getTargetTriple().str(), "x86_64-apple-darwin");
@ -35,7 +36,8 @@ TEST(LinkGraphTest, Construction) {
TEST(LinkGraphTest, AddressAccess) {
// Check that we can get addresses for blocks, symbols, and edges.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec1 =
@ -54,7 +56,8 @@ TEST(LinkGraphTest, AddressAccess) {
TEST(LinkGraphTest, SectionEmpty) {
// Check that Section::empty behaves as expected.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec1 =
G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@ -72,7 +75,8 @@ TEST(LinkGraphTest, SectionEmpty) {
TEST(LinkGraphTest, BlockAndSymbolIteration) {
// Check that we can iterate over blocks within Sections and across sections.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec1 =
G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@ -125,7 +129,8 @@ TEST(LinkGraphTest, BlockAndSymbolIteration) {
TEST(LinkGraphTest, ContentAccessAndUpdate) {
// Check that we can make a defined symbol external.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec =
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -214,7 +219,8 @@ TEST(LinkGraphTest, ContentAccessAndUpdate) {
TEST(LinkGraphTest, MakeExternal) {
// Check that we can make defined and absolute symbols external.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec =
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -284,7 +290,8 @@ TEST(LinkGraphTest, MakeExternal) {
TEST(LinkGraphTest, MakeAbsolute) {
// Check that we can make defined and external symbols absolute.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec =
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -353,7 +360,8 @@ TEST(LinkGraphTest, MakeAbsolute) {
TEST(LinkGraphTest, MakeDefined) {
// Check that we can make an external symbol defined.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec =
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -401,7 +409,8 @@ TEST(LinkGraphTest, MakeDefined) {
TEST(LinkGraphTest, TransferDefinedSymbol) {
// Check that we can transfer a defined symbol from one block to another.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec =
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -436,7 +445,8 @@ TEST(LinkGraphTest, TransferDefinedSymbol) {
TEST(LinkGraphTest, TransferDefinedSymbolAcrossSections) {
// Check that we can transfer a defined symbol from an existing block in one
// section to another.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec1 =
G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@ -470,7 +480,8 @@ TEST(LinkGraphTest, TransferDefinedSymbolAcrossSections) {
TEST(LinkGraphTest, TransferBlock) {
// Check that we can transfer a block (and all associated symbols) from one
// section to another.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec1 =
G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@ -518,7 +529,8 @@ TEST(LinkGraphTest, TransferBlock) {
TEST(LinkGraphTest, MergeSections) {
// Check that we can transfer a block (and all associated symbols) from one
// section to another.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec1 =
G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
@ -604,7 +616,8 @@ TEST(LinkGraphTest, MergeSections) {
TEST(LinkGraphTest, SplitBlock) {
// Check that the LinkGraph::splitBlock test works as expected.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec =
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -716,7 +729,8 @@ TEST(LinkGraphTest, SplitBlock) {
}
TEST(LinkGraphTest, GraphAllocationMethods) {
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
// Test allocation of sized, uninitialized buffer.
@ -737,7 +751,8 @@ TEST(LinkGraphTest, GraphAllocationMethods) {
TEST(LinkGraphTest, IsCStringBlockTest) {
// Check that the LinkGraph::splitBlock test works as expected.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Sec =
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
@ -761,8 +776,8 @@ TEST(LinkGraphTest, IsCStringBlockTest) {
}
TEST(LinkGraphTest, BasicLayoutHonorsNoAlloc) {
// Check that BasicLayout honors NoAlloc.
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
// Create a regular section and block.

@ -11,6 +11,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/JITLink/MachO.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
@ -20,7 +21,8 @@ using namespace llvm::jitlink;
TEST(MachOLinkGraphTest, GetStandardSections) {
// Check that LinkGraph construction works as expected.
LinkGraph G("foo", Triple("arm64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("arm64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto &Data = getMachODefaultRWDataSection(G);

@ -18,9 +18,10 @@ using namespace llvm::jitlink;
TEST(MemoryManagerErrorTest, ErrorOnFirstAllocate) {
// Check that we can get addresses for blocks, symbols, and edges.
auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little,
getGenericEdgeKindName);
auto G = std::make_unique<LinkGraph>(
"foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
ArrayRef<char> Content = "hello, world!";
auto &Sec =

@ -57,7 +57,8 @@ GenerateStub(LinkGraph &G, size_t PointerSize, Edge::Kind PointerEdgeKind) {
TEST(StubsTest, StubsGeneration_x86_64) {
const char PointerJumpStubContent[6] = {
static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};
LinkGraph G("foo", Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("x86_64-apple-darwin"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto [PointerSym, StubSym] = GenerateStub(G, 8U, x86_64::Pointer64);
@ -77,7 +78,8 @@ TEST(StubsTest, StubsGeneration_aarch64) {
0x10, 0x02, 0x40, (char)0xf9u, // LDR x16, [x16, <imm>@pageoff12]
0x00, 0x02, 0x1f, (char)0xd6u // BR x16
};
LinkGraph G("foo", Triple("aarch64-linux-gnu"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("aarch64-linux-gnu"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto [PointerSym, StubSym] = GenerateStub(G, 8U, aarch64::Pointer64);
@ -97,8 +99,9 @@ TEST(StubsTest, StubsGeneration_aarch64) {
TEST(StubsTest, StubsGeneration_i386) {
const char PointerJumpStubContent[6] = {
static_cast<char>(0xFFu), 0x25, 0x00, 0x00, 0x00, 0x00};
LinkGraph G("foo", Triple("i386-unknown-linux-gnu"), 4,
llvm::endianness::little, getGenericEdgeKindName);
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("i386-unknown-linux-gnu"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto [PointerSym, StubSym] = GenerateStub(G, 4U, i386::Pointer32);
EXPECT_EQ(std::distance(StubSym.getBlock().edges().begin(),
@ -126,7 +129,8 @@ TEST(StubsTest, StubsGeneration_loongarch32) {
0x00,
0x4c // jr $t8
};
LinkGraph G("foo", Triple("loongarch32"), 4, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("loongarch32"), 4, llvm::endianness::little,
getGenericEdgeKindName);
auto [PointerSym, StubSym] = GenerateStub(G, 4U, loongarch::Pointer32);
@ -158,7 +162,8 @@ TEST(StubsTest, StubsGeneration_loongarch64) {
0x00,
0x4c // jr $t8
};
LinkGraph G("foo", Triple("loongarch64"), 8, llvm::endianness::little,
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
Triple("loongarch64"), 8, llvm::endianness::little,
getGenericEdgeKindName);
auto [PointerSym, StubSym] = GenerateStub(G, 8U, loongarch::Pointer64);

@ -114,10 +114,10 @@ TEST(EPCGenericJITLinkMemoryManagerTest, AllocFinalizeFree) {
SAs.Deallocate = ExecutorAddr::fromPtr(&testDeallocate);
auto MemMgr = std::make_unique<EPCGenericJITLinkMemoryManager>(*SelfEPC, SAs);
StringRef Hello = "hello";
auto SSA = jitlink::SimpleSegmentAlloc::Create(
*MemMgr, nullptr, {{MemProt::Read, {Hello.size(), Align(1)}}});
*MemMgr, std::make_shared<orc::SymbolStringPool>(), nullptr,
{{MemProt::Read, {Hello.size(), Align(1)}}});
EXPECT_THAT_EXPECTED(SSA, Succeeded());
auto SegInfo = SSA->getSegInfo(MemProt::Read);
memcpy(SegInfo.WorkingMem.data(), Hello.data(), Hello.size());

@ -81,8 +81,8 @@ TEST_F(JITLinkRedirectionManagerTest, BasicRedirectionOperation) {
JD->getDefaultResourceTracker(),
{{RedirectableSymbol, MakeTarget(initialTarget)}}),
Succeeded());
auto RTDef = cantFail(ES->lookup({JD}, RedirectableSymbol));
auto RTDef = cantFail(ES->lookup({JD}, RedirectableSymbol));
auto RTPtr = RTDef.getAddress().toPtr<int (*)()>();
auto Result = RTPtr();
EXPECT_EQ(Result, 42) << "Failed to call initial target";

@ -76,7 +76,8 @@ TEST(MapperJITLinkMemoryManagerTest, InProcess) {
StringRef Hello = "hello";
auto SSA1 = jitlink::SimpleSegmentAlloc::Create(
*MemMgr, nullptr, {{MemProt::Read, {Hello.size(), Align(1)}}});
*MemMgr, std::make_shared<orc::SymbolStringPool>(), nullptr,
{{MemProt::Read, {Hello.size(), Align(1)}}});
EXPECT_THAT_EXPECTED(SSA1, Succeeded());
EXPECT_EQ(Counter->ReserveCount, 1);
@ -92,7 +93,8 @@ TEST(MapperJITLinkMemoryManagerTest, InProcess) {
EXPECT_EQ(Counter->InitCount, 1);
auto SSA2 = jitlink::SimpleSegmentAlloc::Create(
*MemMgr, nullptr, {{MemProt::Read, {Hello.size(), Align(1)}}});
*MemMgr, std::make_shared<orc::SymbolStringPool>(), nullptr,
{{MemProt::Read, {Hello.size(), Align(1)}}});
EXPECT_THAT_EXPECTED(SSA2, Succeeded());
// last reservation should be reused
@ -135,9 +137,10 @@ TEST(MapperJITLinkMemoryManagerTest, Coalescing) {
auto Mapper = cantFail(InProcessMemoryMapper::Create());
auto MemMgr = std::make_unique<MapperJITLinkMemoryManager>(16 * 1024 * 1024,
std::move(Mapper));
auto SSP = std::make_shared<orc::SymbolStringPool>();
auto SSA1 = jitlink::SimpleSegmentAlloc::Create(
*MemMgr, nullptr, {{MemProt::Read, {1024, Align(1)}}});
*MemMgr, SSP, nullptr, {{MemProt::Read, {1024, Align(1)}}});
EXPECT_THAT_EXPECTED(SSA1, Succeeded());
auto SegInfo1 = SSA1->getSegInfo(MemProt::Read);
ExecutorAddr TargetAddr1(SegInfo1.Addr);
@ -145,7 +148,7 @@ TEST(MapperJITLinkMemoryManagerTest, Coalescing) {
EXPECT_THAT_EXPECTED(FA1, Succeeded());
auto SSA2 = jitlink::SimpleSegmentAlloc::Create(
*MemMgr, nullptr, {{MemProt::Read, {1024, Align(1)}}});
*MemMgr, SSP, nullptr, {{MemProt::Read, {1024, Align(1)}}});
EXPECT_THAT_EXPECTED(SSA2, Succeeded());
auto FA2 = SSA2->finalize();
EXPECT_THAT_EXPECTED(FA2, Succeeded());
@ -157,7 +160,7 @@ TEST(MapperJITLinkMemoryManagerTest, Coalescing) {
EXPECT_THAT_ERROR(std::move(Err3), Succeeded());
auto SSA3 = jitlink::SimpleSegmentAlloc::Create(
*MemMgr, nullptr, {{MemProt::Read, {2048, Align(1)}}});
*MemMgr, SSP, nullptr, {{MemProt::Read, {2048, Align(1)}}});
EXPECT_THAT_EXPECTED(SSA3, Succeeded());
auto SegInfo3 = SSA3->getSegInfo(MemProt::Read);

@ -15,6 +15,7 @@
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
@ -44,9 +45,9 @@ protected:
};
TEST_F(ObjectLinkingLayerTest, AddLinkGraph) {
auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little,
x86_64::getEdgeKindName);
auto G = std::make_unique<LinkGraph>(
"foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little, x86_64::getEdgeKindName);
auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
auto &B1 = G->createContentBlock(Sec1, BlockContent,
@ -71,9 +72,9 @@ TEST_F(ObjectLinkingLayerTest, ResourceTracker) {
// may invalidate some iterators internally.
std::vector<ResourceTrackerSP> Trackers;
for (unsigned I = 0; I < 64; I++) {
auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"),
8, llvm::endianness::little,
x86_64::getEdgeKindName);
auto G = std::make_unique<LinkGraph>(
"foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little, x86_64::getEdgeKindName);
auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
auto &B1 = G->createContentBlock(Sec1, BlockContent,
@ -138,10 +139,9 @@ TEST_F(ObjectLinkingLayerTest, ClaimLateDefinedWeakSymbols) {
};
ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little,
x86_64::getEdgeKindName);
auto G = std::make_unique<LinkGraph>(
"foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little, getGenericEdgeKindName);
auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
@ -192,10 +192,9 @@ TEST_F(ObjectLinkingLayerTest, HandleErrorDuringPostAllocationPass) {
ES.setErrorReporter(consumeError);
ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little,
x86_64::getEdgeKindName);
auto G = std::make_unique<LinkGraph>(
"foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little, getGenericEdgeKindName);
auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
@ -247,9 +246,9 @@ TEST_F(ObjectLinkingLayerTest, AddAndRemovePlugins) {
ObjLinkingLayer.addPlugin(P);
{
auto G1 = std::make_unique<LinkGraph>("G1", Triple("x86_64-apple-darwin"),
8, llvm::endianness::little,
x86_64::getEdgeKindName);
auto G1 = std::make_unique<LinkGraph>(
"G1", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little, x86_64::getEdgeKindName);
auto &DataSec = G1->createSection("__data", MemProt::Read | MemProt::Write);
auto &DataBlock = G1->createContentBlock(DataSec, BlockContent,
@ -265,9 +264,9 @@ TEST_F(ObjectLinkingLayerTest, AddAndRemovePlugins) {
ObjLinkingLayer.removePlugin(*P);
{
auto G2 = std::make_unique<LinkGraph>("G2", Triple("x86_64-apple-darwin"),
8, llvm::endianness::little,
x86_64::getEdgeKindName);
auto G2 = std::make_unique<LinkGraph>(
"G2", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"), 8,
llvm::endianness::little, x86_64::getEdgeKindName);
auto &DataSec = G2->createSection("__data", MemProt::Read | MemProt::Write);
auto &DataBlock = G2->createContentBlock(DataSec, BlockContent,
@ -325,8 +324,8 @@ TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
auto G = EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
ES, {}, [&](JITDylib &JD, SymbolMap Syms) {
auto G =
absoluteSymbolsLinkGraph(ES.getTargetTriple(), std::move(Syms));
auto G = absoluteSymbolsLinkGraph(
ES.getTargetTriple(), ES.getSymbolStringPool(), std::move(Syms));
return ObjLinkingLayer.add(JD, std::move(G));
});
ASSERT_THAT_EXPECTED(G, Succeeded());
@ -347,7 +346,7 @@ TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
ADD_FAILURE() << "unexpected unnamed symbol";
continue;
}
if (Sym->getName() == "_testFunc")
if (*Sym->getName() == "_testFunc")
SawSymbolDef = true;
else
ADD_FAILURE() << "unexpected symbol " << Sym->getName();