r278016 - [ARM] Command-line options for embedded position-independent code
Oliver Stannard via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 8 08:28:40 PDT 2016
Author: olista01
Date: Mon Aug 8 10:28:40 2016
New Revision: 278016
URL: http://llvm.org/viewvc/llvm-project?rev=278016&view=rev
Log:
[ARM] Command-line options for embedded position-independent code
This patch (with the corresponding ARM backend patch) adds support for
some new relocation models:
* Read-only position independence (ROPI): Code and read-only data is accessed
PC-relative. The offsets between all code and RO data sections are known at
static link time.
* Read-write position independence (RWPI): Read-write data is accessed relative
to a static base register. The offsets between all writeable data sections
are known at static link time.
These two modes are independent (they specify how different objects
should be addressed), so they can be used individually or together.
These modes are intended for bare-metal systems or systems with small
real-time operating systems. They are designed to avoid the need for a
dynamic linker, the only initialisation required is setting the static
base register to an appropriate value for RWPI code.
There is one C construct not currently supported by these modes: global
variables initialised to the address of another global variable or
function, where that address is not known at static-link time. There are
a few possible ways to solve this:
* Disallow this, and require the user to write their own initialisation
function if they need variables like this.
* Emit dynamic initialisers for these variables in the compiler, called from
the .init_array section (as is currently done for C++ dynamic initialisers).
We have a patch to do this, described in my original RFC email
(http://lists.llvm.org/pipermail/llvm-dev/2015-December/093022.html), but the
feedback from that RFC thread was that this is not something that belongs in
clang.
* Use a small dynamic loader to fix up these variables, by adding the
difference between the load and execution address of the relevant section.
This would require linker co-operation to generate a table of addresses that
need fixing up.
Differential Revision: https://reviews.llvm.org/D23196
Added:
cfe/trunk/test/Driver/ropi-rwpi.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/lib/CodeGen/BackendUtil.cpp
cfe/trunk/lib/Driver/Tools.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=278016&r1=278015&r2=278016&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Mon Aug 8 10:28:40 2016
@@ -240,6 +240,11 @@ def err_test_module_file_extension_forma
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
InGroup<Fallback>;
+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<UnsupportedNan>;
Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=278016&r1=278015&r2=278016&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Mon Aug 8 10:28:40 2016
@@ -1087,6 +1087,10 @@ def fpic : Flag<["-"], "fpic">, Group<f_
def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
def fpie : Flag<["-"], "fpie">, Group<f_Group>;
def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
+def fropi : Flag<["-"], "fropi">, Group<f_Group>;
+def fno_ropi : Flag<["-"], "fno-ropi">, Group<f_Group>;
+def frwpi : Flag<["-"], "frwpi">, Group<f_Group>;
+def fno_rwpi : Flag<["-"], "fno-rwpi">, Group<f_Group>;
def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
def fpreserve_as_comments : Flag<["-"], "fpreserve-as-comments">, Group<f_Group>;
Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=278016&r1=278015&r2=278016&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original)
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Mon Aug 8 10:28:40 2016
@@ -525,6 +525,12 @@ void EmitAssemblyHelper::CreateTargetMac
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!");
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=278016&r1=278015&r2=278016&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Mon Aug 8 10:28:40 2016
@@ -3777,10 +3777,52 @@ ParsePICArgs(const ToolChain &ToolChain,
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(l
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,
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);
Added: cfe/trunk/test/Driver/ropi-rwpi.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/ropi-rwpi.c?rev=278016&view=auto
==============================================================================
--- cfe/trunk/test/Driver/ropi-rwpi.c (added)
+++ cfe/trunk/test/Driver/ropi-rwpi.c Mon Aug 8 10:28:40 2016
@@ -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++
More information about the cfe-commits
mailing list