aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
committerStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
commitdce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch)
treedcebc53f2b182f145a2e659393bf9a0472cedf23 /lib/ExecutionEngine
parent220b921aed042f9e520c26cffd8282a94c66c3d5 (diff)
downloadexternal_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.zip
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.gz
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.bz2
Update LLVM for 3.5 rebase (r209712).
Change-Id: I149556c940fb7dc92d075273c87ff584f400941f
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp146
-rw-r--r--lib/ExecutionEngine/ExecutionEngineBindings.cpp15
-rw-r--r--lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp10
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp67
-rw-r--r--lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp6
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.cpp2
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.h4
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp26
-rw-r--r--lib/ExecutionEngine/JIT/JIT.h2
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp36
-rw-r--r--lib/ExecutionEngine/JIT/JITMemoryManager.cpp57
-rw-r--r--lib/ExecutionEngine/MCJIT/LLVMBuild.txt2
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.cpp35
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.h4
-rw-r--r--lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp2
-rw-r--r--lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp17
-rw-r--r--lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp3
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp13
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h21
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp97
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp107
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h8
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h27
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp483
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h60
-rw-r--r--lib/ExecutionEngine/TargetSelect.cpp8
26 files changed, 788 insertions, 470 deletions
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 4768e67..6766ef1 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -12,7 +12,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "jit"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
@@ -25,6 +24,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueHandle.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ErrorHandling.h"
@@ -37,6 +37,8 @@
#include <cstring>
using namespace llvm;
+#define DEBUG_TYPE "jit"
+
STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");
STATISTIC(NumGlobals , "Number of global vars initialized");
@@ -50,22 +52,31 @@ ExecutionEngine *(*ExecutionEngine::JITCtor)(
std::string *ErrorStr,
JITMemoryManager *JMM,
bool GVsWithCode,
- TargetMachine *TM) = 0;
+ TargetMachine *TM) = nullptr;
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
Module *M,
std::string *ErrorStr,
RTDyldMemoryManager *MCJMM,
bool GVsWithCode,
- TargetMachine *TM) = 0;
+ TargetMachine *TM) = nullptr;
ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
- std::string *ErrorStr) = 0;
+ std::string *ErrorStr) =nullptr;
ExecutionEngine::ExecutionEngine(Module *M)
: EEState(*this),
- LazyFunctionCreator(0) {
+ LazyFunctionCreator(nullptr) {
CompilingLazily = false;
GVCompilationDisabled = false;
SymbolSearchingDisabled = false;
+
+ // IR module verification is enabled by default in debug builds, and disabled
+ // by default in release builds.
+#ifndef NDEBUG
+ VerifyModules = true;
+#else
+ VerifyModules = false;
+#endif
+
Modules.push_back(M);
assert(M && "Module is null?");
}
@@ -111,6 +122,10 @@ char *ExecutionEngine::getMemoryForGV(const GlobalVariable *GV) {
return GVMemoryBlock::Create(GV, *getDataLayout());
}
+void ExecutionEngine::addObjectFile(std::unique_ptr<object::ObjectFile> O) {
+ llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile.");
+}
+
bool ExecutionEngine::removeModule(Module *M) {
for(SmallVectorImpl<Module *>::iterator I = Modules.begin(),
E = Modules.end(); I != E; ++I) {
@@ -129,7 +144,7 @@ Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
if (Function *F = Modules[i]->getFunction(FnName))
return F;
}
- return 0;
+ return nullptr;
}
@@ -141,7 +156,7 @@ void *ExecutionEngineState::RemoveMapping(const MutexGuard &,
// FIXME: This is silly, we shouldn't end up with a mapping -> 0 in the
// GlobalAddressMap.
if (I == GlobalAddressMap.end())
- OldVal = 0;
+ OldVal = nullptr;
else {
OldVal = I->second;
GlobalAddressMap.erase(I);
@@ -157,14 +172,14 @@ void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) {
DEBUG(dbgs() << "JIT: Map \'" << GV->getName()
<< "\' to [" << Addr << "]\n";);
void *&CurVal = EEState.getGlobalAddressMap(locked)[GV];
- assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
+ assert((!CurVal || !Addr) && "GlobalMapping already established!");
CurVal = Addr;
// If we are using the reverse mapping, add it too.
if (!EEState.getGlobalAddressReverseMap(locked).empty()) {
AssertingVH<const GlobalValue> &V =
EEState.getGlobalAddressReverseMap(locked)[Addr];
- assert((V == 0 || GV == 0) && "GlobalMapping already established!");
+ assert((!V || !GV) && "GlobalMapping already established!");
V = GV;
}
}
@@ -193,7 +208,7 @@ void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
EEState.getGlobalAddressMap(locked);
// Deleting from the mapping?
- if (Addr == 0)
+ if (!Addr)
return EEState.RemoveMapping(locked, GV);
void *&CurVal = Map[GV];
@@ -207,7 +222,7 @@ void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
if (!EEState.getGlobalAddressReverseMap(locked).empty()) {
AssertingVH<const GlobalValue> &V =
EEState.getGlobalAddressReverseMap(locked)[Addr];
- assert((V == 0 || GV == 0) && "GlobalMapping already established!");
+ assert((!V || !GV) && "GlobalMapping already established!");
V = GV;
}
return OldVal;
@@ -218,7 +233,7 @@ void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
ExecutionEngineState::GlobalAddressMapTy::iterator I =
EEState.getGlobalAddressMap(locked).find(GV);
- return I != EEState.getGlobalAddressMap(locked).end() ? I->second : 0;
+ return I != EEState.getGlobalAddressMap(locked).end() ? I->second : nullptr;
}
const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) {
@@ -235,7 +250,7 @@ const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) {
std::map<void *, AssertingVH<const GlobalValue> >::iterator I =
EEState.getGlobalAddressReverseMap(locked).find(Addr);
- return I != EEState.getGlobalAddressReverseMap(locked).end() ? I->second : 0;
+ return I != EEState.getGlobalAddressReverseMap(locked).end() ? I->second : nullptr;
}
namespace {
@@ -243,11 +258,11 @@ class ArgvArray {
char *Array;
std::vector<char*> Values;
public:
- ArgvArray() : Array(NULL) {}
+ ArgvArray() : Array(nullptr) {}
~ArgvArray() { clear(); }
void clear() {
delete[] Array;
- Array = NULL;
+ Array = nullptr;
for (size_t I = 0, E = Values.size(); I != E; ++I) {
delete[] Values[I];
}
@@ -283,7 +298,7 @@ void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE,
}
// Null terminate it
- EE->StoreValueToMemory(PTOGV(0),
+ EE->StoreValueToMemory(PTOGV(nullptr),
(GenericValue*)(Array+InputArgv.size()*PtrSize),
SBytePtr);
return Array;
@@ -303,11 +318,11 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module,
// Should be an array of '{ i32, void ()* }' structs. The first value is
// the init priority, which we ignore.
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
- if (InitList == 0)
+ if (!InitList)
return;
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i));
- if (CS == 0) continue;
+ if (!CS) continue;
Constant *FP = CS->getOperand(1);
if (FP->isNullValue())
@@ -418,10 +433,10 @@ ExecutionEngine *ExecutionEngine::createJIT(Module *M,
bool GVsWithCode,
Reloc::Model RM,
CodeModel::Model CMM) {
- if (ExecutionEngine::JITCtor == 0) {
+ if (!ExecutionEngine::JITCtor) {
if (ErrorStr)
*ErrorStr = "JIT has not been linked in.";
- return 0;
+ return nullptr;
}
// Use the defaults for extra parameters. Users can use EngineBuilder to
@@ -437,7 +452,7 @@ ExecutionEngine *ExecutionEngine::createJIT(Module *M,
// TODO: permit custom TargetOptions here
TargetMachine *TM = EB.selectTarget();
- if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0;
+ if (!TM || (ErrorStr && ErrorStr->length() > 0)) return nullptr;
return ExecutionEngine::JITCtor(M, ErrorStr, JMM, GVsWithCode, TM);
}
@@ -447,8 +462,8 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
// Make sure we can resolve symbols in the program as well. The zero arg
// to the function tells DynamicLibrary to load the program, not a library.
- if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
- return 0;
+ if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, ErrorStr))
+ return nullptr;
assert(!(JMM && MCJMM));
@@ -461,7 +476,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
else {
if (ErrorStr)
*ErrorStr = "Cannot create an interpreter with a memory manager.";
- return 0;
+ return nullptr;
}
}
@@ -470,7 +485,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
*ErrorStr =
"Cannot create a legacy JIT with a runtime dyld memory "
"manager.";
- return 0;
+ return nullptr;
}
// Unless the interpreter was explicitly selected or the JIT is not linked,
@@ -483,16 +498,17 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
<< " a different -march switch.\n";
}
- if (UseMCJIT && ExecutionEngine::MCJITCtor) {
- ExecutionEngine *EE =
- ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM,
- AllocateGVsWithCode, TheTM.release());
- if (EE) return EE;
- } else if (ExecutionEngine::JITCtor) {
- ExecutionEngine *EE =
- ExecutionEngine::JITCtor(M, ErrorStr, JMM,
- AllocateGVsWithCode, TheTM.release());
- if (EE) return EE;
+ ExecutionEngine *EE = nullptr;
+ if (UseMCJIT && ExecutionEngine::MCJITCtor)
+ EE = ExecutionEngine::MCJITCtor(M, ErrorStr, MCJMM ? MCJMM : JMM,
+ AllocateGVsWithCode, TheTM.release());
+ else if (ExecutionEngine::JITCtor)
+ EE = ExecutionEngine::JITCtor(M, ErrorStr, JMM,
+ AllocateGVsWithCode, TheTM.release());
+
+ if (EE) {
+ EE->setVerifyModules(VerifyModules);
+ return EE;
}
}
@@ -503,16 +519,16 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
return ExecutionEngine::InterpCtor(M, ErrorStr);
if (ErrorStr)
*ErrorStr = "Interpreter has not been linked in.";
- return 0;
+ return nullptr;
}
- if ((WhichEngine & EngineKind::JIT) && ExecutionEngine::JITCtor == 0 &&
- ExecutionEngine::MCJITCtor == 0) {
+ if ((WhichEngine & EngineKind::JIT) && !ExecutionEngine::JITCtor &&
+ !ExecutionEngine::MCJITCtor) {
if (ErrorStr)
*ErrorStr = "JIT has not been linked in.";
}
- return 0;
+ return nullptr;
}
void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
@@ -848,7 +864,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
break;
case Type::PointerTyID:
if (isa<ConstantPointerNull>(C))
- Result.PointerVal = 0;
+ Result.PointerVal = nullptr;
else if (const Function *F = dyn_cast<Function>(C))
Result = PTOGV(getPointerToFunctionOrStub(const_cast<Function*>(F)));
else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
@@ -1193,20 +1209,18 @@ void ExecutionEngine::emitGlobals() {
if (Modules.size() != 1) {
for (unsigned m = 0, e = Modules.size(); m != e; ++m) {
Module &M = *Modules[m];
- for (Module::const_global_iterator I = M.global_begin(),
- E = M.global_end(); I != E; ++I) {
- const GlobalValue *GV = I;
- if (GV->hasLocalLinkage() || GV->isDeclaration() ||
- GV->hasAppendingLinkage() || !GV->hasName())
+ for (const auto &GV : M.globals()) {
+ if (GV.hasLocalLinkage() || GV.isDeclaration() ||
+ GV.hasAppendingLinkage() || !GV.hasName())
continue;// Ignore external globals and globals with internal linkage.
const GlobalValue *&GVEntry =
- LinkedGlobalsMap[std::make_pair(GV->getName(), GV->getType())];
+ LinkedGlobalsMap[std::make_pair(GV.getName(), GV.getType())];
// If this is the first time we've seen this global, it is the canonical
// version.
if (!GVEntry) {
- GVEntry = GV;
+ GVEntry = &GV;
continue;
}
@@ -1216,8 +1230,8 @@ void ExecutionEngine::emitGlobals() {
// Otherwise, we know it's linkonce/weak, replace it if this is a strong
// symbol. FIXME is this right for common?
- if (GV->hasExternalLinkage() || GVEntry->hasExternalWeakLinkage())
- GVEntry = GV;
+ if (GV.hasExternalLinkage() || GVEntry->hasExternalWeakLinkage())
+ GVEntry = &GV;
}
}
}
@@ -1225,31 +1239,30 @@ void ExecutionEngine::emitGlobals() {
std::vector<const GlobalValue*> NonCanonicalGlobals;
for (unsigned m = 0, e = Modules.size(); m != e; ++m) {
Module &M = *Modules[m];
- for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I) {
+ for (const auto &GV : M.globals()) {
// In the multi-module case, see what this global maps to.
if (!LinkedGlobalsMap.empty()) {
if (const GlobalValue *GVEntry =
- LinkedGlobalsMap[std::make_pair(I->getName(), I->getType())]) {
+ LinkedGlobalsMap[std::make_pair(GV.getName(), GV.getType())]) {
// If something else is the canonical global, ignore this one.
- if (GVEntry != &*I) {
- NonCanonicalGlobals.push_back(I);
+ if (GVEntry != &GV) {
+ NonCanonicalGlobals.push_back(&GV);
continue;
}
}
}
- if (!I->isDeclaration()) {
- addGlobalMapping(I, getMemoryForGV(I));
+ if (!GV.isDeclaration()) {
+ addGlobalMapping(&GV, getMemoryForGV(&GV));
} else {
// External variable reference. Try to use the dynamic loader to
// get a pointer to it.
if (void *SymAddr =
- sys::DynamicLibrary::SearchForAddressOfSymbol(I->getName()))
- addGlobalMapping(I, SymAddr);
+ sys::DynamicLibrary::SearchForAddressOfSymbol(GV.getName()))
+ addGlobalMapping(&GV, SymAddr);
else {
report_fatal_error("Could not resolve external global address: "
- +I->getName());
+ +GV.getName());
}
}
}
@@ -1269,16 +1282,15 @@ void ExecutionEngine::emitGlobals() {
// Now that all of the globals are set up in memory, loop through them all
// and initialize their contents.
- for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I) {
- if (!I->isDeclaration()) {
+ for (const auto &GV : M.globals()) {
+ if (!GV.isDeclaration()) {
if (!LinkedGlobalsMap.empty()) {
if (const GlobalValue *GVEntry =
- LinkedGlobalsMap[std::make_pair(I->getName(), I->getType())])
- if (GVEntry != &*I) // Not the canonical variable.
+ LinkedGlobalsMap[std::make_pair(GV.getName(), GV.getType())])
+ if (GVEntry != &GV) // Not the canonical variable.
continue;
}
- EmitGlobalVariable(I);
+ EmitGlobalVariable(&GV);
}
}
}
@@ -1290,12 +1302,12 @@ void ExecutionEngine::emitGlobals() {
void ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) {
void *GA = getPointerToGlobalIfAvailable(GV);
- if (GA == 0) {
+ if (!GA) {
// If it's not already specified, allocate memory for the global.
GA = getMemoryForGV(GV);
// If we failed to allocate memory for this global, return.
- if (GA == 0) return;
+ if (!GA) return;
addGlobalMapping(GV, GA);
}
diff --git a/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
index db3dead..6ff1e7a 100644
--- a/lib/ExecutionEngine/ExecutionEngineBindings.cpp
+++ b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "jit"
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
@@ -23,17 +22,11 @@
using namespace llvm;
+#define DEBUG_TYPE "jit"
+
// Wrapping the C bindings types.
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
-inline DataLayout *unwrap(LLVMTargetDataRef P) {
- return reinterpret_cast<DataLayout*>(P);
-}
-
-inline LLVMTargetDataRef wrap(const DataLayout *P) {
- return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
-}
-
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
return reinterpret_cast<TargetLibraryInfo*>(P);
}
@@ -410,7 +403,7 @@ uint8_t *SimpleBindingMemoryManager::allocateDataSection(
}
bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
- char *errMsgCString = 0;
+ char *errMsgCString = nullptr;
bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
assert((result || !errMsgCString) &&
"Did not expect an error message if FinalizeMemory succeeded");
@@ -433,7 +426,7 @@ LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
!Destroy)
- return NULL;
+ return nullptr;
SimpleBindingMMFunctions functions;
functions.AllocateCodeSection = AllocateCodeSection;
diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
index 2ca4e3e..9a65fa0 100644
--- a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
+++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
@@ -15,7 +15,6 @@
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
-#define DEBUG_TYPE "amplifier-jit-event-listener"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Metadata.h"
@@ -34,6 +33,8 @@
using namespace llvm;
using namespace llvm::jitprofiling;
+#define DEBUG_TYPE "amplifier-jit-event-listener"
+
namespace {
class IntelJITEventListener : public JITEventListener {
@@ -193,11 +194,10 @@ void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
MethodAddressVector Functions;
// Use symbol info to iterate functions in the object.
- error_code ec;
for (object::symbol_iterator I = Obj.begin_symbols(),
E = Obj.end_symbols();
- I != E && !ec;
- I.increment(ec)) {
+ I != E;
+ ++I) {
std::vector<LineNumberInfo> LineInfo;
std::string SourceFileName;
@@ -234,7 +234,7 @@ void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
FunctionMessage.line_number_table = 0;
} else {
SourceFileName = Lines.front().second.getFileName();
- FunctionMessage.source_file_name = (char *)SourceFileName.c_str();
+ FunctionMessage.source_file_name = const_cast<char *>(SourceFileName.c_str());
FunctionMessage.line_number_size = LineInfo.size();
FunctionMessage.line_number_table = &*LineInfo.begin();
}
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 8a80285..93bb2d1 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "interpreter"
#include "Interpreter.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Statistic.h"
@@ -28,6 +27,8 @@
#include <cmath>
using namespace llvm;
+#define DEBUG_TYPE "interpreter"
+
STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed");
static cl::opt<bool> PrintVolatile("interpreter-print-volatile", cl::Hidden,
@@ -57,7 +58,7 @@ static void executeFAddInst(GenericValue &Dest, GenericValue Src1,
IMPLEMENT_BINARY_OPERATOR(+, Double);
default:
dbgs() << "Unhandled type for FAdd instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
@@ -68,7 +69,7 @@ static void executeFSubInst(GenericValue &Dest, GenericValue Src1,
IMPLEMENT_BINARY_OPERATOR(-, Double);
default:
dbgs() << "Unhandled type for FSub instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
@@ -79,7 +80,7 @@ static void executeFMulInst(GenericValue &Dest, GenericValue Src1,
IMPLEMENT_BINARY_OPERATOR(*, Double);
default:
dbgs() << "Unhandled type for FMul instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
@@ -90,7 +91,7 @@ static void executeFDivInst(GenericValue &Dest, GenericValue Src1,
IMPLEMENT_BINARY_OPERATOR(/, Double);
default:
dbgs() << "Unhandled type for FDiv instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
@@ -105,7 +106,7 @@ static void executeFRemInst(GenericValue &Dest, GenericValue Src1,
break;
default:
dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
@@ -142,7 +143,7 @@ static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(==);
default:
dbgs() << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -156,7 +157,7 @@ static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(!=);
default:
dbgs() << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -170,7 +171,7 @@ static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(<);
default:
dbgs() << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -184,7 +185,7 @@ static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(<);
default:
dbgs() << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -198,7 +199,7 @@ static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(>);
default:
dbgs() << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -212,7 +213,7 @@ static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(>);
default:
dbgs() << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -226,7 +227,7 @@ static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(<=);
default:
dbgs() << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -240,7 +241,7 @@ static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(<=);
default:
dbgs() << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -254,7 +255,7 @@ static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(>=);
default:
dbgs() << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -268,7 +269,7 @@ static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_POINTER_ICMP(>=);
default:
dbgs() << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -293,7 +294,7 @@ void Interpreter::visitICmpInst(ICmpInst &I) {
case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
default:
dbgs() << "Don't know how to handle this ICmp predicate!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
SetValue(&I, R, SF);
@@ -329,7 +330,7 @@ static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2,
IMPLEMENT_VECTOR_FCMP(==);
default:
dbgs() << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -385,7 +386,7 @@ static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_VECTOR_FCMP(!=);
default:
dbgs() << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
// in vector case mask out NaN elements
if (Ty->isVectorTy())
@@ -405,7 +406,7 @@ static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_VECTOR_FCMP(<=);
default:
dbgs() << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -419,7 +420,7 @@ static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_VECTOR_FCMP(>=);
default:
dbgs() << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -433,7 +434,7 @@ static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2,
IMPLEMENT_VECTOR_FCMP(<);
default:
dbgs() << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -447,7 +448,7 @@ static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2,
IMPLEMENT_VECTOR_FCMP(>);
default:
dbgs() << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
@@ -615,7 +616,7 @@ void Interpreter::visitFCmpInst(FCmpInst &I) {
switch (I.getPredicate()) {
default:
dbgs() << "Don't know how to handle this FCmp predicate!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case FCmpInst::FCMP_FALSE: R = executeFCMP_BOOL(Src1, Src2, Ty, false);
break;
@@ -672,7 +673,7 @@ static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
case FCmpInst::FCMP_TRUE: return executeFCMP_BOOL(Src1, Src2, Ty, true);
default:
dbgs() << "Unhandled Cmp predicate\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
@@ -726,7 +727,7 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
switch(I.getOpcode()){
default:
dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case Instruction::Add: INTEGER_VECTOR_OPERATION(+) break;
case Instruction::Sub: INTEGER_VECTOR_OPERATION(-) break;
@@ -754,7 +755,7 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
fmod(Src1.AggregateVal[i].DoubleVal, Src2.AggregateVal[i].DoubleVal);
else {
dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
break;
@@ -763,7 +764,7 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
switch (I.getOpcode()) {
default:
dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case Instruction::Add: R.IntVal = Src1.IntVal + Src2.IntVal; break;
case Instruction::Sub: R.IntVal = Src1.IntVal - Src2.IntVal; break;
@@ -896,7 +897,7 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
GenericValue CondVal = getOperandValue(Cond, SF);
// Check to see if any of the cases match...
- BasicBlock *Dest = 0;
+ BasicBlock *Dest = nullptr;
for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
GenericValue CaseVal = getOperandValue(i.getCaseValue(), SF);
if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
@@ -979,7 +980,7 @@ void Interpreter::visitAllocaInst(AllocaInst &I) {
<< uintptr_t(Memory) << '\n');
GenericValue Result = PTOGV(Memory);
- assert(Result.PointerVal != 0 && "Null pointer returned by malloc!");
+ assert(Result.PointerVal && "Null pointer returned by malloc!");
SetValue(&I, Result, SF);
if (I.getOpcode() == Instruction::Alloca)
@@ -1732,7 +1733,7 @@ void Interpreter::visitVAArgInst(VAArgInst &I) {
IMPLEMENT_VAARG(Double);
default:
dbgs() << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
// Set the Value of this Instruction.
@@ -1756,7 +1757,7 @@ void Interpreter::visitExtractElementInst(ExtractElementInst &I) {
default:
dbgs() << "Unhandled destination type for extractelement instruction: "
<< *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case Type::IntegerTyID:
Dest.IntVal = Src1.AggregateVal[indx].IntVal;
@@ -2073,7 +2074,7 @@ GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) {
//
void Interpreter::callFunction(Function *F,
const std::vector<GenericValue> &ArgVals) {
- assert((ECStack.empty() || ECStack.back().Caller.getInstruction() == 0 ||
+ assert((ECStack.empty() || !ECStack.back().Caller.getInstruction() ||
ECStack.back().Caller.arg_size() == ArgVals.size()) &&
"Incorrect number of arguments passed into function call!");
// Make a new stack frame... and fill it in.
diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
index a03c7f5..671bbee 100644
--- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
+++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
@@ -98,13 +98,13 @@ static ExFunc lookupFunction(const Function *F) {
sys::ScopedLock Writer(*FunctionsLock);
ExFunc FnPtr = FuncNames[ExtName];
- if (FnPtr == 0)
+ if (!FnPtr)
FnPtr = FuncNames["lle_X_" + F->getName().str()];
- if (FnPtr == 0) // Try calling a generic function... if it exists...
+ if (!FnPtr) // Try calling a generic function... if it exists...
FnPtr = (ExFunc)(intptr_t)
sys::DynamicLibrary::SearchForAddressOfSymbol("lle_X_" +
F->getName().str());
- if (FnPtr != 0)
+ if (FnPtr)
ExportedFunctions->insert(std::make_pair(F, FnPtr)); // Cache for later
return FnPtr;
}
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
index 6d4f6f7..c589457 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.cpp
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
@@ -38,7 +38,7 @@ ExecutionEngine *Interpreter::create(Module *M, std::string* ErrStr) {
if (ErrStr)
*ErrStr = EC.message();
// We got an error, just return 0
- return 0;
+ return nullptr;
}
return new Interpreter(M);
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h
index 2e93cae..2145cde 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.h
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.h
@@ -108,7 +108,7 @@ public:
/// create - Create an interpreter ExecutionEngine. This can never fail.
///
- static ExecutionEngine *create(Module *M, std::string *ErrorStr = 0);
+ static ExecutionEngine *create(Module *M, std::string *ErrorStr = nullptr);
/// run - Start execution with the specified function and arguments.
///
@@ -118,7 +118,7 @@ public:
void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) override {
// FIXME: not implemented.
- return 0;
+ return nullptr;
}
/// recompileAndRelinkFunction - For the interpreter, functions are always
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index d3ad77b..f8b2827 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -79,7 +79,7 @@ ExecutionEngine *JIT::createJIT(Module *M,
// Try to register the program as a source of symbols to resolve against.
//
// FIXME: Don't do this here.
- sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);
+ sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
// If the target supports JIT code generation, create the JIT.
if (TargetJITInfo *TJ = TM->getJITInfo()) {
@@ -87,7 +87,7 @@ ExecutionEngine *JIT::createJIT(Module *M,
} else {
if (ErrorStr)
*ErrorStr = "target does not support JIT code generation";
- return 0;
+ return nullptr;
}
}
@@ -157,7 +157,7 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
// Turn the machine code intermediate representation into bytes in memory that
// may be executed.
- if (TM.addPassesToEmitMachineCode(PM, *JCE)) {
+ if (TM.addPassesToEmitMachineCode(PM, *JCE, !getVerifyModules())) {
report_fatal_error("Target does not support machine code emission!");
}
@@ -190,7 +190,7 @@ void JIT::addModule(Module *M) {
// Turn the machine code intermediate representation into bytes in memory
// that may be executed.
- if (TM.addPassesToEmitMachineCode(PM, *JCE)) {
+ if (TM.addPassesToEmitMachineCode(PM, *JCE, !getVerifyModules())) {
report_fatal_error("Target does not support machine code emission!");
}
@@ -210,7 +210,7 @@ bool JIT::removeModule(Module *M) {
if (jitstate && jitstate->getModule() == M) {
delete jitstate;
- jitstate = 0;
+ jitstate = nullptr;
}
if (!jitstate && !Modules.empty()) {
@@ -222,7 +222,7 @@ bool JIT::removeModule(Module *M) {
// Turn the machine code intermediate representation into bytes in memory
// that may be executed.
- if (TM.addPassesToEmitMachineCode(PM, *JCE)) {
+ if (TM.addPassesToEmitMachineCode(PM, *JCE, !getVerifyModules())) {
report_fatal_error("Target does not support machine code emission!");
}
@@ -353,7 +353,7 @@ GenericValue JIT::runFunction(Function *F,
// currently don't support varargs.
SmallVector<Value*, 8> Args;
for (unsigned i = 0, e = ArgValues.size(); i != e; ++i) {
- Constant *C = 0;
+ Constant *C = nullptr;
Type *ArgTy = FTy->getParamType(i);
const GenericValue &AV = ArgValues[i];
switch (ArgTy->getTypeID()) {
@@ -406,13 +406,13 @@ GenericValue JIT::runFunction(Function *F,
}
void JIT::RegisterJITEventListener(JITEventListener *L) {
- if (L == NULL)
+ if (!L)
return;
MutexGuard locked(lock);
EventListeners.push_back(L);
}
void JIT::UnregisterJITEventListener(JITEventListener *L) {
- if (L == NULL)
+ if (!L)
return;
MutexGuard locked(lock);
std::vector<JITEventListener*>::reverse_iterator I=
@@ -584,7 +584,7 @@ void *JIT::getPointerToNamedFunction(const std::string &Name,
report_fatal_error("Program used external function '"+Name+
"' which could not be resolved!");
}
- return 0;
+ return nullptr;
}
@@ -604,7 +604,7 @@ void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) {
return (void*)&__dso_handle;
#endif
Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(GV->getName());
- if (Ptr == 0) {
+ if (!Ptr) {
report_fatal_error("Could not resolve external global address: "
+GV->getName());
}
@@ -629,10 +629,10 @@ void *JIT::recompileAndRelinkFunction(Function *F) {
void *OldAddr = getPointerToGlobalIfAvailable(F);
// If it's not already compiled there is no reason to patch it up.
- if (OldAddr == 0) { return getPointerToFunction(F); }
+ if (!OldAddr) return getPointerToFunction(F);
// Delete the old function mapping.
- addGlobalMapping(F, 0);
+ addGlobalMapping(F, nullptr);
// Recodegen the function
runJITOnFunction(F);
diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h
index b1b0768..d2bd508 100644
--- a/lib/ExecutionEngine/JIT/JIT.h
+++ b/lib/ExecutionEngine/JIT/JIT.h
@@ -189,7 +189,7 @@ public:
TargetMachine *TM);
// Run the JIT on F and return information about the generated code
- void runJITOnFunction(Function *F, MachineCodeInfo *MCI = 0) override;
+ void runJITOnFunction(Function *F, MachineCodeInfo *MCI = nullptr) override;
void RegisterJITEventListener(JITEventListener *L) override;
void UnregisterJITEventListener(JITEventListener *L) override;
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index 9d215ec..cd7a500 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -12,7 +12,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "jit"
#include "JIT.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -52,6 +51,8 @@
#endif
using namespace llvm;
+#define DEBUG_TYPE "jit"
+
STATISTIC(NumBytes, "Number of bytes of machine code compiled");
STATISTIC(NumRelos, "Number of relocations applied");
STATISTIC(NumRetries, "Number of retries with more memory");
@@ -343,7 +344,8 @@ namespace {
void *FunctionBody; // Beginning of the function's allocation.
void *Code; // The address the function's code actually starts at.
void *ExceptionTable;
- EmittedCode() : FunctionBody(0), Code(0), ExceptionTable(0) {}
+ EmittedCode() : FunctionBody(nullptr), Code(nullptr),
+ ExceptionTable(nullptr) {}
};
struct EmittedFunctionConfig : public ValueMapConfig<const Function*> {
typedef JITEmitter *ExtraData;
@@ -360,7 +362,7 @@ namespace {
public:
JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
- : SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0),
+ : SizeEstimate(0), Resolver(jit, *this), MMI(nullptr), CurFn(nullptr),
EmittedFunctions(this), TheJIT(&jit) {
MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
if (jit.getJITInfo().needsGOT()) {
@@ -516,7 +518,7 @@ void *JITResolver::getLazyFunctionStub(Function *F) {
// Call the lazy resolver function if we are JIT'ing lazily. Otherwise we
// must resolve the symbol now.
void *Actual = TheJIT->isCompilingLazily()
- ? (void *)(intptr_t)LazyResolverFn : (void *)0;
+ ? (void *)(intptr_t)LazyResolverFn : (void *)nullptr;
// If this is an external declaration, attempt to resolve the address now
// to place in the stub.
@@ -525,7 +527,7 @@ void *JITResolver::getLazyFunctionStub(Function *F) {
// If we resolved the symbol to a null address (eg. a weak external)
// don't emit a stub. Return a null pointer to the application.
- if (!Actual) return 0;
+ if (!Actual) return nullptr;
}
TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
@@ -592,8 +594,8 @@ void *JITResolver::getExternalFunctionStub(void *FnAddr) {
if (Stub) return Stub;
TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
- JE.startGVStub(0, SL.Size, SL.Alignment);
- Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE);
+ JE.startGVStub(nullptr, SL.Size, SL.Alignment);
+ Stub = TheJIT->getJITInfo().emitFunctionStub(nullptr, FnAddr, JE);
JE.finishGVStub();
DEBUG(dbgs() << "JIT: Stub emitted at [" << Stub
@@ -619,8 +621,8 @@ void *JITResolver::JITCompilerFn(void *Stub) {
JITResolver *JR = StubToResolverMap->getResolverFromStub(Stub);
assert(JR && "Unable to find the corresponding JITResolver to the call site");
- Function* F = 0;
- void* ActualPtr = 0;
+ Function* F = nullptr;
+ void* ActualPtr = nullptr;
{
// Only lock for getting the Function. The call getPointerToFunction made
@@ -688,7 +690,7 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
return TheJIT->getOrEmitGlobalVariable(GV);
if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
- return TheJIT->getPointerToGlobal(GA->getAliasedGlobal());
+ return TheJIT->getPointerToGlobal(GA->getAliasee());
// If we have already compiled the function, return a pointer to its body.
Function *F = cast<Function>(V);
@@ -735,7 +737,7 @@ void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) {
const LLVMContext &Context = EmissionDetails.MF->getFunction()->getContext();
- if (DL.getScope(Context) != 0 && PrevDL != DL) {
+ if (DL.getScope(Context) != nullptr && PrevDL != DL) {
JITEvent_EmittedFunctionDetails::LineStart NextLine;
NextLine.Address = getCurrentPCValue();
NextLine.Loc = DL;
@@ -824,7 +826,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
// Resolve the relocations to concrete pointers.
for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
MachineRelocation &MR = Relocations[i];
- void *ResultPtr = 0;
+ void *ResultPtr = nullptr;
if (!MR.letTargetResolve()) {
if (MR.isExternalSymbol()) {
ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(),
@@ -870,7 +872,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
}
}
- CurFn = 0;
+ CurFn = nullptr;
TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0],
Relocations.size(), MemMgr->getGOTBase());
}
@@ -899,7 +901,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
SizeEstimate = 0;
}
- BufferBegin = CurBufferPtr = 0;
+ BufferBegin = CurBufferPtr = nullptr;
NumBytes += FnEnd-FnStart;
// Invalidate the icache if necessary.
@@ -1017,7 +1019,7 @@ void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
ConstantPoolBase = allocateSpace(Size, Align);
ConstantPool = MCP;
- if (ConstantPoolBase == 0) return; // Buffer overflow.
+ if (!ConstantPoolBase) return; // Buffer overflow.
DEBUG(dbgs() << "JIT: Emitted constant pool at [" << ConstantPoolBase
<< "] (size: " << Size << ", alignment: " << Align << ")\n");
@@ -1073,7 +1075,7 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
return;
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
- if (JT.empty() || JumpTableBase == 0) return;
+ if (JT.empty() || !JumpTableBase) return;
switch (MJTI->getEntryKind()) {
@@ -1243,7 +1245,7 @@ void JIT::updateFunctionStub(Function *F) {
void JIT::freeMachineCodeForFunction(Function *F) {
// Delete translation for this from the ExecutionEngine, so it will get
// retranslated next time it is used.
- updateGlobalMapping(F, 0);
+ updateGlobalMapping(F, nullptr);
// Free the actual memory for the function body and related stuff.
static_cast<JITEmitter*>(JCE)->deallocateMemForFunction(F);
diff --git a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
index 0d1ea02..584b93f 100644
--- a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
+++ b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "jit"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
@@ -40,6 +39,8 @@
using namespace llvm;
+#define DEBUG_TYPE "jit"
+
STATISTIC(NumSlabs, "Number of slabs of memory allocated by the JIT");
JITMemoryManager::~JITMemoryManager() {}
@@ -80,7 +81,7 @@ namespace {
/// getFreeBlockBefore - If the block before this one is free, return it,
/// otherwise return null.
FreeRangeHeader *getFreeBlockBefore() const {
- if (PrevAllocated) return 0;
+ if (PrevAllocated) return nullptr;
intptr_t PrevSize = reinterpret_cast<intptr_t *>(
const_cast<MemoryRangeHeader *>(this))[-1];
return reinterpret_cast<FreeRangeHeader *>(
@@ -174,7 +175,7 @@ FreeRangeHeader *MemoryRangeHeader::FreeBlock(FreeRangeHeader *FreeList) {
// coalesce with it, update our notion of what the free list is.
if (&FollowingFreeBlock == FreeList) {
FreeList = FollowingFreeBlock.Next;
- FreeListToReturn = 0;
+ FreeListToReturn = nullptr;
assert(&FollowingFreeBlock != FreeList && "No tombstone block?");
}
FollowingFreeBlock.RemoveFromFreeList();
@@ -269,13 +270,12 @@ namespace {
class DefaultJITMemoryManager;
- class JITSlabAllocator : public SlabAllocator {
+ class JITAllocator {
DefaultJITMemoryManager &JMM;
public:
- JITSlabAllocator(DefaultJITMemoryManager &jmm) : JMM(jmm) { }
- virtual ~JITSlabAllocator() { }
- MemSlab *Allocate(size_t Size) override;
- void Deallocate(MemSlab *Slab) override;
+ JITAllocator(DefaultJITMemoryManager &jmm) : JMM(jmm) { }
+ void *Allocate(size_t Size, size_t /*Alignment*/);
+ void Deallocate(void *Slab, size_t Size);
};
/// DefaultJITMemoryManager - Manage memory for the JIT code generation.
@@ -313,9 +313,10 @@ namespace {
// Memory slabs allocated by the JIT. We refer to them as slabs so we don't
// confuse them with the blocks of memory described above.
std::vector<sys::MemoryBlock> CodeSlabs;
- JITSlabAllocator BumpSlabAllocator;
- BumpPtrAllocatorImpl<DefaultSlabSize, DefaultSizeThreshold> StubAllocator;
- BumpPtrAllocatorImpl<DefaultSlabSize, DefaultSizeThreshold> DataAllocator;
+ BumpPtrAllocatorImpl<JITAllocator, DefaultSlabSize,
+ DefaultSizeThreshold> StubAllocator;
+ BumpPtrAllocatorImpl<JITAllocator, DefaultSlabSize,
+ DefaultSizeThreshold> DataAllocator;
// Circular list of free blocks.
FreeRangeHeader *FreeMemoryList;
@@ -568,30 +569,24 @@ namespace {
};
}
-MemSlab *JITSlabAllocator::Allocate(size_t Size) {
+void *JITAllocator::Allocate(size_t Size, size_t /*Alignment*/) {
sys::MemoryBlock B = JMM.allocateNewSlab(Size);
- MemSlab *Slab = (MemSlab*)B.base();
- Slab->Size = B.size();
- Slab->NextPtr = 0;
- return Slab;
+ return B.base();
}
-void JITSlabAllocator::Deallocate(MemSlab *Slab) {
- sys::MemoryBlock B(Slab, Slab->Size);
+void JITAllocator::Deallocate(void *Slab, size_t Size) {
+ sys::MemoryBlock B(Slab, Size);
sys::Memory::ReleaseRWX(B);
}
DefaultJITMemoryManager::DefaultJITMemoryManager()
- :
+ :
#ifdef NDEBUG
- PoisonMemory(false),
+ PoisonMemory(false),
#else
- PoisonMemory(true),
+ PoisonMemory(true),
#endif
- LastSlab(0, 0),
- BumpSlabAllocator(*this),
- StubAllocator(BumpSlabAllocator),
- DataAllocator(BumpSlabAllocator) {
+ LastSlab(nullptr, 0), StubAllocator(*this), DataAllocator(*this) {
// Allocate space for code.
sys::MemoryBlock MemBlock = allocateNewSlab(DefaultCodeSlabSize);
@@ -644,11 +639,11 @@ DefaultJITMemoryManager::DefaultJITMemoryManager()
// Start out with the freelist pointing to Mem0.
FreeMemoryList = Mem0;
- GOTBase = NULL;
+ GOTBase = nullptr;
}
void DefaultJITMemoryManager::AllocateGOT() {
- assert(GOTBase == 0 && "Cannot allocate the got multiple times");
+ assert(!GOTBase && "Cannot allocate the got multiple times");
GOTBase = new uint8_t[sizeof(void*) * 8192];
HasGOT = true;
}
@@ -663,9 +658,9 @@ DefaultJITMemoryManager::~DefaultJITMemoryManager() {
sys::MemoryBlock DefaultJITMemoryManager::allocateNewSlab(size_t size) {
// Allocate a new block close to the last one.
std::string ErrMsg;
- sys::MemoryBlock *LastSlabPtr = LastSlab.base() ? &LastSlab : 0;
+ sys::MemoryBlock *LastSlabPtr = LastSlab.base() ? &LastSlab : nullptr;
sys::MemoryBlock B = sys::Memory::AllocateRWX(size, LastSlabPtr, &ErrMsg);
- if (B.base() == 0) {
+ if (!B.base()) {
report_fatal_error("Allocation failed when allocating new memory in the"
" JIT\n" + Twine(ErrMsg));
}
@@ -726,7 +721,7 @@ bool DefaultJITMemoryManager::CheckInvariants(std::string &ErrorStr) {
char *End = Start + I->size();
// Check each memory range.
- for (MemoryRangeHeader *Hdr = (MemoryRangeHeader*)Start, *LastHdr = NULL;
+ for (MemoryRangeHeader *Hdr = (MemoryRangeHeader*)Start, *LastHdr = nullptr;
Start <= (char*)Hdr && (char*)Hdr < End;
Hdr = &Hdr->getBlockAfter()) {
if (Hdr->ThisAllocated == 0) {
@@ -895,7 +890,7 @@ void *DefaultJITMemoryManager::getPointerToNamedFunction(const std::string &Name
report_fatal_error("Program used external function '"+Name+
"' which could not be resolved!");
}
- return 0;
+ return nullptr;
}
diff --git a/lib/ExecutionEngine/MCJIT/LLVMBuild.txt b/lib/ExecutionEngine/MCJIT/LLVMBuild.txt
index 90f4d2f..922cd0d 100644
--- a/lib/ExecutionEngine/MCJIT/LLVMBuild.txt
+++ b/lib/ExecutionEngine/MCJIT/LLVMBuild.txt
@@ -19,4 +19,4 @@
type = Library
name = MCJIT
parent = ExecutionEngine
-required_libraries = Core ExecutionEngine RuntimeDyld Support Target
+required_libraries = Core ExecutionEngine Object RuntimeDyld Support Target
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index 49b6727..42cb4ea 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -50,7 +50,7 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
// Try to register the program as a source of symbols to resolve against.
//
// FIXME: Don't do this here.
- sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);
+ sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager(),
GVsWithCode);
@@ -58,8 +58,8 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM,
bool AllocateGVsWithCode)
- : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(this, MM), Dyld(&MemMgr),
- ObjCache(0) {
+ : ExecutionEngine(m), TM(tm), Ctx(nullptr), MemMgr(this, MM), Dyld(&MemMgr),
+ ObjCache(nullptr) {
OwnedModules.addModule(m);
setDataLayout(TM->getDataLayout());
@@ -113,8 +113,8 @@ bool MCJIT::removeModule(Module *M) {
-void MCJIT::addObjectFile(object::ObjectFile *Obj) {
- ObjectImage *LoadedObject = Dyld.loadObject(Obj);
+void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
+ ObjectImage *LoadedObject = Dyld.loadObject(std::move(Obj));
if (!LoadedObject || Dyld.hasError())
report_fatal_error(Dyld.getErrorString());
@@ -150,7 +150,8 @@ ObjectBufferStream* MCJIT::emitObject(Module *M) {
// Turn the machine code intermediate representation into bytes in memory
// that may be executed.
- if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), false)) {
+ if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(),
+ !getVerifyModules())) {
report_fatal_error("Target does not support MC emission!");
}
@@ -185,9 +186,9 @@ void MCJIT::generateCodeForModule(Module *M) {
std::unique_ptr<ObjectBuffer> ObjectToLoad;
// Try to load the pre-compiled object from cache if possible
- if (0 != ObjCache) {
+ if (ObjCache) {
std::unique_ptr<MemoryBuffer> PreCompiledObject(ObjCache->getObject(M));
- if (0 != PreCompiledObject.get())
+ if (PreCompiledObject.get())
ObjectToLoad.reset(new ObjectBuffer(PreCompiledObject.release()));
}
@@ -285,7 +286,7 @@ Module *MCJIT::findModuleForSymbol(const std::string &Name,
}
}
// We didn't find the symbol in any of our modules.
- return NULL;
+ return nullptr;
}
uint64_t MCJIT::getSymbolAddress(const std::string &Name,
@@ -307,10 +308,10 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name,
std::unique_ptr<object::Binary> ChildBin;
// FIXME: Support nested archives?
if (!ChildIt->getAsBinary(ChildBin) && ChildBin->isObject()) {
- object::ObjectFile *OF = reinterpret_cast<object::ObjectFile *>(
- ChildBin.release());
+ std::unique_ptr<object::ObjectFile> OF(
+ static_cast<object::ObjectFile *>(ChildBin.release()));
// This causes the object file to be loaded.
- addObjectFile(OF);
+ addObjectFile(std::move(OF));
// The address should be here now.
Addr = getExistingSymbolAddress(Name);
if (Addr)
@@ -365,7 +366,7 @@ void *MCJIT::getPointerToFunction(Function *F) {
generateCodeForModule(M);
else if (!OwnedModules.hasModuleBeenLoaded(M))
// If this function doesn't belong to one of our modules, we're done.
- return NULL;
+ return nullptr;
// FIXME: Should the Dyld be retaining module information? Probably not.
//
@@ -409,7 +410,7 @@ Function *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName,
if (Function *F = (*I)->getFunction(FnName))
return F;
}
- return 0;
+ return nullptr;
}
Function *MCJIT::FindFunctionNamed(const char *FnName) {
@@ -541,17 +542,17 @@ void *MCJIT::getPointerToNamedFunction(const std::string &Name,
report_fatal_error("Program used external function '"+Name+
"' which could not be resolved!");
}
- return 0;
+ return nullptr;
}
void MCJIT::RegisterJITEventListener(JITEventListener *L) {
- if (L == NULL)
+ if (!L)
return;
MutexGuard locked(lock);
EventListeners.push_back(L);
}
void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
- if (L == NULL)
+ if (!L)
return;
MutexGuard locked(lock);
SmallVector<JITEventListener*, 2>::reverse_iterator I=
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h
index 066eceb..100e9a2 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -71,7 +71,7 @@ public:
ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
}
- bool finalizeMemory(std::string *ErrMsg = 0) override {
+ bool finalizeMemory(std::string *ErrMsg = nullptr) override {
return ClientMM->finalizeMemory(ErrMsg);
}
@@ -239,7 +239,7 @@ public:
/// @name ExecutionEngine interface implementation
/// @{
void addModule(Module *M) override;
- void addObjectFile(object::ObjectFile *O) override;
+ void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
void addArchive(object::Archive *O) override;
bool removeModule(Module *M) override;
diff --git a/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp b/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
index f1dd5a6..9ceaa90 100644
--- a/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
+++ b/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
@@ -79,7 +79,7 @@ uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup,
ec);
if (ec) {
// FIXME: Add error propagation to the interface.
- return NULL;
+ return nullptr;
}
// Save this address as the basis for our next request
diff --git a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
index 87cef2e..fd37a13 100644
--- a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
+++ b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
@@ -15,7 +15,6 @@
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
-#define DEBUG_TYPE "oprofile-jit-event-listener"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -33,6 +32,8 @@
using namespace llvm;
using namespace llvm::jitprofiling;
+#define DEBUG_TYPE "oprofile-jit-event-listener"
+
namespace {
class OProfileJITEventListener : public JITEventListener {
@@ -170,11 +171,8 @@ void OProfileJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
}
// Use symbol info to iterate functions in the object.
- error_code ec;
- for (object::symbol_iterator I = Obj.begin_symbols(),
- E = Obj.end_symbols();
- I != E && !ec;
- I.increment(ec)) {
+ for (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
+ I != E; ++I) {
object::SymbolRef::Type SymType;
if (I->getType(SymType)) continue;
if (SymType == object::SymbolRef::ST_Function) {
@@ -203,11 +201,8 @@ void OProfileJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
}
// Use symbol info to iterate functions in the object.
- error_code ec;
- for (object::symbol_iterator I = Obj.begin_symbols(),
- E = Obj.end_symbols();
- I != E && !ec;
- I.increment(ec)) {
+ for (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
+ I != E; ++I) {
object::SymbolRef::Type SymType;
if (I->getType(SymType)) continue;
if (SymType == object::SymbolRef::ST_Function) {
diff --git a/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp b/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp
index 6702e20..04edbd2 100644
--- a/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp
+++ b/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp
@@ -13,7 +13,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "oprofile-wrapper"
#include "llvm/ExecutionEngine/OProfileWrapper.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
@@ -29,6 +28,8 @@
#include <sys/stat.h>
#include <unistd.h>
+#define DEBUG_TYPE "oprofile-wrapper"
+
namespace {
// Global mutex to ensure a single thread initializes oprofile agent.
diff --git a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
index 1d0e9b3..8546571 100644
--- a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
@@ -45,7 +45,7 @@ extern "C" {
// We put information about the JITed function in this global, which the
// debugger reads. Make sure to specify the version statically, because the
// debugger checks the version before we can set it during runtime.
- struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
+ struct jit_descriptor __jit_debug_descriptor = { 1, 0, nullptr, nullptr };
// Debuggers puts a breakpoint in this function.
LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() {
@@ -108,10 +108,10 @@ void NotifyDebugger(jit_code_entry* JITCodeEntry) {
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
// Insert this entry at the head of the list.
- JITCodeEntry->prev_entry = NULL;
+ JITCodeEntry->prev_entry = nullptr;
jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry;
JITCodeEntry->next_entry = NextEntry;
- if (NextEntry != NULL) {
+ if (NextEntry) {
NextEntry->prev_entry = JITCodeEntry;
}
__jit_debug_descriptor.first_entry = JITCodeEntry;
@@ -142,11 +142,10 @@ void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) {
"Second attempt to perform debug registration.");
jit_code_entry* JITCodeEntry = new jit_code_entry();
- if (JITCodeEntry == 0) {
+ if (!JITCodeEntry) {
llvm::report_fatal_error(
"Allocation failed when registering a JIT entry!\n");
- }
- else {
+ } else {
JITCodeEntry->symfile_addr = Buffer;
JITCodeEntry->symfile_size = Size;
@@ -198,7 +197,7 @@ void GDBJITRegistrar::deregisterObjectInternal(
}
delete JITCodeEntry;
- JITCodeEntry = NULL;
+ JITCodeEntry = nullptr;
}
llvm::ManagedStatic<GDBJITRegistrar> TheRegistrar;
diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
index 3693c69..4917b93 100644
--- a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
+++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
@@ -18,6 +18,8 @@
#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/Object/ObjectFile.h"
+#include <memory>
+
namespace llvm {
namespace object {
@@ -30,13 +32,13 @@ class ObjectImageCommon : public ObjectImage {
void anchor() override;
protected:
- object::ObjectFile *ObjFile;
+ std::unique_ptr<object::ObjectFile> ObjFile;
// This form of the constructor allows subclasses to use
// format-specific subclasses of ObjectFile directly
- ObjectImageCommon(ObjectBuffer *Input, object::ObjectFile *Obj)
+ ObjectImageCommon(ObjectBuffer *Input, std::unique_ptr<object::ObjectFile> Obj)
: ObjectImage(Input), // saves Input as Buffer and takes ownership
- ObjFile(Obj)
+ ObjFile(std::move(Obj))
{
}
@@ -44,12 +46,13 @@ public:
ObjectImageCommon(ObjectBuffer* Input)
: ObjectImage(Input) // saves Input as Buffer and takes ownership
{
- ObjFile =
- object::ObjectFile::createObjectFile(Buffer->getMemBuffer()).get();
+ // FIXME: error checking? createObjectFile returns an ErrorOr<ObjectFile*>
+ // and should probably be checked for failure.
+ ObjFile.reset(object::ObjectFile::createObjectFile(Buffer->getMemBuffer()).get());
}
- ObjectImageCommon(object::ObjectFile* Input)
- : ObjectImage(NULL), ObjFile(Input) {}
- virtual ~ObjectImageCommon() { delete ObjFile; }
+ ObjectImageCommon(std::unique_ptr<object::ObjectFile> Input)
+ : ObjectImage(nullptr), ObjFile(std::move(Input)) {}
+ virtual ~ObjectImageCommon() { }
object::symbol_iterator begin_symbols() const override
{ return ObjFile->symbol_begin(); }
@@ -66,7 +69,7 @@ public:
StringRef getData() const override { return ObjFile->getData(); }
- object::ObjectFile* getObjectFile() const override { return ObjFile; }
+ object::ObjectFile* getObjectFile() const override { return ObjFile.get(); }
// Subclasses can override these methods to update the image with loaded
// addresses for sections and common symbols
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 986d3a0..c1eb0fd 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dyld"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "JITRegistrar.h"
#include "ObjectImageCommon.h"
@@ -25,6 +24,8 @@
using namespace llvm;
using namespace llvm::object;
+#define DEBUG_TYPE "dyld"
+
// Empty out-of-line virtual destructor as the key function.
RuntimeDyldImpl::~RuntimeDyldImpl() {}
@@ -72,12 +73,40 @@ void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress,
llvm_unreachable("Attempting to remap address of unknown section!");
}
+static error_code getOffset(const SymbolRef &Sym, uint64_t &Result) {
+ uint64_t Address;
+ if (error_code EC = Sym.getAddress(Address))
+ return EC;
+
+ if (Address == UnknownAddressOrSize) {
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+
+ const ObjectFile *Obj = Sym.getObject();
+ section_iterator SecI(Obj->section_begin());
+ if (error_code EC = Sym.getSection(SecI))
+ return EC;
+
+ if (SecI == Obj->section_end()) {
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+
+ uint64_t SectionAddress;
+ if (error_code EC = SecI->getAddress(SectionAddress))
+ return EC;
+
+ Result = Address - SectionAddress;
+ return object_error::success;
+}
+
ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
MutexGuard locked(lock);
std::unique_ptr<ObjectImage> Obj(InputObject);
if (!Obj)
- return NULL;
+ return nullptr;
// Save information about our target
Arch = (Triple::ArchType)Obj->getArch();
@@ -115,36 +144,33 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
bool IsCommon = Flags & SymbolRef::SF_Common;
if (IsCommon) {
// Add the common symbols to a list. We'll allocate them all below.
- uint32_t Align;
- Check(I->getAlignment(Align));
- uint64_t Size = 0;
- Check(I->getSize(Size));
- CommonSize += Size + Align;
- CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
+ if (!GlobalSymbolTable.count(Name)) {
+ uint32_t Align;
+ Check(I->getAlignment(Align));
+ uint64_t Size = 0;
+ Check(I->getSize(Size));
+ CommonSize += Size + Align;
+ CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
+ }
} else {
if (SymType == object::SymbolRef::ST_Function ||
SymType == object::SymbolRef::ST_Data ||
SymType == object::SymbolRef::ST_Unknown) {
- uint64_t FileOffset;
+ uint64_t SectOffset;
StringRef SectionData;
bool IsCode;
section_iterator SI = Obj->end_sections();
- Check(I->getFileOffset(FileOffset));
+ Check(getOffset(*I, SectOffset));
Check(I->getSection(SI));
if (SI == Obj->end_sections())
continue;
Check(SI->getContents(SectionData));
Check(SI->isText(IsCode));
- const uint8_t *SymPtr =
- (const uint8_t *)Obj->getData().data() + (uintptr_t)FileOffset;
- uintptr_t SectOffset =
- (uintptr_t)(SymPtr - (const uint8_t *)SectionData.begin());
unsigned SectionID =
findOrEmitSection(*Obj, *SI, IsCode, LocalSections);
LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
- DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
- << " flags: " << Flags << " SID: " << SectionID
- << " Offset: " << format("%p", SectOffset));
+ DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset)
+ << " flags: " << Flags << " SID: " << SectionID);
GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
}
}
@@ -153,7 +179,7 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
// Allocate common symbols
if (CommonSize != 0)
- emitCommonSymbols(*Obj, CommonSymbols, CommonSize, LocalSymbols);
+ emitCommonSymbols(*Obj, CommonSymbols, CommonSize, GlobalSymbolTable);
// Parse and process relocations
DEBUG(dbgs() << "Parse relocations:\n");
@@ -163,7 +189,10 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
StubMap Stubs;
section_iterator RelocatedSection = SI->getRelocatedSection();
- if (SI->relocation_empty() && !ProcessAllSections)
+ relocation_iterator I = SI->relocation_begin();
+ relocation_iterator E = SI->relocation_end();
+
+ if (I == E && !ProcessAllSections)
continue;
bool IsCode = false;
@@ -172,14 +201,13 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
- for (relocation_iterator I = SI->relocation_begin(),
- E = SI->relocation_end(); I != E;)
+ for (; I != E;)
I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols,
Stubs);
}
// Give the subclasses a chance to tie-up any loose ends.
- finalizeLoad(LocalSections);
+ finalizeLoad(*Obj, LocalSections);
return Obj.release();
}
@@ -400,7 +428,7 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
uintptr_t Allocate;
unsigned SectionID = Sections.size();
uint8_t *Addr;
- const char *pData = 0;
+ const char *pData = nullptr;
// Some sections, such as debug info, don't need to be loaded for execution.
// Leave those where they are.
@@ -441,7 +469,7 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
// to handle later processing (and by 'handle' I mean don't do anything
// with these sections).
Allocate = 0;
- Addr = 0;
+ Addr = nullptr;
DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
<< " obj addr: " << format("%p", data.data()) << " new addr: 0"
<< " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
@@ -490,7 +518,8 @@ void RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE,
}
uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
- if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) {
+ if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be ||
+ Arch == Triple::arm64 || Arch == Triple::arm64_be) {
// This stub has to be able to access the full address space,
// since symbol lookup won't necessarily find a handy, in-range,
// PLT stub for functions which could be anywhere.
@@ -560,6 +589,8 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
*Addr = 0xFF; // jmp
*(Addr+1) = 0x25; // rip
// 32-bit PC-relative address of the GOT entry will be stored at Addr+2
+ } else if (Arch == Triple::x86) {
+ *Addr = 0xE9; // 32-bit pc-relative jump.
}
return Addr;
}
@@ -586,7 +617,7 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
const RelocationEntry &RE = Relocs[i];
// Ignore relocations for sections that were not loaded
- if (Sections[RE.SectionID].Address == 0)
+ if (Sections[RE.SectionID].Address == nullptr)
continue;
resolveRelocation(RE, Value);
}
@@ -651,7 +682,7 @@ RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
// though the public class spawns a new 'impl' instance for each load,
// they share a single memory manager. This can become a problem when page
// permissions are applied.
- Dyld = 0;
+ Dyld = nullptr;
MM = mm;
ProcessAllSections = false;
}
@@ -672,21 +703,23 @@ createRuntimeDyldMachO(RTDyldMemoryManager *MM, bool ProcessAllSections) {
return Dyld;
}
-ObjectImage *RuntimeDyld::loadObject(ObjectFile *InputObject) {
+ObjectImage *RuntimeDyld::loadObject(std::unique_ptr<ObjectFile> InputObject) {
std::unique_ptr<ObjectImage> InputImage;
+ ObjectFile &Obj = *InputObject;
+
if (InputObject->isELF()) {
- InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(InputObject));
+ InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(std::move(InputObject)));
if (!Dyld)
Dyld = createRuntimeDyldELF(MM, ProcessAllSections).release();
} else if (InputObject->isMachO()) {
- InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(InputObject));
+ InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject)));
if (!Dyld)
Dyld = createRuntimeDyldMachO(MM, ProcessAllSections).release();
} else
report_fatal_error("Incompatible object format!");
- if (!Dyld->isCompatibleFile(InputObject))
+ if (!Dyld->isCompatibleFile(&Obj))
report_fatal_error("Incompatible object format!");
Dyld->loadObject(InputImage.get());
@@ -740,7 +773,7 @@ ObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) {
void *RuntimeDyld::getSymbolAddress(StringRef Name) {
if (!Dyld)
- return NULL;
+ return nullptr;
return Dyld->getSymbolAddress(Name);
}
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 3204b81..6ba24b9 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dyld"
#include "RuntimeDyldELF.h"
#include "JITRegistrar.h"
#include "ObjectImageCommon.h"
@@ -29,6 +28,8 @@
using namespace llvm;
using namespace llvm::object;
+#define DEBUG_TYPE "dyld"
+
namespace {
static inline error_code check(error_code Err) {
@@ -50,7 +51,12 @@ template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
+ std::unique_ptr<ObjectFile> UnderlyingFile;
+
public:
+ DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
+ MemoryBuffer *Wrapper, error_code &ec);
+
DyldELFObject(MemoryBuffer *Wrapper, error_code &ec);
void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
@@ -67,13 +73,11 @@ public:
};
template <class ELFT> class ELFObjectImage : public ObjectImageCommon {
-protected:
- DyldELFObject<ELFT> *DyldObj;
bool Registered;
public:
- ELFObjectImage(ObjectBuffer *Input, DyldELFObject<ELFT> *Obj)
- : ObjectImageCommon(Input, Obj), DyldObj(Obj), Registered(false) {}
+ ELFObjectImage(ObjectBuffer *Input, std::unique_ptr<DyldELFObject<ELFT>> Obj)
+ : ObjectImageCommon(Input, std::move(Obj)), Registered(false) {}
virtual ~ELFObjectImage() {
if (Registered)
@@ -83,11 +87,13 @@ public:
// Subclasses can override these methods to update the image with loaded
// addresses for sections and common symbols
void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) override {
- DyldObj->updateSectionAddress(Sec, Addr);
+ static_cast<DyldELFObject<ELFT>*>(getObjectFile())
+ ->updateSectionAddress(Sec, Addr);
}
void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) override {
- DyldObj->updateSymbolAddress(Sym, Addr);
+ static_cast<DyldELFObject<ELFT>*>(getObjectFile())
+ ->updateSymbolAddress(Sym, Addr);
}
void registerWithDebugger() override {
@@ -109,6 +115,14 @@ DyldELFObject<ELFT>::DyldELFObject(MemoryBuffer *Wrapper, error_code &ec)
}
template <class ELFT>
+DyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
+ MemoryBuffer *Wrapper, error_code &ec)
+ : ELFObjectFile<ELFT>(Wrapper, ec),
+ UnderlyingFile(std::move(UnderlyingFile)) {
+ this->isDyldELFObject = true;
+}
+
+template <class ELFT>
void DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec,
uint64_t Addr) {
DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
@@ -164,30 +178,36 @@ void RuntimeDyldELF::deregisterEHFrames() {
}
ObjectImage *
-RuntimeDyldELF::createObjectImageFromFile(object::ObjectFile *ObjFile) {
+RuntimeDyldELF::createObjectImageFromFile(std::unique_ptr<object::ObjectFile> ObjFile) {
if (!ObjFile)
- return NULL;
+ return nullptr;
error_code ec;
MemoryBuffer *Buffer =
MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false);
if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) {
- DyldELFObject<ELFType<support::little, 2, false>> *Obj =
- new DyldELFObject<ELFType<support::little, 2, false>>(Buffer, ec);
- return new ELFObjectImage<ELFType<support::little, 2, false>>(NULL, Obj);
+ auto Obj =
+ llvm::make_unique<DyldELFObject<ELFType<support::little, 2, false>>>(
+ std::move(ObjFile), Buffer, ec);
+ return new ELFObjectImage<ELFType<support::little, 2, false>>(
+ nullptr, std::move(Obj));
} else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) {
- DyldELFObject<ELFType<support::big, 2, false>> *Obj =
- new DyldELFObject<ELFType<support::big, 2, false>>(Buffer, ec);
- return new ELFObjectImage<ELFType<support::big, 2, false>>(NULL, Obj);
+ auto Obj =
+ llvm::make_unique<DyldELFObject<ELFType<support::big, 2, false>>>(
+ std::move(ObjFile), Buffer, ec);
+ return new ELFObjectImage<ELFType<support::big, 2, false>>(nullptr, std::move(Obj));
} else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) {
- DyldELFObject<ELFType<support::big, 2, true>> *Obj =
- new DyldELFObject<ELFType<support::big, 2, true>>(Buffer, ec);
- return new ELFObjectImage<ELFType<support::big, 2, true>>(NULL, Obj);
+ auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 2, true>>>(
+ std::move(ObjFile), Buffer, ec);
+ return new ELFObjectImage<ELFType<support::big, 2, true>>(nullptr,
+ std::move(Obj));
} else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) {
- DyldELFObject<ELFType<support::little, 2, true>> *Obj =
- new DyldELFObject<ELFType<support::little, 2, true>>(Buffer, ec);
- return new ELFObjectImage<ELFType<support::little, 2, true>>(NULL, Obj);
+ auto Obj =
+ llvm::make_unique<DyldELFObject<ELFType<support::little, 2, true>>>(
+ std::move(ObjFile), Buffer, ec);
+ return new ELFObjectImage<ELFType<support::little, 2, true>>(
+ nullptr, std::move(Obj));
} else
llvm_unreachable("Unexpected ELF format");
}
@@ -201,28 +221,29 @@ ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) {
error_code ec;
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
- DyldELFObject<ELFType<support::little, 4, false>> *Obj =
- new DyldELFObject<ELFType<support::little, 4, false>>(
+ auto Obj =
+ llvm::make_unique<DyldELFObject<ELFType<support::little, 4, false>>>(
Buffer->getMemBuffer(), ec);
- return new ELFObjectImage<ELFType<support::little, 4, false>>(Buffer, Obj);
+ return new ELFObjectImage<ELFType<support::little, 4, false>>(
+ Buffer, std::move(Obj));
} else if (Ident.first == ELF::ELFCLASS32 &&
Ident.second == ELF::ELFDATA2MSB) {
- DyldELFObject<ELFType<support::big, 4, false>> *Obj =
- new DyldELFObject<ELFType<support::big, 4, false>>(
+ auto Obj =
+ llvm::make_unique<DyldELFObject<ELFType<support::big, 4, false>>>(
Buffer->getMemBuffer(), ec);
- return new ELFObjectImage<ELFType<support::big, 4, false>>(Buffer, Obj);
+ return new ELFObjectImage<ELFType<support::big, 4, false>>(Buffer,
+ std::move(Obj));
} else if (Ident.first == ELF::ELFCLASS64 &&
Ident.second == ELF::ELFDATA2MSB) {
- DyldELFObject<ELFType<support::big, 8, true>> *Obj =
- new DyldELFObject<ELFType<support::big, 8, true>>(
- Buffer->getMemBuffer(), ec);
- return new ELFObjectImage<ELFType<support::big, 8, true>>(Buffer, Obj);
+ auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 8, true>>>(
+ Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<ELFType<support::big, 8, true>>(Buffer, std::move(Obj));
} else if (Ident.first == ELF::ELFCLASS64 &&
Ident.second == ELF::ELFDATA2LSB) {
- DyldELFObject<ELFType<support::little, 8, true>> *Obj =
- new DyldELFObject<ELFType<support::little, 8, true>>(
+ auto Obj =
+ llvm::make_unique<DyldELFObject<ELFType<support::little, 8, true>>>(
Buffer->getMemBuffer(), ec);
- return new ELFObjectImage<ELFType<support::little, 8, true>>(Buffer, Obj);
+ return new ELFObjectImage<ELFType<support::little, 8, true>>(Buffer, std::move(Obj));
} else
llvm_unreachable("Unexpected ELF format");
}
@@ -845,6 +866,8 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
break;
case Triple::aarch64:
case Triple::aarch64_be:
+ case Triple::arm64:
+ case Triple::arm64_be:
resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
break;
case Triple::arm: // Fall through.
@@ -950,7 +973,8 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
<< "\n");
- if (Arch == Triple::aarch64 &&
+ if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be ||
+ Arch == Triple::arm64 || Arch == Triple::arm64_be) &&
(RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26)) {
// This is an AArch64 branch relocation, need to use a stub function.
DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
@@ -1151,7 +1175,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
// Extra check to avoid relocation againt empty symbols (usually
// the R_PPC64_TOC).
if (SymType != SymbolRef::ST_Unknown && TargetName.empty())
- Value.SymbolName = NULL;
+ Value.SymbolName = nullptr;
if (Value.SymbolName)
addRelocationForSymbol(RE, Value.SymbolName);
@@ -1283,7 +1307,8 @@ void RuntimeDyldELF::updateGOTEntries(StringRef Name, uint64_t Addr) {
for (it = GOTs.begin(); it != end; ++it) {
GOTRelocations &GOTEntries = it->second;
for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
- if (GOTEntries[i].SymbolName != 0 && GOTEntries[i].SymbolName == Name) {
+ if (GOTEntries[i].SymbolName != nullptr &&
+ GOTEntries[i].SymbolName == Name) {
GOTEntries[i].Offset = Addr;
}
}
@@ -1297,6 +1322,9 @@ size_t RuntimeDyldELF::getGOTEntrySize() {
switch (Arch) {
case Triple::x86_64:
case Triple::aarch64:
+ case Triple::aarch64_be:
+ case Triple::arm64:
+ case Triple::arm64_be:
case Triple::ppc64:
case Triple::ppc64le:
case Triple::systemz:
@@ -1331,7 +1359,7 @@ uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t Offset) {
// Find the matching entry in our vector.
uint64_t SymbolOffset = 0;
for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
- if (GOTEntries[i].SymbolName == 0) {
+ if (!GOTEntries[i].SymbolName) {
if (getSectionLoadAddress(GOTEntries[i].SectionID) == LoadAddress &&
GOTEntries[i].Offset == Offset) {
GOTIndex = i;
@@ -1369,7 +1397,8 @@ uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t Offset) {
return 0;
}
-void RuntimeDyldELF::finalizeLoad(ObjSectionToIDMap &SectionMap) {
+void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg,
+ ObjSectionToIDMap &SectionMap) {
// If necessary, allocate the global offset table
if (MemMgr) {
// Allocate the GOT if necessary
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
index 27db5cd..a526073 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
@@ -59,7 +59,8 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
uint64_t Value, uint32_t Type, int64_t Addend);
unsigned getMaxStubSize() override {
- if (Arch == Triple::aarch64)
+ if (Arch == Triple::aarch64 || Arch == Triple::arm64 ||
+ Arch == Triple::aarch64_be || Arch == Triple::arm64_be)
return 20; // movz; movk; movk; movk; br
if (Arch == Triple::arm || Arch == Triple::thumb)
return 8; // 32-bit instruction and 32-bit address
@@ -115,11 +116,12 @@ public:
bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
void registerEHFrames() override;
void deregisterEHFrames() override;
- void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
+ void finalizeLoad(ObjectImage &ObjImg,
+ ObjSectionToIDMap &SectionMap) override;
virtual ~RuntimeDyldELF();
static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
- static ObjectImage *createObjectImageFromFile(object::ObjectFile *Obj);
+ static ObjectImage *createObjectImageFromFile(std::unique_ptr<object::ObjectFile> Obj);
};
} // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index c153ee1..412cf20 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -90,9 +90,17 @@ public:
/// used to make a relocation section relative instead of symbol relative.
int64_t Addend;
+ struct SectionPair {
+ uint32_t SectionA;
+ uint32_t SectionB;
+ };
+
/// SymOffset - Section offset of the relocation entry's symbol (used for GOT
/// lookup).
- uint64_t SymOffset;
+ union {
+ uint64_t SymOffset;
+ SectionPair Sections;
+ };
/// True if this is a PCRel relocation (MachO specific).
bool IsPCRel;
@@ -113,6 +121,16 @@ public:
bool IsPCRel, unsigned Size)
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}
+
+ RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
+ unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB,
+ uint64_t SectionBOffset, bool IsPCRel, unsigned Size)
+ : SectionID(id), Offset(offset), RelType(type),
+ Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel),
+ Size(Size) {
+ Sections.SectionA = SectionA;
+ Sections.SectionB = SectionB;
+ }
};
class RelocationValueRef {
@@ -121,7 +139,8 @@ public:
uint64_t Offset;
int64_t Addend;
const char *SymbolName;
- RelocationValueRef() : SectionID(0), Offset(0), Addend(0), SymbolName(0) {}
+ RelocationValueRef() : SectionID(0), Offset(0), Addend(0),
+ SymbolName(nullptr) {}
inline bool operator==(const RelocationValueRef &Other) const {
return SectionID == Other.SectionID && Offset == Other.Offset &&
@@ -335,7 +354,7 @@ public:
// Work in progress.
SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name);
if (pos == GlobalSymbolTable.end())
- return 0;
+ return nullptr;
SymbolLoc Loc = pos->second;
return getSectionAddress(Loc.first) + Loc.second;
}
@@ -372,7 +391,7 @@ public:
virtual void deregisterEHFrames();
- virtual void finalizeLoad(ObjSectionToIDMap &SectionMap) {}
+ virtual void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) {}
};
} // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 7eae9c2..2b425fb 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -11,17 +11,20 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dyld"
#include "RuntimeDyldMachO.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
using namespace llvm;
using namespace llvm::object;
+#define DEBUG_TYPE "dyld"
+
namespace llvm {
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
intptr_t DeltaForEH) {
+ DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
+ << ", Delta for EH: " << DeltaForEH << "\n");
uint32_t Length = *((uint32_t *)P);
P += 4;
unsigned char *Ret = P + Length;
@@ -66,7 +69,7 @@ void RuntimeDyldMachO::registerEHFrames() {
continue;
SectionEntry *Text = &Sections[SectionInfo.TextSID];
SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
- SectionEntry *ExceptTab = NULL;
+ SectionEntry *ExceptTab = nullptr;
if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
ExceptTab = &Sections[SectionInfo.ExceptTabSID];
@@ -87,7 +90,8 @@ void RuntimeDyldMachO::registerEHFrames() {
UnregisteredEHFrameSections.clear();
}
-void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
+void RuntimeDyldMachO::finalizeLoad(ObjectImage &ObjImg,
+ ObjSectionToIDMap &SectionMap) {
unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
@@ -102,6 +106,12 @@ void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
TextSID = i->second;
else if (Name == "__gcc_except_tab")
ExceptTabSID = i->second;
+ else if (Name == "__jump_table")
+ populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
+ Section, i->second);
+ else if (Name == "__pointers")
+ populatePointersSection(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
+ Section, i->second);
}
UnregisteredEHFrameSections.push_back(
EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID));
@@ -129,91 +139,87 @@ void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
// symbol in the target address space.
void RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
uint64_t Value) {
- const SectionEntry &Section = Sections[RE.SectionID];
- return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
- RE.IsPCRel, RE.Size);
-}
-
-void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
- uint64_t Offset, uint64_t Value,
- uint32_t Type, int64_t Addend,
- bool isPCRel, unsigned LogSize) {
- uint8_t *LocalAddress = Section.Address + Offset;
- uint64_t FinalAddress = Section.LoadAddress + Offset;
- unsigned MachoType = Type;
- unsigned Size = 1 << LogSize;
-
- DEBUG(dbgs() << "resolveRelocation LocalAddress: "
- << format("%p", LocalAddress)
- << " FinalAddress: " << format("%p", FinalAddress)
- << " Value: " << format("%p", Value) << " Addend: " << Addend
- << " isPCRel: " << isPCRel << " MachoType: " << MachoType
- << " Size: " << Size << "\n");
+ DEBUG (
+ const SectionEntry &Section = Sections[RE.SectionID];
+ uint8_t* LocalAddress = Section.Address + RE.Offset;
+ uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
+
+ dbgs() << "resolveRelocation Section: " << RE.SectionID
+ << " LocalAddress: " << format("%p", LocalAddress)
+ << " FinalAddress: " << format("%p", FinalAddress)
+ << " Value: " << format("%p", Value)
+ << " Addend: " << RE.Addend
+ << " isPCRel: " << RE.IsPCRel
+ << " MachoType: " << RE.RelType
+ << " Size: " << (1 << RE.Size) << "\n";
+ );
// This just dispatches to the proper target specific routine.
switch (Arch) {
default:
llvm_unreachable("Unsupported CPU type!");
case Triple::x86_64:
- resolveX86_64Relocation(LocalAddress, FinalAddress, (uintptr_t)Value,
- isPCRel, MachoType, Size, Addend);
+ resolveX86_64Relocation(RE, Value);
break;
case Triple::x86:
- resolveI386Relocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel,
- MachoType, Size, Addend);
+ resolveI386Relocation(RE, Value);
break;
case Triple::arm: // Fall through.
case Triple::thumb:
- resolveARMRelocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel,
- MachoType, Size, Addend);
+ resolveARMRelocation(RE, Value);
break;
+ case Triple::aarch64:
case Triple::arm64:
- resolveARM64Relocation(LocalAddress, FinalAddress, (uintptr_t)Value,
- isPCRel, MachoType, Size, Addend);
+ resolveAArch64Relocation(RE, Value);
break;
}
}
-bool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress,
- uint64_t FinalAddress,
- uint64_t Value, bool isPCRel,
- unsigned Type, unsigned Size,
- int64_t Addend) {
- if (isPCRel)
- Value -= FinalAddress + 4; // see resolveX86_64Relocation
+bool RuntimeDyldMachO::resolveI386Relocation(const RelocationEntry &RE,
+ uint64_t Value) {
+ const SectionEntry &Section = Sections[RE.SectionID];
+ uint8_t* LocalAddress = Section.Address + RE.Offset;
- switch (Type) {
- default:
- llvm_unreachable("Invalid relocation type!");
- case MachO::GENERIC_RELOC_VANILLA: {
- uint8_t *p = LocalAddress;
- uint64_t ValueToWrite = Value + Addend;
- for (unsigned i = 0; i < Size; ++i) {
- *p++ = (uint8_t)(ValueToWrite & 0xff);
- ValueToWrite >>= 8;
- }
- return false;
+ if (RE.IsPCRel) {
+ uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
+ Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.
}
- case MachO::GENERIC_RELOC_SECTDIFF:
- case MachO::GENERIC_RELOC_LOCAL_SECTDIFF:
- case MachO::GENERIC_RELOC_PB_LA_PTR:
- return Error("Relocation type not implemented yet!");
+
+ switch (RE.RelType) {
+ default:
+ llvm_unreachable("Invalid relocation type!");
+ case MachO::GENERIC_RELOC_VANILLA:
+ return applyRelocationValue(LocalAddress, Value + RE.Addend,
+ 1 << RE.Size);
+ case MachO::GENERIC_RELOC_SECTDIFF:
+ case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
+ uint64_t SectionABase = Sections[RE.Sections.SectionA].LoadAddress;
+ uint64_t SectionBBase = Sections[RE.Sections.SectionB].LoadAddress;
+ assert((Value == SectionABase || Value == SectionBBase) &&
+ "Unexpected SECTDIFF relocation value.");
+ Value = SectionABase - SectionBBase + RE.Addend;
+ return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
+ }
+ case MachO::GENERIC_RELOC_PB_LA_PTR:
+ return Error("Relocation type not implemented yet!");
}
}
-bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
- uint64_t FinalAddress,
- uint64_t Value, bool isPCRel,
- unsigned Type, unsigned Size,
- int64_t Addend) {
+bool RuntimeDyldMachO::resolveX86_64Relocation(const RelocationEntry &RE,
+ uint64_t Value) {
+ const SectionEntry &Section = Sections[RE.SectionID];
+ uint8_t* LocalAddress = Section.Address + RE.Offset;
+
// If the relocation is PC-relative, the value to be encoded is the
// pointer difference.
- if (isPCRel)
+ if (RE.IsPCRel) {
// FIXME: It seems this value needs to be adjusted by 4 for an effective PC
// address. Is that expected? Only for branches, perhaps?
- Value -= FinalAddress + 4;
+ uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
+ Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.
+ }
- switch (Type) {
+ switch (RE.RelType) {
default:
llvm_unreachable("Invalid relocation type!");
case MachO::X86_64_RELOC_SIGNED_1:
@@ -221,17 +227,8 @@ bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
case MachO::X86_64_RELOC_SIGNED_4:
case MachO::X86_64_RELOC_SIGNED:
case MachO::X86_64_RELOC_UNSIGNED:
- case MachO::X86_64_RELOC_BRANCH: {
- Value += Addend;
- // Mask in the target value a byte at a time (we don't have an alignment
- // guarantee for the target address, so this is safest).
- uint8_t *p = (uint8_t *)LocalAddress;
- for (unsigned i = 0; i < Size; ++i) {
- *p++ = (uint8_t)Value;
- Value >>= 8;
- }
- return false;
- }
+ case MachO::X86_64_RELOC_BRANCH:
+ return applyRelocationValue(LocalAddress, Value + RE.Addend, 1 << RE.Size);
case MachO::X86_64_RELOC_GOT_LOAD:
case MachO::X86_64_RELOC_GOT:
case MachO::X86_64_RELOC_SUBTRACTOR:
@@ -240,14 +237,15 @@ bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
}
}
-bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
- uint64_t FinalAddress,
- uint64_t Value, bool isPCRel,
- unsigned Type, unsigned Size,
- int64_t Addend) {
+bool RuntimeDyldMachO::resolveARMRelocation(const RelocationEntry &RE,
+ uint64_t Value) {
+ const SectionEntry &Section = Sections[RE.SectionID];
+ uint8_t* LocalAddress = Section.Address + RE.Offset;
+
// If the relocation is PC-relative, the value to be encoded is the
// pointer difference.
- if (isPCRel) {
+ if (RE.IsPCRel) {
+ uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
Value -= FinalAddress;
// ARM PCRel relocations have an effective-PC offset of two instructions
// (four bytes in Thumb mode, 8 bytes in ARM mode).
@@ -255,19 +253,11 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
Value -= 8;
}
- switch (Type) {
+ switch (RE.RelType) {
default:
llvm_unreachable("Invalid relocation type!");
- case MachO::ARM_RELOC_VANILLA: {
- // Mask in the target value a byte at a time (we don't have an alignment
- // guarantee for the target address, so this is safest).
- uint8_t *p = (uint8_t *)LocalAddress;
- for (unsigned i = 0; i < Size; ++i) {
- *p++ = (uint8_t)Value;
- Value >>= 8;
- }
- break;
- }
+ case MachO::ARM_RELOC_VANILLA:
+ return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
case MachO::ARM_RELOC_BR24: {
// Mask the value into the target address. We know instructions are
// 32-bit aligned, so we can do it all at once.
@@ -275,13 +265,16 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
// The low two bits of the value are not encoded.
Value >>= 2;
// Mask the value to 24 bits.
- Value &= 0xffffff;
+ uint64_t FinalValue = Value & 0xffffff;
+ // Check for overflow.
+ if (Value != FinalValue)
+ return Error("ARM BR24 relocation out of range.");
// FIXME: If the destination is a Thumb function (and the instruction
// is a non-predicated BL instruction), we need to change it to a BLX
// instruction instead.
// Insert the value into the instruction.
- *p = (*p & ~0xffffff) | Value;
+ *p = (*p & ~0xffffff) | FinalValue;
break;
}
case MachO::ARM_THUMB_RELOC_BR22:
@@ -297,29 +290,23 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
return false;
}
-bool RuntimeDyldMachO::resolveARM64Relocation(uint8_t *LocalAddress,
- uint64_t FinalAddress,
- uint64_t Value, bool isPCRel,
- unsigned Type, unsigned Size,
- int64_t Addend) {
+bool RuntimeDyldMachO::resolveAArch64Relocation(const RelocationEntry &RE,
+ uint64_t Value) {
+ const SectionEntry &Section = Sections[RE.SectionID];
+ uint8_t* LocalAddress = Section.Address + RE.Offset;
+
// If the relocation is PC-relative, the value to be encoded is the
// pointer difference.
- if (isPCRel)
+ if (RE.IsPCRel) {
+ uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
Value -= FinalAddress;
+ }
- switch (Type) {
+ switch (RE.RelType) {
default:
llvm_unreachable("Invalid relocation type!");
- case MachO::ARM64_RELOC_UNSIGNED: {
- // Mask in the target value a byte at a time (we don't have an alignment
- // guarantee for the target address, so this is safest).
- uint8_t *p = (uint8_t *)LocalAddress;
- for (unsigned i = 0; i < Size; ++i) {
- *p++ = (uint8_t)Value;
- Value >>= 8;
- }
- break;
- }
+ case MachO::ARM64_RELOC_UNSIGNED:
+ return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
case MachO::ARM64_RELOC_BRANCH26: {
// Mask the value into the target address. We know instructions are
// 32-bit aligned, so we can do it all at once.
@@ -327,9 +314,12 @@ bool RuntimeDyldMachO::resolveARM64Relocation(uint8_t *LocalAddress,
// The low two bits of the value are not encoded.
Value >>= 2;
// Mask the value to 26 bits.
- Value &= 0x3ffffff;
+ uint64_t FinalValue = Value & 0x3ffffff;
+ // Check for overflow.
+ if (FinalValue != Value)
+ return Error("ARM64 BRANCH26 relocation out of range.");
// Insert the value into the instruction.
- *p = (*p & ~0x3ffffff) | Value;
+ *p = (*p & ~0x3ffffff) | FinalValue;
break;
}
case MachO::ARM64_RELOC_SUBTRACTOR:
@@ -346,6 +336,198 @@ bool RuntimeDyldMachO::resolveARM64Relocation(uint8_t *LocalAddress,
return false;
}
+void RuntimeDyldMachO::populateJumpTable(MachOObjectFile &Obj,
+ const SectionRef &JTSection,
+ unsigned JTSectionID) {
+ assert(!Obj.is64Bit() &&
+ "__jump_table section not supported in 64-bit MachO.");
+
+ MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
+ MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl());
+ uint32_t JTSectionSize = Sec32.size;
+ unsigned FirstIndirectSymbol = Sec32.reserved1;
+ unsigned JTEntrySize = Sec32.reserved2;
+ unsigned NumJTEntries = JTSectionSize / JTEntrySize;
+ uint8_t* JTSectionAddr = getSectionAddress(JTSectionID);
+ unsigned JTEntryOffset = 0;
+
+ assert((JTSectionSize % JTEntrySize) == 0 &&
+ "Jump-table section does not contain a whole number of stubs?");
+
+ for (unsigned i = 0; i < NumJTEntries; ++i) {
+ unsigned SymbolIndex =
+ Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
+ symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
+ StringRef IndirectSymbolName;
+ SI->getName(IndirectSymbolName);
+ uint8_t* JTEntryAddr = JTSectionAddr + JTEntryOffset;
+ createStubFunction(JTEntryAddr);
+ RelocationEntry RE(JTSectionID, JTEntryOffset + 1,
+ MachO::GENERIC_RELOC_VANILLA, 0, true, 2);
+ addRelocationForSymbol(RE, IndirectSymbolName);
+ JTEntryOffset += JTEntrySize;
+ }
+}
+
+void RuntimeDyldMachO::populatePointersSection(MachOObjectFile &Obj,
+ const SectionRef &PTSection,
+ unsigned PTSectionID) {
+ assert(!Obj.is64Bit() &&
+ "__pointers section not supported in 64-bit MachO.");
+
+ MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
+ MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl());
+ uint32_t PTSectionSize = Sec32.size;
+ unsigned FirstIndirectSymbol = Sec32.reserved1;
+ const unsigned PTEntrySize = 4;
+ unsigned NumPTEntries = PTSectionSize / PTEntrySize;
+ unsigned PTEntryOffset = 0;
+
+ assert((PTSectionSize % PTEntrySize) == 0 &&
+ "Pointers section does not contain a whole number of stubs?");
+
+ DEBUG(dbgs() << "Populating __pointers, Section ID " << PTSectionID
+ << ", " << NumPTEntries << " entries, "
+ << PTEntrySize << " bytes each:\n");
+
+ for (unsigned i = 0; i < NumPTEntries; ++i) {
+ unsigned SymbolIndex =
+ Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
+ symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
+ StringRef IndirectSymbolName;
+ SI->getName(IndirectSymbolName);
+ DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex
+ << ", PT offset: " << PTEntryOffset << "\n");
+ RelocationEntry RE(PTSectionID, PTEntryOffset,
+ MachO::GENERIC_RELOC_VANILLA, 0, false, 2);
+ addRelocationForSymbol(RE, IndirectSymbolName);
+ PTEntryOffset += PTEntrySize;
+ }
+}
+
+
+section_iterator getSectionByAddress(const MachOObjectFile &Obj,
+ uint64_t Addr) {
+ section_iterator SI = Obj.section_begin();
+ section_iterator SE = Obj.section_end();
+
+ for (; SI != SE; ++SI) {
+ uint64_t SAddr, SSize;
+ SI->getAddress(SAddr);
+ SI->getSize(SSize);
+ if ((Addr >= SAddr) && (Addr < SAddr + SSize))
+ return SI;
+ }
+
+ return SE;
+}
+
+relocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
+ unsigned SectionID,
+ relocation_iterator RelI,
+ ObjectImage &Obj,
+ ObjSectionToIDMap &ObjSectionToID) {
+ const MachOObjectFile *MachO =
+ static_cast<const MachOObjectFile*>(Obj.getObjectFile());
+ MachO::any_relocation_info RE =
+ MachO->getRelocation(RelI->getRawDataRefImpl());
+
+ SectionEntry &Section = Sections[SectionID];
+ uint32_t RelocType = MachO->getAnyRelocationType(RE);
+ bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
+ unsigned Size = MachO->getAnyRelocationLength(RE);
+ uint64_t Offset;
+ RelI->getOffset(Offset);
+ uint8_t *LocalAddress = Section.Address + Offset;
+ unsigned NumBytes = 1 << Size;
+ int64_t Addend = 0;
+ memcpy(&Addend, LocalAddress, NumBytes);
+
+ ++RelI;
+ MachO::any_relocation_info RE2 =
+ MachO->getRelocation(RelI->getRawDataRefImpl());
+
+ uint32_t AddrA = MachO->getScatteredRelocationValue(RE);
+ section_iterator SAI = getSectionByAddress(*MachO, AddrA);
+ assert(SAI != MachO->section_end() && "Can't find section for address A");
+ uint64_t SectionABase;
+ SAI->getAddress(SectionABase);
+ uint64_t SectionAOffset = AddrA - SectionABase;
+ SectionRef SectionA = *SAI;
+ bool IsCode;
+ SectionA.isText(IsCode);
+ uint32_t SectionAID = findOrEmitSection(Obj, SectionA, IsCode,
+ ObjSectionToID);
+
+ uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
+ section_iterator SBI = getSectionByAddress(*MachO, AddrB);
+ assert(SBI != MachO->section_end() && "Can't find section for address B");
+ uint64_t SectionBBase;
+ SBI->getAddress(SectionBBase);
+ uint64_t SectionBOffset = AddrB - SectionBBase;
+ SectionRef SectionB = *SBI;
+ uint32_t SectionBID = findOrEmitSection(Obj, SectionB, IsCode,
+ ObjSectionToID);
+
+ if (Addend != AddrA - AddrB)
+ Error("Unexpected SECTDIFF relocation addend.");
+
+ DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA << ", AddrB: " << AddrB
+ << ", Addend: " << Addend << ", SectionA ID: "
+ << SectionAID << ", SectionAOffset: " << SectionAOffset
+ << ", SectionB ID: " << SectionBID << ", SectionBOffset: "
+ << SectionBOffset << "\n");
+ RelocationEntry R(SectionID, Offset, RelocType, 0,
+ SectionAID, SectionAOffset, SectionBID, SectionBOffset,
+ IsPCRel, Size);
+
+ addRelocationForSection(R, SectionAID);
+ addRelocationForSection(R, SectionBID);
+
+ return ++RelI;
+}
+
+relocation_iterator RuntimeDyldMachO::processI386ScatteredVANILLA(
+ unsigned SectionID,
+ relocation_iterator RelI,
+ ObjectImage &Obj,
+ ObjSectionToIDMap &ObjSectionToID) {
+ const MachOObjectFile *MachO =
+ static_cast<const MachOObjectFile*>(Obj.getObjectFile());
+ MachO::any_relocation_info RE =
+ MachO->getRelocation(RelI->getRawDataRefImpl());
+
+ SectionEntry &Section = Sections[SectionID];
+ uint32_t RelocType = MachO->getAnyRelocationType(RE);
+ bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
+ unsigned Size = MachO->getAnyRelocationLength(RE);
+ uint64_t Offset;
+ RelI->getOffset(Offset);
+ uint8_t *LocalAddress = Section.Address + Offset;
+ unsigned NumBytes = 1 << Size;
+ int64_t Addend = 0;
+ memcpy(&Addend, LocalAddress, NumBytes);
+
+ unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE);
+ section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr);
+ assert(TargetSI != MachO->section_end() && "Can't find section for symbol");
+ uint64_t SectionBaseAddr;
+ TargetSI->getAddress(SectionBaseAddr);
+ SectionRef TargetSection = *TargetSI;
+ bool IsCode;
+ TargetSection.isText(IsCode);
+ uint32_t TargetSectionID = findOrEmitSection(Obj, TargetSection, IsCode,
+ ObjSectionToID);
+
+ Addend -= SectionBaseAddr;
+ RelocationEntry R(SectionID, Offset, RelocType, Addend,
+ IsPCRel, Size);
+
+ addRelocationForSection(R, TargetSectionID);
+
+ return ++RelI;
+}
+
relocation_iterator RuntimeDyldMachO::processRelocationRef(
unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
@@ -358,18 +540,28 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
uint32_t RelType = MachO->getAnyRelocationType(RE);
// FIXME: Properly handle scattered relocations.
- // For now, optimistically skip these: they can often be ignored, as
- // the static linker will already have applied the relocation, and it
- // only needs to be reapplied if symbols move relative to one another.
- // Note: This will fail horribly where the relocations *do* need to be
- // applied, but that was already the case.
- if (MachO->isRelocationScattered(RE))
- return ++RelI;
+ // Special case the couple of scattered relocations that we know how
+ // to handle: SECTDIFF relocations, and scattered VANILLA relocations
+ // on I386.
+ // For all other scattered relocations, just bail out and hope for the
+ // best, since the offsets computed by scattered relocations have often
+ // been optimisticaly filled in by the compiler. This will fail
+ // horribly where the relocations *do* need to be applied, but that was
+ // already the case.
+ if (MachO->isRelocationScattered(RE)) {
+ if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
+ RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
+ return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID);
+ else if (Arch == Triple::x86 && RelType == MachO::GENERIC_RELOC_VANILLA)
+ return processI386ScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID);
+ else
+ return ++RelI;
+ }
RelocationValueRef Value;
SectionEntry &Section = Sections[SectionID];
- bool isExtern = MachO->getPlainRelocationExternal(RE);
+ bool IsExtern = MachO->getPlainRelocationExternal(RE);
bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
unsigned Size = MachO->getAnyRelocationLength(RE);
uint64_t Offset;
@@ -379,7 +571,7 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
uint64_t Addend = 0;
memcpy(&Addend, LocalAddress, NumBytes);
- if (isExtern) {
+ if (IsExtern) {
// Obtain the symbol name which is referenced in the relocation
symbol_iterator Symbol = RelI->getSymbol();
StringRef TargetName;
@@ -401,6 +593,17 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
Value.Addend = Addend;
}
}
+
+ // Addends for external, PC-rel relocations on i386 point back to the zero
+ // offset. Calculate the final offset from the relocation target instead.
+ // This allows us to use the same logic for both external and internal
+ // relocations in resolveI386RelocationRef.
+ if (Arch == Triple::x86 && IsPCRel) {
+ uint64_t RelocAddr = 0;
+ RelI->getAddress(RelocAddr);
+ Value.Addend += RelocAddr + 4;
+ }
+
} else {
SectionRef Sec = MachO->getRelocationSection(RE);
bool IsCode = false;
@@ -417,6 +620,10 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
RelType == MachO::X86_64_RELOC_GOT_LOAD)) {
assert(IsPCRel);
assert(Size == 2);
+
+ // FIXME: Teach the generic code above not to prematurely conflate
+ // relocation addends and symbol offsets.
+ Value.Addend -= Addend;
StubMap::const_iterator i = Stubs.find(Value);
uint8_t *Addr;
if (i != Stubs.end()) {
@@ -424,41 +631,45 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
} else {
Stubs[Value] = Section.StubOffset;
uint8_t *GOTEntry = Section.Address + Section.StubOffset;
- RelocationEntry RE(SectionID, Section.StubOffset,
- MachO::X86_64_RELOC_UNSIGNED, 0, false, 3);
+ RelocationEntry GOTRE(SectionID, Section.StubOffset,
+ MachO::X86_64_RELOC_UNSIGNED, Value.Addend, false,
+ 3);
if (Value.SymbolName)
- addRelocationForSymbol(RE, Value.SymbolName);
+ addRelocationForSymbol(GOTRE, Value.SymbolName);
else
- addRelocationForSection(RE, Value.SectionID);
+ addRelocationForSection(GOTRE, Value.SectionID);
Section.StubOffset += 8;
Addr = GOTEntry;
}
- resolveRelocation(Section, Offset, (uint64_t)Addr,
- MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true, 2);
+ RelocationEntry TargetRE(SectionID, Offset,
+ MachO::X86_64_RELOC_UNSIGNED, Addend, true,
+ 2);
+ resolveRelocation(TargetRE, (uint64_t)Addr);
} else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) {
// This is an ARM branch relocation, need to use a stub function.
// Look up for existing stub.
StubMap::const_iterator i = Stubs.find(Value);
- if (i != Stubs.end())
- resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second,
- RelType, 0, IsPCRel, Size);
- else {
+ uint8_t *Addr;
+ if (i != Stubs.end()) {
+ Addr = Section.Address + i->second;
+ } else {
// Create a new stub function.
Stubs[Value] = Section.StubOffset;
uint8_t *StubTargetAddr =
createStubFunction(Section.Address + Section.StubOffset);
- RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
- MachO::GENERIC_RELOC_VANILLA, Value.Addend);
+ RelocationEntry StubRE(SectionID, StubTargetAddr - Section.Address,
+ MachO::GENERIC_RELOC_VANILLA, Value.Addend);
if (Value.SymbolName)
- addRelocationForSymbol(RE, Value.SymbolName);
+ addRelocationForSymbol(StubRE, Value.SymbolName);
else
- addRelocationForSection(RE, Value.SectionID);
- resolveRelocation(Section, Offset,
- (uint64_t)Section.Address + Section.StubOffset, RelType,
- 0, IsPCRel, Size);
+ addRelocationForSection(StubRE, Value.SectionID);
+ Addr = Section.Address + Section.StubOffset;
Section.StubOffset += getMaxStubSize();
}
+ RelocationEntry TargetRE(Value.SectionID, Offset, RelType, 0, IsPCRel,
+ Size);
+ resolveRelocation(TargetRE, (uint64_t)Addr);
} else {
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, IsPCRel, Size);
if (Value.SymbolName)
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
index 1006176..060eb8c 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
@@ -25,22 +25,31 @@ using namespace llvm::object;
namespace llvm {
class RuntimeDyldMachO : public RuntimeDyldImpl {
- bool resolveI386Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
- uint64_t Value, bool isPCRel, unsigned Type,
- unsigned Size, int64_t Addend);
- bool resolveX86_64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
- uint64_t Value, bool isPCRel, unsigned Type,
- unsigned Size, int64_t Addend);
- bool resolveARMRelocation(uint8_t *LocalAddress, uint64_t FinalAddress,
- uint64_t Value, bool isPCRel, unsigned Type,
- unsigned Size, int64_t Addend);
- bool resolveARM64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
- uint64_t Value, bool IsPCRel, unsigned Type,
- unsigned Size, int64_t Addend);
-
- void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
- uint64_t Value, uint32_t Type, int64_t Addend,
- bool isPCRel, unsigned Size);
+private:
+
+ /// Write the least significant 'Size' bytes in 'Value' out at the address
+ /// pointed to by Addr.
+ bool applyRelocationValue(uint8_t *Addr, uint64_t Value, unsigned Size) {
+ for (unsigned i = 0; i < Size; ++i) {
+ *Addr++ = (uint8_t)Value;
+ Value >>= 8;
+ }
+
+ return false;
+ }
+
+ bool resolveI386Relocation(const RelocationEntry &RE, uint64_t Value);
+ bool resolveX86_64Relocation(const RelocationEntry &RE, uint64_t Value);
+ bool resolveARMRelocation(const RelocationEntry &RE, uint64_t Value);
+ bool resolveAArch64Relocation(const RelocationEntry &RE, uint64_t Value);
+
+ // Populate stubs in __jump_table section.
+ void populateJumpTable(MachOObjectFile &Obj, const SectionRef &JTSection,
+ unsigned JTSectionID);
+
+ // Populate __pointers section.
+ void populatePointersSection(MachOObjectFile &Obj, const SectionRef &PTSection,
+ unsigned PTSectionID);
unsigned getMaxStubSize() override {
if (Arch == Triple::arm || Arch == Triple::thumb)
@@ -53,6 +62,18 @@ class RuntimeDyldMachO : public RuntimeDyldImpl {
unsigned getStubAlignment() override { return 1; }
+ relocation_iterator processSECTDIFFRelocation(
+ unsigned SectionID,
+ relocation_iterator RelI,
+ ObjectImage &ObjImg,
+ ObjSectionToIDMap &ObjSectionToID);
+
+ relocation_iterator processI386ScatteredVANILLA(
+ unsigned SectionID,
+ relocation_iterator RelI,
+ ObjectImage &ObjImg,
+ ObjSectionToIDMap &ObjSectionToID);
+
struct EHFrameRelatedSections {
EHFrameRelatedSections()
: EHFrameSID(RTDYLD_INVALID_SECTION_ID),
@@ -81,15 +102,16 @@ public:
bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
bool isCompatibleFile(const object::ObjectFile *Obj) const override;
void registerEHFrames() override;
- void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
+ void finalizeLoad(ObjectImage &ObjImg,
+ ObjSectionToIDMap &SectionMap) override;
static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) {
return new ObjectImageCommon(InputBuffer);
}
static ObjectImage *
- createObjectImageFromFile(object::ObjectFile *InputObject) {
- return new ObjectImageCommon(InputObject);
+ createObjectImageFromFile(std::unique_ptr<object::ObjectFile> InputObject) {
+ return new ObjectImageCommon(std::move(InputObject));
}
};
diff --git a/lib/ExecutionEngine/TargetSelect.cpp b/lib/ExecutionEngine/TargetSelect.cpp
index 9b7d348..b10d51f 100644
--- a/lib/ExecutionEngine/TargetSelect.cpp
+++ b/lib/ExecutionEngine/TargetSelect.cpp
@@ -47,7 +47,7 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
TheTriple.setTriple(sys::getProcessTriple());
// Adjust the triple to match what the user requested.
- const Target *TheTarget = 0;
+ const Target *TheTarget = nullptr;
if (!MArch.empty()) {
for (TargetRegistry::iterator it = TargetRegistry::begin(),
ie = TargetRegistry::end(); it != ie; ++it) {
@@ -61,7 +61,7 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
if (ErrorStr)
*ErrorStr = "No available targets are compatible with this -march, "
"see -version for the available targets.\n";
- return 0;
+ return nullptr;
}
// Adjust the triple to match (if known), otherwise stick with the
@@ -72,10 +72,10 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
} else {
std::string Error;
TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
- if (TheTarget == 0) {
+ if (!TheTarget) {
if (ErrorStr)
*ErrorStr = Error;
- return 0;
+ return nullptr;
}
}