mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-03 10:16:07 +00:00

Introduces a new layer interface, LinkGraphLayer, that can be used to add LinkGraphs to an ExecutionSession. This patch moves most of ObjectLinkingLayer's functionality into a new LinkGraphLinkingLayer which should (in the future) be able to be used without linking libObject. ObjectLinkingLayer now inherits from LinkGraphLinkingLayer and just handles conversion of object files to LinkGraphs, which are then handed down to LinkGraphLinkingLayer to be linked.
106 lines
2.8 KiB
C++
106 lines
2.8 KiB
C++
//===----- LinkGraphLayer.cpp - Add LinkGraphs to an ExecutionSession -----===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ExecutionEngine/Orc/LinkGraphLayer.h"
|
|
|
|
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
|
|
#include "llvm/ExecutionEngine/Orc/Shared/MachOObjectFormat.h"
|
|
#include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h"
|
|
|
|
#define DEBUG_TYPE "orc"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::jitlink;
|
|
using namespace llvm::orc;
|
|
|
|
namespace {
|
|
|
|
bool hasInitializerSection(LinkGraph &G) {
|
|
bool IsMachO = G.getTargetTriple().isOSBinFormatMachO();
|
|
bool IsElf = G.getTargetTriple().isOSBinFormatELF();
|
|
if (!IsMachO && !IsElf)
|
|
return false;
|
|
|
|
for (auto &Sec : G.sections()) {
|
|
if (IsMachO && isMachOInitializerSection(Sec.getName()))
|
|
return true;
|
|
if (IsElf && isELFInitializerSection(Sec.getName()))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
} // end anonymous namespace
|
|
|
|
namespace llvm::orc {
|
|
|
|
LinkGraphLayer::~LinkGraphLayer() = default;
|
|
|
|
MaterializationUnit::Interface LinkGraphLayer::getInterface(LinkGraph &G) {
|
|
|
|
MaterializationUnit::Interface LGI;
|
|
|
|
auto AddSymbol = [&](Symbol *Sym) {
|
|
// Skip local symbols.
|
|
if (Sym->getScope() == Scope::Local)
|
|
return;
|
|
assert(Sym->hasName() && "Anonymous non-local symbol?");
|
|
|
|
LGI.SymbolFlags[Sym->getName()] = getJITSymbolFlagsForSymbol(*Sym);
|
|
};
|
|
|
|
for (auto *Sym : G.defined_symbols())
|
|
AddSymbol(Sym);
|
|
for (auto *Sym : G.absolute_symbols())
|
|
AddSymbol(Sym);
|
|
|
|
if (hasInitializerSection(G)) {
|
|
std::string InitSymString;
|
|
{
|
|
raw_string_ostream(InitSymString)
|
|
<< "$." << G.getName() << ".__inits" << Counter++;
|
|
}
|
|
LGI.InitSymbol = ES.intern(InitSymString);
|
|
}
|
|
|
|
return LGI;
|
|
}
|
|
|
|
JITSymbolFlags LinkGraphLayer::getJITSymbolFlagsForSymbol(Symbol &Sym) {
|
|
JITSymbolFlags Flags;
|
|
|
|
if (Sym.getLinkage() == Linkage::Weak)
|
|
Flags |= JITSymbolFlags::Weak;
|
|
|
|
if (Sym.getScope() == Scope::Default)
|
|
Flags |= JITSymbolFlags::Exported;
|
|
else if (Sym.getScope() == Scope::SideEffectsOnly)
|
|
Flags |= JITSymbolFlags::MaterializationSideEffectsOnly;
|
|
|
|
if (Sym.isCallable())
|
|
Flags |= JITSymbolFlags::Callable;
|
|
|
|
return Flags;
|
|
}
|
|
|
|
StringRef LinkGraphMaterializationUnit::getName() const { return G->getName(); }
|
|
|
|
void LinkGraphMaterializationUnit::discard(const JITDylib &JD,
|
|
const SymbolStringPtr &Name) {
|
|
for (auto *Sym : G->defined_symbols())
|
|
if (Sym->getName() == Name) {
|
|
assert(Sym->getLinkage() == Linkage::Weak &&
|
|
"Discarding non-weak definition");
|
|
G->makeExternal(*Sym);
|
|
break;
|
|
}
|
|
}
|
|
|
|
} // namespace llvm::orc
|