Index: include/llvm/LTO/Config.h =================================================================== --- include/llvm/LTO/Config.h +++ include/llvm/LTO/Config.h @@ -39,7 +39,7 @@ std::string CPU; TargetOptions Options; std::vector MAttrs; - Reloc::Model RelocModel = Reloc::PIC_; + Optional RelocModel = Reloc::PIC_; CodeModel::Model CodeModel = CodeModel::Default; CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; TargetMachine::CodeGenFileType CGFileType = TargetMachine::CGFT_ObjectFile; Index: lib/LTO/LTO.cpp =================================================================== --- lib/LTO/LTO.cpp +++ lib/LTO/LTO.cpp @@ -114,7 +114,8 @@ AddUnsigned((unsigned)Conf.Options.DebuggerTuning); for (auto &A : Conf.MAttrs) AddString(A); - AddUnsigned(Conf.RelocModel); + AddUnsigned(Conf.RelocModel.hasValue() ? *Conf.RelocModel + : static_cast(-1)); AddUnsigned(Conf.CodeModel); AddUnsigned(Conf.CGOptLevel); AddUnsigned(Conf.CGFileType); Index: lib/LTO/LTOBackend.cpp =================================================================== --- lib/LTO/LTOBackend.cpp +++ lib/LTO/LTOBackend.cpp @@ -118,17 +118,23 @@ std::unique_ptr createTargetMachine(Config &Conf, StringRef TheTriple, - const Target *TheTarget) { + const Target *TheTarget, Reloc::Model RelocModel) { SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(Triple(TheTriple)); for (const std::string &A : Conf.MAttrs) Features.AddFeature(A); return std::unique_ptr(TheTarget->createTargetMachine( - TheTriple, Conf.CPU, Features.getString(), Conf.Options, Conf.RelocModel, + TheTriple, Conf.CPU, Features.getString(), Conf.Options, RelocModel, Conf.CodeModel, Conf.CGOptLevel)); } +static Reloc::Model relocModelForModule(Config &C, Module &M) { + if (C.RelocModel.hasValue()) + return *C.RelocModel; + return M.getPICLevel() == PICLevel::NotPIC ? Reloc::Static : Reloc::PIC_; +} + static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel) { PassBuilder PB(TM); AAManager AA; @@ -311,7 +317,8 @@ std::unique_ptr MPartInCtx = std::move(MOrErr.get()); std::unique_ptr TM = - createTargetMachine(C, MPartInCtx->getTargetTriple(), T); + createTargetMachine(C, MPartInCtx->getTargetTriple(), T, + relocModelForModule(C, *MPartInCtx)); codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx); }, @@ -360,8 +367,8 @@ if (!TOrErr) return TOrErr.takeError(); - std::unique_ptr TM = - createTargetMachine(C, Mod->getTargetTriple(), *TOrErr); + std::unique_ptr TM = createTargetMachine( + C, Mod->getTargetTriple(), *TOrErr, relocModelForModule(C, *Mod)); // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( @@ -397,8 +404,8 @@ if (!TOrErr) return TOrErr.takeError(); - std::unique_ptr TM = - createTargetMachine(Conf, Mod.getTargetTriple(), *TOrErr); + std::unique_ptr TM = createTargetMachine( + Conf, Mod.getTargetTriple(), *TOrErr, relocModelForModule(Conf, Mod)); if (Conf.CodeGenOnly) { codegen(Conf, TM.get(), AddStream, Task, Mod); Index: test/tools/gold/X86/relocation-model-pic.ll =================================================================== --- /dev/null +++ test/tools/gold/X86/relocation-model-pic.ll @@ -0,0 +1,63 @@ +; RUN: cat %s >%t.pic.ll +; RUN: echo '!llvm.module.flags = !{!0}' >>%t.pic.ll +; RUN: echo '!0 = !{i32 1, !"PIC Level", i32 2}' >>%t.pic.ll + +; RUN: llvm-as %s -o %t.o +; RUN: llvm-as %t.pic.ll -o %t.pic.o + +;; Non-PIC source. + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --shared \ +; RUN: --plugin-opt=save-temps %t.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=PIC + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --export-dynamic --noinhibit-exec -pie \ +; RUN: --plugin-opt=save-temps %t.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=PIC + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --export-dynamic --noinhibit-exec \ +; RUN: --plugin-opt=save-temps %t.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=STATIC + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: -r \ +; RUN: --plugin-opt=save-temps %t.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=STATIC + +;; PIC source. + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --shared \ +; RUN: --plugin-opt=save-temps %t.pic.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=PIC + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --export-dynamic --noinhibit-exec -pie \ +; RUN: --plugin-opt=save-temps %t.pic.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=PIC + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --export-dynamic --noinhibit-exec \ +; RUN: --plugin-opt=save-temps %t.pic.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=STATIC + +; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: -r \ +; RUN: --plugin-opt=save-temps %t.pic.o -o %t-out +; RUN: llvm-readobj -r %t-out.o | FileCheck %s --check-prefix=PIC + + +; PIC: R_X86_64_GOTPCREL foo +; STATIC: R_X86_64_PC32 foo + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@foo = external global i32 +define i32 @main() { + %t = load i32, i32* @foo + ret i32 %t +} Index: tools/gold/gold-plugin.cpp =================================================================== --- tools/gold/gold-plugin.cpp +++ tools/gold/gold-plugin.cpp @@ -102,7 +102,7 @@ static ld_plugin_set_extra_library_path set_extra_library_path = nullptr; static ld_plugin_get_view get_view = nullptr; static bool IsExecutable = false; -static Optional RelocationModel; +static Optional RelocationModel = None; static std::string output_name = ""; static std::list Modules; static DenseMap FDToLeaderHandle; @@ -282,6 +282,8 @@ case LDPT_LINKER_OUTPUT: switch (tv->tv_u.tv_val) { case LDPO_REL: // .o + IsExecutable = false; + break; case LDPO_DYN: // .so IsExecutable = false; RelocationModel = Reloc::PIC_; @@ -726,7 +728,7 @@ Conf.Options.RelaxELFRelocations = false; Conf.MAttrs = MAttrs; - Conf.RelocModel = *RelocationModel; + Conf.RelocModel = RelocationModel; Conf.CGOptLevel = getCGOptLevel(); Conf.DisableVerify = options::DisableVerify; Conf.OptLevel = options::OptLevel;