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
