@@ -65,6 +65,21 @@ class ReflectionSection {
65
65
size_t size () const {
66
66
return Size;
67
67
}
68
+
69
+ bool containsRemoteAddress (uint64_t remoteAddr,
70
+ uint64_t size) const {
71
+ return Start.getAddressData () <= remoteAddr
72
+ && remoteAddr + size <= Start.getAddressData () + Size;
73
+ }
74
+
75
+ template <typename U>
76
+ RemoteRef<U> getRemoteRef (uint64_t remoteAddr) const {
77
+ assert (containsRemoteAddress (remoteAddr, sizeof (U)));
78
+ auto localAddr = (uint64_t )(uintptr_t )Start.getLocalBuffer ()
79
+ + (remoteAddr - Start.getAddressData ());
80
+
81
+ return RemoteRef<U>(remoteAddr, (const U*)localAddr);
82
+ }
68
83
};
69
84
70
85
template <typename Self, typename Descriptor>
@@ -239,17 +254,12 @@ class TypeRefBuilder {
239
254
using BuiltTypeDecl = Optional<std::string>;
240
255
using BuiltProtocolDecl = Optional<std::pair<std::string, bool /* isObjC*/ >>;
241
256
242
- TypeRefBuilder ();
243
-
244
257
TypeRefBuilder (const TypeRefBuilder &other) = delete ;
245
258
TypeRefBuilder &operator =(const TypeRefBuilder &other) = delete ;
246
259
247
260
private:
248
261
Demangle::Demangler Dem;
249
262
250
- std::function<const TypeRef* (const void *, unsigned )>
251
- OpaqueUnderlyingTypeReader;
252
-
253
263
// / Makes sure dynamically allocated TypeRefs stick around for the life of
254
264
// / this TypeRefBuilder and are automatically released.
255
265
std::vector<std::unique_ptr<const TypeRef>> TypeRefPool;
@@ -555,106 +565,66 @@ class TypeRefBuilder {
555
565
return ReflectionInfos;
556
566
}
557
567
568
+ public:
569
+ enum ForTesting_t { ForTesting };
570
+
571
+ // Only for testing. A TypeRefBuilder built this way will not be able to
572
+ // decode records in remote memory.
573
+ explicit TypeRefBuilder (ForTesting_t) : TC(*this ) {}
574
+
558
575
private:
559
576
std::vector<ReflectionInfo> ReflectionInfos;
560
-
561
- uint64_t getRemoteAddrOfTypeRefPointer (const void *pointer);
562
-
563
- std::function<auto (SymbolicReferenceKind kind,
564
- Directness directness,
565
- int32_t offset, const void *base) -> Demangle::Node *>
566
- SymbolicReferenceResolver;
567
-
577
+
568
578
std::string normalizeReflectionName (RemoteRef<char > name);
569
579
bool reflectionNameMatches (RemoteRef<char > reflectionName,
570
580
StringRef searchName);
571
581
572
582
public:
583
+ RemoteRef<char > readTypeRef (uint64_t remoteAddr);
584
+
573
585
template <typename Record, typename Field>
574
586
RemoteRef<char > readTypeRef (RemoteRef<Record> record,
575
587
const Field &field) {
576
588
uint64_t remoteAddr = record.resolveRelativeFieldData (field);
577
- // TODO: This assumes the remote and local buffer addresses are contiguous,
578
- // which should not be a guarantee that MemoryReaders need to maintain.
579
- // Ultimately this should use the MemoryReader to read the string.
580
- auto localAddr = (uint64_t )(uintptr_t )record.getLocalBuffer ()
581
- + (int64_t )(remoteAddr - record.getAddressData ());
582
-
583
- // Skip the mangling prefix, if any.
584
- auto localPtr = (const char *)localAddr;
585
- if (localPtr[0 ] == ' $' && localPtr[1 ] == ' s' ) {
586
- remoteAddr += 2 ;
587
- localPtr += 2 ;
588
- }
589
589
590
- return RemoteRef< char > (remoteAddr, localPtr );
590
+ return readTypeRef (remoteAddr);
591
591
}
592
-
592
+
593
593
StringRef getTypeRefString (RemoteRef<char > record) {
594
594
return Demangle::makeSymbolicMangledNameStringRef (record.getLocalBuffer ());
595
595
}
596
596
597
- Demangle::Node *demangleTypeRef (RemoteRef<char > string) {
598
- // TODO: Use the remote addr in the RemoteRef to resolve and read from
599
- // remote addresses in the resolver function.
600
- return Dem.demangleType (getTypeRefString (string),
601
- SymbolicReferenceResolver);
602
- }
597
+ private:
598
+ // These fields are captured from the MetadataReader template passed into the
599
+ // TypeRefBuilder struct, to isolate its template-ness from the rest of
600
+ // TypeRefBuilder.
601
+ unsigned PointerSize;
602
+ std::function<Demangle::Node * (RemoteRef<char >)>
603
+ TypeRefDemangler;
604
+ std::function<const TypeRef* (const void *, unsigned )>
605
+ OpaqueUnderlyingTypeReader;
603
606
607
+ public:
604
608
template <typename Runtime>
605
- void setMetadataReader (
606
- remote::MetadataReader<Runtime, TypeRefBuilder> &reader) {
607
- // Have the TypeRefBuilder demangle symbolic references by reading their
608
- // demangling out of the referenced context descriptors in the target
609
- // process.
610
- SymbolicReferenceResolver =
611
- [this , &reader](SymbolicReferenceKind kind,
612
- Directness directness,
613
- int32_t offset, const void *base) -> Demangle::Node * {
614
- // Resolve the reference to a remote address.
615
- auto remoteAddress = getRemoteAddrOfTypeRefPointer (base);
616
- if (remoteAddress == 0 )
617
- return nullptr ;
618
-
619
- auto address = remoteAddress + offset;
620
- if (directness == Directness::Indirect) {
621
- if (auto indirectAddress = reader.readPointerValue (address)) {
622
- address = *indirectAddress;
623
- } else {
624
- return nullptr ;
625
- }
626
- }
627
-
628
- switch (kind) {
629
- case Demangle::SymbolicReferenceKind::Context: {
630
- auto context = reader.readContextDescriptor (address);
631
- if (!context)
632
- return nullptr ;
633
- // Try to preserve a reference to an OpaqueTypeDescriptor symbolically,
634
- // since we'd like to read out and resolve the type ref to the
635
- // underlying type if available.
636
- if (context->getKind () == ContextDescriptorKind::OpaqueType) {
637
- return Dem.createNode (
638
- Node::Kind::OpaqueTypeDescriptorSymbolicReference,
639
- context.getAddressData ());
640
- }
641
-
642
- return reader.buildContextMangling (context, Dem);
643
- }
644
- case Demangle::SymbolicReferenceKind::AccessorFunctionReference:
645
- // The symbolic reference points at a resolver function, but we can't
646
- // execute code in the target process to resolve it from here.
647
- return nullptr ;
648
- }
649
-
650
- return nullptr ;
651
- };
652
-
653
- OpaqueUnderlyingTypeReader =
654
- [&reader](const void *descriptor, unsigned ordinal) -> const TypeRef* {
655
- auto context = (typename Runtime::StoredPointer)descriptor;
656
- return reader.readUnderlyingTypeForOpaqueTypeDescriptor (context, ordinal);
657
- };
609
+ TypeRefBuilder (remote::MetadataReader<Runtime, TypeRefBuilder> &reader)
610
+ : TC(*this ),
611
+ PointerSize (sizeof (typename Runtime::StoredPointer)),
612
+ TypeRefDemangler(
613
+ [this , &reader](RemoteRef<char > string) -> Demangle::Node * {
614
+ return reader.demangle (string,
615
+ remote::MangledNameKind::Type,
616
+ Dem, /* useOpaqueTypeSymbolicReferences*/ true );
617
+ }),
618
+ OpaqueUnderlyingTypeReader (
619
+ [&reader](const void *descriptor, unsigned ordinal) -> const TypeRef* {
620
+ auto context = (typename Runtime::StoredPointer)descriptor;
621
+ return reader.readUnderlyingTypeForOpaqueTypeDescriptor (context,
622
+ ordinal);
623
+ })
624
+ {}
625
+
626
+ Demangle::Node *demangleTypeRef (RemoteRef<char > string) {
627
+ return TypeRefDemangler (string);
658
628
}
659
629
660
630
TypeConverter &getTypeConverter () { return TC; }
0 commit comments