llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb

@llvm/pr-subscribers-clang-codegen

Author: Jonas Devlieghere (JDevlieghere)

<details>
<summary>Changes</summary>

When targeting arm64e, vtable pointers are signed with a discriminator that 
incorporates the object's address (PointerAuthVTPtrAddressDiscrimination) and 
class type (PointerAuthVTPtrTypeDiscrimination).

I had to make a small change to clang, specifically in 
getPointerAuthDeclDiscriminator(). Previously, that was computing the 
discriminator based on getMangledName(). The latter returns the AsmLabelAttr, 
which for functions imported by lldb, is prefixed with `$__lldb_func`, causing 
a different discriminator to be generated.

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


5 Files Affected:

- (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+16-2) 
- (modified) 
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (+2) 
- (added) lldb/test/API/commands/expression/ptrauth-vtable/Makefile (+8) 
- (added) 
lldb/test/API/commands/expression/ptrauth-vtable/TestPtrAuthVTableExpressions.py
 (+48) 
- (added) lldb/test/API/commands/expression/ptrauth-vtable/main.cpp (+27) 


``````````diff
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp 
b/clang/lib/CodeGen/CGPointerAuth.cpp
index 84b5c86e69a57..a083d10e9dbec 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -11,6 +11,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "CGCXXABI.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/CodeGen/CodeGenABITypes.h"
@@ -62,8 +63,21 @@ CodeGenModule::getPointerAuthDeclDiscriminator(GlobalDecl 
Declaration) {
   uint16_t &EntityHash = PtrAuthDiscriminatorHashes[Declaration];
 
   if (EntityHash == 0) {
-    StringRef Name = getMangledName(Declaration);
-    EntityHash = llvm::getPointerAuthStableSipHash(Name);
+    const auto *ND = cast<NamedDecl>(Declaration.getDecl());
+    // If the declaration has an AsmLabelAttr (e.g., LLDB expression evaluator
+    // attaches one to map imported decls to debuggee symbols), the asm label
+    // would be used as the mangled name, producing a wrong discriminator.
+    // Compute the real C++ mangled name instead so the discriminator matches
+    // what the original translation unit used.
+    if (ND->hasAttr<AsmLabelAttr>()) {
+      SmallString<256> Buffer;
+      llvm::raw_svector_ostream Out(Buffer);
+      getCXXABI().getMangleContext().mangleCXXName(Declaration, Out);
+      EntityHash = llvm::getPointerAuthStableSipHash(Out.str());
+    } else {
+      StringRef Name = getMangledName(Declaration);
+      EntityHash = llvm::getPointerAuthStableSipHash(Name);
+    }
   }
 
   return EntityHash;
diff --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 0956406960b23..7955fffa26c5a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -729,6 +729,8 @@ static void SetPointerAuthOptionsForArm64e(LangOptions 
&lang_opts) {
   lang_opts.PointerAuthIntrinsics = true;
   lang_opts.PointerAuthCalls = true;
   lang_opts.PointerAuthReturns = true;
+  lang_opts.PointerAuthVTPtrAddressDiscrimination = true;
+  lang_opts.PointerAuthVTPtrTypeDiscrimination = true;
 }
 
 ClangExpressionParser::ClangExpressionParser(
diff --git a/lldb/test/API/commands/expression/ptrauth-vtable/Makefile 
b/lldb/test/API/commands/expression/ptrauth-vtable/Makefile
new file mode 100644
index 0000000000000..3c6bc2dd007e1
--- /dev/null
+++ b/lldb/test/API/commands/expression/ptrauth-vtable/Makefile
@@ -0,0 +1,8 @@
+CXX_SOURCES := main.cpp
+
+override ARCH := arm64e
+
+# We need an arm64e stblib.
+USE_SYSTEM_STDLIB := 1
+
+include Makefile.rules
diff --git 
a/lldb/test/API/commands/expression/ptrauth-vtable/TestPtrAuthVTableExpressions.py
 
b/lldb/test/API/commands/expression/ptrauth-vtable/TestPtrAuthVTableExpressions.py
new file mode 100644
index 0000000000000..07a806dd53355
--- /dev/null
+++ 
b/lldb/test/API/commands/expression/ptrauth-vtable/TestPtrAuthVTableExpressions.py
@@ -0,0 +1,48 @@
+"""
+VTable pointers are signed with a discriminator that incorporates the object's
+address (PointerAuthVTPtrAddressDiscrimination) and class type (
+PointerAuthVTPtrTypeDiscrimination).
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestPtrAuthVTableExpressions(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    @skipUnlessArm64eSupported
+    def test_virtual_call_on_debuggee_object(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp", False)
+        )
+
+        self.expect_expr("d.value()", result_type="int", result_value="20")
+        self.expect_expr("od.value()", result_type="int", result_value="30")
+
+    @skipUnlessArm64eSupported
+    def test_virtual_call_through_base_pointer(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp", False)
+        )
+
+        self.expect_expr(
+            "base_ptr->value()", result_type="int", result_value="20"
+        )
+
+    @skipUnlessArm64eSupported
+    def test_virtual_call_via_helper(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.cpp", False)
+        )
+
+        self.expect_expr("call_value(&d)", result_type="int", 
result_value="20")
+        self.expect_expr("call_value(&od)", result_type="int", 
result_value="30")
+        self.expect_expr(
+            "call_value(base_ptr)", result_type="int", result_value="20"
+        )
diff --git a/lldb/test/API/commands/expression/ptrauth-vtable/main.cpp 
b/lldb/test/API/commands/expression/ptrauth-vtable/main.cpp
new file mode 100644
index 0000000000000..d9dec9b9a6a41
--- /dev/null
+++ b/lldb/test/API/commands/expression/ptrauth-vtable/main.cpp
@@ -0,0 +1,27 @@
+#include <cstdio>
+
+class Base {
+public:
+  virtual int value() { return 10; }
+  virtual ~Base() = default;
+};
+
+class Derived : public Base {
+public:
+  int value() override { return 20; }
+};
+
+class OtherDerived : public Base {
+public:
+  int value() override { return 30; }
+};
+
+int call_value(Base *obj) { return obj->value(); }
+
+int main() {
+  Derived d;
+  OtherDerived od;
+  Base *base_ptr = &d;
+  printf("%d %d %d\n", d.value(), od.value(), base_ptr->value());
+  return 0; // break here
+}

``````````

</details>


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

Reply via email to