Skip to content

Commit 848b8ef

Browse files
author
Alexander Shaposhnikov
committed
[Reflection] Add first bits to support COFF
In this diff we add first bits to make reflection work on Windows, in particular, properly extract the metadata from the corresponding sections. With this diff box_descriptors.sil and capture_descriptors.sil start passing on Windows after some minor tweaks to the lit testing infrastructure.
1 parent 86d14a8 commit 848b8ef

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
#ifndef SWIFT_REFLECTION_REFLECTIONCONTEXT_H
1919
#define SWIFT_REFLECTION_REFLECTIONCONTEXT_H
2020

21+
#include "llvm/BinaryFormat/COFF.h"
2122
#include "llvm/BinaryFormat/MachO.h"
2223
#include "llvm/BinaryFormat/ELF.h"
24+
#include "llvm/Object/COFF.h"
2325

2426
#include "swift/Remote/MemoryReader.h"
2527
#include "swift/Remote/MetadataReader.h"
@@ -286,6 +288,100 @@ class ReflectionContext
286288
return readMachOSections<MachOTraits<8>>(ImageStart);
287289
return false;
288290
}
291+
292+
#elif defined(_WIN32)
293+
bool addImage(RemoteAddress ImageStart) {
294+
auto DOSHdrBuf = this->getReader().readBytes(
295+
ImageStart, sizeof(llvm::object::dos_header));
296+
auto DOSHdr =
297+
reinterpret_cast<const llvm::object::dos_header *>(DOSHdrBuf.get());
298+
auto COFFFileHdrAddr = ImageStart.getAddressData() +
299+
DOSHdr->AddressOfNewExeHeader +
300+
sizeof(llvm::COFF::PEMagic);
301+
302+
auto COFFFileHdrBuf = this->getReader().readBytes(
303+
RemoteAddress(COFFFileHdrAddr), sizeof(llvm::object::coff_file_header));
304+
auto COFFFileHdr = reinterpret_cast<const llvm::object::coff_file_header *>(
305+
COFFFileHdrBuf.get());
306+
307+
auto SectionTableAddr = COFFFileHdrAddr +
308+
sizeof(llvm::object::coff_file_header) +
309+
COFFFileHdr->SizeOfOptionalHeader;
310+
auto SectionTableBuf = this->getReader().readBytes(
311+
RemoteAddress(SectionTableAddr),
312+
sizeof(llvm::object::coff_section) * COFFFileHdr->NumberOfSections);
313+
314+
auto findCOFFSectionByName = [&](llvm::StringRef Name)
315+
-> std::pair<std::pair<const char *, const char *>, uint32_t> {
316+
for (size_t i = 0; i < COFFFileHdr->NumberOfSections; ++i) {
317+
const llvm::object::coff_section *COFFSec =
318+
reinterpret_cast<const llvm::object::coff_section *>(
319+
SectionTableBuf.get()) +
320+
i;
321+
llvm::StringRef SectionName =
322+
(COFFSec->Name[llvm::COFF::NameSize - 1] == 0)
323+
? COFFSec->Name
324+
: llvm::StringRef(COFFSec->Name, llvm::COFF::NameSize);
325+
if (SectionName != Name)
326+
continue;
327+
auto Addr = ImageStart.getAddressData() + COFFSec->PointerToRawData;
328+
auto Buf = this->getReader().readBytes(RemoteAddress(Addr),
329+
COFFSec->VirtualSize);
330+
const char *Begin = reinterpret_cast<const char *>(Buf.get());
331+
const char *End = Begin + COFFSec->VirtualSize;
332+
savedBuffers.push_back(std::move(Buf));
333+
return {{Begin, End},
334+
COFFSec->VirtualAddress - COFFSec->PointerToRawData};
335+
}
336+
return {{nullptr, nullptr}, 0};
337+
};
338+
339+
std::pair<std::pair<const char *, const char *>, uint32_t> CaptureSec =
340+
findCOFFSectionByName(".sw5cptr");
341+
std::pair<std::pair<const char *, const char *>, uint32_t> TypeRefMdSec =
342+
findCOFFSectionByName(".sw5tyrf");
343+
344+
// FIXME: Make use of .sw5flmd section (the section content appears to be
345+
// incorrect on Windows at the moment).
346+
std::pair<std::pair<const char *, const char *>, uint32_t> FieldMdSec = {
347+
{nullptr, nullptr}, 0};
348+
// FIXME: Make use of .sw5asty.
349+
std::pair<std::pair<const char *, const char *>, uint32_t> AssocTySec = {
350+
{nullptr, nullptr}, 0};
351+
// FIXME: Make use of .sw5bltn.
352+
std::pair<std::pair<const char *, const char *>, uint32_t> BuiltinTySec = {
353+
{nullptr, nullptr}, 0};
354+
// FIXME: Make use of .sw5repl.
355+
std::pair<std::pair<const char *, const char *>, uint32_t> ReflStrMdSec = {
356+
{nullptr, nullptr}, 0};
357+
358+
if (FieldMdSec.first.first == nullptr &&
359+
AssocTySec.first.first == nullptr &&
360+
BuiltinTySec.first.first == nullptr &&
361+
CaptureSec.first.first == nullptr &&
362+
TypeRefMdSec.first.first == nullptr &&
363+
ReflStrMdSec.first.first == nullptr)
364+
return false;
365+
auto LocalStartAddress = reinterpret_cast<uintptr_t>(DOSHdrBuf.get());
366+
auto RemoteStartAddress =
367+
static_cast<uintptr_t>(ImageStart.getAddressData());
368+
369+
ReflectionInfo Info = {
370+
{{FieldMdSec.first.first, FieldMdSec.first.second}, FieldMdSec.second},
371+
{{AssocTySec.first.first, AssocTySec.first.second}, AssocTySec.second},
372+
{{BuiltinTySec.first.first, BuiltinTySec.first.second},
373+
BuiltinTySec.second},
374+
{{CaptureSec.first.first, CaptureSec.first.second}, CaptureSec.second},
375+
{{TypeRefMdSec.first.first, TypeRefMdSec.first.second},
376+
TypeRefMdSec.second},
377+
{{ReflStrMdSec.first.first, ReflStrMdSec.first.second},
378+
ReflStrMdSec.second},
379+
LocalStartAddress,
380+
RemoteStartAddress};
381+
this->addReflectionInfo(Info);
382+
return true;
383+
}
384+
289385
#else // ELF platforms.
290386
template <typename T> bool readELFSections(RemoteAddress ImageStart) {
291387
auto Buf =

0 commit comments

Comments
 (0)