diff options
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine')
27 files changed, 856 insertions, 276 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h b/contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h index 911d1d6..314db8b 100644 --- a/contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h +++ b/contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h @@ -14,11 +14,11 @@ #ifndef EVENT_LISTENER_COMMON_H #define EVENT_LISTENER_COMMON_H -#include "llvm/DebugInfo.h" -#include "llvm/Metadata.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/Support/ValueHandle.h" +#include "llvm/DebugInfo.h" +#include "llvm/IR/Metadata.h" #include "llvm/Support/Path.h" +#include "llvm/Support/ValueHandle.h" namespace llvm { diff --git a/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index 05987f2..906a3a3 100644 --- a/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -14,22 +14,22 @@ #define DEBUG_TYPE "jit" #include "llvm/ExecutionEngine/ExecutionEngine.h" - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Host.h" #include "llvm/Support/MutexGuard.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/DynamicLibrary.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/DataLayout.h" #include "llvm/Target/TargetMachine.h" #include <cmath> #include <cstring> @@ -535,6 +535,8 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { if (isa<UndefValue>(C)) { GenericValue Result; switch (C->getType()->getTypeID()) { + default: + break; case Type::IntegerTyID: case Type::X86_FP80TyID: case Type::FP128TyID: @@ -543,7 +545,16 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { // with the correct bit width. Result.IntVal = APInt(C->getType()->getPrimitiveSizeInBits(), 0); break; - default: + case Type::VectorTyID: + // if the whole vector is 'undef' just reserve memory for the value. + const VectorType* VTy = dyn_cast<VectorType>(C->getType()); + const Type *ElemTy = VTy->getElementType(); + unsigned int elemNum = VTy->getNumElements(); + Result.AggregateVal.resize(elemNum); + if (ElemTy->isIntegerTy()) + for (unsigned int i = 0; i < elemNum; ++i) + Result.AggregateVal[i].IntVal = + APInt(ElemTy->getPrimitiveSizeInBits(), 0); break; } return Result; @@ -556,11 +567,11 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { case Instruction::GetElementPtr: { // Compute the index GenericValue Result = getConstantValue(Op0); - SmallVector<Value*, 8> Indices(CE->op_begin()+1, CE->op_end()); - uint64_t Offset = TD->getIndexedOffset(Op0->getType(), Indices); + APInt Offset(TD->getPointerSizeInBits(), 0); + cast<GEPOperator>(CE)->accumulateConstantOffset(*TD, Offset); char* tmp = (char*) Result.PointerVal; - Result = PTOGV(tmp + Offset); + Result = PTOGV(tmp + Offset.getSExtValue()); return Result; } case Instruction::Trunc: { @@ -632,7 +643,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { else if (Op0->getType()->isDoubleTy()) GV.IntVal = APIntOps::RoundDoubleToAPInt(GV.DoubleVal, BitWidth); else if (Op0->getType()->isX86_FP80Ty()) { - APFloat apf = APFloat(GV.IntVal); + APFloat apf = APFloat(APFloat::x87DoubleExtended, GV.IntVal); uint64_t v; bool ignored; (void)apf.convertToInteger(&v, BitWidth, @@ -751,27 +762,32 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { case Type::X86_FP80TyID: case Type::PPC_FP128TyID: case Type::FP128TyID: { - APFloat apfLHS = APFloat(LHS.IntVal); + const fltSemantics &Sem = CE->getOperand(0)->getType()->getFltSemantics(); + APFloat apfLHS = APFloat(Sem, LHS.IntVal); switch (CE->getOpcode()) { default: llvm_unreachable("Invalid long double opcode"); case Instruction::FAdd: - apfLHS.add(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); + apfLHS.add(APFloat(Sem, RHS.IntVal), APFloat::rmNearestTiesToEven); GV.IntVal = apfLHS.bitcastToAPInt(); break; case Instruction::FSub: - apfLHS.subtract(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); + apfLHS.subtract(APFloat(Sem, RHS.IntVal), + APFloat::rmNearestTiesToEven); GV.IntVal = apfLHS.bitcastToAPInt(); break; case Instruction::FMul: - apfLHS.multiply(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); + apfLHS.multiply(APFloat(Sem, RHS.IntVal), + APFloat::rmNearestTiesToEven); GV.IntVal = apfLHS.bitcastToAPInt(); break; case Instruction::FDiv: - apfLHS.divide(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); + apfLHS.divide(APFloat(Sem, RHS.IntVal), + APFloat::rmNearestTiesToEven); GV.IntVal = apfLHS.bitcastToAPInt(); break; case Instruction::FRem: - apfLHS.mod(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); + apfLHS.mod(APFloat(Sem, RHS.IntVal), + APFloat::rmNearestTiesToEven); GV.IntVal = apfLHS.bitcastToAPInt(); break; } @@ -820,6 +836,101 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { else llvm_unreachable("Unknown constant pointer type!"); break; + case Type::VectorTyID: { + unsigned elemNum; + Type* ElemTy; + const ConstantDataVector *CDV = dyn_cast<ConstantDataVector>(C); + const ConstantVector *CV = dyn_cast<ConstantVector>(C); + const ConstantAggregateZero *CAZ = dyn_cast<ConstantAggregateZero>(C); + + if (CDV) { + elemNum = CDV->getNumElements(); + ElemTy = CDV->getElementType(); + } else if (CV || CAZ) { + VectorType* VTy = dyn_cast<VectorType>(C->getType()); + elemNum = VTy->getNumElements(); + ElemTy = VTy->getElementType(); + } else { + llvm_unreachable("Unknown constant vector type!"); + } + + Result.AggregateVal.resize(elemNum); + // Check if vector holds floats. + if(ElemTy->isFloatTy()) { + if (CAZ) { + GenericValue floatZero; + floatZero.FloatVal = 0.f; + std::fill(Result.AggregateVal.begin(), Result.AggregateVal.end(), + floatZero); + break; + } + if(CV) { + for (unsigned i = 0; i < elemNum; ++i) + if (!isa<UndefValue>(CV->getOperand(i))) + Result.AggregateVal[i].FloatVal = cast<ConstantFP>( + CV->getOperand(i))->getValueAPF().convertToFloat(); + break; + } + if(CDV) + for (unsigned i = 0; i < elemNum; ++i) + Result.AggregateVal[i].FloatVal = CDV->getElementAsFloat(i); + + break; + } + // Check if vector holds doubles. + if (ElemTy->isDoubleTy()) { + if (CAZ) { + GenericValue doubleZero; + doubleZero.DoubleVal = 0.0; + std::fill(Result.AggregateVal.begin(), Result.AggregateVal.end(), + doubleZero); + break; + } + if(CV) { + for (unsigned i = 0; i < elemNum; ++i) + if (!isa<UndefValue>(CV->getOperand(i))) + Result.AggregateVal[i].DoubleVal = cast<ConstantFP>( + CV->getOperand(i))->getValueAPF().convertToDouble(); + break; + } + if(CDV) + for (unsigned i = 0; i < elemNum; ++i) + Result.AggregateVal[i].DoubleVal = CDV->getElementAsDouble(i); + + break; + } + // Check if vector holds integers. + if (ElemTy->isIntegerTy()) { + if (CAZ) { + GenericValue intZero; + intZero.IntVal = APInt(ElemTy->getScalarSizeInBits(), 0ull); + std::fill(Result.AggregateVal.begin(), Result.AggregateVal.end(), + intZero); + break; + } + if(CV) { + for (unsigned i = 0; i < elemNum; ++i) + if (!isa<UndefValue>(CV->getOperand(i))) + Result.AggregateVal[i].IntVal = cast<ConstantInt>( + CV->getOperand(i))->getValue(); + else { + Result.AggregateVal[i].IntVal = + APInt(CV->getOperand(i)->getType()->getPrimitiveSizeInBits(), 0); + } + break; + } + if(CDV) + for (unsigned i = 0; i < elemNum; ++i) + Result.AggregateVal[i].IntVal = APInt( + CDV->getElementType()->getPrimitiveSizeInBits(), + CDV->getElementAsInteger(i)); + + break; + } + llvm_unreachable("Unknown constant pointer type!"); + } + break; + default: SmallString<256> Msg; raw_svector_ostream OS(Msg); @@ -861,6 +972,9 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val, const unsigned StoreBytes = getDataLayout()->getTypeStoreSize(Ty); switch (Ty->getTypeID()) { + default: + dbgs() << "Cannot store value of type " << *Ty << "!\n"; + break; case Type::IntegerTyID: StoreIntToMemory(Val.IntVal, (uint8_t*)Ptr, StoreBytes); break; @@ -880,8 +994,19 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val, *((PointerTy*)Ptr) = Val.PointerVal; break; - default: - dbgs() << "Cannot store value of type " << *Ty << "!\n"; + case Type::VectorTyID: + for (unsigned i = 0; i < Val.AggregateVal.size(); ++i) { + if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) + *(((double*)Ptr)+i) = Val.AggregateVal[i].DoubleVal; + if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) + *(((float*)Ptr)+i) = Val.AggregateVal[i].FloatVal; + if (cast<VectorType>(Ty)->getElementType()->isIntegerTy()) { + unsigned numOfBytes =(Val.AggregateVal[i].IntVal.getBitWidth()+7)/8; + StoreIntToMemory(Val.AggregateVal[i].IntVal, + (uint8_t*)Ptr + numOfBytes*i, numOfBytes); + } + } + break; } if (sys::isLittleEndianHost() != getDataLayout()->isLittleEndian()) @@ -893,7 +1018,8 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val, /// from Src into IntVal, which is assumed to be wide enough and to hold zero. static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) { assert((IntVal.getBitWidth()+7)/8 >= LoadBytes && "Integer too small!"); - uint8_t *Dst = (uint8_t *)IntVal.getRawData(); + uint8_t *Dst = reinterpret_cast<uint8_t *>( + const_cast<uint64_t *>(IntVal.getRawData())); if (sys::isLittleEndianHost()) // Little-endian host - the destination must be ordered from LSB to MSB. @@ -945,6 +1071,31 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result, Result.IntVal = APInt(80, y); break; } + case Type::VectorTyID: { + const VectorType *VT = cast<VectorType>(Ty); + const Type *ElemT = VT->getElementType(); + const unsigned numElems = VT->getNumElements(); + if (ElemT->isFloatTy()) { + Result.AggregateVal.resize(numElems); + for (unsigned i = 0; i < numElems; ++i) + Result.AggregateVal[i].FloatVal = *((float*)Ptr+i); + } + if (ElemT->isDoubleTy()) { + Result.AggregateVal.resize(numElems); + for (unsigned i = 0; i < numElems; ++i) + Result.AggregateVal[i].DoubleVal = *((double*)Ptr+i); + } + if (ElemT->isIntegerTy()) { + GenericValue intZero; + const unsigned elemBitWidth = cast<IntegerType>(ElemT)->getBitWidth(); + intZero.IntVal = APInt(elemBitWidth, 0); + Result.AggregateVal.resize(numElems, intZero); + for (unsigned i = 0; i < numElems; ++i) + LoadIntFromMemory(Result.AggregateVal[i].IntVal, + (uint8_t*)Ptr+((elemBitWidth+7)/8)*i, (elemBitWidth+7)/8); + } + break; + } default: SmallString<256> Msg; raw_svector_ostream OS(Msg); diff --git a/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp index 1e790e7..f4e8246 100644 --- a/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp +++ b/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp @@ -13,8 +13,8 @@ #define DEBUG_TYPE "jit" #include "llvm-c/ExecutionEngine.h" -#include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/Support/ErrorHandling.h" #include <cstring> diff --git a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index 4cb0270..7dc295f 100644 --- a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -17,11 +17,14 @@ #define DEBUG_TYPE "amplifier-jit-event-listener" #include "llvm/DebugInfo.h" -#include "llvm/Function.h" -#include "llvm/Metadata.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Metadata.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Errno.h" @@ -41,6 +44,11 @@ class IntelJITEventListener : public JITEventListener { MethodIDMap MethodIDs; FilenameCache Filenames; + typedef SmallVector<const void *, 64> MethodAddressVector; + typedef DenseMap<const void *, MethodAddressVector> ObjectMap; + + ObjectMap LoadedObjectMap; + public: IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) { Wrapper.reset(libraryWrapper); @@ -72,6 +80,17 @@ static LineNumberInfo LineStartToIntelJITFormat( return Result; } +static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress, + uintptr_t Address, + DILineInfo Line) { + LineNumberInfo Result; + + Result.Offset = Address - StartAddress; + Result.LineNumber = Line.getLine(); + + return Result; +} + static iJIT_Method_Load FunctionDescToIntelJITFormat( IntelJITEventsWrapper& Wrapper, const char* FnName, @@ -169,9 +188,101 @@ void IntelJITEventListener::NotifyFreeingMachineCode(void *FnStart) { } void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) { + // Get the address of the object image for use as a unique identifier + const void* ObjData = Obj.getData().data(); + DIContext* Context = DIContext::getDWARFContext(Obj.getObjectFile()); + 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)) { + std::vector<LineNumberInfo> LineInfo; + std::string SourceFileName; + + object::SymbolRef::Type SymType; + if (I->getType(SymType)) continue; + if (SymType == object::SymbolRef::ST_Function) { + StringRef Name; + uint64_t Addr; + uint64_t Size; + if (I->getName(Name)) continue; + if (I->getAddress(Addr)) continue; + if (I->getSize(Size)) continue; + + // Record this address in a local vector + Functions.push_back((void*)Addr); + + // Build the function loaded notification message + iJIT_Method_Load FunctionMessage = FunctionDescToIntelJITFormat(*Wrapper, + Name.data(), + Addr, + Size); + if (Context) { + DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); + DILineInfoTable::iterator Begin = Lines.begin(); + DILineInfoTable::iterator End = Lines.end(); + for (DILineInfoTable::iterator It = Begin; It != End; ++It) { + LineInfo.push_back(DILineInfoToIntelJITFormat((uintptr_t)Addr, + It->first, + It->second)); + } + if (LineInfo.size() == 0) { + FunctionMessage.source_file_name = 0; + FunctionMessage.line_number_size = 0; + FunctionMessage.line_number_table = 0; + } else { + SourceFileName = Lines.front().second.getFileName(); + FunctionMessage.source_file_name = (char *)SourceFileName.c_str(); + FunctionMessage.line_number_size = LineInfo.size(); + FunctionMessage.line_number_table = &*LineInfo.begin(); + } + } else { + FunctionMessage.source_file_name = 0; + FunctionMessage.line_number_size = 0; + FunctionMessage.line_number_table = 0; + } + + Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, + &FunctionMessage); + MethodIDs[(void*)Addr] = FunctionMessage.method_id; + } + } + + // To support object unload notification, we need to keep a list of + // registered function addresses for each loaded object. We will + // use the MethodIDs map to get the registered ID for each function. + LoadedObjectMap[ObjData] = Functions; } void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) { + // Get the address of the object image for use as a unique identifier + const void* ObjData = Obj.getData().data(); + + // Get the object's function list from LoadedObjectMap + ObjectMap::iterator OI = LoadedObjectMap.find(ObjData); + if (OI == LoadedObjectMap.end()) + return; + MethodAddressVector& Functions = OI->second; + + // Walk the function list, unregistering each function + for (MethodAddressVector::iterator FI = Functions.begin(), + FE = Functions.end(); + FI != FE; + ++FI) { + void* FnStart = const_cast<void*>(*FI); + MethodIDMap::iterator MI = MethodIDs.find(FnStart); + if (MI != MethodIDs.end()) { + Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_UNLOAD_START, + &MI->second); + MethodIDs.erase(MI); + } + } + + // Erase the object from LoadedObjectMap + LoadedObjectMap.erase(OI); } } // anonymous namespace. diff --git a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h index 7ab08e1..3d9ff535 100644 --- a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h +++ b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h @@ -35,8 +35,6 @@ class IntelJITEventsWrapper { NotifyEventPtr NotifyEventFunc; RegisterCallbackExPtr RegisterCallbackExFunc; IsProfilingActivePtr IsProfilingActiveFunc; - FinalizeThreadPtr FinalizeThreadFunc; - FinalizeProcessPtr FinalizeProcessFunc; GetNewMethodIDPtr GetNewMethodIDFunc; public: @@ -48,8 +46,6 @@ public: : NotifyEventFunc(::iJIT_NotifyEvent), RegisterCallbackExFunc(::iJIT_RegisterCallbackEx), IsProfilingActiveFunc(::iJIT_IsProfilingActive), - FinalizeThreadFunc(::FinalizeThread), - FinalizeProcessFunc(::FinalizeProcess), GetNewMethodIDFunc(::iJIT_GetNewMethodID) { } @@ -62,8 +58,6 @@ public: : NotifyEventFunc(NotifyEventImpl), RegisterCallbackExFunc(RegisterCallbackExImpl), IsProfilingActiveFunc(IsProfilingActiveImpl), - FinalizeThreadFunc(FinalizeThreadImpl), - FinalizeProcessFunc(FinalizeProcessImpl), GetNewMethodIDFunc(GetNewMethodIDImpl) { } diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp index 5202b09..526c04e 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -13,16 +13,16 @@ #define DEBUG_TYPE "interpreter" #include "Interpreter.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/CodeGen/IntrinsicLowering.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/IntrinsicLowering.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" #include <algorithm> #include <cmath> @@ -1169,10 +1169,12 @@ void Interpreter::visitVAArgInst(VAArgInst &I) { .VarArgs[VAList.UIntPairVal.second]; Type *Ty = I.getType(); switch (Ty->getTypeID()) { - case Type::IntegerTyID: Dest.IntVal = Src.IntVal; - IMPLEMENT_VAARG(Pointer); - IMPLEMENT_VAARG(Float); - IMPLEMENT_VAARG(Double); + case Type::IntegerTyID: + Dest.IntVal = Src.IntVal; + break; + IMPLEMENT_VAARG(Pointer); + IMPLEMENT_VAARG(Float); + IMPLEMENT_VAARG(Double); default: dbgs() << "Unhandled dest type for vaarg instruction: " << *Ty << "\n"; llvm_unreachable(0); @@ -1185,6 +1187,39 @@ void Interpreter::visitVAArgInst(VAArgInst &I) { ++VAList.UIntPairVal.second; } +void Interpreter::visitExtractElementInst(ExtractElementInst &I) { + ExecutionContext &SF = ECStack.back(); + GenericValue Src1 = getOperandValue(I.getOperand(0), SF); + GenericValue Src2 = getOperandValue(I.getOperand(1), SF); + GenericValue Dest; + + Type *Ty = I.getType(); + const unsigned indx = unsigned(Src2.IntVal.getZExtValue()); + + if(Src1.AggregateVal.size() > indx) { + switch (Ty->getTypeID()) { + default: + dbgs() << "Unhandled destination type for extractelement instruction: " + << *Ty << "\n"; + llvm_unreachable(0); + break; + case Type::IntegerTyID: + Dest.IntVal = Src1.AggregateVal[indx].IntVal; + break; + case Type::FloatTyID: + Dest.FloatVal = Src1.AggregateVal[indx].FloatVal; + break; + case Type::DoubleTyID: + Dest.DoubleVal = Src1.AggregateVal[indx].DoubleVal; + break; + } + } else { + dbgs() << "Invalid index in extractelement instruction\n"; + } + + SetValue(&I, Dest, SF); +} + GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, ExecutionContext &SF) { switch (CE->getOpcode()) { diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index e16e2d1..bef4bbf 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -20,19 +20,19 @@ //===----------------------------------------------------------------------===// #include "Interpreter.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" #include "llvm/Config/config.h" // Detect libffi -#include "llvm/Support/ErrorHandling.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Module.h" #include "llvm/Support/DynamicLibrary.h" -#include "llvm/DataLayout.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" +#include <cmath> #include <csignal> #include <cstdio> -#include <map> -#include <cmath> #include <cstring> +#include <map> #ifdef HAVE_FFI_CALL #ifdef HAVE_FFI_H diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp index 55152db..9ee9d94 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp @@ -15,8 +15,8 @@ #include "Interpreter.h" #include "llvm/CodeGen/IntrinsicLowering.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Module.h" #include <cstring> using namespace llvm; diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h index 72c42c1..2952d7e 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -14,14 +14,14 @@ #ifndef LLI_INTERPRETER_H #define LLI_INTERPRETER_H -#include "llvm/Function.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/DataLayout.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/InstVisitor.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/InstVisitor.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -178,6 +178,7 @@ public: void visitAShr(BinaryOperator &I); void visitVAArgInst(VAArgInst &I); + void visitExtractElementInst(ExtractElementInst &I); void visitInstruction(Instruction &I) { errs() << I << "\n"; llvm_unreachable("Instruction not interpretable yet!"); diff --git a/contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp index 1ad3382..53ea0a2 100644 --- a/contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp +++ b/contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp @@ -13,26 +13,26 @@ //===----------------------------------------------------------------------===// #include "JIT.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Instructions.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/JITCodeEmitter.h" #include "llvm/CodeGen/MachineCodeInfo.h" +#include "llvm/Config/config.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/DataLayout.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetJITInfo.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instructions.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MutexGuard.h" -#include "llvm/Support/DynamicLibrary.h" -#include "llvm/Config/config.h" +#include "llvm/Target/TargetJITInfo.h" +#include "llvm/Target/TargetMachine.h" using namespace llvm; @@ -522,7 +522,8 @@ GenericValue JIT::runFunction(Function *F, case Type::PPC_FP128TyID: case Type::X86_FP80TyID: case Type::FP128TyID: - C = ConstantFP::get(F->getContext(), APFloat(AV.IntVal)); + C = ConstantFP::get(F->getContext(), APFloat(ArgTy->getFltSemantics(), + AV.IntVal)); break; case Type::PointerTyID: void *ArgPtr = GVTOP(AV); diff --git a/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp index 19c1979..35d2b8b 100644 --- a/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp +++ b/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp @@ -12,21 +12,21 @@ // //===----------------------------------------------------------------------===// -#include "JIT.h" #include "JITDwarfEmitter.h" -#include "llvm/Function.h" +#include "JIT.h" #include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/JITCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/MC/MachineLocation.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/DataLayout.h" -#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetFrameLowering.h" +#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; diff --git a/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.h b/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.h index 9cdbeac..98ac340 100644 --- a/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.h +++ b/contrib/llvm/lib/ExecutionEngine/JIT/JITDwarfEmitter.h @@ -15,9 +15,13 @@ #ifndef LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H #define LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H +#include "llvm/Support/DataTypes.h" +#include <vector> + namespace llvm { class Function; +class JIT; class JITCodeEmitter; class MachineFunction; class MachineModuleInfo; diff --git a/contrib/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp b/contrib/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp index ecafda7..c273876 100644 --- a/contrib/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/contrib/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -15,39 +15,39 @@ #define DEBUG_TYPE "jit" #include "JIT.h" #include "JITDwarfEmitter.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/Constants.h" -#include "llvm/DebugInfo.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/ValueMap.h" #include "llvm/CodeGen/JITCodeEmitter.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRelocation.h" +#include "llvm/DebugInfo.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/DataLayout.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetJITInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Disassembler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Memory.h" #include "llvm/Support/MutexGuard.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Disassembler.h" -#include "llvm/Support/Memory.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/ValueMap.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetJITInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include <algorithm> #ifndef NDEBUG #include <iomanip> @@ -969,14 +969,24 @@ bool JITEmitter::finishFunction(MachineFunction &F) { SavedBufferBegin = BufferBegin; SavedBufferEnd = BufferEnd; SavedCurBufferPtr = CurBufferPtr; - - BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), - ActualSize); - BufferEnd = BufferBegin+ActualSize; - EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin; - uint8_t *EhStart; - uint8_t *FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, - EhStart); + uint8_t *FrameRegister; + + while (true) { + BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), + ActualSize); + BufferEnd = BufferBegin+ActualSize; + EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin; + uint8_t *EhStart; + FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, EhStart); + + // If the buffer was large enough to hold the table then we are done. + if (CurBufferPtr != BufferEnd) + break; + + // Try again with twice as much space. + ActualSize = (CurBufferPtr - BufferBegin) * 2; + MemMgr->deallocateExceptionTable(BufferBegin); + } MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, FrameRegister); BufferBegin = SavedBufferBegin; diff --git a/contrib/llvm/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/JIT/JITMemoryManager.cpp index 61bc119..66aeb77 100644 --- a/contrib/llvm/lib/ExecutionEngine/JIT/JITMemoryManager.cpp +++ b/contrib/llvm/lib/ExecutionEngine/JIT/JITMemoryManager.cpp @@ -16,20 +16,19 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/Twine.h" -#include "llvm/GlobalValue.h" +#include "llvm/Config/config.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Memory.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/DynamicLibrary.h" -#include "llvm/Config/config.h" -#include <vector> +#include "llvm/Support/raw_ostream.h" #include <cassert> #include <climits> #include <cstring> +#include <vector> #if defined(__linux__) #if defined(HAVE_SYS_STAT_H) @@ -73,15 +72,20 @@ namespace { /// getBlockAfter - Return the memory block immediately after this one. /// MemoryRangeHeader &getBlockAfter() const { - return *(MemoryRangeHeader*)((char*)this+BlockSize); + return *reinterpret_cast<MemoryRangeHeader *>( + reinterpret_cast<char*>( + const_cast<MemoryRangeHeader *>(this))+BlockSize); } /// getFreeBlockBefore - If the block before this one is free, return it, /// otherwise return null. FreeRangeHeader *getFreeBlockBefore() const { if (PrevAllocated) return 0; - intptr_t PrevSize = ((intptr_t *)this)[-1]; - return (FreeRangeHeader*)((char*)this-PrevSize); + intptr_t PrevSize = reinterpret_cast<intptr_t *>( + const_cast<MemoryRangeHeader *>(this))[-1]; + return reinterpret_cast<FreeRangeHeader *>( + reinterpret_cast<char*>( + const_cast<MemoryRangeHeader *>(this))-PrevSize); } /// FreeBlock - Turn an allocated block into a free block, adjusting @@ -501,10 +505,14 @@ namespace { /// allocateDataSection - Allocate memory for a data section. uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) { + unsigned SectionID, bool IsReadOnly) { return (uint8_t*)DataAllocator.Allocate(Size, Alignment); } + bool applyPermissions(std::string *ErrMsg) { + return false; + } + /// startExceptionTable - Use startFunctionBody to allocate memory for the /// function's exception table. uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) { diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 752c5b7..fee10e1 100644 --- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -8,20 +8,20 @@ //===----------------------------------------------------------------------===// #include "MCJIT.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MutexGuard.h" -#include "llvm/DataLayout.h" using namespace llvm; @@ -118,17 +118,26 @@ void MCJIT::emitObject(Module *m) { // FIXME: Add a parameter to identify which object is being finalized when // MCJIT supports multiple modules. +// FIXME: Provide a way to separate code emission, relocations and page +// protection in the interface. void MCJIT::finalizeObject() { // If the module hasn't been compiled, just do that. if (!isCompiled) { // If the call to Dyld.resolveRelocations() is removed from emitObject() // we'll need to do that here. emitObject(M); + + // Set page permissions. + MemMgr->applyPermissions(); + return; } // Resolve any relocations. Dyld.resolveRelocations(); + + // Set page permissions. + MemMgr->applyPermissions(); } void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h index 571080d..283a8e5 100644 --- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -10,10 +10,10 @@ #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_H #define LLVM_LIB_EXECUTIONENGINE_MCJIT_H -#include "llvm/PassManager.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" +#include "llvm/PassManager.h" namespace llvm { diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp new file mode 100644 index 0000000..fa35acd --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp @@ -0,0 +1,226 @@ +//===- SectionMemoryManager.cpp - Memory manager for MCJIT/RtDyld *- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the section-based memory manager used by the MCJIT +// execution engine and RuntimeDyld +// +//===----------------------------------------------------------------------===// + +#include "llvm/Config/config.h" +#include "llvm/ExecutionEngine/SectionMemoryManager.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/MathExtras.h" + +#ifdef __linux__ + // These includes used by SectionMemoryManager::getPointerToNamedFunction() + // for Glibc trickery. See comments in this function for more information. + #ifdef HAVE_SYS_STAT_H + #include <sys/stat.h> + #endif + #include <fcntl.h> + #include <unistd.h> +#endif + +namespace llvm { + +uint8_t *SectionMemoryManager::allocateDataSection(uintptr_t Size, + unsigned Alignment, + unsigned SectionID, + bool IsReadOnly) { + if (IsReadOnly) + return allocateSection(RODataMem, Size, Alignment); + return allocateSection(RWDataMem, Size, Alignment); +} + +uint8_t *SectionMemoryManager::allocateCodeSection(uintptr_t Size, + unsigned Alignment, + unsigned SectionID) { + return allocateSection(CodeMem, Size, Alignment); +} + +uint8_t *SectionMemoryManager::allocateSection(MemoryGroup &MemGroup, + uintptr_t Size, + unsigned Alignment) { + if (!Alignment) + Alignment = 16; + + assert(!(Alignment & (Alignment - 1)) && "Alignment must be a power of two."); + + uintptr_t RequiredSize = Alignment * ((Size + Alignment - 1)/Alignment + 1); + uintptr_t Addr = 0; + + // Look in the list of free memory regions and use a block there if one + // is available. + for (int i = 0, e = MemGroup.FreeMem.size(); i != e; ++i) { + sys::MemoryBlock &MB = MemGroup.FreeMem[i]; + if (MB.size() >= RequiredSize) { + Addr = (uintptr_t)MB.base(); + uintptr_t EndOfBlock = Addr + MB.size(); + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + // Store cutted free memory block. + MemGroup.FreeMem[i] = sys::MemoryBlock((void*)(Addr + Size), + EndOfBlock - Addr - Size); + return (uint8_t*)Addr; + } + } + + // No pre-allocated free block was large enough. Allocate a new memory region. + // Note that all sections get allocated as read-write. The permissions will + // be updated later based on memory group. + // + // FIXME: It would be useful to define a default allocation size (or add + // it as a constructor parameter) to minimize the number of allocations. + // + // FIXME: Initialize the Near member for each memory group to avoid + // interleaving. + error_code ec; + sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(RequiredSize, + &MemGroup.Near, + sys::Memory::MF_READ | + sys::Memory::MF_WRITE, + ec); + if (ec) { + // FIXME: Add error propogation to the interface. + return NULL; + } + + // Save this address as the basis for our next request + MemGroup.Near = MB; + + MemGroup.AllocatedMem.push_back(MB); + Addr = (uintptr_t)MB.base(); + uintptr_t EndOfBlock = Addr + MB.size(); + + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + + // The allocateMappedMemory may allocate much more memory than we need. In + // this case, we store the unused memory as a free memory block. + unsigned FreeSize = EndOfBlock-Addr-Size; + if (FreeSize > 16) + MemGroup.FreeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize)); + + // Return aligned address + return (uint8_t*)Addr; +} + +bool SectionMemoryManager::applyPermissions(std::string *ErrMsg) +{ + // FIXME: Should in-progress permissions be reverted if an error occurs? + error_code ec; + + // Make code memory executable. + ec = applyMemoryGroupPermissions(CodeMem, + sys::Memory::MF_READ | sys::Memory::MF_EXEC); + if (ec) { + if (ErrMsg) { + *ErrMsg = ec.message(); + } + return true; + } + + // Make read-only data memory read-only. + ec = applyMemoryGroupPermissions(RODataMem, + sys::Memory::MF_READ | sys::Memory::MF_EXEC); + if (ec) { + if (ErrMsg) { + *ErrMsg = ec.message(); + } + return true; + } + + // Read-write data memory already has the correct permissions + + return false; +} + +error_code SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup, + unsigned Permissions) { + + for (int i = 0, e = MemGroup.AllocatedMem.size(); i != e; ++i) { + error_code ec; + ec = sys::Memory::protectMappedMemory(MemGroup.AllocatedMem[i], + Permissions); + if (ec) { + return ec; + } + } + + return error_code::success(); +} + +void SectionMemoryManager::invalidateInstructionCache() { + for (int i = 0, e = CodeMem.AllocatedMem.size(); i != e; ++i) + sys::Memory::InvalidateInstructionCache(CodeMem.AllocatedMem[i].base(), + CodeMem.AllocatedMem[i].size()); +} + +static int jit_noop() { + return 0; +} + +void *SectionMemoryManager::getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure) { +#if defined(__linux__) + //===--------------------------------------------------------------------===// + // Function stubs that are invoked instead of certain library calls + // + // Force the following functions to be linked in to anything that uses the + // JIT. This is a hack designed to work around the all-too-clever Glibc + // strategy of making these functions work differently when inlined vs. when + // not inlined, and hiding their real definitions in a separate archive file + // that the dynamic linker can't see. For more info, search for + // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. + if (Name == "stat") return (void*)(intptr_t)&stat; + if (Name == "fstat") return (void*)(intptr_t)&fstat; + if (Name == "lstat") return (void*)(intptr_t)&lstat; + if (Name == "stat64") return (void*)(intptr_t)&stat64; + if (Name == "fstat64") return (void*)(intptr_t)&fstat64; + if (Name == "lstat64") return (void*)(intptr_t)&lstat64; + if (Name == "atexit") return (void*)(intptr_t)&atexit; + if (Name == "mknod") return (void*)(intptr_t)&mknod; +#endif // __linux__ + + // We should not invoke parent's ctors/dtors from generated main()! + // On Mingw and Cygwin, the symbol __main is resolved to + // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors + // (and register wrong callee's dtors with atexit(3)). + // We expect ExecutionEngine::runStaticConstructorsDestructors() + // is called before ExecutionEngine::runFunctionAsMain() is called. + if (Name == "__main") return (void*)(intptr_t)&jit_noop; + + const char *NameStr = Name.c_str(); + void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); + if (Ptr) return Ptr; + + // If it wasn't found and if it starts with an underscore ('_') character, + // try again without the underscore. + if (NameStr[0] == '_') { + Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); + if (Ptr) return Ptr; + } + + if (AbortOnFailure) + report_fatal_error("Program used external function '" + Name + + "' which could not be resolved!"); + return 0; +} + +SectionMemoryManager::~SectionMemoryManager() { + for (unsigned i = 0, e = CodeMem.AllocatedMem.size(); i != e; ++i) + sys::Memory::releaseMappedMemory(CodeMem.AllocatedMem[i]); + for (unsigned i = 0, e = RWDataMem.AllocatedMem.size(); i != e; ++i) + sys::Memory::releaseMappedMemory(RWDataMem.AllocatedMem[i]); + for (unsigned i = 0, e = RODataMem.AllocatedMem.size(); i != e; ++i) + sys::Memory::releaseMappedMemory(RODataMem.AllocatedMem[i]); +} + +} // namespace llvm + diff --git a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp index 6b8e9d1..38867ec 100644 --- a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp +++ b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp @@ -17,7 +17,7 @@ #define DEBUG_TYPE "oprofile-jit-event-listener" #include "llvm/DebugInfo.h" -#include "llvm/Function.h" +#include "llvm/IR/Function.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/ExecutionEngine/OProfileWrapper.h" diff --git a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp index d67f537..7c0d395 100644 --- a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp +++ b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp @@ -29,6 +29,7 @@ #include <dirent.h> #include <sys/stat.h> #include <fcntl.h> +#include <unistd.h> namespace { diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp index 50cd072..603c526 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp @@ -9,10 +9,10 @@ #include "JITRegistrar.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/Support/MutexGuard.h" -#include "llvm/Support/Mutex.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" using namespace llvm; @@ -44,7 +44,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. - static struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; + struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; // Debuggers puts a breakpoint in this function. LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() { } diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h index 17f3a21..89350cc 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h @@ -1,76 +1,78 @@ -//===-- ObjectImageCommon.h - Format independent executuable object image -===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares a file format independent ObjectImage class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
-#define LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
-
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/ExecutionEngine/ObjectImage.h"
-#include "llvm/ExecutionEngine/ObjectBuffer.h"
-
-namespace llvm {
-
-class ObjectImageCommon : public ObjectImage {
- ObjectImageCommon(); // = delete
- ObjectImageCommon(const ObjectImageCommon &other); // = delete
-
-protected:
- object::ObjectFile *ObjFile;
-
- // This form of the constructor allows subclasses to use
- // format-specific subclasses of ObjectFile directly
- ObjectImageCommon(ObjectBuffer *Input, object::ObjectFile *Obj)
- : ObjectImage(Input), // saves Input as Buffer and takes ownership
- ObjFile(Obj)
- {
- }
-
-public:
- ObjectImageCommon(ObjectBuffer* Input)
- : ObjectImage(Input) // saves Input as Buffer and takes ownership
- {
- ObjFile = object::ObjectFile::createObjectFile(Buffer->getMemBuffer());
- }
- virtual ~ObjectImageCommon() { delete ObjFile; }
-
- virtual object::symbol_iterator begin_symbols() const
- { return ObjFile->begin_symbols(); }
- virtual object::symbol_iterator end_symbols() const
- { return ObjFile->end_symbols(); }
-
- virtual object::section_iterator begin_sections() const
- { return ObjFile->begin_sections(); }
- virtual object::section_iterator end_sections() const
- { return ObjFile->end_sections(); }
-
- virtual /* Triple::ArchType */ unsigned getArch() const
- { return ObjFile->getArch(); }
-
- virtual StringRef getData() const { return ObjFile->getData(); }
-
- // Subclasses can override these methods to update the image with loaded
- // addresses for sections and common symbols
- virtual void updateSectionAddress(const object::SectionRef &Sec,
- uint64_t Addr) {}
- virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr)
- {}
-
- // Subclasses can override these methods to provide JIT debugging support
- virtual void registerWithDebugger() {}
- virtual void deregisterWithDebugger() {}
-};
-
-} // end namespace llvm
-
-#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-
+//===-- ObjectImageCommon.h - Format independent executuable object image -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares a file format independent ObjectImage class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H +#define LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H + +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/Object/ObjectFile.h" + +namespace llvm { + +class ObjectImageCommon : public ObjectImage { + ObjectImageCommon(); // = delete + ObjectImageCommon(const ObjectImageCommon &other); // = delete + +protected: + object::ObjectFile *ObjFile; + + // This form of the constructor allows subclasses to use + // format-specific subclasses of ObjectFile directly + ObjectImageCommon(ObjectBuffer *Input, object::ObjectFile *Obj) + : ObjectImage(Input), // saves Input as Buffer and takes ownership + ObjFile(Obj) + { + } + +public: + ObjectImageCommon(ObjectBuffer* Input) + : ObjectImage(Input) // saves Input as Buffer and takes ownership + { + ObjFile = object::ObjectFile::createObjectFile(Buffer->getMemBuffer()); + } + virtual ~ObjectImageCommon() { delete ObjFile; } + + virtual object::symbol_iterator begin_symbols() const + { return ObjFile->begin_symbols(); } + virtual object::symbol_iterator end_symbols() const + { return ObjFile->end_symbols(); } + + virtual object::section_iterator begin_sections() const + { return ObjFile->begin_sections(); } + virtual object::section_iterator end_sections() const + { return ObjFile->end_sections(); } + + virtual /* Triple::ArchType */ unsigned getArch() const + { return ObjFile->getArch(); } + + virtual StringRef getData() const { return ObjFile->getData(); } + + virtual object::ObjectFile* getObjectFile() const { return ObjFile; } + + // Subclasses can override these methods to update the image with loaded + // addresses for sections and common symbols + virtual void updateSectionAddress(const object::SectionRef &Sec, + uint64_t Addr) {} + virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr) + {} + + // Subclasses can override these methods to provide JIT debugging support + virtual void registerWithDebugger() {} + virtual void deregisterWithDebugger() {} +}; + +} // end namespace llvm + +#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H + diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index a180e36..409b25f 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -12,12 +12,13 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "dyld" +#include "llvm/ExecutionEngine/RuntimeDyld.h" #include "ObjectImageCommon.h" -#include "RuntimeDyldImpl.h" #include "RuntimeDyldELF.h" +#include "RuntimeDyldImpl.h" #include "RuntimeDyldMachO.h" -#include "llvm/Support/Path.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/Path.h" using namespace llvm; using namespace llvm::object; @@ -106,28 +107,24 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) { SymType == object::SymbolRef::ST_Unknown) { uint64_t FileOffset; StringRef SectionData; + bool IsCode; section_iterator si = obj->end_sections(); Check(i->getFileOffset(FileOffset)); 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*)InputBuffer->getBufferStart() + (uintptr_t)FileOffset; uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)SectionData.begin()); - unsigned SectionID = - findOrEmitSection(*obj, - *si, - SymType == object::SymbolRef::ST_Function, - LocalSections); + 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)); - bool isGlobal = flags & SymbolRef::SF_Global; - if (isGlobal) - GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset); + GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset); } } DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n"); @@ -182,7 +179,7 @@ void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, // Allocate memory for the section unsigned SectionID = Sections.size(); uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void*), - SectionID); + SectionID, false); if (!Addr) report_fatal_error("Unable to allocate memory for common symbols!"); uint64_t Offset = 0; @@ -237,11 +234,13 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, bool IsRequired; bool IsVirtual; bool IsZeroInit; + bool IsReadOnly; uint64_t DataSize; StringRef Name; Check(Section.isRequiredForExecution(IsRequired)); Check(Section.isVirtual(IsVirtual)); Check(Section.isZeroInit(IsZeroInit)); + Check(Section.isReadOnlyData(IsReadOnly)); Check(Section.getSize(DataSize)); Check(Section.getName(Name)); @@ -256,7 +255,7 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, Allocate = DataSize + StubBufSize; Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID) - : MemMgr->allocateDataSection(Allocate, Alignment, SectionID); + : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, IsReadOnly); if (!Addr) report_fatal_error("Unable to allocate section memory!"); @@ -433,14 +432,20 @@ void RuntimeDyldImpl::resolveExternalSymbols() { RelocationList &Relocs = i->second; SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name); if (Loc == GlobalSymbolTable.end()) { - // This is an external symbol, try to get it address from - // MemoryManager. - uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(), + if (Name.size() == 0) { + // This is an absolute symbol, use an address of zero. + DEBUG(dbgs() << "Resolving absolute relocations." << "\n"); + resolveRelocationList(Relocs, 0); + } else { + // This is an external symbol, try to get its address from + // MemoryManager. + uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(), true); - DEBUG(dbgs() << "Resolving relocations Name: " << Name - << "\t" << format("%p", Addr) - << "\n"); - resolveRelocationList(Relocs, (uintptr_t)Addr); + DEBUG(dbgs() << "Resolving relocations Name: " << Name + << "\t" << format("%p", Addr) + << "\n"); + resolveRelocationList(Relocs, (uintptr_t)Addr); + } } else { report_fatal_error("Expected external symbol"); } @@ -451,6 +456,12 @@ void RuntimeDyldImpl::resolveExternalSymbols() { //===----------------------------------------------------------------------===// // RuntimeDyld class implementation RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { + // FIXME: There's a potential issue lurking here if a single instance of + // RuntimeDyld is used to load multiple objects. The current implementation + // associates a single memory manager with a RuntimeDyld instance. Even + // 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; MM = mm; } diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index f7015cd..b8537b1 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -15,16 +15,16 @@ #include "RuntimeDyldELF.h" #include "JITRegistrar.h" #include "ObjectImageCommon.h" +#include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/IntervalMap.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/ExecutionEngine/ObjectImage.h" -#include "llvm/ExecutionEngine/ObjectBuffer.h" -#include "llvm/Support/ELF.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/Object/ELF.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/ELF.h" using namespace llvm; using namespace llvm::object; @@ -38,19 +38,22 @@ error_code check(error_code Err) { return Err; } -template<support::endianness target_endianness, bool is64Bits> -class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> { - LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) +template<class ELFT> +class DyldELFObject + : public ELFObjectFile<ELFT> { + LLVM_ELF_IMPORT_TYPES(ELFT) - typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; - typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; - typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; - typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; + typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; + typedef Elf_Sym_Impl<ELFT> Elf_Sym; + typedef + Elf_Rel_Impl<ELFT, false> Elf_Rel; + typedef + Elf_Rel_Impl<ELFT, true> Elf_Rela; - typedef Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr; + typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; typedef typename ELFDataTypeTypedefHelper< - target_endianness, is64Bits>::value_type addr_type; + ELFT>::value_type addr_type; public: DyldELFObject(MemoryBuffer *Wrapper, error_code &ec); @@ -60,24 +63,25 @@ public: // Methods for type inquiry through isa, cast and dyn_cast static inline bool classof(const Binary *v) { - return (isa<ELFObjectFile<target_endianness, is64Bits> >(v) - && classof(cast<ELFObjectFile<target_endianness, is64Bits> >(v))); + return (isa<ELFObjectFile<ELFT> >(v) + && classof(cast<ELFObjectFile + <ELFT> >(v))); } static inline bool classof( - const ELFObjectFile<target_endianness, is64Bits> *v) { + const ELFObjectFile<ELFT> *v) { return v->isDyldType(); } }; -template<support::endianness target_endianness, bool is64Bits> +template<class ELFT> class ELFObjectImage : public ObjectImageCommon { protected: - DyldELFObject<target_endianness, is64Bits> *DyldObj; + DyldELFObject<ELFT> *DyldObj; bool Registered; public: ELFObjectImage(ObjectBuffer *Input, - DyldELFObject<target_endianness, is64Bits> *Obj) + DyldELFObject<ELFT> *Obj) : ObjectImageCommon(Input, Obj), DyldObj(Obj), Registered(false) {} @@ -113,17 +117,15 @@ class ELFObjectImage : public ObjectImageCommon { // The MemoryBuffer passed into this constructor is just a wrapper around the // actual memory. Ultimately, the Binary parent class will take ownership of // this MemoryBuffer object but not the underlying memory. -template<support::endianness target_endianness, bool is64Bits> -DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Wrapper, - error_code &ec) - : ELFObjectFile<target_endianness, is64Bits>(Wrapper, ec) { +template<class ELFT> +DyldELFObject<ELFT>::DyldELFObject(MemoryBuffer *Wrapper, error_code &ec) + : ELFObjectFile<ELFT>(Wrapper, ec) { this->isDyldELFObject = true; } -template<support::endianness target_endianness, bool is64Bits> -void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress( - const SectionRef &Sec, - uint64_t Addr) { +template<class ELFT> +void DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec, + uint64_t Addr) { DataRefImpl ShdrRef = Sec.getRawDataRefImpl(); Elf_Shdr *shdr = const_cast<Elf_Shdr*>( reinterpret_cast<const Elf_Shdr *>(ShdrRef.p)); @@ -133,14 +135,12 @@ void DyldELFObject<target_endianness, is64Bits>::updateSectionAddress( shdr->sh_addr = static_cast<addr_type>(Addr); } -template<support::endianness target_endianness, bool is64Bits> -void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress( - const SymbolRef &SymRef, - uint64_t Addr) { +template<class ELFT> +void DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef, + uint64_t Addr) { Elf_Sym *sym = const_cast<Elf_Sym*>( - ELFObjectFile<target_endianness, is64Bits>:: - getSymbol(SymRef.getRawDataRefImpl())); + ELFObjectFile<ELFT>::getSymbol(SymRef.getRawDataRefImpl())); // This assumes the address passed in matches the target address bitness // The template-based type cast handles everything else. @@ -149,7 +149,6 @@ void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress( } // namespace - namespace llvm { ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { @@ -161,24 +160,28 @@ ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { error_code ec; if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { - DyldELFObject<support::little, false> *Obj = - new DyldELFObject<support::little, false>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::little, false>(Buffer, Obj); + DyldELFObject<ELFType<support::little, 4, false> > *Obj = + new DyldELFObject<ELFType<support::little, 4, false> >( + Buffer->getMemBuffer(), ec); + return new ELFObjectImage<ELFType<support::little, 4, false> >(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) { - DyldELFObject<support::big, false> *Obj = - new DyldELFObject<support::big, false>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::big, false>(Buffer, Obj); + DyldELFObject<ELFType<support::big, 4, false> > *Obj = + new DyldELFObject<ELFType<support::big, 4, false> >( + Buffer->getMemBuffer(), ec); + return new ELFObjectImage<ELFType<support::big, 4, false> >(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) { - DyldELFObject<support::big, true> *Obj = - new DyldELFObject<support::big, true>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::big, true>(Buffer, Obj); + 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); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { - DyldELFObject<support::little, true> *Obj = - new DyldELFObject<support::little, true>(Buffer->getMemBuffer(), ec); - return new ELFObjectImage<support::little, true>(Buffer, Obj); + DyldELFObject<ELFType<support::little, 8, true> > *Obj = + new DyldELFObject<ELFType<support::little, 8, true> >( + Buffer->getMemBuffer(), ec); + return new ELFObjectImage<ELFType<support::little, 8, true> >(Buffer, Obj); } else llvm_unreachable("Unexpected ELF format"); @@ -207,7 +210,7 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section, case ELF::R_X86_64_32S: { Value += Addend; assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) || - (Type == ELF::R_X86_64_32S && + (Type == ELF::R_X86_64_32S && ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN))); uint32_t TruncatedAddr = (Value & 0xFFFFFFFF); uint32_t *Target = reinterpret_cast<uint32_t*>(Section.Address + Offset); @@ -288,8 +291,9 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, default: llvm_unreachable("Not implemented relocation type!"); - // Write a 32bit value to relocation address, taking into account the + // Write a 32bit value to relocation address, taking into account the // implicit addend encoded in the target. + case ELF::R_ARM_TARGET1 : case ELF::R_ARM_ABS32 : *TargetPtr += Value; break; @@ -298,7 +302,7 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, // Last 4 bit should be shifted. case ELF::R_ARM_MOVW_ABS_NC : // We are not expecting any other addend in the relocation address. - // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2 + // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2 // non-contiguous fields. assert((*TargetPtr & 0x000F0FFF) == 0); Value = Value & 0xFFFF; @@ -516,6 +520,12 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, uint8_t aalk = *(LocalAddress+3); writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc)); } break; + case ELF::R_PPC64_ADDR32 : { + int32_t Result = static_cast<int32_t>(Value + Addend); + if (SignExtend32<32>(Result) != Result) + llvm_unreachable("Relocation R_PPC64_ADDR32 overflow"); + writeInt32BE(LocalAddress, Result); + } break; case ELF::R_PPC64_REL24 : { uint64_t FinalAddress = (Section.LoadAddress + Offset); int32_t delta = static_cast<int32_t>(Value - FinalAddress + Addend); @@ -524,6 +534,13 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, // Generates a 'bl <address>' instruction writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC)); } break; + case ELF::R_PPC64_REL32 : { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + int32_t delta = static_cast<int32_t>(Value - FinalAddress + Addend); + if (SignExtend32<32>(delta) != delta) + llvm_unreachable("Relocation R_PPC64_REL32 overflow"); + writeInt32BE(LocalAddress, delta); + } break; case ELF::R_PPC64_ADDR64 : writeInt64BE(LocalAddress, Value + Addend); break; @@ -543,7 +560,6 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section, } } - void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, @@ -623,9 +639,9 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, // Default to 'true' in case isText fails (though it never does). bool isCode = true; si->isText(isCode); - Value.SectionID = findOrEmitSection(Obj, - (*si), - isCode, + Value.SectionID = findOrEmitSection(Obj, + (*si), + isCode, ObjSectionToID); Value.Addend = Addend; break; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index a292ee1..f100994 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -14,12 +14,12 @@ #ifndef LLVM_RUNTIME_DYLD_IMPL_H #define LLVM_RUNTIME_DYLD_IMPL_H -#include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Triple.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 987c0c3..bcc3df1 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -12,10 +12,10 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "dyld" +#include "RuntimeDyldMachO.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/STLExtras.h" -#include "RuntimeDyldMachO.h" +#include "llvm/ADT/StringRef.h" using namespace llvm; using namespace llvm::object; @@ -96,6 +96,7 @@ bool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress, *p++ = (uint8_t)(ValueToWrite & 0xff); ValueToWrite >>= 8; } + return false; } case macho::RIT_Difference: case macho::RIT_Generic_LocalDifference: diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index fe3539d..62d8487 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -14,10 +14,10 @@ #ifndef LLVM_RUNTIME_DYLD_MACHO_H #define LLVM_RUNTIME_DYLD_MACHO_H +#include "RuntimeDyldImpl.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/Object/MachOObject.h" #include "llvm/Support/Format.h" -#include "RuntimeDyldImpl.h" using namespace llvm; using namespace llvm::object; diff --git a/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp b/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp index 8b6104f..ca4330f 100644 --- a/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp +++ b/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp @@ -15,13 +15,13 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Module.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/Module.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Host.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Target/TargetMachine.h" using namespace llvm; @@ -32,8 +32,7 @@ TargetMachine *EngineBuilder::selectTarget() { // must use the host architecture. if (UseMCJIT && WhichEngine != EngineKind::Interpreter && M) TT.setTriple(M->getTargetTriple()); - else - TT.setTriple(LLVM_HOSTTRIPLE); + return selectTarget(TT, MArch, MCPU, MAttrs); } @@ -45,7 +44,7 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple, const SmallVectorImpl<std::string>& MAttrs) { Triple TheTriple(TargetTriple); if (TheTriple.getTriple().empty()) - TheTriple.setTriple(sys::getDefaultTargetTriple()); + TheTriple.setTriple(sys::getProcessTriple()); // Adjust the triple to match what the user requested. const Target *TheTarget = 0; |