[Lldb-commits] [lldb] [lldb][ObjC] Fix method list entry offset calculation (PR #115571)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Nov 8 16:29:13 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Michael Buch (Michael137)
<details>
<summary>Changes</summary>
The `relative_list_list_entry_t` offset field in the Objective-C runtime is of type `int64_t`. There are cases where these offsets are negative values. For negative offsets, LLDB would currently incorrectly zero-extend the offset (dropping the fact that the offset was negative), instead producing large offsets that, when added to the `m_baseMethods_ptr` result in addresses that had their upper bits set (e.g., `0x00017ff81b3241b0`). We then would try to `GetMethodList` from such an address but fail to read it (because it's an invalid address). This would manifest in Objective-C decls not getting completed correctly (and formatters not working). We noticed this in CI failures on our Intel bots. This happened to work fine on arm64 because we strip the upper bits when calling `ClassDescriptorV2::method_list_t::Read` using the `FixCodeAddress` ABI plugin API (which doesn't do that on Intel).
The fix is to sign-extend the offset calculation.
Example failure before this patch:
```
======================================================================
FAIL: test_break_dwarf (TestRuntimeTypes.RuntimeTypesTestCase)
Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/michaelbuch/Git/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1769, in test_method
return attrvalue(self)
File "/Users/michaelbuch/Git/llvm-project/lldb/test/API/lang/objc/foundation/TestRuntimeTypes.py", line 48, in test_break
self.expect(
File "/Users/michaelbuch/Git/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 2370, in expect
self.runCmd(
File "/Users/michaelbuch/Git/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1000, in runCmd
self.assertTrue(self.res.Succeeded(), msg + output)
AssertionError: False is not true : Got a valid type
Error output:
error: <user expression 1>:1:11: no known method '+stringWithCString:encoding:'; cast the message send to the method's return type
1 | [NSString stringWithCString:"foo" encoding:1]
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Config=x86_64-/Users/michaelbuch/Git/lldb-build-main-no-modules/bin/clang
---------------------------------------------------------------------- ```
---
Full diff: https://github.com/llvm/llvm-project/pull/115571.diff
1 Files Affected:
- (modified) lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp (+1-1)
``````````diff
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 39969520b74556..54c9f328b5b78b 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -394,7 +394,7 @@ bool ClassDescriptorV2::relative_list_entry_t::Read(Process *process,
lldb::offset_t cursor = 0;
uint64_t raw_entry = extractor.GetU64_unchecked(&cursor);
m_image_index = raw_entry & 0xFFFF;
- m_list_offset = (int64_t)(raw_entry >> 16);
+ m_list_offset = llvm::SignExtend64<48>(raw_entry >> 16);
return true;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/115571
More information about the lldb-commits
mailing list