
Also moves object interface building functions out of Mangling.h and in to the new ObjectFileInterfaces.h header, and updates the llvm-jitlink tool to use custom object interfaces rather than a custom link layer. ObjectLayer::add overloads are added to match the old signatures (which do not take a MaterializationUnit::Interface). These overloads use the standard getObjectFileInterface function to build an interface. Passing a MaterializationUnit::Interface explicitly makes it easier to alter the effective interface of the object file being added, e.g. by changing symbol visibility/linkage, or renaming symbols (in both cases the changes will need to be mirrored by a JITLink pass at link time to update the LinkGraph to match the explicit interface). Altering interfaces in this way can be useful when lazily compiling (e.g. for renaming function bodies) or emulating linker options (e.g. demoting all symbols to hidden visibility to emulate -load_hidden).
85 lines
2.7 KiB
C++
85 lines
2.7 KiB
C++
//===----------- Mangling.cpp -- Name Mangling Utilities for ORC ----------===//
|
|
//
|
|
// 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/Mangling.h"
|
|
#include "llvm/IR/Constants.h"
|
|
#include "llvm/IR/Mangler.h"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#define DEBUG_TYPE "orc"
|
|
|
|
namespace llvm {
|
|
namespace orc {
|
|
|
|
MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL)
|
|
: ES(ES), DL(DL) {}
|
|
|
|
SymbolStringPtr MangleAndInterner::operator()(StringRef Name) {
|
|
std::string MangledName;
|
|
{
|
|
raw_string_ostream MangledNameStream(MangledName);
|
|
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
|
|
}
|
|
return ES.intern(MangledName);
|
|
}
|
|
|
|
void IRSymbolMapper::add(ExecutionSession &ES, const ManglingOptions &MO,
|
|
ArrayRef<GlobalValue *> GVs,
|
|
SymbolFlagsMap &SymbolFlags,
|
|
SymbolNameToDefinitionMap *SymbolToDefinition) {
|
|
if (GVs.empty())
|
|
return;
|
|
|
|
MangleAndInterner Mangle(ES, GVs[0]->getParent()->getDataLayout());
|
|
for (auto *G : GVs) {
|
|
assert(G && "GVs cannot contain null elements");
|
|
if (!G->hasName() || G->isDeclaration() || G->hasLocalLinkage() ||
|
|
G->hasAvailableExternallyLinkage() || G->hasAppendingLinkage())
|
|
continue;
|
|
|
|
if (G->isThreadLocal() && MO.EmulatedTLS) {
|
|
auto *GV = cast<GlobalVariable>(G);
|
|
|
|
auto Flags = JITSymbolFlags::fromGlobalValue(*GV);
|
|
|
|
auto EmuTLSV = Mangle(("__emutls_v." + GV->getName()).str());
|
|
SymbolFlags[EmuTLSV] = Flags;
|
|
if (SymbolToDefinition)
|
|
(*SymbolToDefinition)[EmuTLSV] = GV;
|
|
|
|
// If this GV has a non-zero initializer we'll need to emit an
|
|
// __emutls.t symbol too.
|
|
if (GV->hasInitializer()) {
|
|
const auto *InitVal = GV->getInitializer();
|
|
|
|
// Skip zero-initializers.
|
|
if (isa<ConstantAggregateZero>(InitVal))
|
|
continue;
|
|
const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);
|
|
if (InitIntValue && InitIntValue->isZero())
|
|
continue;
|
|
|
|
auto EmuTLST = Mangle(("__emutls_t." + GV->getName()).str());
|
|
SymbolFlags[EmuTLST] = Flags;
|
|
if (SymbolToDefinition)
|
|
(*SymbolToDefinition)[EmuTLST] = GV;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// Otherwise we just need a normal linker mangling.
|
|
auto MangledName = Mangle(G->getName());
|
|
SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(*G);
|
|
if (SymbolToDefinition)
|
|
(*SymbolToDefinition)[MangledName] = G;
|
|
}
|
|
}
|
|
|
|
} // End namespace orc.
|
|
} // End namespace llvm.
|