https://github.com/zyedidia updated 
https://github.com/llvm/llvm-project/pull/167061

>From 9ca2065bc60b13f54504251dbb32e3b0784feb85 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <[email protected]>
Date: Mon, 20 Oct 2025 13:19:32 -0700
Subject: [PATCH 1/7] [LFI] Add aarch64_lfi subtarget

---
 llvm/include/llvm/TargetParser/Triple.h | 7 +++++++
 llvm/lib/TargetParser/Triple.cpp        | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/llvm/include/llvm/TargetParser/Triple.h 
b/llvm/include/llvm/TargetParser/Triple.h
index 0e82dd212f34d..91f095091308d 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -153,6 +153,7 @@ class Triple {
 
     AArch64SubArch_arm64e,
     AArch64SubArch_arm64ec,
+    AArch64SubArch_lfi,
 
     KalimbaSubArch_v3,
     KalimbaSubArch_v4,
@@ -924,6 +925,12 @@ class Triple {
     return getArch() == Triple::arm || getArch() == Triple::armeb;
   }
 
+  /// Tests whether the target is LFI.
+  bool isLFI() const {
+    return getArch() == Triple::aarch64 &&
+           getSubArch() == Triple::AArch64SubArch_lfi;
+  }
+
   /// Tests whether the target supports the EHABI exception
   /// handling standard.
   bool isTargetEHABICompatible() const {
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 11ba9ee32f66a..2577b15b19992 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -116,6 +116,8 @@ StringRef Triple::getArchName(ArchType Kind, SubArchType 
SubArch) {
       return "arm64ec";
     if (SubArch == AArch64SubArch_arm64e)
       return "arm64e";
+    if (SubArch == AArch64SubArch_lfi)
+      return "aarch64_lfi";
     break;
   case Triple::spirv:
     switch (SubArch) {
@@ -594,6 +596,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
           .Case("aarch64", Triple::aarch64)
           .Case("aarch64_be", Triple::aarch64_be)
           .Case("aarch64_32", Triple::aarch64_32)
+          .Case("aarch64_lfi", Triple::aarch64)
           .Case("arc", Triple::arc)
           .Case("arm64", Triple::aarch64)
           .Case("arm64_32", Triple::aarch64_32)
@@ -832,6 +835,9 @@ static Triple::SubArchType parseSubArch(StringRef 
SubArchName) {
   if (SubArchName == "arm64ec")
     return Triple::AArch64SubArch_arm64ec;
 
+  if (SubArchName == "aarch64_lfi")
+    return Triple::AArch64SubArch_lfi;
+
   if (SubArchName.starts_with("spirv"))
     return StringSwitch<Triple::SubArchType>(SubArchName)
         .EndsWith("v1.0", Triple::SPIRVSubArch_v10)

>From 2b46bc05742d63b918593ac445979b752502fb93 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <[email protected]>
Date: Mon, 20 Oct 2025 13:48:50 -0700
Subject: [PATCH 2/7] [LFI] Reserve LFI registers

---
 llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp | 11 +++++++++++
 llvm/lib/Target/AArch64/AArch64Subtarget.h      |  1 +
 2 files changed, 12 insertions(+)

diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp 
b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index a5048b9c9e61d..7b72c052fba36 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -461,6 +461,17 @@ AArch64RegisterInfo::getStrictlyReservedRegs(const 
MachineFunction &MF) const {
       markSuperRegs(Reserved, i);
   }
 
+  if (MF.getSubtarget<AArch64Subtarget>().isLFI()) {
+    markSuperRegs(Reserved, AArch64::W28);
+    markSuperRegs(Reserved, AArch64::W27);
+    markSuperRegs(Reserved, AArch64::W26);
+    markSuperRegs(Reserved, AArch64::W25);
+    if (!MF.getProperties().hasNoVRegs()) {
+      markSuperRegs(Reserved, AArch64::LR);
+      markSuperRegs(Reserved, AArch64::W30);
+    }
+  }
+
   for (size_t i = 0; i < AArch64::GPR32commonRegClass.getNumRegs(); ++i) {
     if (MF.getSubtarget<AArch64Subtarget>().isXRegisterReserved(i))
       markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h 
b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 8974965c41fe3..dbab11a5628af 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -293,6 +293,7 @@ class AArch64Subtarget final : public 
AArch64GenSubtargetInfo {
   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
   bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
   bool isWindowsArm64EC() const { return TargetTriple.isWindowsArm64EC(); }
+  bool isLFI() const { return TargetTriple.isLFI(); }
 
   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }

>From 7a771ec23d79ab79a9efa080151cc9b3a94fa425 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <[email protected]>
Date: Mon, 20 Oct 2025 13:54:17 -0700
Subject: [PATCH 3/7] [LFI] Add Clang driver toolchain for LFI

---
 clang/lib/Basic/Targets/AArch64.cpp      |  3 ++
 clang/lib/Driver/CMakeLists.txt          |  1 +
 clang/lib/Driver/Driver.cpp              |  3 ++
 clang/lib/Driver/ToolChains/LFILinux.cpp | 29 ++++++++++++++++++++
 clang/lib/Driver/ToolChains/LFILinux.h   | 35 ++++++++++++++++++++++++
 5 files changed, 71 insertions(+)
 create mode 100644 clang/lib/Driver/ToolChains/LFILinux.cpp
 create mode 100644 clang/lib/Driver/ToolChains/LFILinux.h

diff --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index a97e93470987c..0cc4db1e637ce 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -412,6 +412,9 @@ 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/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 7c4f70b966c48..9060b63d75d6e 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -65,6 +65,7 @@ add_clang_library(clangDriver
   ToolChains/Hexagon.cpp
   ToolChains/HLSL.cpp
   ToolChains/Hurd.cpp
+  ToolChains/LFILinux.cpp
   ToolChains/Linux.cpp
   ToolChains/Managarm.cpp
   ToolChains/MipsLinux.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a0b82cec9a372..e0323cf631fca 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -29,6 +29,7 @@
 #include "ToolChains/Haiku.h"
 #include "ToolChains/Hexagon.h"
 #include "ToolChains/Hurd.h"
+#include "ToolChains/LFILinux.h"
 #include "ToolChains/Lanai.h"
 #include "ToolChains/Linux.h"
 #include "ToolChains/MSP430.h"
@@ -6864,6 +6865,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
         TC = std::make_unique<toolchains::OHOS>(*this, Target, Args);
       else if (Target.isWALI())
         TC = std::make_unique<toolchains::WebAssembly>(*this, Target, Args);
+      else if (Target.isLFI())
+        TC = std::make_unique<toolchains::LFILinuxToolChain>(*this, Target, 
Args);
       else
         TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
       break;
diff --git a/clang/lib/Driver/ToolChains/LFILinux.cpp 
b/clang/lib/Driver/ToolChains/LFILinux.cpp
new file mode 100644
index 0000000000000..7ab2372756af9
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/LFILinux.cpp
@@ -0,0 +1,29 @@
+//===-- LFILinux.cpp - LFI ToolChain Implementations ------------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LFILinux.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+
+using namespace clang::driver::toolchains;
+using namespace llvm::opt;
+
+void LFILinuxToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
+                                            ArgStringList &CmdArgs) const {
+  switch (GetCXXStdlibType(Args)) {
+  case ToolChain::CST_Libcxx:
+    CmdArgs.push_back("-lc++");
+    if (Args.hasArg(options::OPT_fexperimental_library))
+      CmdArgs.push_back("-lc++experimental");
+    CmdArgs.push_back("-lc++abi");
+    break;
+  case ToolChain::CST_Libstdcxx:
+    CmdArgs.push_back("-lstdc++");
+    break;
+  }
+}
diff --git a/clang/lib/Driver/ToolChains/LFILinux.h 
b/clang/lib/Driver/ToolChains/LFILinux.h
new file mode 100644
index 0000000000000..e85f74803c1ce
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/LFILinux.h
@@ -0,0 +1,35 @@
+//===--- LFILinux.h - LFI ToolChain Implementations -------------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LFI_LINUX_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LFI_LINUX_H
+
+#include "Linux.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY LFILinuxToolChain : public Linux {
+public:
+  LFILinuxToolChain(const Driver &D, const llvm::Triple &Triple,
+                    const llvm::opt::ArgList &Args)
+      : Linux(D, Triple, Args) {
+    ExtraOpts.push_back("-z");
+    ExtraOpts.push_back("separate-code");
+  }
+
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LFI_LINUX_H

>From c07a2ce127b67ec379e4c7cf0da61da4aed58ec4 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <[email protected]>
Date: Mon, 20 Oct 2025 13:58:34 -0700
Subject: [PATCH 4/7] [LFI] Update compiler-rt cmake for LFI

---
 compiler-rt/cmake/builtin-config-ix.cmake | 2 +-
 compiler-rt/lib/builtins/CMakeLists.txt   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler-rt/cmake/builtin-config-ix.cmake 
b/compiler-rt/cmake/builtin-config-ix.cmake
index eaff8135cff45..3298fe96cd236 100644
--- a/compiler-rt/cmake/builtin-config-ix.cmake
+++ b/compiler-rt/cmake/builtin-config-ix.cmake
@@ -78,7 +78,7 @@ else()
 endif()
 
 set(AMDGPU amdgcn)
-set(ARM64 aarch64 arm64ec)
+set(ARM64 aarch64 arm64ec aarch64_lfi)
 set(ARM32 arm armhf armv4t armv5te armv6 armv6m armv7m armv7em armv7 armv7s 
armv7k armv8m.base armv8m.main armv8.1m.main)
 set(AVR avr)
 set(HEXAGON hexagon)
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt 
b/compiler-rt/lib/builtins/CMakeLists.txt
index 6c226aa7d2d48..29c5a08b828cb 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -692,6 +692,7 @@ set(arm64_SOURCES ${aarch64_SOURCES})
 set(arm64e_SOURCES ${aarch64_SOURCES})
 set(arm64_32_SOURCES ${aarch64_SOURCES})
 set(arm64ec_SOURCES ${aarch64_SOURCES})
+set(aarch64_lfi_SOURCES ${aarch64_SOURCES})
 
 # macho_embedded archs
 set(armv6m_SOURCES ${thumb1_SOURCES})

>From 60de70003eb4e2149c98e592293c1c218549d2c7 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <[email protected]>
Date: Fri, 7 Nov 2025 16:18:27 -0800
Subject: [PATCH 5/7] [LFI] Add LFI.rst documentation

---
 llvm/docs/LFI.rst | 387 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 387 insertions(+)
 create mode 100644 llvm/docs/LFI.rst

diff --git a/llvm/docs/LFI.rst b/llvm/docs/LFI.rst
new file mode 100644
index 0000000000000..22af7b1174e86
--- /dev/null
+++ b/llvm/docs/LFI.rst
@@ -0,0 +1,387 @@
+=========================================
+Lightweight Fault Isolation (LFI) in LLVM
+=========================================
+
+.. contents::
+   :local:
+
+Introduction
+++++++++++++
+
+Lightweight Fault Isolation (LFI) is a compiler-based sandboxing technology for
+native code. Like WebAssembly and Native Client, LFI isolates sandboxed code 
in-process
+(i.e., in the same address space as a host application).
+
+LFI is designed from the ground up to sandbox existing code, such as C/C++
+libraries (including assembly code) and device drivers.
+
+LFI aims for the following goals:
+
+* Compatibility: LFI can be used to sandbox nearly all existing C/C++/assembly
+  libraries unmodified (they just need to be recompiled). Sandboxed libraries
+  work with existing system call interfaces, and are compatible with existing
+  development tools such as profilers, debuggers, and sanitizers.
+* Performance: LFI aims for minimal overhead vs. unsandboxed code.
+* Security: The LFI runtime and compiler elements aim to be simple and
+  verifiable when possible.
+* Usability: LFI aims to make it easy as possible to used retrofit sandboxing,
+  i.e., to migrate from unsandboxed to sandboxed libraries with minimal effort.
+
+When building a program for the LFI target the compiler is designed to ensure
+that the program will only be able to access memory within a limited region of
+the virtual address space, starting from where the program is loaded (the
+current design sets this region to a size of 4GiB of virtual memory). Programs
+built for the LFI target are restricted to using a subset of the instruction
+set, designed so that the programs can be soundly confined to their sandbox
+region. LFI programs must run inside of an "emulator" (usually called the LFI
+runtime), responsible for initializing the sandbox region, loading the program,
+and servicing system call requests, or other forms of runtime calls.
+
+LFI uses an architecture-specific sandboxing scheme based on the general
+technique of Software-Based Fault Isolation (SFI). Initial support for LFI in
+LLVM is focused on the AArch64 platform, with x86-64 support planned for the
+future. The initial version of LFI for AArch64 is designed to support the
+Armv8.1 AArch64 architecture.
+
+See `https://github.com/lfi-project <https://github.com/lfi-project/>`__ for
+details about the LFI project and additional software needed to run LFI
+programs.
+
+Compiler Requirements
++++++++++++++++++++++
+
+When building for the ``aarch64_lfi`` target, the compiler must restrict use of
+the instruction set to a subset of instructions, which are known to be safe
+from a sandboxing perspective. To do this, we apply a set of simple rewrites at
+the assembly language level to transform standard native AArch64 assembly into
+LFI-compatible AArch64 assembly.
+
+These rewrites (also called "expansions") are applied at the very end of the
+LLVM compilation pipeline (during the assembler step). This allows the rewrites
+to be applied to hand-written assembly, including inline assembly.
+
+Compiler Options
+================
+
+The LFI target has several configuration options.
+
+* ``+lfi-stores``: create a "stores-only" sandbox, where rewrites are not 
applied to loads.
+* ``+lfi-jumps``: create a "jumps-only" sandbox, where rewrites are not 
applied to loads/stores.
+
+Reserved Registers
+==================
+
+The LFI target uses a custom ABI that reserves additional registers for the
+platform. The registers are listed below, along with the security invariant
+that must be maintained.
+
+* ``x27``: always holds the sandbox base address.
+* ``x28``: always holds an address within the sandbox.
+* ``sp``: always holds an address within the sandbox.
+* ``x30``: always holds an address within the sandbox.
+* ``x26``: scratch register.
+* ``x25``: points to a thread-local virtual register file for storing runtime 
context information.
+
+Linker Support
+==============
+
+In the initial version, LFI only supports static linking, and only supports
+creating ``static-pie`` binaries. There is nothing that fundamentally precludes
+support for dynamic linking on the LFI target, but such support would require
+that the code generated by the linker for PLT entries be slightly modified in
+order to conform to the LFI architecture subset.
+
+Assembly Rewrites
+=================
+
+Terminology
+~~~~~~~~~~~
+
+In the following assembly rewrites, some shorthand is used.
+
+* ``xN`` or ``wN``: refers to any general-purpose non-reserved register.
+* ``{a,b,c}``: matches any of ``a``, ``b``, or ``c``.
+* ``LDSTr``: a load/store instruction that supports register-register 
addressing modes, with one source/destination register.
+* ``LDSTx``: a load/store instruction not matched by ``LDSTr``.
+
+Control flow
+~~~~~~~~~~~~
+
+Indirect branches get rewritten to branch through register ``x28``, which must
+always contain an address within the sandbox. An ``add`` is used to safely load
+``x28`` with the destination address. Since ``ret`` uses ``x30`` by default,
+which already must contain an address within the sandbox, it does not require
+any rewrite.
+
++--------------------+---------------------------+
+|      Original      |         Rewritten         |
++--------------------+---------------------------+
+| .. code-block::    | .. code-block::           |
+|                    |                           |
+|    {br,blr,ret} xN |    add x28, x27, wN, uxtw |
+|                    |    {br,blr,ret} x28       |
+|                    |                           |
++--------------------+---------------------------+
+| .. code-block::    | .. code-block::           |
+|                    |                           |
+|    ret             |    ret                    |
+|                    |                           |
++--------------------+---------------------------+
+
+Memory accesses
+~~~~~~~~~~~~~~~
+
+Memory accesses are rewritten to use the ``[x27, wM, uxtw]`` addressing mode if
+it is available, which is automatically safe. Otherwise, rewrites fall back to
+using ``x28`` along with an instruction to safely load it with the target
+address.
+
++---------------------------------+-------------------------------+
+|            Original             |           Rewritten           |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTr xN, [xM]               |    LDSTr xN, [x27, wM, uxtw]  |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTr xN, [xM, #I]           |    add x28, x27, wM, uxtw     |
+|                                 |    LDSTr xN, [x28, #I]        |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTr xN, [xM, #I]!          |    add xM, xM, #I             |
+|                                 |    LDSTr xN, [x27, wM, uxtw]  |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTr xN, [xM], #I           |    LDSTr xN, [x27, wM, uxtw]  |
+|                                 |    add xM, xM, #I             |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTr xN, [xM1, xM2]         |    add x26, xM1, xM2          |
+|                                 |    LDSTr xN, [x27, w26, uxtw] |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTr xN, [xM1, xM2, MOD #I] |    add x26, xM1, xM2, MOD #I  |
+|                                 |    LDSTr xN, [x27, w26, uxtw] |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTx ..., [xM]              |    add x28, x27, wM, uxtw     |
+|                                 |    LDSTx ..., [x28]           |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTx ..., [xM, #I]          |    add x28, x27, wM, uxtw     |
+|                                 |    LDSTx ..., [x28, #I]       |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTx ..., [xM, #I]!         |    add x28, x27, wM, uxtw     |
+|                                 |    LDSTx ..., [x28, #I]       |
+|                                 |    add xM, xM, #I             |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTx ..., [xM], #I          |    add x28, x27, wM, uxtw     |
+|                                 |    LDSTx ..., [x28]           |
+|                                 |    add xM, xM, #I             |
+|                                 |                               |
++---------------------------------+-------------------------------+
+| .. code-block::                 | .. code-block::               |
+|                                 |                               |
+|    LDSTx ..., [xM1], xM2        |    add x28, x27, wM1, uxtw    |
+|                                 |    LDSTx ..., [x28]           |
+|                                 |    add xM1, xM1, xM2          |
+|                                 |                               |
++---------------------------------+-------------------------------+
+
+Stack pointer modification
+~~~~~~~~~~~~~~~~~~
+
+When the stack pointer is modified, we write the modified value to a temporary,
+before loading it back into ``sp`` with a safe ``add``.
+
++------------------------------+-------------------------------+
+|           Original           |           Rewritten           |
++------------------------------+-------------------------------+
+| .. code-block::              | .. code-block::               |
+|                              |                               |
+|    mov sp, xN                |    add sp, x27, wN, uxtw      |
+|                              |                               |
++------------------------------+-------------------------------+
+| .. code-block::              | .. code-block::               |
+|                              |                               |
+|    {add,sub} sp, sp, {#I,xN} |    {add,sub} x26, sp, {#I,xN} |
+|                              |    add sp, x27, w26, uxtw     |
+|                              |                               |
++------------------------------+-------------------------------+
+
+Link register modification
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When the link register is modified, we write the modified value to a
+temporary, before loading it back into ``x30`` with a safe ``add``.
+
++-----------------------+----------------------------+
+|       Original        |         Rewritten          |
++-----------------------+----------------------------+
+| .. code-block::       | .. code-block::            |
+|                       |                            |
+|    ldr x30, [...]     |    ldr x26, [...]          |
+|                       |    add x30, x27, w26, uxtw |
+|                       |                            |
++-----------------------+----------------------------+
+| .. code-block::       | .. code-block::            |
+|                       |                            |
+|    ldp xN, x30, [...] |    ldp xN, x26, [...]      |
+|                       |    add x30, x27, w26, uxtw |
+|                       |                            |
++-----------------------+----------------------------+
+| .. code-block::       | .. code-block::            |
+|                       |                            |
+|    ldp x30, xN, [...] |    ldp x26, xN, [...]      |
+|                       |    add x30, x27, w26, uxtw |
+|                       |                            |
++-----------------------+----------------------------+
+
+System instructions
+~~~~~~~~~~~~~~~~~~~
+
+System calls are rewritten into a sequence that loads the address of the first
+runtime call entrypoint and jumps to it. The runtime call entrypoint table is
+stored at the start of the sandbox, so it can be referenced by ``x27``. The
+rewrite also saves and restores the link register, since it is used for
+branching into the runtime.
+
++-----------------+----------------------------+
+|    Original     |         Rewritten          |
++-----------------+----------------------------+
+| .. code-block:: | .. code-block::            |
+|                 |                            |
+|    svc #0       |    mov w26, w30            |
+|                 |    ldr x30, [x27]          |
+|                 |    blr x30                 |
+|                 |    add x30, x27, w26, uxtw |
+|                 |                            |
++-----------------+----------------------------+
+
+Thread-local storage
+~~~~~~~~~~~~~~~~~~~~
+
+TLS accesses are rewritten into accesses offset from ``x25``, which is a
+reserved register that points to a virtual register file, with a location for
+storing the sandbox's thread pointer. ``TP`` is the offset into that virtual
+register file where the thread pointer is stored.
+
++----------------------+-----------------------+
+|       Original       |       Rewritten       |
++----------------------+-----------------------+
+| .. code-block::      | .. code-block::       |
+|                      |                       |
+|    mrs xN, tpidr_el0 |    ldr xN, [x25, #TP] |
+|                      |                       |
++----------------------+-----------------------+
+| .. code-block::      | .. code-block::       |
+|                      |                       |
+|    mrs tpidr_el0, xN |    str xN, [x25, #TP] |
+|                      |                       |
++----------------------+-----------------------+
+
+Optimizations
+=============
+
+Basic guard elimination
+~~~~~~~~~~~~~~~~~~~~~~~
+
+If a register is guarded multiple times in the same basic block without any
+modifications to it during the intervening instructions, then subsequent guards
+can be removed.
+
++---------------------------+---------------------------+
+|         Original          |         Rewritten         |
++---------------------------+---------------------------+
+| .. code-block::           | .. code-block::           |
+|                           |                           |
+|    add x28, x27, wN, uxtw |    add x28, x27, wN, uxtw |
+|    ldur xN, [x28]         |    ldur xN, [x28]         |
+|    add x28, x27, wN, uxtw |    ldur xN, [x28, #8]     |
+|    ldur xN, [x28, #8]     |    ldur xN, [x28, #16]    |
+|    add x28, x27, wN, uxtw |                           |
+|    ldur xN, [x28, #16]    |                           |
+|                           |                           |
++---------------------------+---------------------------+
+
+Stack guard elimination
+~~~~~~~~~~~~~~~~~~~~~~~
+
+**Note**: this optimization has not been implemented.
+
+If the stack pointer is modified by adding/subtracting a small immediate, and
+then later used to perform a memory access without any intervening jumps, then
+the guard on the stack pointer modification can be removed. This is because the
+load/store is guaranteed to trap if the stack pointer has been moved outside of
+the sandbox region.
+
++---------------------------+---------------------------+
+|         Original          |         Rewritten         |
++---------------------------+---------------------------+
+| .. code-block::           | .. code-block::           |
+|                           |                           |
+|    add x26, sp, #8        |    add sp, sp, #8         |
+|    add sp, x27, w26, uxtw |    ... (same basic block) |
+|    ... (same basic block) |    ldr xN, [sp]           |
+|    ldr xN, [sp]           |                           |
+|                           |                           |
++---------------------------+---------------------------+
+
+Guard hoisting
+~~~~~~~~~~~~~~
+
+**Note**: this optimization has not been implemented.
+
+In certain cases, guards may be hoisted outside of loops.
+
++-----------------------+-------------------------------+
+|       Original        |           Rewritten           |
++-----------------------+-------------------------------+
+| .. code-block::       | .. code-block::               |
+|                       |                               |
+|        mov w8, #10    |        mov w8, #10            |
+|        mov w9, #0     |        mov w9, #0             |
+|    .loop:             |        add x28, x27, wM, uxtw |
+|        add w9, w9, #1 |    .loop:                     |
+|        ldr xN, [xM]   |        add w9, w9, #1         |
+|        cmp w9, w8     |        ldr xN, [x28]          |
+|        b.lt .loop     |        cmp w9, w8             |
+|    .end:              |        b.lt .loop             |
+|                       |    .end:                      |
+|                       |                               |
++-----------------------+-------------------------------+
+
+References
+++++++++++
+
+For more information, please see the following resources:
+
+* `LFI project page <https://github.com/lfi-project/>`__
+* `LFI RFC 
<https://discourse.llvm.org/t/rfc-lightweight-fault-isolation-lfi-efficient-native-code-sandboxing-upstream-lfi-target-and-compiler-changes/88380>`__
+* `LFI paper <https://zyedidia.github.io/papers/lfi_asplos24.pdf>`__
+
+Contact info:
+
+* Zachary Yedidia - [email protected]
+* Tal Garfinkel - [email protected]
+* Sharjeel Khan - [email protected]

>From cb99f0a8517ffa2e369a8fab9477eb248db5715c Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <[email protected]>
Date: Fri, 7 Nov 2025 16:38:31 -0800
Subject: [PATCH 6/7] [LFI] Apply clang-format to Driver.cpp

---
 clang/lib/Driver/Driver.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index e0323cf631fca..ba0aae9ebba14 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -6866,7 +6866,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
       else if (Target.isWALI())
         TC = std::make_unique<toolchains::WebAssembly>(*this, Target, Args);
       else if (Target.isLFI())
-        TC = std::make_unique<toolchains::LFILinuxToolChain>(*this, Target, 
Args);
+        TC = std::make_unique<toolchains::LFILinuxToolChain>(*this, Target,
+                                                             Args);
       else
         TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
       break;

>From facd934e3a08c03884c2c4fe4bad47f6e928016e Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <[email protected]>
Date: Mon, 10 Nov 2025 11:46:11 -0800
Subject: [PATCH 7/7] [LFI] Fix title underline in docs/LFI.rst

---
 llvm/docs/LFI.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/LFI.rst b/llvm/docs/LFI.rst
index 22af7b1174e86..613a8a80b6984 100644
--- a/llvm/docs/LFI.rst
+++ b/llvm/docs/LFI.rst
@@ -209,7 +209,7 @@ address.
 +---------------------------------+-------------------------------+
 
 Stack pointer modification
-~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 When the stack pointer is modified, we write the modified value to a temporary,
 before loading it back into ``sp`` with a safe ``add``.

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

Reply via email to