Skip to content

Commit 6f8b2bf

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-rebranch
2 parents eb2ec9d + 12bf25e commit 6f8b2bf

File tree

7 files changed

+168
-255
lines changed

7 files changed

+168
-255
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 101 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "swift/Reflection/TypeRef.h"
3131
#include "swift/Reflection/TypeRefBuilder.h"
3232
#include "swift/Runtime/Unreachable.h"
33-
#include "../../../stdlib/public/runtime/ImageInspectionELF.h"
3433

3534
#include <iostream>
3635
#include <set>
@@ -60,15 +59,15 @@ template <unsigned char ELFClass> struct ELFTraits;
6059

6160
template <> struct ELFTraits<llvm::ELF::ELFCLASS32> {
6261
using Header = const struct llvm::ELF::Elf32_Ehdr;
63-
using ProgramHeader = const struct llvm::ELF::Elf32_Phdr;
62+
using Section = const struct llvm::ELF::Elf32_Shdr;
6463
using Offset = llvm::ELF::Elf32_Off;
6564
using Size = llvm::ELF::Elf32_Word;
6665
static constexpr unsigned char ELFClass = llvm::ELF::ELFCLASS32;
6766
};
6867

6968
template <> struct ELFTraits<llvm::ELF::ELFCLASS64> {
7069
using Header = const struct llvm::ELF::Elf64_Ehdr;
71-
using ProgramHeader = const struct llvm::ELF::Elf64_Phdr;
70+
using Section = const struct llvm::ELF::Elf64_Shdr;
7271
using Offset = llvm::ELF::Elf64_Off;
7372
using Size = llvm::ELF::Elf64_Xword;
7473
static constexpr unsigned char ELFClass = llvm::ELF::ELFCLASS64;
@@ -113,7 +112,7 @@ class ReflectionContext
113112

114113
ReflectionContext(const ReflectionContext &other) = delete;
115114
ReflectionContext &operator=(const ReflectionContext &other) = delete;
116-
115+
117116
MemoryReader &getReader() {
118117
return *this->Reader;
119118
}
@@ -196,9 +195,9 @@ class ReflectionContext
196195
// introduce misaligned pointers mapping between local and remote
197196
// address space.
198197
RangeStart = RangeStart & ~7;
199-
RangeEnd = RangeEnd + 7 & ~7;
198+
RangeEnd = RangeEnd + 7 & ~7;
200199
}
201-
200+
202201
if (RangeStart == UINT64_MAX && RangeEnd == UINT64_MAX)
203202
return false;
204203

@@ -238,18 +237,13 @@ class ReflectionContext
238237
ReflStrMdSec.first == nullptr)
239238
return false;
240239

241-
auto LocalStartAddress = reinterpret_cast<uint64_t>(SectBuf.get());
242-
auto RemoteStartAddress = static_cast<uint64_t>(RangeStart);
243-
244240
ReflectionInfo info = {
245241
{FieldMdSec.first, FieldMdSec.second},
246242
{AssocTySec.first, AssocTySec.second},
247243
{BuiltinTySec.first, BuiltinTySec.second},
248244
{CaptureSec.first, CaptureSec.second},
249245
{TypeRefMdSec.first, TypeRefMdSec.second},
250-
{ReflStrMdSec.first, ReflStrMdSec.second},
251-
LocalStartAddress,
252-
RemoteStartAddress};
246+
{ReflStrMdSec.first, ReflStrMdSec.second}};
253247

254248
this->addReflectionInfo(info);
255249

@@ -347,19 +341,13 @@ class ReflectionContext
347341
ReflStrMdSec.first == nullptr)
348342
return false;
349343

350-
auto LocalStartAddress = reinterpret_cast<uintptr_t>(DOSHdrBuf.get());
351-
auto RemoteStartAddress =
352-
static_cast<uintptr_t>(ImageStart.getAddressData());
353-
354344
ReflectionInfo Info = {
355345
{FieldMdSec.first, FieldMdSec.second},
356346
{AssocTySec.first, AssocTySec.second},
357347
{BuiltinTySec.first, BuiltinTySec.second},
358348
{CaptureSec.first, CaptureSec.second},
359349
{TypeRefMdSec.first, TypeRefMdSec.second},
360-
{ReflStrMdSec.first, ReflStrMdSec.second},
361-
LocalStartAddress,
362-
RemoteStartAddress};
350+
{ReflStrMdSec.first, ReflStrMdSec.second}};
363351
this->addReflectionInfo(Info);
364352
return true;
365353
}
@@ -387,105 +375,110 @@ class ReflectionContext
387375
}
388376

389377
template <typename T> bool readELFSections(RemoteAddress ImageStart) {
390-
auto HeaderBuf =
378+
auto Buf =
391379
this->getReader().readBytes(ImageStart, sizeof(typename T::Header));
392380

393-
auto Hdr = reinterpret_cast<const typename T::Header *>(HeaderBuf.get());
381+
auto Hdr = reinterpret_cast<const typename T::Header *>(Buf.get());
394382
assert(Hdr->getFileClass() == T::ELFClass && "invalid ELF file class");
395383

396-
const auto ProgramHdrAddress = ImageStart.getAddressData() + Hdr->e_phoff;
397-
const auto NumEntries = Hdr->e_phnum;
398-
const auto EntrySize = Hdr->e_phentsize;
399-
400-
uintptr_t MetadataSectionsPtrValue = 0;
401-
for (unsigned I = 0; I < NumEntries; ++I) {
402-
const StringRef MagicString =
403-
SWIFT_REFLECTION_METADATA_ELF_NOTE_MAGIC_STRING;
404-
auto ProgramHdrBuf = this->getReader().readBytes(
405-
RemoteAddress(ProgramHdrAddress + (I * EntrySize)), EntrySize);
406-
auto ProgramHdr = reinterpret_cast<const typename T::ProgramHeader *>(
407-
ProgramHdrBuf.get());
408-
if (ProgramHdr->p_type != llvm::ELF::PT_NOTE ||
409-
ProgramHdr->p_memsz <= MagicString.size())
410-
continue;
411-
const auto SegmentAddr =
412-
ImageStart.getAddressData() + ProgramHdr->p_vaddr;
413-
const auto SegmentSize = ProgramHdr->p_memsz;
414-
auto SegmentBuf =
415-
this->getReader().readBytes(RemoteAddress(SegmentAddr), SegmentSize);
416-
const char *SegmentData =
417-
reinterpret_cast<const char *>(SegmentBuf.get());
418-
if (!StringRef(SegmentData, SegmentSize).startswith(MagicString))
419-
continue;
420-
MetadataSectionsPtrValue = *reinterpret_cast<const uintptr_t *>(
421-
SegmentData + MagicString.size() + 1);
422-
break;
384+
// From the header, grab informations about the section header table.
385+
auto SectionHdrAddress = ImageStart.getAddressData() + Hdr->e_shoff;
386+
auto SectionHdrNumEntries = Hdr->e_shnum;
387+
auto SectionEntrySize = Hdr->e_shentsize;
388+
389+
// Collect all the section headers, we need them to look up the
390+
// reflection sections (by name) and the string table.
391+
std::vector<const typename T::Section *> SecHdrVec;
392+
for (unsigned I = 0; I < SectionHdrNumEntries; ++I) {
393+
auto SecBuf = this->getReader().readBytes(
394+
RemoteAddress(SectionHdrAddress + (I * SectionEntrySize)),
395+
SectionEntrySize);
396+
auto SecHdr =
397+
reinterpret_cast<const typename T::Section *>(SecBuf.get());
398+
SecHdrVec.push_back(SecHdr);
423399
}
424-
if (!MetadataSectionsPtrValue)
425-
return false;
426400

427-
auto MetadataSectionsStructBuf = this->getReader().readBytes(
428-
RemoteAddress(MetadataSectionsPtrValue), sizeof(MetadataSections));
429-
const auto *Sections = reinterpret_cast<const MetadataSections *>(
430-
MetadataSectionsStructBuf.get());
431-
432-
auto BeginAddr = std::min(
433-
{Sections->swift5_fieldmd.start, Sections->swift5_assocty.start,
434-
Sections->swift5_builtin.start, Sections->swift5_capture.start,
435-
Sections->swift5_typeref.start, Sections->swift5_reflstr.start});
436-
auto EndAddr = std::max({
437-
Sections->swift5_fieldmd.start + Sections->swift5_fieldmd.length,
438-
Sections->swift5_assocty.start + Sections->swift5_assocty.length,
439-
Sections->swift5_builtin.start + Sections->swift5_builtin.length,
440-
Sections->swift5_capture.start + Sections->swift5_capture.length,
441-
Sections->swift5_typeref.start + Sections->swift5_typeref.length,
442-
Sections->swift5_reflstr.start + Sections->swift5_reflstr.length,
443-
});
444-
445-
// Extend the range [BeginAddr, EndAddr) to include the data segments.
446-
for (unsigned I = 0; I < NumEntries; ++I) {
447-
auto ProgramHdrBuf = this->getReader().readBytes(
448-
RemoteAddress(ProgramHdrAddress + (I * EntrySize)), EntrySize);
449-
auto ProgramHdr = reinterpret_cast<const typename T::ProgramHeader *>(
450-
ProgramHdrBuf.get());
451-
if (ProgramHdr->p_type == llvm::ELF::PT_LOAD &&
452-
ProgramHdr->p_flags & (llvm::ELF::PF_W & llvm::ELF::PF_R)) {
453-
const decltype(BeginAddr) SegmentBeginAddr =
454-
ImageStart.getAddressData() + ProgramHdr->p_vaddr;
455-
const decltype(BeginAddr) SegmentEndAddr =
456-
SegmentBeginAddr + ProgramHdr->p_memsz;
457-
BeginAddr = std::min(BeginAddr, SegmentBeginAddr);
458-
EndAddr = std::max(EndAddr, SegmentEndAddr);
459-
}
401+
// This provides quick access to the section header string table index.
402+
// We also here handle the unlikely even where the section index overflows
403+
// and it's just a pointer to secondary storage (SHN_XINDEX).
404+
uint32_t SecIdx = Hdr->e_shstrndx;
405+
if (SecIdx == llvm::ELF::SHN_XINDEX) {
406+
assert(!SecHdrVec.empty() && "malformed ELF object");
407+
SecIdx = SecHdrVec[0]->sh_link;
460408
}
461409

462-
auto Buf = this->getReader().readBytes(RemoteAddress(BeginAddr),
463-
EndAddr - BeginAddr);
464-
auto RemoteAddrToRemoteRef = [&](uintptr_t Addr) -> RemoteRef<void> {
465-
return RemoteRef<void>(
466-
Addr, reinterpret_cast<void *>(
467-
reinterpret_cast<uintptr_t>(Buf.get()) + Addr - BeginAddr));
410+
assert(SecIdx < SecHdrVec.size() && "malformed ELF object");
411+
412+
const typename T::Section *SecHdrStrTab = SecHdrVec[SecIdx];
413+
typename T::Offset StrTabOffset = SecHdrStrTab->sh_offset;
414+
typename T::Size StrTabSize = SecHdrStrTab->sh_size;
415+
416+
auto StrTabStart =
417+
RemoteAddress(ImageStart.getAddressData() + StrTabOffset);
418+
auto StrTabBuf = this->getReader().readBytes(StrTabStart, StrTabSize);
419+
auto StrTab = reinterpret_cast<const char *>(StrTabBuf.get());
420+
421+
auto findELFSectionByName = [&](std::string Name)
422+
-> std::pair<RemoteRef<void>, uint64_t> {
423+
// Now for all the sections, find their name.
424+
for (const typename T::Section *Hdr : SecHdrVec) {
425+
uint32_t Offset = Hdr->sh_name;
426+
auto SecName = std::string(StrTab + Offset);
427+
if (SecName != Name)
428+
continue;
429+
auto SecStart =
430+
RemoteAddress(ImageStart.getAddressData() + Hdr->sh_addr);
431+
auto SecSize = Hdr->sh_size;
432+
auto SecBuf = this->getReader().readBytes(SecStart, SecSize);
433+
auto SecContents = RemoteRef<void>(SecStart.getAddressData(),
434+
SecBuf.get());
435+
savedBuffers.push_back(std::move(SecBuf));
436+
return {SecContents, SecSize};
437+
}
438+
return {nullptr, 0};
468439
};
469-
#define SECTION_INFO(NAME) \
470-
{RemoteAddrToRemoteRef(Sections->NAME.start), Sections->NAME.length}
471-
ReflectionInfo Info = {
472-
SECTION_INFO(swift5_fieldmd), SECTION_INFO(swift5_assocty),
473-
SECTION_INFO(swift5_builtin), SECTION_INFO(swift5_capture),
474-
SECTION_INFO(swift5_typeref), SECTION_INFO(swift5_reflstr),
475-
reinterpret_cast<uint64_t>(Buf.get()), BeginAddr};
476-
#undef SECTION_INFO
477-
this->addReflectionInfo(Info);
440+
441+
auto FieldMdSec = findELFSectionByName("swift5_fieldmd");
442+
auto AssocTySec = findELFSectionByName("swift5_assocty");
443+
auto BuiltinTySec = findELFSectionByName("swift5_builtin");
444+
auto CaptureSec = findELFSectionByName("swift5_capture");
445+
auto TypeRefMdSec = findELFSectionByName("swift5_typeref");
446+
auto ReflStrMdSec = findELFSectionByName("swift5_reflstr");
447+
448+
// We succeed if at least one of the sections is present in the
449+
// ELF executable.
450+
if (FieldMdSec.first == nullptr &&
451+
AssocTySec.first == nullptr &&
452+
BuiltinTySec.first == nullptr &&
453+
CaptureSec.first == nullptr &&
454+
TypeRefMdSec.first == nullptr &&
455+
ReflStrMdSec.first == nullptr)
456+
return false;
457+
458+
ReflectionInfo info = {
459+
{FieldMdSec.first, FieldMdSec.second},
460+
{AssocTySec.first, AssocTySec.second},
461+
{BuiltinTySec.first, BuiltinTySec.second},
462+
{CaptureSec.first, CaptureSec.second},
463+
{TypeRefMdSec.first, TypeRefMdSec.second},
464+
{ReflStrMdSec.first, ReflStrMdSec.second}};
465+
466+
this->addReflectionInfo(info);
467+
478468
savedBuffers.push_back(std::move(Buf));
479469
return true;
480470
}
481-
471+
482472
bool readELF(RemoteAddress ImageStart) {
483473
auto Buf =
484474
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
475+
485476
// Read the header.
486477
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
478+
487479
if (!Hdr->checkMagic())
488480
return false;
481+
489482
// Check if we have a ELFCLASS32 or ELFCLASS64
490483
unsigned char FileClass = Hdr->getFileClass();
491484
if (FileClass == llvm::ELF::ELFCLASS64) {
@@ -502,34 +495,34 @@ class ReflectionContext
502495
auto Magic = this->getReader().readBytes(ImageStart, sizeof(uint32_t));
503496
if (!Magic)
504497
return false;
505-
498+
506499
uint32_t MagicWord;
507500
memcpy(&MagicWord, Magic.get(), sizeof(MagicWord));
508-
501+
509502
// 32- and 64-bit Mach-O.
510503
if (MagicWord == llvm::MachO::MH_MAGIC) {
511504
return readMachOSections<MachOTraits<4>>(ImageStart);
512505
}
513-
506+
514507
if (MagicWord == llvm::MachO::MH_MAGIC_64) {
515508
return readMachOSections<MachOTraits<8>>(ImageStart);
516509
}
517-
510+
518511
// PE. (This just checks for the DOS header; `readPECOFF` will further
519512
// validate the existence of the PE header.)
520513
auto MagicBytes = (const char*)Magic.get();
521514
if (MagicBytes[0] == 'M' && MagicBytes[1] == 'Z') {
522515
return readPECOFF(ImageStart);
523516
}
524-
517+
525518
// ELF.
526519
if (MagicBytes[0] == llvm::ELF::ElfMagic[0]
527520
&& MagicBytes[1] == llvm::ELF::ElfMagic[1]
528521
&& MagicBytes[2] == llvm::ELF::ElfMagic[2]
529522
&& MagicBytes[3] == llvm::ELF::ElfMagic[3]) {
530523
return readELF(ImageStart);
531524
}
532-
525+
533526
// We don't recognize the format.
534527
return false;
535528
}
@@ -544,7 +537,7 @@ class ReflectionContext
544537
return true;
545538
return ownsAddress(RemoteAddress(*MetadataAddress));
546539
}
547-
540+
548541
/// Returns true if the address falls within a registered image.
549542
bool ownsAddress(RemoteAddress Address) {
550543
for (auto Range : imageRanges) {
@@ -554,10 +547,10 @@ class ReflectionContext
554547
&& Address.getAddressData() < End.getAddressData())
555548
return true;
556549
}
557-
550+
558551
return false;
559552
}
560-
553+
561554
/// Return a description of the layout of a class instance with the given
562555
/// metadata as its isa pointer.
563556
const TypeInfo *getMetadataTypeInfo(StoredPointer MetadataAddress) {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,6 @@ struct ReflectionInfo {
203203
CaptureSection Capture;
204204
GenericSection TypeReference;
205205
GenericSection ReflectionString;
206-
207-
uint64_t LocalStartAddress;
208-
uint64_t RemoteStartAddress;
209206
};
210207

211208
struct ClosureContextInfo {

lib/Demangling/NodePrinter.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,18 @@ static DemanglerPrinter &operator<<(DemanglerPrinter &printer,
7979
case '\n': printer << "\\n"; break;
8080
case '\r': printer << "\\r"; break;
8181
case '"': printer << "\\\""; break;
82-
case '\'': printer << '\''; break; // no need to escape these
8382
case '\0': printer << "\\0"; break;
8483
default:
85-
auto c = static_cast<char>(C);
86-
// Other ASCII control characters should get escaped.
87-
if (c < 0x20 || c == 0x7F) {
84+
auto c = static_cast<unsigned char>(C);
85+
// Other control or high-bit characters should get escaped.
86+
if (c < 0x20 || c >= 0x7F) {
8887
static const char Hexdigit[] = {
8988
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
9089
'A', 'B', 'C', 'D', 'E', 'F'
9190
};
9291
printer << "\\x" << Hexdigit[c >> 4] << Hexdigit[c & 0xF];
9392
} else {
94-
printer << c;
93+
printer << (char)c;
9594
}
9695
break;
9796
}

stdlib/public/Reflection/TypeRefBuilder.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,13 @@ TypeRefBuilder::getBuiltinTypeInfo(const TypeRef *TR) {
268268
return nullptr;
269269
}
270270

271-
// TODO: This can probably be eliminated.
272271
RemoteRef<CaptureDescriptor>
273272
TypeRefBuilder::getCaptureDescriptor(uint64_t RemoteAddress) {
274273
for (auto Info : ReflectionInfos) {
275274
for (auto CD : Info.Capture) {
276-
auto OtherAddr = (reinterpret_cast<uint64_t>(CD.getLocalBuffer()) -
277-
Info.LocalStartAddress + Info.RemoteStartAddress);
278-
if (OtherAddr == RemoteAddress)
275+
if (RemoteAddress == CD.getAddressData()) {
279276
return CD;
277+
}
280278
}
281279
}
282280

0 commit comments

Comments
 (0)