From b9f1b014e1aa47550e1e4bb0c0bf143fc01f6c20 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Mon, 22 May 2017 21:11:35 +0000 Subject: [PATCH] Infer relocation model from module flags in relocatable LTO link. Fix for PR33096. llvm-svn: 303578 --- llvm/include/llvm/LTO/Config.h | 2 +- llvm/lib/LTO/LTO.cpp | 5 +- llvm/lib/LTO/LTOBackend.cpp | 21 +++++--- llvm/test/tools/gold/X86/relocation-model-pic.ll | 63 ++++++++++++++++++++++++ llvm/tools/gold/gold-plugin.cpp | 6 ++- 5 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 llvm/test/tools/gold/X86/relocation-model-pic.ll diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index ede6637..5ba8492 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -39,7 +39,7 @@ struct Config { 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; diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index c73b6b6..c69f385 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -114,7 +114,10 @@ static void computeCacheKey( AddUnsigned((unsigned)Conf.Options.DebuggerTuning); for (auto &A : Conf.MAttrs) AddString(A); - AddUnsigned(Conf.RelocModel); + if (Conf.RelocModel) + AddUnsigned(*Conf.RelocModel); + else + AddUnsigned(-1); AddUnsigned(Conf.CodeModel); AddUnsigned(Conf.CGOptLevel); AddUnsigned(Conf.CGFileType); diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 30447c5..668667a 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -117,15 +117,22 @@ Error Config::addSaveTemps(std::string OutputFileName, namespace { std::unique_ptr -createTargetMachine(Config &Conf, StringRef TheTriple, - const Target *TheTarget) { +createTargetMachine(Config &Conf, const Target *TheTarget, Module &M) { + StringRef TheTriple = M.getTargetTriple(); SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(Triple(TheTriple)); for (const std::string &A : Conf.MAttrs) Features.AddFeature(A); + Reloc::Model RelocModel; + if (Conf.RelocModel) + RelocModel = *Conf.RelocModel; + else + RelocModel = + M.getPICLevel() == PICLevel::NotPIC ? Reloc::Static : Reloc::PIC_; + 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)); } @@ -311,7 +318,7 @@ void splitCodeGen(Config &C, TargetMachine *TM, AddStreamFn AddStream, std::unique_ptr MPartInCtx = std::move(MOrErr.get()); std::unique_ptr TM = - createTargetMachine(C, MPartInCtx->getTargetTriple(), T); + createTargetMachine(C, T, *MPartInCtx); codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx); }, @@ -360,8 +367,7 @@ Error lto::backend(Config &C, AddStreamFn AddStream, if (!TOrErr) return TOrErr.takeError(); - std::unique_ptr TM = - createTargetMachine(C, Mod->getTargetTriple(), *TOrErr); + std::unique_ptr TM = createTargetMachine(C, *TOrErr, *Mod); // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( @@ -397,8 +403,7 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream, if (!TOrErr) return TOrErr.takeError(); - std::unique_ptr TM = - createTargetMachine(Conf, Mod.getTargetTriple(), *TOrErr); + std::unique_ptr TM = createTargetMachine(Conf, *TOrErr, Mod); if (Conf.CodeGenOnly) { codegen(Conf, TM.get(), AddStream, Task, Mod); diff --git a/llvm/test/tools/gold/X86/relocation-model-pic.ll b/llvm/test/tools/gold/X86/relocation-model-pic.ll new file mode 100644 index 0000000..65b7bee --- /dev/null +++ b/llvm/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 +} diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp index 9b783d1..cf207d9 100644 --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -102,7 +102,7 @@ static ld_plugin_add_input_file add_input_file = nullptr; 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 @@ ld_plugin_status onload(ld_plugin_tv *tv) { 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 @@ static std::unique_ptr createLTO() { Conf.Options.RelaxELFRelocations = false; Conf.MAttrs = MAttrs; - Conf.RelocModel = *RelocationModel; + Conf.RelocModel = RelocationModel; Conf.CGOptLevel = getCGOptLevel(); Conf.DisableVerify = options::DisableVerify; Conf.OptLevel = options::OptLevel; -- 2.7.4