Skip to content

Add functionality that returns correct reflection section name for different object files (Mach-O, ELF, COFF) [master-next] #33415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions include/swift/ABI/ObjectFile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//===--- ObjectFile.h - Object File Related Information ------*- C++ -*-===//
//
// Object File related data structures.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_ABI_OBJECTFILE_H
#define SWIFT_ABI_OBJECTFILE_H

#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/StringRef.h"

namespace swift {

/// Represents the six reflection sections used by Swift
enum ReflectionSectionKind : uint8_t {
fieldmd,
assocty,
builtin,
capture,
typeref,
reflstr
};

/// Abstract base class responsible for providing the correct reflection section
/// string identifier for a given object file type (Mach-O, ELF, COFF).
class SwiftObjectFileFormat {
public:
virtual ~SwiftObjectFileFormat() {}
virtual llvm::StringRef getSectionName(ReflectionSectionKind section) = 0;
};

/// Responsible for providing the Mach-O reflection section identifiers.
class SwiftObjectFileFormatMachO : SwiftObjectFileFormat {
public:
llvm::StringRef getSectionName(ReflectionSectionKind section) override {
switch (section) {
case fieldmd:
return "__swift5_fieldmd";
case assocty:
return "__swift5_assocty";
case builtin:
return "__swift5_builtin";
case capture:
return "__swift5_capture";
case typeref:
return "__swift5_typeref";
case reflstr:
return "__swift5_reflstr";
}
llvm_unreachable("Section type not found.");
}
};

/// Responsible for providing the ELF reflection section identifiers.
class SwiftObjectFileFormatELF : SwiftObjectFileFormat {
public:
llvm::StringRef getSectionName(ReflectionSectionKind section) override {
switch (section) {
case fieldmd:
return "swift5_fieldmd";
case assocty:
return "swift5_assocty";
case builtin:
return "swift5_builtin";
case capture:
return "swift5_capture";
case typeref:
return "swift5_typeref";
case reflstr:
return "swift5_reflstr";
}
llvm_unreachable("Section type not found.");
}
};

/// Responsible for providing the COFF reflection section identifiers
class SwiftObjectFileFormatCOFF : SwiftObjectFileFormat {
public:
llvm::StringRef getSectionName(ReflectionSectionKind section) override {
switch (section) {
case fieldmd:
return ".sw5flmd";
case assocty:
return ".sw5asty";
case builtin:
return ".sw5bltn";
case capture:
return ".sw5cptr";
case typeref:
return ".sw5tyrf";
case reflstr:
return ".sw5rfst";
}
llvm_unreachable("Section not found.");
}
};
} // namespace swift
#endif // SWIFT_ABI_OBJECTFILE_H
64 changes: 43 additions & 21 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/Object/COFF.h"

#include "swift/ABI/Enum.h"
#include "swift/ABI/ObjectFile.h"
#include "swift/Remote/MemoryReader.h"
#include "swift/Remote/MetadataReader.h"
#include "swift/Reflection/Records.h"
Expand Down Expand Up @@ -210,12 +211,12 @@ class ReflectionContext
auto SectBuf = this->getReader().readBytes(RemoteAddress(RangeStart),
RangeEnd - RangeStart);

auto findMachOSectionByName = [&](std::string Name)
auto findMachOSectionByName = [&](llvm::StringRef Name)
-> std::pair<RemoteRef<void>, uint64_t> {
for (unsigned I = 0; I < NumSect; ++I) {
auto S = reinterpret_cast<typename T::Section *>(
SectionsBuf + (I * sizeof(typename T::Section)));
if (strncmp(S->sectname, Name.c_str(), strlen(Name.c_str())) != 0)
if (strncmp(S->sectname, Name.data(), strlen(Name.data())) != 0)
continue;
auto RemoteSecStart = S->addr + Slide;
auto SectBufData = reinterpret_cast<const char *>(SectBuf.get());
Expand All @@ -228,12 +229,19 @@ class ReflectionContext
return {nullptr, 0};
};

auto FieldMdSec = findMachOSectionByName("__swift5_fieldmd");
auto AssocTySec = findMachOSectionByName("__swift5_assocty");
auto BuiltinTySec = findMachOSectionByName("__swift5_builtin");
auto CaptureSec = findMachOSectionByName("__swift5_capture");
auto TypeRefMdSec = findMachOSectionByName("__swift5_typeref");
auto ReflStrMdSec = findMachOSectionByName("__swift5_reflstr");
SwiftObjectFileFormatMachO ObjectFileFormat;
auto FieldMdSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::fieldmd));
auto AssocTySec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::assocty));
auto BuiltinTySec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::builtin));
auto CaptureSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::capture));
auto TypeRefMdSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
auto ReflStrMdSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));

if (FieldMdSec.first == nullptr &&
AssocTySec.first == nullptr &&
Expand Down Expand Up @@ -330,12 +338,19 @@ class ReflectionContext
return {nullptr, 0};
};

auto CaptureSec = findCOFFSectionByName(".sw5cptr");
auto TypeRefMdSec = findCOFFSectionByName(".sw5tyrf");
auto FieldMdSec = findCOFFSectionByName(".sw5flmd");
auto AssocTySec = findCOFFSectionByName(".sw5asty");
auto BuiltinTySec = findCOFFSectionByName(".sw5bltn");
auto ReflStrMdSec = findCOFFSectionByName(".sw5rfst");
SwiftObjectFileFormatCOFF ObjectFileFormat;
auto FieldMdSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::fieldmd));
auto AssocTySec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::assocty));
auto BuiltinTySec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::builtin));
auto CaptureSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::capture));
auto TypeRefMdSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
auto ReflStrMdSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));

if (FieldMdSec.first == nullptr &&
AssocTySec.first == nullptr &&
Expand Down Expand Up @@ -424,7 +439,7 @@ class ReflectionContext
auto StrTabBuf = this->getReader().readBytes(StrTabStart, StrTabSize);
auto StrTab = reinterpret_cast<const char *>(StrTabBuf.get());

auto findELFSectionByName = [&](std::string Name)
auto findELFSectionByName = [&](llvm::StringRef Name)
-> std::pair<RemoteRef<void>, uint64_t> {
// Now for all the sections, find their name.
for (const typename T::Section *Hdr : SecHdrVec) {
Expand All @@ -444,12 +459,19 @@ class ReflectionContext
return {nullptr, 0};
};

auto FieldMdSec = findELFSectionByName("swift5_fieldmd");
auto AssocTySec = findELFSectionByName("swift5_assocty");
auto BuiltinTySec = findELFSectionByName("swift5_builtin");
auto CaptureSec = findELFSectionByName("swift5_capture");
auto TypeRefMdSec = findELFSectionByName("swift5_typeref");
auto ReflStrMdSec = findELFSectionByName("swift5_reflstr");
SwiftObjectFileFormatELF ObjectFileFormat;
auto FieldMdSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::fieldmd));
auto AssocTySec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::assocty));
auto BuiltinTySec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::builtin));
auto CaptureSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::capture));
auto TypeRefMdSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
auto ReflStrMdSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));

// We succeed if at least one of the sections is present in the
// ELF executable.
Expand Down