diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/llvm/lib/ExecutionEngine/JIT/JIT.cpp index 3fd5be7d16ed..633a75ed61c5 100644 --- a/llvm/lib/ExecutionEngine/JIT/JIT.cpp +++ b/llvm/lib/ExecutionEngine/JIT/JIT.cpp @@ -609,12 +609,12 @@ void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) { return (void*)&__dso_handle; #endif Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(GV->getName().c_str()); - if (Ptr == 0) { + if (Ptr == 0 && !areDlsymStubsEnabled()) { cerr << "Could not resolve external global address: " << GV->getName() << "\n"; abort(); - addGlobalMapping(GV, Ptr); } + addGlobalMapping(GV, Ptr); } else { // GlobalVariable's which are not "constant" will cause trouble in a server // situation. It's returned in the same block of memory as code which may diff --git a/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp b/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp index 5c6236dcaebb..22515f3a82c1 100644 --- a/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -1348,12 +1348,22 @@ void JIT::updateDlsymStubTable() { for (unsigned i = 0; i != GVs.size(); ++i) MCE->emitInt32(Offsets[i]); - // Emit the pointers - for (unsigned i = 0; i != GVs.size(); ++i) + // Emit the pointers. Verify that they are at least 2-byte aligned, and set + // the low bit to 0 == GV, 1 == Function, so that the client code doing the + // relocation can write the relocated pointer at the appropriate place in + // the stub. + for (unsigned i = 0; i != GVs.size(); ++i) { + intptr_t Ptr = (intptr_t)Ptrs[i]; + assert((Ptr & 1) == 0 && "Stub pointers must be at least 2-byte aligned!"); + + if (isa(GVs[i])) + Ptr |= (intptr_t)1; + if (sizeof(void *) == 8) - MCE->emitInt64((intptr_t)Ptrs[i]); + MCE->emitInt64(Ptr); else - MCE->emitInt32((intptr_t)Ptrs[i]); + MCE->emitInt32(Ptr); + } // Emit the strings for (unsigned i = 0; i != GVs.size(); ++i)