18
18
#ifndef SWIFT_REFLECTION_REFLECTIONCONTEXT_H
19
19
#define SWIFT_REFLECTION_REFLECTIONCONTEXT_H
20
20
21
+ #if defined(__APPLE__) && defined(__MACH__)
22
+ #include < mach-o/getsect.h>
23
+ #endif
24
+
21
25
#include " swift/Remote/MemoryReader.h"
22
26
#include " swift/Remote/MetadataReader.h"
23
27
#include " swift/Reflection/Records.h"
30
34
#include < set>
31
35
#include < vector>
32
36
#include < unordered_map>
37
+ #include < utility>
38
+
39
+ #if defined(__APPLE__) && defined(__MACH__)
40
+ #ifndef __LP64__
41
+ typedef const struct mach_header MachHeader;
42
+ #else
43
+ typedef const struct mach_header_64 MachHeader;
44
+ #endif
45
+ #endif
46
+
47
+ #if defined(__APPLE__) && defined(__MACH__)
48
+ template <typename Section>
49
+ static std::pair<Section, bool > findSection (MachHeader *Header,
50
+ const char *Name) {
51
+ unsigned long Size;
52
+ auto Address = getsectiondata (Header, " __TEXT" , Name, &Size);
53
+ if (!Address)
54
+ return {{nullptr , nullptr }, false };
55
+
56
+ auto End = reinterpret_cast <uintptr_t >(Address) + Size;
57
+
58
+ return {{reinterpret_cast <const void *>(Address),
59
+ reinterpret_cast <const void *>(End)},
60
+ true };
61
+ }
62
+ #endif
33
63
34
64
namespace swift {
35
65
namespace reflection {
@@ -46,6 +76,11 @@ class ReflectionContext
46
76
47
77
std::unordered_map<typename super::StoredPointer, const TypeInfo *> Cache;
48
78
79
+ // / All buffers we need to keep around long term. This will automatically free them
80
+ // / when this object is destroyed.
81
+ std::vector<MemoryReader::ReadBytesResult> savedBuffers;
82
+ std::vector<std::tuple<RemoteAddress, RemoteAddress>> dataSegments;
83
+
49
84
public:
50
85
using super::getBuilder;
51
86
using super::readDemanglingForContextDescriptor;
@@ -62,7 +97,7 @@ class ReflectionContext
62
97
63
98
ReflectionContext (const ReflectionContext &other) = delete ;
64
99
ReflectionContext &operator =(const ReflectionContext &other) = delete ;
65
-
100
+
66
101
MemoryReader &getReader () {
67
102
return *this ->Reader ;
68
103
}
@@ -76,10 +111,108 @@ class ReflectionContext
76
111
getBuilder ().dumpAllSections ();
77
112
}
78
113
114
+ #if defined(__APPLE__) && defined(__MACH__)
115
+ bool addImage (RemoteAddress ImageStart) {
116
+ auto Buf = this ->getReader ().readBytes (ImageStart, sizeof (MachHeader));
117
+ if (!Buf)
118
+ return false ;
119
+
120
+ auto Header = reinterpret_cast <MachHeader *>(Buf.get ());
121
+ if (Header->magic != MH_MAGIC && Header->magic != MH_MAGIC_64) {
122
+ return false ;
123
+ }
124
+ auto Length = Header->sizeofcmds ;
125
+
126
+ // Read the commands.
127
+ Buf = this ->getReader ().readBytes (ImageStart, Length);
128
+ if (!Buf)
129
+ return false ;
130
+
131
+ // Find the TEXT segment and figure out where the end is.
132
+ Header = reinterpret_cast <MachHeader *>(Buf.get ());
133
+ unsigned long TextSize;
134
+ auto *TextSegment = getsegmentdata (Header, " __TEXT" , &TextSize);
135
+ if (TextSegment == nullptr )
136
+ return false ;
137
+
138
+ auto TextEnd =
139
+ TextSegment - reinterpret_cast <const uint8_t *>(Buf.get ()) + TextSize;
140
+
141
+ // Read everything including the TEXT segment.
142
+ Buf = this ->getReader ().readBytes (ImageStart, TextEnd);
143
+ if (!Buf)
144
+ return false ;
145
+
146
+ // Read all the metadata parts.
147
+ Header = reinterpret_cast <MachHeader *>(Buf.get ());
148
+
149
+ // The docs say "not all sections may be present." We'll succeed if ANY of
150
+ // them are present. Not sure if that's the right thing to do.
151
+ auto FieldMd = findSection<FieldSection>(Header, " __swift5_fieldmd" );
152
+ auto AssocTyMd =
153
+ findSection<AssociatedTypeSection>(Header, " __swift5_assocty" );
154
+ auto BuiltinTyMd =
155
+ findSection<BuiltinTypeSection>(Header, " __swift5_builtin" );
156
+ auto CaptureMd = findSection<CaptureSection>(Header, " __swift5_capture" );
157
+ auto TyperefMd = findSection<GenericSection>(Header, " __swift5_typeref" );
158
+ auto ReflStrMd = findSection<GenericSection>(Header, " __swift5_reflstr" );
159
+
160
+ bool success = FieldMd.second || AssocTyMd.second || BuiltinTyMd.second ||
161
+ CaptureMd.second || TyperefMd.second || ReflStrMd.second ;
162
+ if (!success)
163
+ return false ;
164
+
165
+ auto LocalStartAddress = reinterpret_cast <uintptr_t >(Buf.get ());
166
+ auto RemoteStartAddress = static_cast <uintptr_t >(ImageStart.getAddressData ());
167
+
168
+ ReflectionInfo info = {
169
+ {{FieldMd.first .startAddress (), FieldMd.first .endAddress ()}, 0 },
170
+ {{AssocTyMd.first .startAddress (), AssocTyMd.first .endAddress ()}, 0 },
171
+ {{BuiltinTyMd.first .startAddress (), BuiltinTyMd.first .endAddress ()}, 0 },
172
+ {{CaptureMd.first .startAddress (), CaptureMd.first .endAddress ()}, 0 },
173
+ {{TyperefMd.first .startAddress (), TyperefMd.first .endAddress ()}, 0 },
174
+ {{ReflStrMd.first .startAddress (), ReflStrMd.first .endAddress ()}, 0 },
175
+ LocalStartAddress,
176
+ RemoteStartAddress};
177
+
178
+ this ->addReflectionInfo (info);
179
+
180
+ unsigned long DataSize;
181
+ auto *DataSegment = getsegmentdata (Header, " __DATA" , &DataSize);
182
+ if (DataSegment != nullptr ) {
183
+ auto DataSegmentStart = DataSegment - reinterpret_cast <const uint8_t *>(Buf.get ())
184
+ + ImageStart.getAddressData ();
185
+ auto DataSegmentEnd = DataSegmentStart + DataSize;
186
+ dataSegments.push_back (std::make_tuple (RemoteAddress (DataSegmentStart),
187
+ RemoteAddress (DataSegmentEnd)));
188
+ }
189
+
190
+ savedBuffers.push_back (std::move (Buf));
191
+
192
+ return true ;
193
+ }
194
+ #endif // defined(__APPLE__) && defined(__MACH__)
195
+
79
196
void addReflectionInfo (ReflectionInfo I) {
80
197
getBuilder ().addReflectionInfo (I);
81
198
}
82
-
199
+
200
+ bool ownsObject (RemoteAddress ObjectAddress) {
201
+ auto MetadataAddress = readMetadataFromInstance (ObjectAddress.getAddressData ());
202
+ if (!MetadataAddress)
203
+ return 0 ;
204
+
205
+ for (auto Segment : dataSegments) {
206
+ auto Start = std::get<0 >(Segment);
207
+ auto End = std::get<1 >(Segment);
208
+ if (Start.getAddressData () <= *MetadataAddress
209
+ && *MetadataAddress < End.getAddressData ())
210
+ return 1 ;
211
+ }
212
+
213
+ return 0 ;
214
+ }
215
+
83
216
// / Return a description of the layout of a class instance with the given
84
217
// / metadata as its isa pointer.
85
218
const TypeInfo *getMetadataTypeInfo (StoredPointer MetadataAddress) {
0 commit comments