summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r--clang/lib/Driver/Tools.cpp57
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);
OpenPOWER on IntegriCloud