Skip to content

Commit 76b31a9

Browse files
committed
swift-reflection-test: Increase reading robustness
- Check return values from `read` - Make the reflstr section optional, as it can be stripped by -strip-reflection-names.
1 parent 0f62e66 commit 76b31a9

File tree

2 files changed

+125
-74
lines changed

2 files changed

+125
-74
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,8 @@ class ReflectionContext {
564564
for (auto Info : ReflectionInfos) {
565565
for (auto &FieldDescriptor : Info.fieldmd) {
566566
auto CandidateMangledName = FieldDescriptor.MangledTypeName.get();
567+
if (!CandidateMangledName)
568+
continue;
567569
if (MangledName.compare(CandidateMangledName) != 0)
568570
continue;
569571
for (auto &Field : FieldDescriptor) {

tools/swift-reflection-test/swift-reflection-test.cpp

Lines changed: 123 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -204,47 +204,77 @@ static int doDumpReflectionSections(std::string BinaryFilename,
204204
}
205205

206206
namespace {
207+
template <typename Runtime>
207208
struct Section {
208-
addr_t StartAddress;
209-
addr_t Size;
210-
211-
addr_t getEndAddress() const {
209+
using StoredPointer = typename Runtime::StoredPointer;
210+
StoredPointer StartAddress;
211+
StoredPointer Size;
212+
StoredPointer getEndAddress() const {
212213
return StartAddress + Size;
213214
}
214215
};
215216

217+
template <typename Runtime>
216218
struct RemoteReflectionInfo {
219+
using StoredPointer = typename Runtime::StoredPointer;
220+
using StoredSize = typename Runtime::StoredSize;
221+
217222
const std::string ImageName;
218-
const Section fieldmd;
219-
const Section assocty;
220-
const Section reflstr;
221-
const Section typeref;
222-
const addr_t StartAddress;
223-
const size_t TotalSize;
224-
225-
RemoteReflectionInfo(std::string ImageName, Section fieldmd, Section assocty,
226-
Section reflstr, Section typeref)
227-
: fieldmd(fieldmd), assocty(assocty), reflstr(reflstr), typeref(typeref),
223+
const Section<Runtime> fieldmd;
224+
const Section<Runtime> assocty;
225+
const llvm::Optional<Section<Runtime>> reflstr;
226+
const Section<Runtime> typeref;
227+
const StoredPointer StartAddress;
228+
const StoredSize TotalSize;
229+
230+
RemoteReflectionInfo(std::string ImageName,
231+
Section<Runtime> fieldmd,
232+
Section<Runtime> assocty,
233+
llvm::Optional<Section<Runtime>> reflstr,
234+
Section<Runtime> typeref)
235+
: ImageName(ImageName),
236+
fieldmd(fieldmd),
237+
assocty(assocty),
238+
reflstr(reflstr),
239+
typeref(typeref),
228240
StartAddress(std::min({
229-
fieldmd.StartAddress, typeref.StartAddress,
230-
reflstr.StartAddress, assocty.StartAddress})),
231-
TotalSize(std::max({fieldmd.getEndAddress(), assocty.getEndAddress(),
232-
reflstr.getEndAddress(), typeref.getEndAddress()}) - StartAddress) {}
241+
fieldmd.StartAddress,
242+
typeref.StartAddress,
243+
reflstr.hasValue()
244+
? reflstr.getValue().StartAddress
245+
: fieldmd.StartAddress,
246+
assocty.StartAddress})),
247+
TotalSize(std::max({
248+
fieldmd.getEndAddress(),
249+
assocty.getEndAddress(),
250+
reflstr.hasValue()
251+
? reflstr.getValue().getEndAddress()
252+
: fieldmd.getEndAddress(),
253+
typeref.getEndAddress()
254+
}) - StartAddress) {}
233255
};
234256
}
235257

236-
template <typename StoredPointer>
258+
template <typename Runtime>
237259
class PipeMemoryReader : public MemoryReader {
260+
using StoredPointer = typename Runtime::StoredPointer;
261+
238262
static constexpr size_t ReadEnd = 0;
239263
static constexpr size_t WriteEnd = 1;
240-
static constexpr size_t ParentEnd = 1;
241-
static constexpr size_t ChildEnd = 0;
242264

243265
int to_child[2];
244266
int from_child[2];
245267

246268
public:
247269

270+
int getParentReadFD() const {
271+
return from_child[ReadEnd];
272+
}
273+
274+
int getChildWriteFD() const {
275+
return from_child[WriteEnd];
276+
}
277+
248278
int getParentWriteFD() const {
249279
return to_child[WriteEnd];
250280
}
@@ -253,13 +283,6 @@ class PipeMemoryReader : public MemoryReader {
253283
return to_child[ReadEnd];
254284
}
255285

256-
int getParentReadFD() const {
257-
return from_child[ReadEnd];
258-
}
259-
260-
int getChildWriteFD() const {
261-
return from_child[WriteEnd];
262-
}
263286

264287
PipeMemoryReader() {
265288
if (pipe(to_child))
@@ -278,19 +301,33 @@ class PipeMemoryReader : public MemoryReader {
278301
return 8;
279302
}
280303

304+
template <typename T>
305+
void collectBytesFromPipe(T *Value, size_t Size) {
306+
auto Dest = reinterpret_cast<uint8_t *>(&Value);
307+
while (Size) {
308+
auto bytesRead = read(getParentReadFD(), Value, Size);
309+
if (bytesRead <= 0)
310+
errorAndExit("collectBytesFromPipe");
311+
Size -= bytesRead;
312+
Dest += bytesRead;
313+
}
314+
}
315+
281316
bool readBytes(addr_t Address, uint8_t *Dest, uint64_t Size) override {
317+
318+
StoredPointer TargetAddress = (StoredPointer)Address;
282319
write(getParentWriteFD(), REQUEST_READ_BYTES, 2);
283-
write(getParentWriteFD(), &Address, sizeof(Address));
320+
write(getParentWriteFD(), &TargetAddress, sizeof(TargetAddress));
284321
write(getParentWriteFD(), &Size, sizeof(Size));
285-
auto bytesRead = read(getParentReadFD(), Dest, Size);
286-
return bytesRead == (int64_t)Size;
322+
collectBytesFromPipe(Dest, Size);
323+
return true;
287324
}
288325

289-
uint64_t getParentWriteFD(addr_t Address) {
326+
uint64_t getParentWriteFD(StoredPointer Address) {
290327
write(getParentWriteFD(), REQUEST_STRING_LENGTH, 2);
291328
StoredPointer Length;
292329
write(getParentWriteFD(), &Address, sizeof(Address));
293-
read(getParentReadFD(), &Length, sizeof(Length));
330+
collectBytesFromPipe(&Length, sizeof(Length));
294331
return static_cast<uint64_t>(Length);
295332
}
296333

@@ -299,14 +336,14 @@ class PipeMemoryReader : public MemoryReader {
299336
write(getParentWriteFD(), REQUEST_SYMBOL_ADDRESS, 2);
300337
write(getParentWriteFD(), SymbolName.c_str(), SymbolName.size());
301338
write(getParentWriteFD(), "\n", 1);
302-
read(getParentReadFD(), &Address, sizeof(Address));
303-
return static_cast<addr_t>(Address);
339+
collectBytesFromPipe(&Address, sizeof(Address));
340+
return static_cast<StoredPointer>(Address);
304341
}
305342

306-
addr_t receiveInstanceAddress() {
343+
StoredPointer receiveInstanceAddress() {
307344
write(getParentWriteFD(), REQUEST_INSTANCE_ADDRESS, 2);
308-
addr_t InstanceAddress = 0;
309-
read(getParentReadFD(), &InstanceAddress, sizeof(InstanceAddress));
345+
StoredPointer InstanceAddress = 0;
346+
collectBytesFromPipe(&InstanceAddress, sizeof(InstanceAddress));
310347
return InstanceAddress;
311348
}
312349

@@ -316,50 +353,52 @@ class PipeMemoryReader : public MemoryReader {
316353

317354
uint8_t receivePointerSize() {
318355
write(getParentWriteFD(), REQUEST_POINTER_SIZE, 2);
319-
uint8_t PointerSize;
320-
read(getParentReadFD(), &PointerSize, sizeof(PointerSize));
356+
uint8_t PointerSize = 0;
357+
collectBytesFromPipe(&PointerSize, sizeof(PointerSize));
321358
return PointerSize;
322359
}
323360

324361
std::vector<ReflectionInfo> receiveReflectionInfo() {
325362
write(getParentWriteFD(), REQUEST_REFLECTION_INFO, 2);
326363
uint64_t NumReflectionInfos = 0;
327-
read(getParentReadFD(), &NumReflectionInfos, sizeof(NumReflectionInfos));
364+
collectBytesFromPipe(&NumReflectionInfos, sizeof(NumReflectionInfos));
328365

329-
std::vector<RemoteReflectionInfo> RemoteInfos;
366+
std::vector<RemoteReflectionInfo<Runtime>> RemoteInfos;
330367
for (uint64_t i = 0; i < NumReflectionInfos; ++i) {
331368
uint64_t ImageNameLength;
332-
read(getParentReadFD(), &ImageNameLength, sizeof(ImageNameLength));
369+
collectBytesFromPipe(&ImageNameLength, sizeof(ImageNameLength));
333370
char c;
334371
std::string ImageName;
335372
for (uint64_t i = 0; i < ImageNameLength; ++i) {
336-
read(getParentReadFD(), &c, 1);
373+
collectBytesFromPipe(&c, 1);
337374
ImageName.push_back(c);
338375
}
339376

340-
addr_t fieldmd_start;
341-
addr_t fieldmd_size;
342-
addr_t typeref_start;
343-
addr_t typeref_size;
344-
addr_t reflstr_start;
345-
addr_t reflstr_size;
346-
addr_t assocty_start;
347-
addr_t assocty_size;
348-
349-
read(getParentReadFD(), &fieldmd_start, sizeof(fieldmd_start));
350-
read(getParentReadFD(), &fieldmd_size, sizeof(fieldmd_size));
351-
read(getParentReadFD(), &typeref_start, sizeof(typeref_start));
352-
read(getParentReadFD(), &typeref_size, sizeof(typeref_size));
353-
read(getParentReadFD(), &reflstr_start, sizeof(reflstr_start));
354-
read(getParentReadFD(), &reflstr_size, sizeof(reflstr_size));
355-
read(getParentReadFD(), &assocty_start, sizeof(assocty_start));
356-
read(getParentReadFD(), &assocty_size, sizeof(assocty_size));
377+
StoredPointer fieldmd_start;
378+
StoredPointer fieldmd_size;
379+
StoredPointer typeref_start;
380+
StoredPointer typeref_size;
381+
StoredPointer reflstr_start;
382+
StoredPointer reflstr_size;
383+
StoredPointer assocty_start;
384+
StoredPointer assocty_size;
385+
386+
collectBytesFromPipe(&fieldmd_start, sizeof(fieldmd_start));
387+
collectBytesFromPipe(&fieldmd_size, sizeof(fieldmd_size));
388+
collectBytesFromPipe(&typeref_start, sizeof(typeref_start));
389+
collectBytesFromPipe(&typeref_size, sizeof(typeref_size));
390+
collectBytesFromPipe(&reflstr_start, sizeof(reflstr_start));
391+
collectBytesFromPipe(&reflstr_size, sizeof(reflstr_size));
392+
collectBytesFromPipe(&assocty_start, sizeof(assocty_start));
393+
collectBytesFromPipe(&assocty_size, sizeof(assocty_size));
357394

358395
RemoteInfos.push_back({
359396
ImageName,
360397
{fieldmd_start, fieldmd_size},
361398
{typeref_start, typeref_size},
362-
{reflstr_start, reflstr_size},
399+
reflstr_size > 0
400+
? llvm::Optional<Section<Runtime>>({reflstr_start, reflstr_size})
401+
: llvm::None,
363402
{assocty_start, assocty_size},
364403
});
365404
}
@@ -369,29 +408,39 @@ class PipeMemoryReader : public MemoryReader {
369408

370409
auto buffer = (uint8_t *)malloc(RemoteInfo.TotalSize);
371410

372-
readBytes(RemoteInfo.StartAddress, buffer, RemoteInfo.TotalSize);
373-
374-
auto fieldmd_base = buffer + RemoteInfo.fieldmd.StartAddress - RemoteInfo.StartAddress;
375-
auto typeref_base = buffer + RemoteInfo.typeref.StartAddress - RemoteInfo.StartAddress;
376-
auto reflstr_base = buffer + RemoteInfo.reflstr.StartAddress - RemoteInfo.StartAddress;
377-
auto assocty_base = buffer + RemoteInfo.assocty.StartAddress - RemoteInfo.StartAddress;
411+
if (!readBytes(RemoteInfo.StartAddress, buffer, RemoteInfo.TotalSize))
412+
errorAndExit("Couldn't read reflection information");
413+
414+
auto fieldmd_base
415+
= buffer + RemoteInfo.fieldmd.StartAddress - RemoteInfo.StartAddress;
416+
auto typeref_base
417+
= buffer + RemoteInfo.typeref.StartAddress - RemoteInfo.StartAddress;
418+
auto reflstr_base
419+
= RemoteInfo.reflstr.hasValue()
420+
? buffer + RemoteInfo.reflstr.getValue().StartAddress
421+
- RemoteInfo.StartAddress
422+
: 0;
423+
auto assocty_base
424+
= buffer + RemoteInfo.assocty.StartAddress - RemoteInfo.StartAddress;
378425
ReflectionInfo Info {
379426
RemoteInfo.ImageName,
380427
{fieldmd_base, fieldmd_base + RemoteInfo.fieldmd.Size},
381428
{typeref_base, typeref_base + RemoteInfo.typeref.Size},
382-
{reflstr_base, reflstr_base + RemoteInfo.reflstr.Size},
429+
{reflstr_base, reflstr_base + (RemoteInfo.reflstr.hasValue()
430+
? RemoteInfo.reflstr.getValue().Size
431+
: 0)},
383432
{assocty_base, assocty_base + RemoteInfo.assocty.Size},
384433
};
385434
Infos.push_back(Info);
386435
}
387436
return Infos;
388437
}
389438

390-
uint64_t getStringLength(addr_t Address) {
439+
uint64_t getStringLength(StoredPointer Address) {
391440
write(getParentWriteFD(), REQUEST_STRING_LENGTH, 2);
392441
StoredPointer Length;
393442
write(getParentWriteFD(), &Address, sizeof(Address));
394-
read(getParentReadFD(), &Length, sizeof(Length));
443+
collectBytesFromPipe(&Length, sizeof(Length));
395444
return static_cast<uint64_t>(Length);
396445
}
397446

@@ -411,7 +460,7 @@ template <typename Runtime>
411460
static int doDumpHeapInstance(std::string BinaryFilename) {
412461
using StoredPointer = typename Runtime::StoredPointer;
413462

414-
PipeMemoryReader<StoredPointer> Pipe;
463+
PipeMemoryReader<Runtime> Pipe;
415464

416465
pid_t pid = fork();
417466
switch (pid) {
@@ -436,12 +485,12 @@ static int doDumpHeapInstance(std::string BinaryFilename) {
436485
if (PointerSize != Runtime::PointerSize)
437486
errorAndExit("Child process had unexpected architecture");
438487

439-
addr_t instance = Pipe.receiveInstanceAddress();
488+
StoredPointer instance = Pipe.receiveInstanceAddress();
440489
assert(instance);
441490
std::cerr << "Parent: instance pointer in child address space: 0x";
442491
std::cerr << std::hex << instance << std::endl;
443492

444-
addr_t isa;
493+
StoredPointer isa;
445494
if (!Pipe.readInteger(instance, &isa))
446495
errorAndExit("Couldn't get heap object's metadata address");
447496

0 commit comments

Comments
 (0)