@@ -128,7 +128,8 @@ class ReflectionContext
128
128
// / All buffers we need to keep around long term. This will automatically free them
129
129
// / when this object is destroyed.
130
130
std::vector<MemoryReader::ReadBytesResult> savedBuffers;
131
- std::vector<std::tuple<RemoteAddress, RemoteAddress>> imageRanges;
131
+ std::vector<std::tuple<RemoteAddress, RemoteAddress>> textRanges;
132
+ std::vector<std::tuple<RemoteAddress, RemoteAddress>> dataRanges;
132
133
133
134
bool setupTargetPointers = false ;
134
135
typename super::StoredPointer target_non_future_adapter = 0 ;
@@ -253,7 +254,7 @@ class ReflectionContext
253
254
uint64_t Offset = 0 ;
254
255
255
256
// Find the __TEXT segment.
256
- typename T::SegmentCmd *Command = nullptr ;
257
+ typename T::SegmentCmd *TextCommand = nullptr ;
257
258
for (unsigned I = 0 ; I < NumCommands; ++I) {
258
259
auto CmdBuf = this ->getReader ().readBytes (
259
260
RemoteAddress (CmdStartAddress.getAddressData () + Offset),
@@ -262,15 +263,15 @@ class ReflectionContext
262
263
return false ;
263
264
auto CmdHdr = reinterpret_cast <typename T::SegmentCmd *>(CmdBuf.get ());
264
265
if (strncmp (CmdHdr->segname , " __TEXT" , sizeof (CmdHdr->segname )) == 0 ) {
265
- Command = CmdHdr;
266
+ TextCommand = CmdHdr;
266
267
savedBuffers.push_back (std::move (CmdBuf));
267
268
break ;
268
269
}
269
270
Offset += CmdHdr->cmdsize ;
270
271
}
271
272
272
273
// No __TEXT segment, bail out.
273
- if (!Command )
274
+ if (!TextCommand )
274
275
return false ;
275
276
276
277
// Find the load command offset.
@@ -293,7 +294,7 @@ class ReflectionContext
293
294
if (!Sections)
294
295
return false ;
295
296
296
- auto Slide = ImageStart.getAddressData () - Command ->vmaddr ;
297
+ auto Slide = ImageStart.getAddressData () - TextCommand ->vmaddr ;
297
298
auto SectionsBuf = reinterpret_cast <const char *>(Sections.get ());
298
299
299
300
auto findMachOSectionByName = [&](llvm::StringRef Name)
@@ -357,22 +358,27 @@ class ReflectionContext
357
358
358
359
auto InfoID = this ->addReflectionInfo (info);
359
360
360
- // Find the __DATA segment.
361
+ auto TextSegmentStart = Slide + TextCommand->vmaddr ;
362
+ auto TextSegmentEnd = TextSegmentStart + TextCommand->vmsize ;
363
+ textRanges.push_back (std::make_tuple (RemoteAddress (TextSegmentStart),
364
+ RemoteAddress (TextSegmentEnd)));
365
+
366
+ // Find the __DATA segments.
361
367
for (unsigned I = 0 ; I < NumCommands; ++I) {
362
368
auto CmdBuf = this ->getReader ().readBytes (
363
369
RemoteAddress (CmdStartAddress.getAddressData () + Offset),
364
370
SegmentCmdHdrSize);
365
371
if (!CmdBuf)
366
372
return false ;
367
373
auto CmdHdr = reinterpret_cast <typename T::SegmentCmd *>(CmdBuf.get ());
368
- if (strncmp (CmdHdr->segname , " __DATA" , sizeof (CmdHdr->segname )) == 0 ) {
369
- auto DataSegmentEnd =
370
- ImageStart.getAddressData () + CmdHdr->vmaddr + CmdHdr->vmsize ;
371
- assert (DataSegmentEnd > ImageStart.getAddressData () &&
374
+ // Look for any segment name starting with __DATA.
375
+ if (strncmp (CmdHdr->segname , " __DATA" , 6 ) == 0 ) {
376
+ auto DataSegmentStart = Slide + CmdHdr->vmaddr ;
377
+ auto DataSegmentEnd = DataSegmentStart + CmdHdr->vmsize ;
378
+ assert (DataSegmentStart > ImageStart.getAddressData () &&
372
379
" invalid range for __DATA" );
373
- imageRanges.push_back (
374
- std::make_tuple (ImageStart, RemoteAddress (DataSegmentEnd)));
375
- break ;
380
+ dataRanges.push_back (std::make_tuple (RemoteAddress (DataSegmentStart),
381
+ RemoteAddress (DataSegmentEnd)));
376
382
}
377
383
Offset += CmdHdr->cmdsize ;
378
384
}
@@ -831,9 +837,11 @@ class ReflectionContext
831
837
return ownsAddress (RemoteAddress (*MetadataAddress));
832
838
}
833
839
834
- // / Returns true if the address falls within a registered image.
835
- bool ownsAddressRaw (RemoteAddress Address) {
836
- for (auto Range : imageRanges) {
840
+ // / Returns true if the address falls within the given address ranges.
841
+ bool ownsAddress (
842
+ RemoteAddress Address,
843
+ const std::vector<std::tuple<RemoteAddress, RemoteAddress>> &ranges) {
844
+ for (auto Range : ranges) {
837
845
auto Start = std::get<0 >(Range);
838
846
auto End = std::get<1 >(Range);
839
847
if (Start.getAddressData () <= Address.getAddressData ()
@@ -845,11 +853,14 @@ class ReflectionContext
845
853
}
846
854
847
855
// / Returns true if the address is known to the reflection context.
848
- // / Currently, that means that either the address falls within a registered
849
- // / image, or the address points to a Metadata whose type context descriptor
850
- // / is within a registered image.
856
+ // / Currently, that means that either the address falls within the text or
857
+ // / data segments of a registered image, or the address points to a Metadata
858
+ // / whose type context descriptor is within the text segment of a registered
859
+ // / image.
851
860
bool ownsAddress (RemoteAddress Address) {
852
- if (ownsAddressRaw (Address))
861
+ if (ownsAddress (Address, textRanges))
862
+ return true ;
863
+ if (ownsAddress (Address, dataRanges))
853
864
return true ;
854
865
855
866
// This is usually called on a Metadata address which might have been
@@ -858,7 +869,7 @@ class ReflectionContext
858
869
if (auto Metadata = readMetadata (Address.getAddressData ()))
859
870
if (auto DescriptorAddress =
860
871
super::readAddressOfNominalTypeDescriptor (Metadata, true ))
861
- if (ownsAddressRaw (RemoteAddress (DescriptorAddress)))
872
+ if (ownsAddress (RemoteAddress (DescriptorAddress), textRanges ))
862
873
return true ;
863
874
864
875
return false ;
@@ -1208,6 +1219,8 @@ class ReflectionContext
1208
1219
super::readAddressOfNominalTypeDescriptor (Metadata);
1209
1220
if (!DescriptorAddress)
1210
1221
return false ;
1222
+ if (!ownsAddress (RemoteAddress (DescriptorAddress), textRanges))
1223
+ return false ;
1211
1224
1212
1225
auto DescriptorBytes =
1213
1226
getReader ().readBytes (RemoteAddress (DescriptorAddress),
0 commit comments