Author: Jonas Devlieghere
Date: 2026-03-20T16:58:30-05:00
New Revision: 2b78c71cb5aaa794562d263ebd7b16fa707abc36

URL: 
https://github.com/llvm/llvm-project/commit/2b78c71cb5aaa794562d263ebd7b16fa707abc36
DIFF: 
https://github.com/llvm/llvm-project/commit/2b78c71cb5aaa794562d263ebd7b16fa707abc36.diff

LOG: [lldb] Support -fptrauth-indirect-gotos in the expression evaluator 
(#187562)

When targeting arm64e, we enable `-fptrauth-indirect-gotos` by default,
which signs label addresses and authenticates indirect branches. Add
support (and a test) for this in the LLDB expression evaluator.

Added: 
    

Modified: 
    lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
    lldb/test/API/commands/expression/ptrauth/TestPtrAuthExpressions.py
    lldb/test/API/commands/expression/ptrauth/main.c

Removed: 
    


################################################################################
diff  --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 32d48d2219ebe..f46cb32865f3b 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -730,6 +730,7 @@ static void SetPointerAuthOptionsForArm64e(LangOptions 
&lang_opts) {
   lang_opts.PointerAuthCalls = true;
   lang_opts.PointerAuthReturns = true;
   lang_opts.PointerAuthAuthTraps = true;
+  lang_opts.PointerAuthIndirectGotos = true;
 }
 
 ClangExpressionParser::ClangExpressionParser(

diff  --git 
a/lldb/test/API/commands/expression/ptrauth/TestPtrAuthExpressions.py 
b/lldb/test/API/commands/expression/ptrauth/TestPtrAuthExpressions.py
index 2f9b3096614a5..4d0d4026cc0c4 100644
--- a/lldb/test/API/commands/expression/ptrauth/TestPtrAuthExpressions.py
+++ b/lldb/test/API/commands/expression/ptrauth/TestPtrAuthExpressions.py
@@ -73,3 +73,46 @@ def test_debuggee_signed_pointer(self):
             result_type="int",
             result_value="30",
         )
+
+    @skipUnlessArm64eSupported
+    def test_indirect_goto(self):
+        """Test that computed gotos (GCC labels-as-values) work in the
+        expression evaluator on arm64e, where -fptrauth-indirect-gotos signs
+        label addresses and the indirect branch authenticates them."""
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.c", False)
+        )
+
+        # Call a debuggee function that uses a computed-goto dispatch table.
+        self.expect_expr(
+            "indirect_goto_dispatch(0)",
+            result_type="int",
+            result_value="10",
+        )
+        self.expect_expr(
+            "indirect_goto_dispatch(1)",
+            result_type="int",
+            result_value="20",
+        )
+        self.expect_expr(
+            "indirect_goto_dispatch(2)",
+            result_type="int",
+            result_value="30",
+        )
+
+        # Evaluate a computed goto directly in a user expression.
+        # Use individual variables (not an array) so that the label addresses
+        # are signed inline with pacia/braa instructions, avoiding @AUTH
+        # relocations in global constant tables that RuntimeDyld cannot handle.
+        self.expect_expr(
+            "({ int result; void *t0 = &&L0, *t1 = &&L1, *t2 = &&L2; "
+            "goto *t1; "
+            "L0: result = 100; goto Lend; "
+            "L1: result = 200; goto Lend; "
+            "L2: result = 300; goto Lend; "
+            "Lend: result; })",
+            result_type="int",
+            result_value="200",
+        )

diff  --git a/lldb/test/API/commands/expression/ptrauth/main.c 
b/lldb/test/API/commands/expression/ptrauth/main.c
index 143d8f324e0f4..893a89a6f07b9 100644
--- a/lldb/test/API/commands/expression/ptrauth/main.c
+++ b/lldb/test/API/commands/expression/ptrauth/main.c
@@ -12,6 +12,21 @@ int caller(int (*fn)(int, int), int a, int b) { return fn(a, 
b); }
 // process-specific, so this catches inter-process key mismatches.
 int (*__ptrauth(1, 0, 0) global_fp)(int, int) = &add;
 
+// A helper that uses computed gotos (labels-as-values) to implement a
+// simple dispatch table to test -fptrauth-indirect-gotos support.
+int indirect_goto_dispatch(int idx) {
+  static void *table[] = {&&case0, &&case1, &&case2};
+  if (idx < 0 || idx > 2)
+    return -1;
+  goto *table[idx];
+case0:
+  return 10;
+case1:
+  return 20;
+case2:
+  return 30;
+}
+
 int main(void) {
   printf("%d %d\n", add(2, 3), mul(4, 5));
   return 0; // break here


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

Reply via email to