|
18 | 18 | #ifndef SWIFT_REFLECTION_REFLECTIONCONTEXT_H
|
19 | 19 | #define SWIFT_REFLECTION_REFLECTIONCONTEXT_H
|
20 | 20 |
|
| 21 | +#include "llvm/BinaryFormat/COFF.h" |
21 | 22 | #include "llvm/BinaryFormat/MachO.h"
|
22 | 23 | #include "llvm/BinaryFormat/ELF.h"
|
| 24 | +#include "llvm/Object/COFF.h" |
23 | 25 |
|
24 | 26 | #include "swift/Remote/MemoryReader.h"
|
25 | 27 | #include "swift/Remote/MetadataReader.h"
|
@@ -286,6 +288,100 @@ class ReflectionContext
|
286 | 288 | return readMachOSections<MachOTraits<8>>(ImageStart);
|
287 | 289 | return false;
|
288 | 290 | }
|
| 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 | + |
289 | 385 | #else // ELF platforms.
|
290 | 386 | template <typename T> bool readELFSections(RemoteAddress ImageStart) {
|
291 | 387 | auto Buf =
|
|
0 commit comments