diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86TargetMachine.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86TargetMachine.cpp | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index 1fe98a66c7c..3ff847a062d 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -106,15 +106,51 @@ static std::string computeDataLayout(const Triple &TT) { return Ret; } +static Reloc::Model getEffectiveRelocModel(const Triple &TT, + Optional<Reloc::Model> RM) { + bool is64Bit = TT.getArch() == Triple::x86_64; + if (!RM.hasValue()) { + // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode. + // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we + // use static relocation model by default. + if (TT.isOSDarwin()) { + if (is64Bit) + return Reloc::PIC_; + return Reloc::DynamicNoPIC; + } + if (TT.isOSWindows() && is64Bit) + return Reloc::PIC_; + return Reloc::Static; + } + + // ELF and X86-64 don't have a distinct DynamicNoPIC model. DynamicNoPIC + // is defined as a model for code which may be used in static or dynamic + // executables but not necessarily a shared library. On X86-32 we just + // compile in -static mode, in x86-64 we use PIC. + if (*RM == Reloc::DynamicNoPIC) { + if (is64Bit) + return Reloc::PIC_; + if (!TT.isOSDarwin()) + return Reloc::Static; + } + + // If we are on Darwin, disallow static relocation model in X86-64 mode, since + // the Mach-O file format doesn't support it. + if (*RM == Reloc::Static && TT.isOSDarwin() && is64Bit) + return Reloc::PIC_; + + return *RM; +} + /// Create an X86 target. /// X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, - Reloc::Model RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, RM, CM, - OL), + Optional<Reloc::Model> RM, + CodeModel::Model CM, CodeGenOpt::Level OL) + : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, + getEffectiveRelocModel(TT, RM), CM, OL), TLOF(createTLOF(getTargetTriple())), Subtarget(TT, CPU, FS, *this, Options.StackAlignmentOverride) { // Windows stack unwinder gets confused when execution flow "falls through" |