Index: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td @@ -240,6 +240,11 @@ def warn_drv_invoking_fallback : Warning<"falling back to %0">, InGroup; +def err_drv_ropi_rwpi_incompatible_with_pic : Error< + "embedded and GOT-based position independence are incompatible">; +def err_drv_ropi_incompatible_with_cxx : Error< + "ROPI is not compatible with c++">; + def warn_target_unsupported_nan2008 : Warning< "ignoring '-mnan=2008' option because the '%0' architecture does not support it">, InGroup; Index: cfe/trunk/include/clang/Driver/Options.td =================================================================== --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1087,6 +1087,10 @@ def fno_pic : Flag<["-"], "fno-pic">, Group; def fpie : Flag<["-"], "fpie">, Group; def fno_pie : Flag<["-"], "fno-pie">, Group; +def fropi : Flag<["-"], "fropi">, Group; +def fno_ropi : Flag<["-"], "fno-ropi">, Group; +def frwpi : Flag<["-"], "frwpi">, Group; +def fno_rwpi : Flag<["-"], "fno-rwpi">, Group; def fplugin_EQ : Joined<["-"], "fplugin=">, Group, Flags<[DriverOption]>, MetaVarName<"">, HelpText<"Load the named plugin (dynamic shared object)">; def fpreserve_as_comments : Flag<["-"], "fpreserve-as-comments">, Group; Index: cfe/trunk/lib/CodeGen/BackendUtil.cpp =================================================================== --- cfe/trunk/lib/CodeGen/BackendUtil.cpp +++ cfe/trunk/lib/CodeGen/BackendUtil.cpp @@ -525,6 +525,12 @@ RM = llvm::Reloc::Static; } else if (CodeGenOpts.RelocationModel == "pic") { RM = llvm::Reloc::PIC_; + } else if (CodeGenOpts.RelocationModel == "ropi") { + RM = llvm::Reloc::ROPI; + } else if (CodeGenOpts.RelocationModel == "rwpi") { + RM = llvm::Reloc::RWPI; + } else if (CodeGenOpts.RelocationModel == "ropi-rwpi") { + RM = llvm::Reloc::ROPI_RWPI; } else { assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" && "Invalid PIC model!"); Index: cfe/trunk/lib/Driver/Tools.cpp =================================================================== --- cfe/trunk/lib/Driver/Tools.cpp +++ cfe/trunk/lib/Driver/Tools.cpp @@ -3777,10 +3777,52 @@ 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 @@ 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 @@ 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); Index: cfe/trunk/test/Driver/ropi-rwpi.c =================================================================== --- cfe/trunk/test/Driver/ropi-rwpi.c +++ cfe/trunk/test/Driver/ropi-rwpi.c @@ -0,0 +1,38 @@ +// RUN: %clang -target arm-none-eabi -### -c %s 2>&1 | FileCheck --check-prefix=STATIC %s +// RUN: %clang -target arm-none-eabi -fropi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI %s +// RUN: %clang -target arm-none-eabi -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=RWPI %s +// RUN: %clang -target arm-none-eabi -fropi -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI-RWPI %s + +// RUN: %clang -target armeb-none-eabi -fropi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI %s +// RUN: %clang -target thumb-none-eabi -fropi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI %s +// RUN: %clang -target thumbeb-none-eabi -fropi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI %s + +// RUN: %clang -target x86_64-linux-gnu -fropi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI-NON-ARM %s +// RUN: %clang -target x86_64-linux-gnu -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=RWPI-NON-ARM %s +// RUN: %clang -target x86_64-linux-gnu -fropi -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI-NON-ARM --check-prefix=RWPI-NON-ARM %s + +// RUN: %clang -target arm-none-eabi -fpic -fropi -### -c %s 2>&1 | FileCheck --check-prefix=PIC %s +// RUN: %clang -target arm-none-eabi -fpie -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=PIC %s +// RUN: %clang -target arm-none-eabi -fPIC -fropi -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=PIC %s +// RUN: %clang -target arm-none-eabi -fno-pic -fropi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI %s + +// RUN: %clang -target arm-none-eabi -x c++ -fropi -### -c %s 2>&1 | FileCheck --check-prefix=CXX %s +// RUN: %clang -target arm-none-eabi -x c++ -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=RWPI %s +// RUN: %clang -target arm-none-eabi -x c++ -fropi -frwpi -### -c %s 2>&1 | FileCheck --check-prefix=CXX %s +// RUN: %clang -target arm-none-eabi -x c++ -fallow-unsupported -fropi -### -c %s 2>&1 | FileCheck --check-prefix=ROPI %s + + +// STATIC: "-mrelocation-model" "static" + +// ROPI: "-mrelocation-model" "ropi" + +// RWPI: "-mrelocation-model" "rwpi" + +// ROPI-RWPI: "-mrelocation-model" "ropi-rwpi" + +// ROPI-NON-ARM: error: unsupported option '-fropi' for target 'x86_64--linux-gnu' +// RWPI-NON-ARM: error: unsupported option '-frwpi' for target 'x86_64--linux-gnu' + +// PIC: error: embedded and GOT-based position independence are incompatible + +// CXX: error: ROPI is not compatible with c++