https://github.com/Michael137 created 
https://github.com/llvm/llvm-project/pull/115571

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       
                                               
----------------------------------------------------------------------      ```

>From d25d0a6660d7acf8dcd609338e514c91b0a7fe2b Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Fri, 8 Nov 2024 23:26:00 +0000
Subject: [PATCH] [lldb][ObjC] Fix method list entry offset calculation

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.
---
 .../ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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;
 }
 

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to