[lld] [LLD] Add flag to force PLT entries to have a BTI (PR #168365)

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 17 05:29:04 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld

Author: Gergely Bálint (bgergely0)

<details>
<summary>Changes</summary>

Added the `--force-bti-plt` flag to make sure the PacBtiPlts have a `BTI c` landing pad regardless of indirect calls inside the linked binary.
Post-link optimizations may require adding new thunks. Having this flag would simplify these optimizations by requiring less patching by tools.

Note that always adding a `BTI c` to PLT stubs is the default behaviour for GNU BFD.

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


5 Files Affected:

- (modified) lld/ELF/Arch/AArch64.cpp (+2-2) 
- (modified) lld/ELF/Config.h (+1) 
- (modified) lld/ELF/Driver.cpp (+1) 
- (modified) lld/ELF/Options.td (+2) 
- (modified) lld/test/ELF/aarch64-feature-bti.s (+7) 


``````````diff
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 2a97df4785ecb..a9702fde05b9b 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -1186,8 +1186,8 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
   // address may escape if referenced by a direct relocation. If relative
   // vtables are used then if the vtable is in a shared object the offsets will
   // be to the PLT entry. The condition is conservative.
-  bool hasBti = btiHeader &&
-                (sym.hasFlag(NEEDS_COPY) || sym.isInIplt || sym.thunkAccessed);
+  bool hasBti = btiHeader && (sym.hasFlag(NEEDS_COPY) || sym.isInIplt ||
+                              sym.thunkAccessed || ctx.arg.forceBtiPlt);
   if (hasBti) {
     memcpy(buf, btiData, sizeof(btiData));
     buf += sizeof(btiData);
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 8ec5a2c04e71c..b1060bf165ac8 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -330,6 +330,7 @@ struct Config {
   bool exportDynamic;
   bool fixCortexA53Errata843419;
   bool fixCortexA8;
+  bool forceBtiPlt = false;
   bool formatBinary = false;
   bool fortranCommon;
   bool gcSections;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 8647752be31fe..14c6b6f8a1dad 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1486,6 +1486,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
   ctx.arg.nmagic = args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
   ctx.arg.noinhibitExec = args.hasArg(OPT_noinhibit_exec);
   ctx.arg.nostdlib = args.hasArg(OPT_nostdlib);
+  ctx.arg.forceBtiPlt = args.hasArg(OPT_bti_plt);
   ctx.arg.oFormatBinary = isOutputFormatBinary(ctx, args);
   ctx.arg.omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
   ctx.arg.optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 75184de496448..2059e0c62d748 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -212,6 +212,8 @@ defm eh_frame_hdr: B<"eh-frame-hdr",
 
 def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">;
 
+def bti_plt: FF<"force-bti-plt">, HelpText<"Force all PLT entries to have BTI">;
+
 def enable_new_dtags: F<"enable-new-dtags">,
   HelpText<"Enable new dynamic tags (default)">;
 
diff --git a/lld/test/ELF/aarch64-feature-bti.s b/lld/test/ELF/aarch64-feature-bti.s
index 8d7c1f2826c17..191e3710054f8 100644
--- a/lld/test/ELF/aarch64-feature-bti.s
+++ b/lld/test/ELF/aarch64-feature-bti.s
@@ -262,6 +262,13 @@
 # REPORT-ERR: error: unknown -z bti-report= value: u{{$}}
 # REPORT-EMPTY:
 
+## Force all PLT entries to start with BTI with the force-bti-plt command line option.
+# RUN: ld.lld %t.o %t2.o -z force-bti --force-bti-plt %t.so -o %tforcebtiplt.exe
+# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+bti --no-show-raw-insn %tforcebtiplt.exe | FileCheck --check-prefix=FORCE-BTI %s
+
+# FORCE-BTI: 00000000002103a0 <func2 at plt>:
+# FORCE-BTI-NEXT:   2103a0: bti c
+
 .section ".note.gnu.property", "a"
 .long 4
 .long 0x10

``````````

</details>


https://github.com/llvm/llvm-project/pull/168365


More information about the llvm-commits mailing list