mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-19 11:41:53 +00:00
Temporarily revert r231726 and r231724 as they're breaking the build.:
Author: Lang Hames <lhames@gmail.com> Date: Mon Mar 9 23:51:09 2015 +0000 [Orc][MCJIT][RuntimeDyld] Add header that was accidentally left out of r231724. Author: Lang Hames <lhames@gmail.com> Date: Mon Mar 9 23:44:13 2015 +0000 [Orc][MCJIT][RuntimeDyld] Add symbol flags to symbols in RuntimeDyld. Thread the new types through MCJIT and Orc. In particular, add a 'weak' flag. When plumbed through RTDyldMemoryManager, this will allow us to distinguish between weak and strong definitions and find the right ones during symbol resolution. llvm-svn: 231731
This commit is contained in:
parent
bf1458c86c
commit
0c42dfb65e
@ -1,81 +0,0 @@
|
||||
//===------ JITSymbolFlags.h - Flags for symbols in the JIT -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Symbol flags for symbols in the JIT (e.g. weak, exported).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H
|
||||
#define LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H
|
||||
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// @brief Flags for symbols in the JIT.
|
||||
enum class JITSymbolFlags : char {
|
||||
None = 0,
|
||||
Weak = 1U << 0,
|
||||
Exported = 1U << 1
|
||||
};
|
||||
|
||||
JITSymbolFlags operator|(JITSymbolFlags LHS, JITSymbolFlags RHS) {
|
||||
typedef std::underlying_type<JITSymbolFlags>::type UT;
|
||||
return static_cast<JITSymbolFlags>(
|
||||
static_cast<UT>(LHS) | static_cast<UT>(RHS));
|
||||
}
|
||||
|
||||
JITSymbolFlags& operator |=(JITSymbolFlags &LHS, JITSymbolFlags RHS) {
|
||||
LHS = LHS | RHS;
|
||||
return LHS;
|
||||
}
|
||||
|
||||
JITSymbolFlags operator&(JITSymbolFlags LHS, JITSymbolFlags RHS) {
|
||||
typedef std::underlying_type<JITSymbolFlags>::type UT;
|
||||
return static_cast<JITSymbolFlags>(
|
||||
static_cast<UT>(LHS) & static_cast<UT>(RHS));
|
||||
}
|
||||
|
||||
JITSymbolFlags& operator &=(JITSymbolFlags &LHS, JITSymbolFlags RHS) {
|
||||
LHS = LHS & RHS;
|
||||
return LHS;
|
||||
}
|
||||
|
||||
/// @brief Base class for symbols in the JIT.
|
||||
class JITSymbolBase {
|
||||
public:
|
||||
JITSymbolBase(JITSymbolFlags Flags) : Flags(Flags) {}
|
||||
|
||||
JITSymbolFlags getFlags() const { return Flags; }
|
||||
|
||||
bool isWeak() const {
|
||||
return (Flags & JITSymbolFlags::Weak) == JITSymbolFlags::Weak;
|
||||
}
|
||||
|
||||
bool isExported() const {
|
||||
return (Flags & JITSymbolFlags::Exported) == JITSymbolFlags::Exported;
|
||||
}
|
||||
|
||||
static JITSymbolFlags flagsFromGlobalValue(const GlobalValue &GV) {
|
||||
JITSymbolFlags Flags = JITSymbolFlags::None;
|
||||
if (GV.hasWeakLinkage())
|
||||
Flags |= JITSymbolFlags::Weak;
|
||||
if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())
|
||||
Flags |= JITSymbolFlags::Exported;
|
||||
return Flags;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
JITSymbolFlags Flags;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -14,7 +14,6 @@
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
|
||||
|
||||
#include "llvm/ExecutionEngine/JITSymbolFlags.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
@ -26,19 +25,17 @@ namespace orc {
|
||||
typedef uint64_t TargetAddress;
|
||||
|
||||
/// @brief Represents a symbol in the JIT.
|
||||
class JITSymbol : public JITSymbolBase {
|
||||
public:
|
||||
|
||||
class JITSymbol {
|
||||
public:
|
||||
typedef std::function<TargetAddress()> GetAddressFtor;
|
||||
|
||||
/// @brief Create a 'null' symbol that represents failure to find a symbol
|
||||
/// definition.
|
||||
JITSymbol(std::nullptr_t)
|
||||
: JITSymbolBase(JITSymbolFlags::None), CachedAddr(0) {}
|
||||
JITSymbol(std::nullptr_t) : CachedAddr(0) {}
|
||||
|
||||
/// @brief Create a symbol for a definition with a known address.
|
||||
JITSymbol(TargetAddress Addr, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), CachedAddr(Addr) {}
|
||||
JITSymbol(TargetAddress Addr)
|
||||
: CachedAddr(Addr) {}
|
||||
|
||||
/// @brief Create a symbol for a definition that doesn't have a known address
|
||||
/// yet.
|
||||
@ -49,8 +46,8 @@ public:
|
||||
/// definition without actually materializing the definition up front. The
|
||||
/// user can materialize the definition at any time by calling the getAddress
|
||||
/// method.
|
||||
JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), GetAddress(std::move(GetAddress)), CachedAddr(0) {}
|
||||
JITSymbol(GetAddressFtor GetAddress)
|
||||
: CachedAddr(0), GetAddress(std::move(GetAddress)) {}
|
||||
|
||||
/// @brief Returns true if the symbol exists, false otherwise.
|
||||
explicit operator bool() const { return CachedAddr || GetAddress; }
|
||||
@ -67,8 +64,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
GetAddressFtor GetAddress;
|
||||
TargetAddress CachedAddr;
|
||||
GetAddressFtor GetAddress;
|
||||
};
|
||||
|
||||
} // End namespace orc.
|
||||
|
@ -45,25 +45,23 @@ private:
|
||||
JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
|
||||
switch (EmitState) {
|
||||
case NotEmitted:
|
||||
if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
|
||||
if (provides(Name, ExportedSymbolsOnly)) {
|
||||
// Create a std::string version of Name to capture here - the argument
|
||||
// (a StringRef) may go away before the lambda is executed.
|
||||
// FIXME: Use capture-init when we move to C++14.
|
||||
auto PName = Name;
|
||||
JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV);
|
||||
auto GetAddress =
|
||||
[this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
|
||||
if (this->EmitState == Emitting)
|
||||
return 0;
|
||||
else if (this->EmitState == NotEmitted) {
|
||||
this->EmitState = Emitting;
|
||||
Handle = this->emitToBaseLayer(B);
|
||||
this->EmitState = Emitted;
|
||||
}
|
||||
auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
|
||||
return Sym.getAddress();
|
||||
};
|
||||
return JITSymbol(std::move(GetAddress), Flags);
|
||||
std::string PName = Name;
|
||||
return JITSymbol(
|
||||
[this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
|
||||
if (this->EmitState == Emitting)
|
||||
return 0;
|
||||
else if (this->EmitState == NotEmitted) {
|
||||
this->EmitState = Emitting;
|
||||
Handle = this->emitToBaseLayer(B);
|
||||
this->EmitState = Emitted;
|
||||
}
|
||||
return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly)
|
||||
.getAddress();
|
||||
});
|
||||
} else
|
||||
return nullptr;
|
||||
case Emitting:
|
||||
@ -100,8 +98,7 @@ private:
|
||||
std::unique_ptr<RTDyldMemoryManager> MM);
|
||||
|
||||
protected:
|
||||
virtual const GlobalValue* searchGVs(StringRef Name,
|
||||
bool ExportedSymbolsOnly) const = 0;
|
||||
virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
|
||||
virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
|
||||
|
||||
private:
|
||||
@ -118,48 +115,46 @@ private:
|
||||
|
||||
protected:
|
||||
|
||||
const GlobalValue* searchGVs(StringRef Name,
|
||||
bool ExportedSymbolsOnly) const override {
|
||||
BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
|
||||
// We don't need the mangled names set any more: Once we've emitted this
|
||||
// to the base layer we'll just look for symbols there.
|
||||
MangledNames.reset();
|
||||
return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
|
||||
}
|
||||
|
||||
bool provides(StringRef Name, bool ExportedSymbolsOnly) const override {
|
||||
// FIXME: We could clean all this up if we had a way to reliably demangle
|
||||
// names: We could just demangle name and search, rather than
|
||||
// mangling everything else.
|
||||
|
||||
// If we have already built the mangled name set then just search it.
|
||||
if (MangledSymbols) {
|
||||
auto VI = MangledSymbols->find(Name);
|
||||
if (VI == MangledSymbols->end())
|
||||
return nullptr;
|
||||
auto GV = VI->second;
|
||||
if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
|
||||
return GV;
|
||||
return nullptr;
|
||||
if (MangledNames) {
|
||||
auto VI = MangledNames->find(Name);
|
||||
if (VI == MangledNames->end())
|
||||
return false;
|
||||
return !ExportedSymbolsOnly || VI->second;
|
||||
}
|
||||
|
||||
// If we haven't built the mangled name set yet, try to build it. As an
|
||||
// optimization this will leave MangledNames set to nullptr if we find
|
||||
// Name in the process of building the set.
|
||||
return buildMangledSymbols(Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
|
||||
// We don't need the mangled names set any more: Once we've emitted this
|
||||
// to the base layer we'll just look for symbols there.
|
||||
MangledSymbols.reset();
|
||||
return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
|
||||
buildMangledNames(Name, ExportedSymbolsOnly);
|
||||
if (!MangledNames)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// If the mangled name of the given GlobalValue matches the given search
|
||||
// name (and its visibility conforms to the ExportedSymbolsOnly flag) then
|
||||
// return the symbol. Otherwise, add the mangled name to the Names map and
|
||||
// return nullptr.
|
||||
const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
|
||||
const GlobalValue &GV,
|
||||
const Mangler &Mang, StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
// just return 'true'. Otherwise, add the mangled name to the Names map and
|
||||
// return 'false'.
|
||||
bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV,
|
||||
const Mangler &Mang, StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
// Modules don't "provide" decls or common symbols.
|
||||
if (GV.isDeclaration() || GV.hasCommonLinkage())
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
// Mangle the GV name.
|
||||
std::string MangledName;
|
||||
@ -172,42 +167,39 @@ private:
|
||||
// bail out early.
|
||||
if (MangledName == SearchName)
|
||||
if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
|
||||
return &GV;
|
||||
return true;
|
||||
|
||||
// Otherwise add this to the map for later.
|
||||
Names[MangledName] = &GV;
|
||||
return nullptr;
|
||||
Names[MangledName] = GV.hasDefaultVisibility();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build the MangledSymbols map. Bails out early (with MangledSymbols left set
|
||||
// Build the MangledNames map. Bails out early (with MangledNames left set
|
||||
// to nullptr) if the given SearchName is found while building the map.
|
||||
const GlobalValue* buildMangledSymbols(StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
assert(!MangledSymbols && "Mangled symbols map already exists?");
|
||||
void buildMangledNames(StringRef SearchName,
|
||||
bool ExportedSymbolsOnly) const {
|
||||
assert(!MangledNames && "Mangled names map already exists?");
|
||||
|
||||
auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
|
||||
auto Names = llvm::make_unique<StringMap<bool>>();
|
||||
|
||||
for (const auto &M : Ms) {
|
||||
Mangler Mang(&M->getDataLayout());
|
||||
|
||||
for (const auto &V : M->globals())
|
||||
if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName,
|
||||
ExportedSymbolsOnly))
|
||||
return GV;
|
||||
for (const auto &GV : M->globals())
|
||||
if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly))
|
||||
return;
|
||||
|
||||
for (const auto &F : *M)
|
||||
if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName,
|
||||
ExportedSymbolsOnly))
|
||||
return GV;
|
||||
if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly))
|
||||
return;
|
||||
}
|
||||
|
||||
MangledSymbols = std::move(Symbols);
|
||||
return nullptr;
|
||||
MangledNames = std::move(Names);
|
||||
}
|
||||
|
||||
ModuleSetT Ms;
|
||||
std::unique_ptr<RTDyldMemoryManager> MM;
|
||||
mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
|
||||
mutable std::unique_ptr<StringMap<bool>> MangledNames;
|
||||
};
|
||||
|
||||
typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
|
||||
|
@ -51,8 +51,10 @@ protected:
|
||||
return RTDyld->loadObject(Obj);
|
||||
}
|
||||
|
||||
RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
|
||||
return RTDyld->getSymbol(Name);
|
||||
TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
|
||||
if (ExportedSymbolsOnly)
|
||||
return RTDyld->getExportedSymbolLoadAddress(Name);
|
||||
return RTDyld->getSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
bool NeedsFinalization() const { return (State == Raw); }
|
||||
@ -212,32 +214,28 @@ public:
|
||||
/// given object set.
|
||||
JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
if (auto Sym = H->getSymbol(Name)) {
|
||||
if (Sym.isExported() || !ExportedSymbolsOnly) {
|
||||
auto Addr = Sym.getAddress();
|
||||
auto Flags = Sym.getFlags();
|
||||
if (!H->NeedsFinalization()) {
|
||||
// If this instance has already been finalized then we can just return
|
||||
// the address.
|
||||
return JITSymbol(Addr, Flags);
|
||||
} else {
|
||||
// If this instance needs finalization return a functor that will do
|
||||
// it. The functor still needs to double-check whether finalization is
|
||||
// required, in case someone else finalizes this set before the
|
||||
// functor is called.
|
||||
auto GetAddress =
|
||||
[this, Addr, H]() {
|
||||
if (H->NeedsFinalization()) {
|
||||
H->Finalize();
|
||||
if (NotifyFinalized)
|
||||
NotifyFinalized(H);
|
||||
}
|
||||
return Addr;
|
||||
};
|
||||
return JITSymbol(std::move(GetAddress), Flags);
|
||||
}
|
||||
if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
|
||||
if (!H->NeedsFinalization()) {
|
||||
// If this instance has already been finalized then we can just return
|
||||
// the address.
|
||||
return JITSymbol(Addr);
|
||||
} else {
|
||||
// If this instance needs finalization return a functor that will do it.
|
||||
// The functor still needs to double-check whether finalization is
|
||||
// required, in case someone else finalizes this set before the functor
|
||||
// is called.
|
||||
return JITSymbol(
|
||||
[this, Addr, H]() {
|
||||
if (H->NeedsFinalization()) {
|
||||
H->Finalize();
|
||||
if (NotifyFinalized)
|
||||
NotifyFinalized(H);
|
||||
}
|
||||
return Addr;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
|
||||
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
|
||||
|
||||
#include "JITSymbolFlags.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/Support/Memory.h"
|
||||
@ -29,7 +28,7 @@ namespace object {
|
||||
|
||||
class RuntimeDyldImpl;
|
||||
class RuntimeDyldCheckerImpl;
|
||||
|
||||
|
||||
class RuntimeDyld {
|
||||
friend class RuntimeDyldCheckerImpl;
|
||||
|
||||
@ -48,18 +47,6 @@ protected:
|
||||
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
|
||||
public:
|
||||
|
||||
/// \brief Information about a named symbol.
|
||||
class SymbolInfo : public JITSymbolBase {
|
||||
public:
|
||||
SymbolInfo(std::nullptr_t) : JITSymbolBase(JITSymbolFlags::None), Address(0) {}
|
||||
SymbolInfo(uint64_t Address, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), Address(Address) {}
|
||||
explicit operator bool() const { return Address != 0; }
|
||||
uint64_t getAddress() const { return Address; }
|
||||
private:
|
||||
uint64_t Address;
|
||||
};
|
||||
|
||||
/// \brief Information about the loaded object.
|
||||
class LoadedObjectInfo {
|
||||
friend class RuntimeDyldImpl;
|
||||
@ -92,11 +79,15 @@ public:
|
||||
/// Get the address of our local copy of the symbol. This may or may not
|
||||
/// be the address used for relocation (clients can copy the data around
|
||||
/// and resolve relocatons based on where they put it).
|
||||
void *getSymbolLocalAddress(StringRef Name) const;
|
||||
void *getSymbolAddress(StringRef Name) const;
|
||||
|
||||
/// Get the target address and flags for the named symbol.
|
||||
/// This address is the one used for relocation.
|
||||
SymbolInfo getSymbol(StringRef Name) const;
|
||||
/// Get the address of the target copy of the symbol (works for both exported
|
||||
/// and non-exported symbols). This is the address used for relocation.
|
||||
uint64_t getSymbolLoadAddress(StringRef Name) const;
|
||||
|
||||
/// Get the address of the target copy of the symbol (works for exported
|
||||
/// symbols only). This is the address used for relocation.
|
||||
uint64_t getExportedSymbolLoadAddress(StringRef Name) const;
|
||||
|
||||
/// Resolve the relocations for all symbols we currently know about.
|
||||
void resolveRelocations();
|
||||
|
@ -86,12 +86,12 @@ public:
|
||||
/// \brief Returns the address of the requested section (or an error message
|
||||
/// in the second element of the pair if the address cannot be found).
|
||||
///
|
||||
/// if 'LocalAddress' is true, this returns the address of the section
|
||||
/// within the linker's memory. If 'LocalAddress' is false it returns the
|
||||
/// if 'LinkerAddress' is true, this returns the address of the section
|
||||
/// within the linker's memory. If 'LinkerAddress' is false it returns the
|
||||
/// address within the target process (i.e. the load address).
|
||||
std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
|
||||
StringRef SectionName,
|
||||
bool LocalAddress);
|
||||
bool LinkerAddress);
|
||||
|
||||
private:
|
||||
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
|
||||
|
@ -257,7 +257,7 @@ uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
|
||||
Mangler Mang(TM->getDataLayout());
|
||||
SmallString<128> FullName;
|
||||
Mang.getNameWithPrefix(FullName, Name);
|
||||
return Dyld.getSymbol(FullName).getAddress();
|
||||
return Dyld.getSymbolLoadAddress(FullName);
|
||||
}
|
||||
|
||||
Module *MCJIT::findModuleForSymbol(const std::string &Name,
|
||||
@ -383,7 +383,7 @@ void *MCJIT::getPointerToFunction(Function *F) {
|
||||
//
|
||||
// This is the accessor for the target address, so make sure to check the
|
||||
// load address of the symbol, not the local address.
|
||||
return (void*)Dyld.getSymbol(Name).getAddress();
|
||||
return (void*)Dyld.getSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
|
||||
|
@ -197,13 +197,10 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
||||
<< " SID: " << SectionID << " Offset: "
|
||||
<< format("%p", (uintptr_t)SectOffset)
|
||||
<< " flags: " << Flags << "\n");
|
||||
JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
|
||||
if (Flags & SymbolRef::SF_Weak)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Weak;
|
||||
if (Flags & SymbolRef::SF_Exported)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Exported;
|
||||
GlobalSymbolTable[Name] =
|
||||
SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags);
|
||||
SymbolInfo::Visibility Vis =
|
||||
(Flags & SymbolRef::SF_Exported) ?
|
||||
SymbolInfo::Default : SymbolInfo::Hidden;
|
||||
GlobalSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -528,15 +525,12 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
|
||||
Offset += AlignOffset;
|
||||
}
|
||||
uint32_t Flags = Sym.getFlags();
|
||||
JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
|
||||
if (Flags & SymbolRef::SF_Weak)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Weak;
|
||||
if (Flags & SymbolRef::SF_Exported)
|
||||
RTDyldSymFlags |= JITSymbolFlags::Exported;
|
||||
SymbolInfo::Visibility Vis =
|
||||
(Flags & SymbolRef::SF_Exported) ?
|
||||
SymbolInfo::Default : SymbolInfo::Hidden;
|
||||
DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
|
||||
<< format("%p", Addr) << "\n");
|
||||
GlobalSymbolTable[Name] =
|
||||
SymbolTableEntry(SectionID, Offset, RTDyldSymFlags);
|
||||
GlobalSymbolTable[Name] = SymbolInfo(SectionID, Offset, Vis);
|
||||
Offset += Size;
|
||||
Addr += Size;
|
||||
}
|
||||
@ -900,16 +894,22 @@ RuntimeDyld::loadObject(const ObjectFile &Obj) {
|
||||
return Dyld->loadObject(Obj);
|
||||
}
|
||||
|
||||
void *RuntimeDyld::getSymbolLocalAddress(StringRef Name) const {
|
||||
void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
|
||||
if (!Dyld)
|
||||
return nullptr;
|
||||
return Dyld->getSymbolLocalAddress(Name);
|
||||
return Dyld->getSymbolAddress(Name);
|
||||
}
|
||||
|
||||
RuntimeDyld::SymbolInfo RuntimeDyld::getSymbol(StringRef Name) const {
|
||||
uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) const {
|
||||
if (!Dyld)
|
||||
return nullptr;
|
||||
return Dyld->getSymbol(Name);
|
||||
return 0;
|
||||
return Dyld->getSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyld::getExportedSymbolLoadAddress(StringRef Name) const {
|
||||
if (!Dyld)
|
||||
return 0;
|
||||
return Dyld->getExportedSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
|
||||
|
@ -310,7 +310,7 @@ private:
|
||||
"");
|
||||
|
||||
uint64_t SymbolAddr = PCtx.IsInsideLoad
|
||||
? Checker.getSymbolLocalAddr(Symbol)
|
||||
? Checker.getSymbolLinkerAddr(Symbol)
|
||||
: Checker.getSymbolRemoteAddr(Symbol);
|
||||
uint64_t NextPC = SymbolAddr + InstSize;
|
||||
|
||||
@ -437,7 +437,7 @@ private:
|
||||
// The value for the symbol depends on the context we're evaluating in:
|
||||
// Inside a load this is the address in the linker's memory, outside a
|
||||
// load it's the address in the target processes memory.
|
||||
uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
|
||||
uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLinkerAddr(Symbol)
|
||||
: Checker.getSymbolRemoteAddr(Symbol);
|
||||
|
||||
// Looks like a plain symbol reference.
|
||||
@ -727,17 +727,17 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
|
||||
}
|
||||
|
||||
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
|
||||
return getRTDyld().getSymbolLocalAddress(Symbol) != nullptr;
|
||||
return getRTDyld().getSymbolAddress(Symbol) != nullptr;
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolLinkerAddr(StringRef Symbol) const {
|
||||
return static_cast<uint64_t>(
|
||||
reinterpret_cast<uintptr_t>(getRTDyld().getSymbolLocalAddress(Symbol)));
|
||||
reinterpret_cast<uintptr_t>(getRTDyld().getSymbolAddress(Symbol)));
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
|
||||
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
|
||||
return InternalSymbol.getAddress();
|
||||
if (uint64_t InternalSymbolAddr = getRTDyld().getSymbolLoadAddress(Symbol))
|
||||
return InternalSymbolAddr;
|
||||
return getRTDyld().MemMgr->getSymbolAddress(Symbol);
|
||||
}
|
||||
|
||||
@ -929,6 +929,6 @@ bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix,
|
||||
|
||||
std::pair<uint64_t, std::string>
|
||||
RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
|
||||
bool LocalAddress) {
|
||||
return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
|
||||
bool LinkerAddress) {
|
||||
return Impl->getSectionAddr(FileName, SectionName, LinkerAddress);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ private:
|
||||
RuntimeDyldImpl &getRTDyld() const { return *RTDyld.Dyld; }
|
||||
|
||||
bool isSymbolValid(StringRef Symbol) const;
|
||||
uint64_t getSymbolLocalAddr(StringRef Symbol) const;
|
||||
uint64_t getSymbolLinkerAddr(StringRef Symbol) const;
|
||||
uint64_t getSymbolRemoteAddr(StringRef Symbol) const;
|
||||
uint64_t readMemoryAtAddr(uint64_t Addr, unsigned Size) const;
|
||||
|
||||
|
@ -164,24 +164,27 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Symbol info for RuntimeDyld.
|
||||
class SymbolTableEntry : public JITSymbolBase {
|
||||
/// @brief Symbol info for RuntimeDyld.
|
||||
class SymbolInfo {
|
||||
public:
|
||||
SymbolTableEntry()
|
||||
: JITSymbolBase(JITSymbolFlags::None), Offset(0), SectionID(0) {}
|
||||
typedef enum { Hidden = 0, Default = 1 } Visibility;
|
||||
|
||||
SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags)
|
||||
: JITSymbolBase(Flags), Offset(Offset), SectionID(SectionID) {}
|
||||
SymbolInfo() : Offset(0), SectionID(0), Vis(Hidden) {}
|
||||
|
||||
SymbolInfo(unsigned SectionID, uint64_t Offset, Visibility Vis)
|
||||
: Offset(Offset), SectionID(SectionID), Vis(Vis) {}
|
||||
|
||||
unsigned getSectionID() const { return SectionID; }
|
||||
uint64_t getOffset() const { return Offset; }
|
||||
Visibility getVisibility() const { return Vis; }
|
||||
|
||||
private:
|
||||
uint64_t Offset;
|
||||
unsigned SectionID;
|
||||
unsigned SectionID : 31;
|
||||
Visibility Vis : 1;
|
||||
};
|
||||
|
||||
typedef StringMap<SymbolTableEntry> RTDyldSymbolTable;
|
||||
typedef StringMap<SymbolInfo> RTDyldSymbolTable;
|
||||
|
||||
class RuntimeDyldImpl {
|
||||
friend class RuntimeDyld::LoadedObjectInfo;
|
||||
@ -391,7 +394,7 @@ public:
|
||||
virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
|
||||
loadObject(const object::ObjectFile &Obj) = 0;
|
||||
|
||||
uint8_t* getSymbolLocalAddress(StringRef Name) const {
|
||||
uint8_t* getSymbolAddress(StringRef Name) const {
|
||||
// FIXME: Just look up as a function for now. Overly simple of course.
|
||||
// Work in progress.
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
@ -401,16 +404,24 @@ public:
|
||||
return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
|
||||
uint64_t getSymbolLoadAddress(StringRef Name) const {
|
||||
// FIXME: Just look up as a function for now. Overly simple of course.
|
||||
// Work in progress.
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
if (pos == GlobalSymbolTable.end())
|
||||
return nullptr;
|
||||
const auto &SymEntry = pos->second;
|
||||
uint64_t TargetAddr =
|
||||
getSectionLoadAddress(SymEntry.getSectionID()) + SymEntry.getOffset();
|
||||
return RuntimeDyld::SymbolInfo(TargetAddr, SymEntry.getFlags());
|
||||
return 0;
|
||||
const auto &SymInfo = pos->second;
|
||||
return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
uint64_t getExportedSymbolLoadAddress(StringRef Name) const {
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
if (pos == GlobalSymbolTable.end())
|
||||
return 0;
|
||||
const auto &SymInfo = pos->second;
|
||||
if (SymInfo.getVisibility() == SymbolInfo::Hidden)
|
||||
return 0;
|
||||
return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
void resolveRelocations();
|
||||
|
@ -298,7 +298,7 @@ static int executeInput() {
|
||||
// FIXME: Error out if there are unresolved relocations.
|
||||
|
||||
// Get the address of the entry point (_main by default).
|
||||
void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint);
|
||||
void *MainAddress = Dyld.getSymbolAddress(EntryPoint);
|
||||
if (!MainAddress)
|
||||
return Error("no definition for '" + EntryPoint + "'");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user