llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Zachary Yedidia (zyedidia)

<details>
<summary>Changes</summary>

This adds a new `-mlfi=...` flag to the Clang frontend to control LFI subtarget 
features. For now that is just `no-loads` and `no-stores`, setting the 
corresponding `+no-lfi-loads` and `+no-lfi-stores` LLVM subtarget features. 
Currently this only affects AArch64, but these features will also be supported 
on the X86 LFI subtarget when it is added so I've implemented this in a 
target-agnostic location.

Clang will also now define the `__LFI_NO_LOADS__` and `__LFI_NO_STORES__` 
preprocessor macros for these subtarget features, in addition to the existing 
`__LFI__`.

---
Full diff: https://github.com/llvm/llvm-project/pull/204689.diff


7 Files Affected:

- (modified) clang/include/clang/Options/Options.td (+5) 
- (modified) clang/lib/Basic/Targets/AArch64.cpp (-3) 
- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+20) 
- (modified) clang/lib/Frontend/InitPreprocessor.cpp (+11) 
- (added) clang/test/Driver/lfi.c (+11) 
- (added) clang/test/Preprocessor/lfi.c (+13) 
- (modified) llvm/docs/LFI.rst (+22-1) 


``````````diff
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 5028684731b2d..58bf45d6cf22d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -5802,6 +5802,11 @@ def mharden_sls_EQ : Joined<["-"], "mharden-sls=">, 
Group<m_Group>,
            " blr(ARM/AArch64), comdat(ARM/AArch64), nocomdat(ARM/AArch64),"
            " return(X86), indirect-jmp(X86)">;
 
+def mlfi_EQ : CommaJoined<["-"], "mlfi=">, Group<m_Group>,
+  HelpText<"Configure Lightweight Fault Isolation (LFI) features. <arg> is a"
+           " comma-separated list of: no-loads, no-stores">,
+  Values<"no-loads,no-stores">;
+
 def matomics : Flag<["-"], "matomics">, Group<m_wasm_Features_Group>;
 def mno_atomics : Flag<["-"], "mno-atomics">, Group<m_wasm_Features_Group>;
 def mbulk_memory : Flag<["-"], "mbulk-memory">, Group<m_wasm_Features_Group>;
diff --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index 9afe6cb10729d..42fd29c2c412f 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -417,9 +417,6 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions 
&Opts,
     Builder.defineMacro("__aarch64__");
   }
 
-  if (getTriple().isLFI())
-    Builder.defineMacro("__LFI__");
-
   // Inline assembly supports AArch64 flag outputs.
   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
 
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 48724746d9330..f854ce4a60de5 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -925,6 +925,26 @@ void tools::getTargetFeatures(const Driver &D, const 
llvm::Triple &Triple,
     break;
   }
 
+  // The mlfi option configures LFI subtarget features.
+  if (const Arg *A = Args.getLastArg(options::OPT_mlfi_EQ)) {
+    if (!Triple.isLFI()) {
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getSpelling() << Triple.getTriple();
+    } else {
+      for (StringRef Value : A->getValues()) {
+        StringRef Feature = llvm::StringSwitch<StringRef>(Value)
+                                .Case("no-loads", "+no-lfi-loads")
+                                .Case("no-stores", "+no-lfi-stores")
+                                .Default("");
+        if (Feature.empty())
+          D.Diag(diag::err_drv_unsupported_option_argument)
+              << A->getSpelling() << Value;
+        else
+          Features.push_back(Feature);
+      }
+    }
+  }
+
   for (auto Feature : unifyTargetFeatures(Features)) {
     CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature");
     CmdArgs.push_back(Feature.data());
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index ec009211ec6de..7450a472b8c07 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1541,6 +1541,17 @@ static void InitializePredefinedMacros(const TargetInfo 
&TI,
 
   // Get other target #defines.
   TI.getTargetDefines(LangOpts, Builder);
+
+  // Defines for the LFI subtarget specifying enabled subtarget features.
+  if (TI.getTriple().isLFI()) {
+    Builder.defineMacro("__LFI__");
+    for (StringRef Feature : TI.getTargetOpts().Features) {
+      if (Feature == "+no-lfi-loads")
+        Builder.defineMacro("__LFI_NO_LOADS__");
+      else if (Feature == "+no-lfi-stores")
+        Builder.defineMacro("__LFI_NO_STORES__");
+    }
+  }
 }
 
 static void InitializePGOProfileMacros(const CodeGenOptions &CodeGenOpts,
diff --git a/clang/test/Driver/lfi.c b/clang/test/Driver/lfi.c
new file mode 100644
index 0000000000000..78f35b162e6dc
--- /dev/null
+++ b/clang/test/Driver/lfi.c
@@ -0,0 +1,11 @@
+// Check that -mlfi= lowers LFI configuration to subtarget features.
+
+// RUN: %clang --target=aarch64_lfi-linux -mlfi=no-loads,no-stores -c %s -### 
2>&1 | FileCheck %s
+// CHECK-DAG: "-target-feature" "+no-lfi-loads"
+// CHECK-DAG: "-target-feature" "+no-lfi-stores"
+
+// RUN: not %clang --target=aarch64_lfi-linux -mlfi=unknown -c %s -### 2>&1 | 
FileCheck %s --check-prefix=BAD
+// BAD: unsupported argument 'unknown' to option '-mlfi='
+
+// RUN: not %clang --target=aarch64-linux -mlfi=no-loads -c %s -### 2>&1 | 
FileCheck %s --check-prefix=NOLFI
+// NOLFI: unsupported option '-mlfi=' for target
diff --git a/clang/test/Preprocessor/lfi.c b/clang/test/Preprocessor/lfi.c
new file mode 100644
index 0000000000000..42115054190c6
--- /dev/null
+++ b/clang/test/Preprocessor/lfi.c
@@ -0,0 +1,13 @@
+// Check LFI predefined macros.
+
+// RUN: %clang --target=aarch64_lfi-linux -E -dM %s -o - | FileCheck %s 
--implicit-check-not=__LFI_NO
+// RUN: %clang --target=aarch64_lfi-linux -mlfi=no-loads,no-stores -E -dM %s 
-o - | FileCheck %s --check-prefix=CONFIG
+// RUN: %clang --target=aarch64-linux -E -dM %s -o - | FileCheck %s 
--check-prefix=OFF --implicit-check-not=__LFI
+
+// CHECK: #define __LFI__ 1
+
+// CONFIG-DAG: #define __LFI__ 1
+// CONFIG-DAG: #define __LFI_NO_LOADS__ 1
+// CONFIG-DAG: #define __LFI_NO_STORES__ 1
+
+// OFF: #define __aarch64__ 1
diff --git a/llvm/docs/LFI.rst b/llvm/docs/LFI.rst
index b0f5e31d87ee9..712b7c88d509d 100644
--- a/llvm/docs/LFI.rst
+++ b/llvm/docs/LFI.rst
@@ -115,7 +115,8 @@ Example:
 Compiler Options
 ++++++++++++++++
 
-The LFI target has several configuration options, specified via ``-mattr=``:
+The LFI target has several configuration options. At the LLVM level they are
+specified as subtarget features via ``-mattr=``:
 
 * ``+no-lfi-loads``: Disable sandboxing for load instructions (stores-only 
mode).
 * ``+no-lfi-stores``: Disable sandboxing for store instructions.
@@ -128,6 +129,26 @@ read/write outside the sandbox region but may not transfer 
control outside
 (e.g., may not execute system calls directly). This is primarily useful in
 combination with some other form of memory sandboxing, such as Intel MPK.
 
+When driving the compiler with Clang, these same options are exposed through 
the
+``-mlfi=`` flag, which takes a comma-separated list of configuration
+knobs and lowers them to the corresponding subtarget features:
+
+* ``-mlfi=no-loads``.
+* ``-mlfi=no-stores``.
+
+Preprocessor Macros
++++++++++++++++++++
+
+When compiling for an LFI target, Clang predefines ``__LFI__``. The enabled LFI
+configuration knobs are additionally communicated to the preprocessor so that
+source code can adapt to the sandbox configuration. Each macro is defined only
+when the corresponding feature is active:
+
+* ``__LFI_NO_LOADS__``: defined when load sandboxing is disabled
+  (``-mlfi=no-loads`` / ``+no-lfi-loads``).
+* ``__LFI_NO_STORES__``: defined when store sandboxing is disabled
+  (``-mlfi=no-stores`` / ``+no-lfi-stores``).
+
 AArch64
 +++++++
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/204689
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to