Skip to content

Commit 4f969b4

Browse files
authored
Merge pull request #22641 from fredriss/fixes-for-lldb-5.1
Fixes for lldb 5.1
2 parents 663f49c + 28d1cd3 commit 4f969b4

File tree

7 files changed

+404
-83
lines changed

7 files changed

+404
-83
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -520,15 +520,14 @@ class ReflectionContext
520520
readMetadataAndValueOpaqueExistential(ExistentialAddress);
521521
if (!OptMetaAndValue)
522522
return false;
523-
RemoteAddress MetadataAddress = OptMetaAndValue->first;
524-
RemoteAddress ValueAddress = OptMetaAndValue->second;
525523

526-
auto InstanceTR = readTypeFromMetadata(MetadataAddress.getAddressData());
524+
auto InstanceTR = readTypeFromMetadata(
525+
OptMetaAndValue->MetadataAddress.getAddressData());
527526
if (!InstanceTR)
528527
return false;
529528

530529
*OutInstanceTR = InstanceTR;
531-
*OutInstanceAddress = ValueAddress;
530+
*OutInstanceAddress = OptMetaAndValue->PayloadAddress;
532531
return true;
533532
}
534533
case RecordKind::ErrorExistential: {
@@ -537,16 +536,15 @@ class ReflectionContext
537536
if (!OptMetaAndValue)
538537
return false;
539538

540-
RemoteAddress InstanceMetadataAddress = OptMetaAndValue->first;
541-
RemoteAddress InstanceAddress = OptMetaAndValue->second;
539+
// FIXME: Check third value, 'IsBridgedError'
542540

543-
auto InstanceTR =
544-
readTypeFromMetadata(InstanceMetadataAddress.getAddressData());
541+
auto InstanceTR = readTypeFromMetadata(
542+
OptMetaAndValue->MetadataAddress.getAddressData());
545543
if (!InstanceTR)
546544
return false;
547545

548546
*OutInstanceTR = InstanceTR;
549-
*OutInstanceAddress = RemoteAddress(InstanceAddress);
547+
*OutInstanceAddress = OptMetaAndValue->PayloadAddress;
550548
return true;
551549
}
552550
default:

include/swift/Remote/MetadataReader.h

Lines changed: 196 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,26 @@ struct delete_with_free {
8686
}
8787
};
8888

89+
/// A structure representing an opened existential type.
90+
struct RemoteExistential {
91+
/// The payload's concrete type metadata.
92+
RemoteAddress MetadataAddress;
93+
94+
/// The address of the payload value.
95+
RemoteAddress PayloadAddress;
96+
97+
/// True if this is an NSError instance transparently bridged to an Error
98+
/// existential.
99+
bool IsBridgedError;
100+
101+
RemoteExistential(RemoteAddress MetadataAddress,
102+
RemoteAddress PayloadAddress,
103+
bool IsBridgedError=false)
104+
: MetadataAddress(MetadataAddress),
105+
PayloadAddress(PayloadAddress),
106+
IsBridgedError(IsBridgedError) {}
107+
};
108+
89109
/// A generic reader of metadata.
90110
///
91111
/// BuilderType must implement a particular interface which is currently
@@ -171,6 +191,38 @@ class MetadataReader {
171191
StoredPointer IndexedClassesCountPointer;
172192
StoredPointer LastIndexedClassesCount = 0;
173193

194+
enum class TaggedPointerEncodingKind {
195+
/// We haven't checked yet.
196+
Unknown,
197+
198+
/// There was an error trying to find out the tagged pointer encoding.
199+
Error,
200+
201+
/// The "extended" encoding.
202+
///
203+
/// 1 bit: is-tagged
204+
/// 3 bits: class index (for objc_debug_taggedpointer_classes[])
205+
/// 60 bits: payload
206+
///
207+
/// Class index 0b111 represents 256 additional classes:
208+
///
209+
/// 1 bit: is-tagged
210+
/// 3 bits: 0b111
211+
/// 8 bits: extended class index (for objc_debug_taggedpointer_ext_classes[])
212+
/// 54 bits: payload
213+
Extended
214+
};
215+
TaggedPointerEncodingKind TaggedPointerEncoding =
216+
TaggedPointerEncodingKind::Unknown;
217+
StoredPointer TaggedPointerMask;
218+
StoredPointer TaggedPointerSlotShift;
219+
StoredPointer TaggedPointerSlotMask;
220+
StoredPointer TaggedPointerClasses;
221+
StoredPointer TaggedPointerExtendedMask;
222+
StoredPointer TaggedPointerExtendedSlotShift;
223+
StoredPointer TaggedPointerExtendedSlotMask;
224+
StoredPointer TaggedPointerExtendedClasses;
225+
174226
Demangle::NodeFactory Factory;
175227

176228
Demangle::NodeFactory &getNodeFactory() { return Factory; }
@@ -294,8 +346,10 @@ class MetadataReader {
294346
}
295347

296348
/// Given a pointer to a known-error existential, attempt to discover the
297-
/// pointer to its metadata address and its value address.
298-
Optional<std::pair<RemoteAddress, RemoteAddress>>
349+
/// pointer to its metadata address, its value address, and whether this
350+
/// is a toll-free-bridged NSError or an actual Error existential wrapper
351+
/// around a native Swift value.
352+
Optional<RemoteExistential>
299353
readMetadataAndValueErrorExistential(RemoteAddress ExistentialAddress) {
300354
// An pointer to an error existential is always an heap object.
301355
auto MetadataAddress =
@@ -304,13 +358,16 @@ class MetadataReader {
304358
return None;
305359

306360
bool isObjC = false;
361+
bool isBridged = false;
307362

308363
// If we can determine the Objective-C class name, this is probably an
309364
// error existential with NSError-compatible layout.
310365
std::string ObjCClassName;
311366
if (readObjCClassName(*MetadataAddress, ObjCClassName)) {
312367
if (ObjCClassName == "__SwiftNativeNSError")
313368
isObjC = true;
369+
else
370+
isBridged = true;
314371
} else {
315372
// Otherwise, we can check to see if this is a class metadata with the
316373
// kind value's least significant bit set, which indicates a pure
@@ -323,6 +380,13 @@ class MetadataReader {
323380
isObjC = ClassMeta->isPureObjC();
324381
}
325382

383+
if (isBridged) {
384+
// NSError instances don't need to be unwrapped.
385+
return RemoteExistential(RemoteAddress(*MetadataAddress),
386+
ExistentialAddress,
387+
isBridged);
388+
}
389+
326390
// In addition to the isa pointer and two 32-bit reference counts, if the
327391
// error existential is layout-compatible with NSError, we also need to
328392
// skip over its three word-sized fields: the error code, the domain,
@@ -354,14 +418,15 @@ class MetadataReader {
354418
auto Offset = (sizeof(HeapObject) + AlignmentMask) & ~AlignmentMask;
355419
InstanceAddress += Offset;
356420

357-
return Optional<std::pair<RemoteAddress, RemoteAddress>>(
358-
{RemoteAddress(*InstanceMetadataAddress),
359-
RemoteAddress(InstanceAddress)});
421+
return RemoteExistential(
422+
RemoteAddress(*InstanceMetadataAddress),
423+
RemoteAddress(InstanceAddress),
424+
isBridged);
360425
}
361426

362427
/// Given a known-opaque existential, attemp to discover the pointer to its
363428
/// metadata address and its value.
364-
Optional<std::pair<RemoteAddress, RemoteAddress>>
429+
Optional<RemoteExistential>
365430
readMetadataAndValueOpaqueExistential(RemoteAddress ExistentialAddress) {
366431
// OpaqueExistentialContainer is the layout of an opaque existential.
367432
// `Type` is the pointer to the metadata.
@@ -381,8 +446,8 @@ class MetadataReader {
381446
// Inline representation (the value fits in the existential container).
382447
// So, the value starts at the first word of the container.
383448
if (VWT->isValueInline())
384-
return Optional<std::pair<RemoteAddress, RemoteAddress>>(
385-
{RemoteAddress(MetadataAddress), ExistentialAddress});
449+
return RemoteExistential(RemoteAddress(MetadataAddress),
450+
ExistentialAddress);
386451

387452
// Non-inline (box'ed) representation.
388453
// The first word of the container stores the address to the box.
@@ -393,8 +458,8 @@ class MetadataReader {
393458
auto AlignmentMask = VWT->getAlignmentMask();
394459
auto Offset = (sizeof(HeapObject) + AlignmentMask) & ~AlignmentMask;
395460
auto StartOfValue = BoxAddress + Offset;
396-
return Optional<std::pair<RemoteAddress, RemoteAddress>>(
397-
{RemoteAddress(MetadataAddress), RemoteAddress(StartOfValue)});
461+
return RemoteExistential(RemoteAddress(MetadataAddress),
462+
RemoteAddress(StartOfValue));
398463
}
399464

400465
/// Read a protocol from a reference to said protocol.
@@ -463,10 +528,28 @@ class MetadataReader {
463528
if (!Meta) return BuiltType();
464529

465530
switch (Meta->getKind()) {
466-
case MetadataKind::Class:
467-
if (!cast<TargetClassMetadata<Runtime>>(Meta)->isTypeMetadata())
468-
return BuiltType();
531+
case MetadataKind::Class: {
532+
auto classMeta = cast<TargetClassMetadata<Runtime>>(Meta);
533+
if (!classMeta->isTypeMetadata()) {
534+
std::string className;
535+
if (!readObjCClassName(MetadataAddress, className))
536+
return BuiltType();
537+
538+
BuiltType BuiltObjCClass = Builder.createObjCClassType(std::move(className));
539+
if (!BuiltObjCClass) {
540+
// Try the superclass.
541+
if (!classMeta->Superclass)
542+
return BuiltType();
543+
544+
BuiltObjCClass = readTypeFromMetadata(classMeta->Superclass,
545+
skipArtificialSubclasses);
546+
}
547+
548+
TypeCache[MetadataAddress] = BuiltObjCClass;
549+
return BuiltObjCClass;
550+
}
469551
return readNominalTypeFromMetadata(Meta, skipArtificialSubclasses);
552+
}
470553
case MetadataKind::Struct:
471554
case MetadataKind::Enum:
472555
case MetadataKind::Optional:
@@ -657,10 +740,48 @@ class MetadataReader {
657740
return buildContextMangling(context, Dem);
658741
}
659742

743+
bool isTaggedPointer(StoredPointer objectAddress) {
744+
if (getTaggedPointerEncoding() != TaggedPointerEncodingKind::Extended)
745+
return false;
746+
747+
return objectAddress & TaggedPointerMask;
748+
}
749+
750+
/// Read the isa pointer of an Object-C tagged pointer value.
751+
Optional<StoredPointer>
752+
readMetadataFromTaggedPointer(StoredPointer objectAddress) {
753+
auto readArrayElement = [&](StoredPointer base, StoredPointer tag)
754+
-> Optional<StoredPointer> {
755+
StoredPointer addr = base + tag * sizeof(StoredPointer);
756+
StoredPointer isa;
757+
if (!Reader->readInteger(RemoteAddress(addr), &isa))
758+
return None;
759+
return isa;
760+
};
761+
762+
// Extended pointers have a tag of 0b111, using 8 additional bits
763+
// to specify the class.
764+
if (TaggedPointerExtendedMask != 0 &&
765+
((objectAddress & TaggedPointerExtendedMask)
766+
== TaggedPointerExtendedMask)) {
767+
auto tag = ((objectAddress >> TaggedPointerExtendedSlotShift) &
768+
TaggedPointerExtendedSlotMask);
769+
return readArrayElement(TaggedPointerExtendedClasses, tag);
770+
}
771+
772+
// Basic tagged pointers use a 3 bit tag to specify the class.
773+
auto tag = ((objectAddress >> TaggedPointerSlotShift) &
774+
TaggedPointerSlotMask);
775+
return readArrayElement(TaggedPointerClasses, tag);
776+
}
777+
660778
/// Read the isa pointer of a class or closure context instance and apply
661779
/// the isa mask.
662780
Optional<StoredPointer>
663781
readMetadataFromInstance(StoredPointer objectAddress) {
782+
if (isTaggedPointer(objectAddress))
783+
return readMetadataFromTaggedPointer(objectAddress);
784+
664785
StoredPointer isa;
665786
if (!Reader->readInteger(RemoteAddress(objectAddress), &isa))
666787
return None;
@@ -2290,9 +2411,71 @@ class MetadataReader {
22902411
}
22912412
}
22922413

2414+
# undef tryFindSymbol
2415+
# undef tryReadSymbol
2416+
# undef tryFindAndReadSymbol
2417+
22932418
return finish(IsaEncodingKind::None);
22942419
}
22952420

2421+
TaggedPointerEncodingKind getTaggedPointerEncoding() {
2422+
if (TaggedPointerEncoding != TaggedPointerEncodingKind::Unknown)
2423+
return TaggedPointerEncoding;
2424+
2425+
auto finish = [&](TaggedPointerEncodingKind result)
2426+
-> TaggedPointerEncodingKind {
2427+
TaggedPointerEncoding = result;
2428+
return result;
2429+
};
2430+
2431+
/// Look up the given global symbol and bind 'varname' to its
2432+
/// address if its exists.
2433+
# define tryFindSymbol(varname, symbolName) \
2434+
auto varname = Reader->getSymbolAddress(symbolName); \
2435+
if (!varname) \
2436+
return finish(TaggedPointerEncodingKind::Error)
2437+
/// Read from the given pointer into 'dest'.
2438+
# define tryReadSymbol(varname, dest) do { \
2439+
if (!Reader->readInteger(varname, &dest)) \
2440+
return finish(TaggedPointerEncodingKind::Error); \
2441+
} while (0)
2442+
/// Read from the given global symbol into 'dest'.
2443+
# define tryFindAndReadSymbol(dest, symbolName) do { \
2444+
tryFindSymbol(_address, symbolName); \
2445+
tryReadSymbol(_address, dest); \
2446+
} while (0)
2447+
2448+
tryFindAndReadSymbol(TaggedPointerMask,
2449+
"objc_debug_taggedpointer_mask");
2450+
tryFindAndReadSymbol(TaggedPointerSlotShift,
2451+
"objc_debug_taggedpointer_slot_shift");
2452+
tryFindAndReadSymbol(TaggedPointerSlotMask,
2453+
"objc_debug_taggedpointer_slot_mask");
2454+
tryFindSymbol(TaggedPointerClassesAddr,
2455+
"objc_debug_taggedpointer_classes");
2456+
if (!TaggedPointerClassesAddr)
2457+
finish(TaggedPointerEncodingKind::Error);
2458+
TaggedPointerClasses = TaggedPointerClassesAddr.getAddressData();
2459+
tryFindAndReadSymbol(TaggedPointerExtendedMask,
2460+
"objc_debug_taggedpointer_ext_mask");
2461+
tryFindAndReadSymbol(TaggedPointerExtendedSlotShift,
2462+
"objc_debug_taggedpointer_ext_slot_shift");
2463+
tryFindAndReadSymbol(TaggedPointerExtendedSlotMask,
2464+
"objc_debug_taggedpointer_ext_slot_mask");
2465+
tryFindSymbol(TaggedPointerExtendedClassesAddr,
2466+
"objc_debug_taggedpointer_ext_classes");
2467+
if (!TaggedPointerExtendedClassesAddr)
2468+
finish(TaggedPointerEncodingKind::Error);
2469+
TaggedPointerExtendedClasses =
2470+
TaggedPointerExtendedClassesAddr.getAddressData();
2471+
2472+
# undef tryFindSymbol
2473+
# undef tryReadSymbol
2474+
# undef tryFindAndReadSymbol
2475+
2476+
return finish(TaggedPointerEncodingKind::Extended);
2477+
}
2478+
22962479
template <class T>
22972480
static constexpr T roundUpToAlignment(T offset, T alignment) {
22982481
return (offset + alignment - 1) & ~(alignment - 1);

0 commit comments

Comments
 (0)