diff options
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index f5110731db4..d0dee663cf1 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -3777,10 +3777,52 @@ ParsePICArgs(const ToolChain &ToolChain, const llvm::Triple &Triple, return std::make_tuple(llvm::Reloc::DynamicNoPIC, PIC ? 2U : 0U, false); } + bool EmbeddedPISupported; + switch (ToolChain.getArch()) { + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: + EmbeddedPISupported = true; + break; + default: + EmbeddedPISupported = false; + break; + } + + bool ROPI = false, RWPI = false; + Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi); + if (LastROPIArg && LastROPIArg->getOption().matches(options::OPT_fropi)) { + if (!EmbeddedPISupported) + ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target) + << LastROPIArg->getSpelling() << ToolChain.getTriple().str(); + ROPI = true; + } + Arg *LastRWPIArg = Args.getLastArg(options::OPT_frwpi, options::OPT_fno_rwpi); + if (LastRWPIArg && LastRWPIArg->getOption().matches(options::OPT_frwpi)) { + if (!EmbeddedPISupported) + ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target) + << LastRWPIArg->getSpelling() << ToolChain.getTriple().str(); + RWPI = true; + } + + // ROPI and RWPI are not comaptible with PIC or PIE. + if ((ROPI || RWPI) && (PIC || PIE)) { + ToolChain.getDriver().Diag(diag::err_drv_ropi_rwpi_incompatible_with_pic); + } + if (PIC) return std::make_tuple(llvm::Reloc::PIC_, IsPICLevelTwo ? 2U : 1U, PIE); - return std::make_tuple(llvm::Reloc::Static, 0U, false); + llvm::Reloc::Model RelocM = llvm::Reloc::Static; + if (ROPI && RWPI) + RelocM = llvm::Reloc::ROPI_RWPI; + else if (ROPI) + RelocM = llvm::Reloc::ROPI; + else if (RWPI) + RelocM = llvm::Reloc::RWPI; + + return std::make_tuple(RelocM, 0U, false); } static const char *RelocationModelName(llvm::Reloc::Model Model) { @@ -3791,6 +3833,12 @@ static const char *RelocationModelName(llvm::Reloc::Model Model) { return "pic"; case llvm::Reloc::DynamicNoPIC: return "dynamic-no-pic"; + case llvm::Reloc::ROPI: + return "ropi"; + case llvm::Reloc::RWPI: + return "rwpi"; + case llvm::Reloc::ROPI_RWPI: + return "ropi-rwpi"; } llvm_unreachable("Unknown Reloc::Model kind"); } @@ -4075,6 +4123,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, ParsePICArgs(getToolChain(), Triple, Args); const char *RMName = RelocationModelName(RelocationModel); + + if ((RelocationModel == llvm::Reloc::ROPI || + RelocationModel == llvm::Reloc::ROPI_RWPI) && + types::isCXX(Input.getType()) && + !Args.hasArg(options::OPT_fallow_unsupported)) + D.Diag(diag::err_drv_ropi_incompatible_with_cxx); + if (RMName) { CmdArgs.push_back("-mrelocation-model"); CmdArgs.push_back(RMName); |