Skip to content

Commit be0ced0

Browse files
committed
Revert "Revert "Add support for fetching signed values from tagged pointers.""
This reverts commit 602ab18. The patch replicated an lldbassert for a certain type of NSNumber for tagged pointers. This really shouldn't be an assert since we don't do anything wrong with these numbers, we just don't print a summary. So this patch changed the lldbassert to a log message in reverting the revert.
1 parent 30b3aab commit be0ced0

File tree

6 files changed

+99
-18
lines changed

6 files changed

+99
-18
lines changed

lldb/source/Plugins/Language/ObjC/Cocoa.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value,
351351
}
352352

353353
static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream,
354-
uint64_t value, lldb::LanguageType lang) {
354+
int64_t value, lldb::LanguageType lang) {
355355
static ConstString g_TypeHint("NSNumber:long");
356356

357357
std::string prefix, suffix;
@@ -426,6 +426,8 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
426426
if (!process_sp)
427427
return false;
428428

429+
Log * log
430+
= lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
429431
ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
430432

431433
if (!runtime)
@@ -456,9 +458,17 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
456458
return NSDecimalNumberSummaryProvider(valobj, stream, options);
457459

458460
if (class_name == "NSNumber" || class_name == "__NSCFNumber") {
459-
uint64_t value = 0;
461+
int64_t value = 0;
460462
uint64_t i_bits = 0;
461-
if (descriptor->GetTaggedPointerInfo(&i_bits, &value)) {
463+
if (descriptor->GetTaggedPointerInfoSigned(&i_bits, &value)) {
464+
// Check for "preserved" numbers. We still don't support them yet.
465+
if (i_bits & 0x8) {
466+
if (log)
467+
log->Printf("Unsupported (preserved) NSNumber tagged pointer 0x%"
468+
PRIu64, valobj_addr);
469+
return false;
470+
}
471+
462472
switch (i_bits) {
463473
case 0:
464474
NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
@@ -512,7 +522,9 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
512522

513523
bool is_preserved_number = cfinfoa & 0x8;
514524
if (is_preserved_number) {
515-
lldbassert(!static_cast<bool>("We should handle preserved numbers!"));
525+
if (log)
526+
log->Printf("Unsupported preserved NSNumber tagged pointer 0x%"
527+
PRIu64, valobj_addr);
516528
return false;
517529
}
518530

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor {
4141
return false;
4242
}
4343

44+
bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
45+
int64_t *value_bits = nullptr,
46+
uint64_t *payload = nullptr) override {
47+
return false;
48+
}
49+
4450
uint64_t GetInstanceSize() override;
4551

4652
ObjCLanguageRuntime::ObjCISA GetISA() override { return m_objc_class_ptr; }
@@ -253,7 +259,7 @@ class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor {
253259

254260
ClassDescriptorV2Tagged(
255261
ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp,
256-
uint64_t payload) {
262+
uint64_t u_payload, int64_t s_payload) {
257263
if (!actual_class_sp) {
258264
m_valid = false;
259265
return;
@@ -264,9 +270,10 @@ class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor {
264270
return;
265271
}
266272
m_valid = true;
267-
m_payload = payload;
273+
m_payload = u_payload;
268274
m_info_bits = (m_payload & 0x0FULL);
269275
m_value_bits = (m_payload & ~0x0FULL) >> 4;
276+
m_value_bits_signed = (s_payload & ~0x0FLL) >> 4;
270277
}
271278

272279
~ClassDescriptorV2Tagged() override = default;
@@ -308,6 +315,18 @@ class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor {
308315
return true;
309316
}
310317

318+
bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
319+
int64_t *value_bits = nullptr,
320+
uint64_t *payload = nullptr) override {
321+
if (info_bits)
322+
*info_bits = GetInfoBits();
323+
if (value_bits)
324+
*value_bits = GetValueBitsSigned();
325+
if (payload)
326+
*payload = GetPayload();
327+
return true;
328+
}
329+
311330
uint64_t GetInstanceSize() override {
312331
return (IsValid() ? m_pointer_size : 0);
313332
}
@@ -319,6 +338,10 @@ class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor {
319338
// these calls are not part of any formal tagged pointers specification
320339
virtual uint64_t GetValueBits() { return (IsValid() ? m_value_bits : 0); }
321340

341+
virtual int64_t GetValueBitsSigned() {
342+
return (IsValid() ? m_value_bits_signed : 0);
343+
}
344+
322345
virtual uint64_t GetInfoBits() { return (IsValid() ? m_info_bits : 0); }
323346

324347
virtual uint64_t GetPayload() { return (IsValid() ? m_payload : 0); }
@@ -329,6 +352,7 @@ class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor {
329352
bool m_valid;
330353
uint64_t m_info_bits;
331354
uint64_t m_value_bits;
355+
int64_t m_value_bits_signed;
332356
uint64_t m_payload;
333357
};
334358

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ class AppleObjCRuntimeV1 : public AppleObjCRuntime {
6464
return false;
6565
}
6666

67+
bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
68+
int64_t *value_bits = nullptr,
69+
uint64_t *payload = nullptr) override {
70+
return false;
71+
}
72+
6773
uint64_t GetInstanceSize() override { return m_instance_size; }
6874

6975
ObjCISA GetISA() override { return m_isa; }

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2460,7 +2460,6 @@ ObjCLanguageRuntime::ClassDescriptorSP
24602460
AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
24612461
lldb::addr_t ptr) {
24622462
ClassDescriptorSP actual_class_descriptor_sp;
2463-
uint64_t data_payload;
24642463
uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
24652464

24662465
if (!IsPossibleTaggedPointer(unobfuscated))
@@ -2488,12 +2487,15 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
24882487
m_cache[slot] = actual_class_descriptor_sp;
24892488
}
24902489

2491-
data_payload =
2490+
uint64_t data_payload =
24922491
(((uint64_t)unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
24932492
m_objc_debug_taggedpointer_payload_rshift);
2494-
2495-
return ClassDescriptorSP(
2496-
new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
2493+
int64_t data_payload_signed =
2494+
((int64_t)((int64_t)unobfuscated
2495+
<< m_objc_debug_taggedpointer_payload_lshift) >>
2496+
m_objc_debug_taggedpointer_payload_rshift);
2497+
return ClassDescriptorSP(new ClassDescriptorV2Tagged(
2498+
actual_class_descriptor_sp, data_payload, data_payload_signed));
24972499
}
24982500

24992501
AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended(
@@ -2545,7 +2547,6 @@ ObjCLanguageRuntime::ClassDescriptorSP
25452547
AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
25462548
lldb::addr_t ptr) {
25472549
ClassDescriptorSP actual_class_descriptor_sp;
2548-
uint64_t data_payload;
25492550
uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
25502551

25512552
if (!IsPossibleTaggedPointer(unobfuscated))
@@ -2576,12 +2577,16 @@ AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
25762577
m_ext_cache[slot] = actual_class_descriptor_sp;
25772578
}
25782579

2579-
data_payload = (((uint64_t)unobfuscated
2580-
<< m_objc_debug_taggedpointer_ext_payload_lshift) >>
2581-
m_objc_debug_taggedpointer_ext_payload_rshift);
2580+
uint64_t data_payload = (((uint64_t)unobfuscated
2581+
<< m_objc_debug_taggedpointer_ext_payload_lshift) >>
2582+
m_objc_debug_taggedpointer_ext_payload_rshift);
2583+
int64_t data_payload_signed =
2584+
((int64_t)((int64_t)unobfuscated
2585+
<< m_objc_debug_taggedpointer_ext_payload_lshift) >>
2586+
m_objc_debug_taggedpointer_ext_payload_rshift);
25822587

2583-
return ClassDescriptorSP(
2584-
new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
2588+
return ClassDescriptorSP(new ClassDescriptorV2Tagged(
2589+
actual_class_descriptor_sp, data_payload, data_payload_signed));
25852590
}
25862591

25872592
AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache(

lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,20 @@ class ObjCLanguageRuntime : public LanguageRuntime {
8787

8888
virtual bool IsValid() = 0;
8989

90+
/// There are two routines in the ObjC runtime that tagged pointer clients
91+
/// can call to get the value from their tagged pointer, one that retrieves
92+
/// it as an unsigned value and one a signed value. These two
93+
/// GetTaggedPointerInfo methods mirror those two ObjC runtime calls.
94+
/// @{
9095
virtual bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
9196
uint64_t *value_bits = nullptr,
9297
uint64_t *payload = nullptr) = 0;
9398

99+
virtual bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
100+
int64_t *value_bits = nullptr,
101+
uint64_t *payload = nullptr) = 0;
102+
/// @}
103+
94104
virtual uint64_t GetInstanceSize() = 0;
95105

96106
// use to implement version-specific additional constraints on pointers

lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCCF.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def test_coreframeworks_and_run_command(self):
4545
'(Point) point = (v=7, h=12)', '(Point *) point_ptr = (v=7, h=12)',
4646
'(SEL) foo_selector = "foo_selector_impl"'
4747
]
48-
4948
self.expect("frame variable", substrs=expect_strings)
5049

5150
if self.getArchitecture() in ['i386', 'x86_64']:
@@ -56,3 +55,28 @@ def test_coreframeworks_and_run_command(self):
5655
'(HIRect) hi_rect = origin=(x = 3, y = 5) size=(width = 4, height = 6)',
5756
]
5857
self.expect("frame variable", substrs=extra_string)
58+
59+
# The original tests left out testing the NSNumber values, so do that here.
60+
# This set is all pointers, with summaries, so we only check the summary.
61+
var_list_pointer = [
62+
['NSNumber *', 'num1', '(int)5'],
63+
['NSNumber *', 'num2', '(float)3.140000'],
64+
['NSNumber *', 'num3', '(double)3.14'],
65+
['NSNumber *', 'num4', '(int128_t)18446744073709551614'],
66+
['NSNumber *', 'num5', '(char)65'],
67+
['NSNumber *', 'num6', '(long)255'],
68+
['NSNumber *', 'num7', '(long)2000000'],
69+
['NSNumber *', 'num8_Y', 'YES'],
70+
['NSNumber *', 'num8_N', 'NO'],
71+
['NSNumber *', 'num9', '(short)-31616'],
72+
['NSNumber *', 'num_at1', '(int)12'],
73+
['NSNumber *', 'num_at2', '(int)-12'],
74+
['NSNumber *', 'num_at3', '(double)12.5'],
75+
['NSNumber *', 'num_at4', '(double)-12.5'],
76+
['NSDecimalNumber *', 'decimal_number', '123456 x 10^-10'],
77+
['NSDecimalNumber *', 'decimal_number_neg', '-123456 x 10^10']
78+
]
79+
for type, var_path, summary in var_list_pointer:
80+
self.expect_var_path(var_path, summary, None, type)
81+
82+

0 commit comments

Comments
 (0)