Index: include/llvm-c/ExecutionEngine.h =================================================================== --- include/llvm-c/ExecutionEngine.h +++ include/llvm-c/ExecutionEngine.h @@ -43,6 +43,7 @@ struct LLVMMCJITCompilerOptions { unsigned OptLevel; + LLVMRelocMode RelMode; LLVMCodeModel CodeModel; LLVMBool NoFramePointerElim; LLVMBool EnableFastISel; Index: include/llvm/Support/CodeGenCWrappers.h =================================================================== --- include/llvm/Support/CodeGenCWrappers.h +++ include/llvm/Support/CodeGenCWrappers.h @@ -58,6 +58,35 @@ llvm_unreachable("Bad CodeModel!"); } +inline Reloc::Model unwrap(LLVMRelocMode Model) { + switch (Model) { + case LLVMRelocDefault: + case LLVMRelocStatic: + return Reloc::Static; + case LLVMRelocPIC: + return Reloc::PIC_; + case LLVMRelocDynamicNoPic: + return Reloc::DynamicNoPIC; + } + llvm_unreachable("Invalid LLVMRelocMode!"); +} + +inline LLVMRelocMode wrap(Reloc::Model Model) { + switch (Model) { + case Reloc::Static: + return LLVMRelocStatic; + case Reloc::PIC_: + return LLVMRelocPIC; + case Reloc::DynamicNoPIC: + return LLVMRelocDynamicNoPic; + case Reloc::ROPI: + case Reloc::RWPI: + case Reloc::ROPI_RWPI: + break; + } + llvm_unreachable("Unsupported Reloc::Model!"); +} + } // end llvm namespace #endif Index: lib/ExecutionEngine/ExecutionEngineBindings.cpp =================================================================== --- lib/ExecutionEngine/ExecutionEngineBindings.cpp +++ lib/ExecutionEngine/ExecutionEngineBindings.cpp @@ -196,10 +196,11 @@ std::string Error; EngineBuilder builder(std::move(Mod)); builder.setEngineKind(EngineKind::JIT) - .setErrorStr(&Error) - .setOptLevel((CodeGenOpt::Level)options.OptLevel) - .setCodeModel(unwrap(options.CodeModel)) - .setTargetOptions(targetOptions); + .setErrorStr(&Error) + .setOptLevel((CodeGenOpt::Level)options.OptLevel) + .setCodeModel(unwrap(options.CodeModel)) + .setRelocationModel(unwrap(options.RelMode)) + .setTargetOptions(targetOptions); if (options.MCJMM) builder.setMCJITMemoryManager( std::unique_ptr(unwrap(options.MCJMM))); Index: unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp =================================================================== --- unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp +++ unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp @@ -29,6 +29,7 @@ static bool didCallAllocateCodeSection; static bool didAllocateCompactUnwindSection; static bool didCallYield; +static bool didAllocateGot; static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size, unsigned alignment, @@ -46,6 +47,8 @@ LLVMBool isReadOnly) { if (!strcmp(sectionName, "__compact_unwind")) didAllocateCompactUnwindSection = true; + else if (!strcmp(sectionName, ".got")) + didAllocateGot = true; return static_cast(object)->allocateDataSection( size, alignment, sectionID, sectionName, isReadOnly); } @@ -451,6 +454,24 @@ EXPECT_TRUE(MM->UsedDataSizeRW > 0); } +TEST_F(MCJITCAPITest, position_independent_code) { + SKIP_UNSUPPORTED_PLATFORM; + + buildModuleWithCodeAndData(); + buildMCJITOptions(); + Options.RelMode = LLVMRelocPIC; + Options.CodeModel = LLVMCodeModelSmall; + useRoundTripSectionMemoryManager(); + buildMCJITEngine(); + buildAndRunPasses(); + + auto SetGlobalFct = reinterpret_cast( + reinterpret_cast(LLVMGetPointerToGlobal(Engine, Function2))); + + SetGlobalFct(789); + EXPECT_TRUE(didAllocateGot); +} + TEST_F(MCJITCAPITest, yield) { SKIP_UNSUPPORTED_PLATFORM;