forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 348
🍒[lldb][Expression] Cherry-pick ABI-tagged structor lookup infrastructure to 21.x #11350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(cherry picked from commit 672f82a)
llvm#155483) Part of llvm#149827 Allows us to use the mangling substitution facilities in CPlusPlusLanguage but also SymbolFileDWARF. Added tests now that they're "public". (cherry picked from commit 9dd38b0)
…een declaration and definition (llvm#154137) This patch is motivated by llvm#149827, where we plan on using mangled names on structor declarations to find the exact structor definition that LLDB's expression evaluator should call. So far LLVM expects the declaration and definition linkage names to be identical (or the declaration to just not have a linkage name). But we plan on attaching the GCC-style "unified" mangled name to declarations, which will be different to linkage name on the definition. This patch relaxes this restriction. (cherry picked from commit c6286b3)
…gic (llvm#156642) This patch moves the `frame_lang` logic to just the logging (because that's what it was always used for anyway). The callsites decide whether to fall back on to the frame language or not when running the expression. (cherry picked from commit 25a3045)
…for LLDB JIT expressions (llvm#155485) Part of llvm#149827 This patch adds special handling for `AsmLabel`s created by LLDB. LLDB uses `AsmLabel`s to encode information about a function declaration to make it easier to locate function symbols when JITing C++ expressions. For constructors/destructors LLDB doesn't know at the time of creating the `AsmLabelAttr` which structor variant the expression evaluator will need to call (this is decided when compiling the expression). So we make the Clang mangler inject this information into our custom label when we're JITting the expression. (cherry picked from commit db8cad0)
…clarations (llvm#154142) Depends on llvm#154137 This patch is motivated by llvm#149827, where we plan on using mangled names on structor declarations to find the exact structor definition that LLDB's expression evaluator should call. Given a `DW_TAG_subprogram` for a function declaration, the most convenient way for a debugger to find the corresponding definition is to use the `DW_AT_linkage_name` (i.e., the mangled name). However, we currently can't do that for constructors/destructors because Clang doesn't attach linkage names to them. This is because, depending on ABI, there can be multiple definitions for a single constructor/destructor declaration. The way GCC works around this is by producing a `C4`/`D4` "unified" mangling for structor declarations (see [godbolt](https://godbolt.org/z/Wds6cja9K)). GDB uses this to locate the relevant definitions. This patch aligns Clang with GCC's DWARF output and allows us to implement the same lookup scheme in LLDB. (cherry picked from commit 06d202b)
@swift-ci test |
llvm#149827) Depends on * llvm#148877 * llvm#155483 * llvm#155485 * llvm#154137 * llvm#154142 This patch is an implementation of [this discussion](https://discourse.llvm.org/t/rfc-lldb-handling-abi-tagged-constructors-destructors-in-expression-evaluator/82816/7) about handling ABI-tagged structors during expression evaluation. **Motivation** LLDB encodes the mangled name of a `DW_TAG_subprogram` into `AsmLabel`s on function and method Clang AST nodes. This means that when calls to these functions get lowered into IR (when running JITted expressions), the address resolver can locate the appropriate symbol by mangled name (and it is guaranteed to find the symbol because we got the mangled name from debug-info, instead of letting Clang mangle it based on AST structure). However, we don't do this for `CXXConstructorDecl`s/`CXXDestructorDecl`s because these structor declarations in DWARF don't have a linkage name. This is because there can be multiple variants of a structor, each with a distinct mangling in the Itanium ABI. Each structor variant has its own definition `DW_TAG_subprogram`. So LLDB doesn't know which mangled name to put into the `AsmLabel`. Currently this means using ABI-tagged structors in LLDB expressions won't work (see [this RFC](https://discourse.llvm.org/t/rfc-lldb-handling-abi-tagged-constructors-destructors-in-expression-evaluator/82816) for concrete examples). **Proposed Solution** The `FunctionCallLabel` encoding that we put into `AsmLabel`s already supports stuffing more info about a DIE into it. So this patch extends the `FunctionCallLabel` to contain an optional discriminator (a sequence of bytes) which the `SymbolFileDWARF` plugin interprets as the constructor/destructor variant of that DIE. So when searching for the definition DIE, LLDB will include the structor variant in its heuristic for determining a match. There's a few subtleties here: 1. At the point at which LLDB first constructs the label, it has no way of knowing (just by looking at the debug-info declaration), which structor variant the expression evaluator is supposed to call. That's something that gets decided when compiling the expression. So we let the Clang mangler inject the correct structor variant into the `AsmLabel` during JITing. I adjusted the `AsmLabelAttr` mangling for this in llvm#155485. An option would've been to create a new Clang attribute which behaved like an `AsmLabel` but with these special semantics for LLDB. My main concern there is that we'd have to adjust all the `AsmLabelAttr` checks around Clang to also now account for this new attribute. 2. The compiler is free to omit the `C1` variant of a constructor if the `C2` variant is sufficient. In that case it may alias `C1` to `C2`, leaving us with only the `C2` `DW_TAG_subprogram` in the object file. Linux is one of the platforms where this occurs. For those cases I added a heuristic in `SymbolFileDWARF` where we pick `C2` if we asked for `C1` but it doesn't exist. This may not always be correct (e.g., if the compiler decided to drop `C1` for other reasons). 3. In llvm#154142 Clang will emit `C4`/`D4` variants of ctors/dtors on declarations. When resolving the `FunctionCallLabel` we will now substitute the actual variant that Clang told us we need to call into the mangled name. We do this using LLDB's `ManglingSubstitutor`. That way we find the definition DIE exactly the same way we do for regular function calls. 4. In cases where declarations and definitions live in separate modules, the DIE ID encoded in the function call label may not be enough to find the definition DIE in the encoded module ID. For those cases we fall back to how LLDB used to work: look up in all images of the target. To make sure we don't use the unified mangled name for the fallback lookup, we change the lookup name to whatever mangled name the FunctionCallLabel resolved to. rdar://104968288 (cherry picked from commit 57a7907)
This is failing on the lldb-aarch64-windows bots with (see error below). XFAIL for now because it's unlikely that these expression evaluator calls were supported before they were added. ``` ====================================================================== FAIL: test_nested_no_structor_linkage_names_dwarf (TestAbiTagStructors.AbiTagStructorsTestCase.test_nested_no_structor_linkage_names_dwarf) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 1828, in test_method return attrvalue(self) ^^^^^^^^^^^^^^^ File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\lang\cpp\abi_tag_structors\TestAbiTagStructors.py", line 108, in test_nested_no_structor_linkage_names self.do_nested_structor_test() File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\lang\cpp\abi_tag_structors\TestAbiTagStructors.py", line 102, in do_nested_structor_test self.expect( File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2453, in expect self.assertFalse( AssertionError: True is not false : Command 'expression TaggedLocal()' is expected to fail! Config=aarch64-C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\clang.exe ====================================================================== FAIL: test_nested_with_structor_linkage_names_dwarf (TestAbiTagStructors.AbiTagStructorsTestCase.test_nested_with_structor_linkage_names_dwarf) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 1828, in test_method return attrvalue(self) ^^^^^^^^^^^^^^^ File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\lang\cpp\abi_tag_structors\TestAbiTagStructors.py", line 112, in test_nested_with_structor_linkage_names self.do_nested_structor_test() File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\lang\cpp\abi_tag_structors\TestAbiTagStructors.py", line 102, in do_nested_structor_test self.expect( File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2453, in expect self.assertFalse( AssertionError: True is not false : Command 'expression TaggedLocal()' is expected to fail! Config=aarch64-C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\clang.exe ====================================================================== FAIL: test_no_structor_linkage_names_dwarf (TestAbiTagStructors.AbiTagStructorsTestCase.test_no_structor_linkage_names_dwarf) Test that without linkage names on structor declarations we can't call ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 1828, in test_method return attrvalue(self) ^^^^^^^^^^^^^^^ File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\lang\cpp\abi_tag_structors\TestAbiTagStructors.py", line 81, in test_no_structor_linkage_names self.expect("expr Tagged t3(t1)", error=True) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2453, in expect self.assertFalse( AssertionError: True is not false : Command 'expr Tagged t3(t1)' is expected to fail! Config=aarch64-C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\clang.exe ====================================================================== FAIL: test_with_structor_linkage_names_dwarf (TestAbiTagStructors.AbiTagStructorsTestCase.test_with_structor_linkage_names_dwarf) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 1828, in test_method return attrvalue(self) ^^^^^^^^^^^^^^^ File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\lang\cpp\abi_tag_structors\TestAbiTagStructors.py", line 20, in test_with_structor_linkage_names self.expect_expr( File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2596, in expect_expr value_check.check_value(self, eval_result, str(eval_result)) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 301, in check_value test_base.assertSuccess(val.GetError()) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2631, in assertSuccess self.fail(self._formatMessage(msg, "'{}' is not success".format(error))) AssertionError: 'error: Internal error [IRForTarget]: Result variable (??__F$__lldb_expr_result@?1??$__lldb_expr@@YAXPEAX@Z@YAXXZ) is defined, but is not a global variable ``` (cherry picked from commit 6dfc255)
@swift-ci test |
adrian-prantl
approved these changes
Sep 9, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Cherry-picks patch series in llvm#149827
Deliberately didn't cherry-pick into upstream
release/21.x
branch because we didn't cherry-pick the underlyingFunctionCallLabel
infrastructure eitherrdar://104968288