Skip to content
Merged
49 changes: 48 additions & 1 deletion include/swift/ABI/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,9 @@ namespace {

using TypeContextDescriptor = TargetTypeContextDescriptor<InProcess>;

template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
using ExternalTypeContextDescriptor = TargetTypeContextDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;

// FIXME: https://bugs.swift.org/browse/SR-1155
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-offsetof"
Expand Down Expand Up @@ -2106,7 +2109,10 @@ using ProtocolRequirement = TargetProtocolRequirement<InProcess>;

template<typename Runtime> struct TargetProtocolDescriptor;
using ProtocolDescriptor = TargetProtocolDescriptor<InProcess>;


template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
using ExternalProtocolDescriptor = TargetProtocolDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;

/// A witness table for a protocol.
///
/// With the exception of the initial protocol conformance descriptor,
Expand Down Expand Up @@ -2722,6 +2728,16 @@ struct TargetProtocolConformanceDescriptor final
return TypeRef.getTypeDescriptor(getTypeKind());
}

constexpr inline auto
getTypeRefDescriptorOffset() const -> typename Runtime::StoredSize {
return offsetof(typename std::remove_reference<decltype(*this)>::type, TypeRef);
}

constexpr inline auto
getProtocolDescriptorOffset() const -> typename Runtime::StoredSize {
return offsetof(typename std::remove_reference<decltype(*this)>::type, Protocol);
}

TargetContextDescriptor<Runtime> * __ptrauth_swift_type_descriptor *
_getTypeDescriptorLocation() const {
if (getTypeKind() != TypeReferenceKind::IndirectTypeDescriptor)
Expand Down Expand Up @@ -2840,6 +2856,12 @@ using TargetProtocolConformanceRecord =

using ProtocolConformanceRecord = TargetProtocolConformanceRecord<InProcess>;

template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
using ExternalProtocolConformanceDescriptor = TargetProtocolConformanceDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;

template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
using ExternalProtocolConformanceRecord = TargetProtocolConformanceRecord<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;

template<typename Runtime>
struct TargetGenericContext;

Expand Down Expand Up @@ -2876,6 +2898,11 @@ struct TargetContextDescriptor {
: 0;
}

constexpr inline auto
getParentOffset() const -> typename Runtime::StoredSize {
return offsetof(typename std::remove_reference<decltype(*this)>::type, Parent);
}

#ifndef NDEBUG
LLVM_ATTRIBUTE_DEPRECATED(void dump() const,
"only for use in the debugger");
Expand All @@ -2889,6 +2916,8 @@ struct TargetContextDescriptor {
};

using ContextDescriptor = TargetContextDescriptor<InProcess>;
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
using ExternalContextDescriptor = TargetContextDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;

inline bool isCImportedModuleName(llvm::StringRef name) {
// This does not include MANGLING_MODULE_CLANG_IMPORTER because that's
Expand All @@ -2908,13 +2937,21 @@ struct TargetModuleContextDescriptor final : TargetContextDescriptor<Runtime> {
return isCImportedModuleName(Name.get());
}

constexpr inline auto
getNameOffset() const -> typename Runtime::StoredSize {
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
}

static bool classof(const TargetContextDescriptor<Runtime> *cd) {
return cd->getKind() == ContextDescriptorKind::Module;
}
};

using ModuleContextDescriptor = TargetModuleContextDescriptor<InProcess>;

template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
using ExternalModuleContextDescriptor = TargetModuleContextDescriptor<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;

template<typename Runtime>
inline bool TargetContextDescriptor<Runtime>::isCImportedContext() const {
return getModuleContext()->isCImportedContext();
Expand Down Expand Up @@ -3413,6 +3450,11 @@ struct TargetProtocolDescriptor final
NumRequirements};
}

constexpr inline auto
getNameOffset() const -> typename Runtime::StoredSize {
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
}

/// Retrieve the requirement base descriptor address.
ConstTargetPointer<Runtime, TargetProtocolRequirement<Runtime>>
getRequirementBaseDescriptor() const {
Expand Down Expand Up @@ -4077,6 +4119,11 @@ class TargetTypeContextDescriptor
/// type's metadata. The returned value is measured in sizeof(StoredPointer).
int32_t getGenericArgumentOffset() const;

constexpr inline auto
getNameOffset() const -> typename Runtime::StoredSize {
return offsetof(typename std::remove_reference<decltype(*this)>::type, Name);
}

/// Return the start of the generic arguments array in the nominal
/// type's metadata. The returned value is measured in sizeof(StoredPointer).
const TargetMetadata<Runtime> * const *getGenericArguments(
Expand Down
18 changes: 16 additions & 2 deletions include/swift/ABI/ObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@

namespace swift {

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

/// Abstract base class responsible for providing the correct reflection section
Expand Down Expand Up @@ -47,6 +49,10 @@ class SwiftObjectFileFormatMachO : public SwiftObjectFileFormat {
return "__swift5_typeref";
case reflstr:
return "__swift5_reflstr";
case conform:
return "__swift5_proto";
case protocs:
return "__swift5_protos";
}
llvm_unreachable("Section type not found.");
}
Expand All @@ -69,6 +75,10 @@ class SwiftObjectFileFormatELF : public SwiftObjectFileFormat {
return "swift5_typeref";
case reflstr:
return "swift5_reflstr";
case conform:
return "swift5_protocol_conformances";
case protocs:
return "swift5_protocols";
}
llvm_unreachable("Section type not found.");
}
Expand All @@ -91,6 +101,10 @@ class SwiftObjectFileFormatCOFF : public SwiftObjectFileFormat {
return ".sw5tyrf";
case reflstr:
return ".sw5rfst";
case conform:
return ".sw5prtc$B";
case protocs:
return ".sw5prt$B";
}
llvm_unreachable("Section not found.");
}
Expand Down
15 changes: 15 additions & 0 deletions include/swift/Basic/RelativePointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,17 @@ class RelativeDirectPointerImpl {
return reinterpret_cast<PointerTy>(absolute);
}

/// Apply the offset to a parameter, instead of `this`.
PointerTy getRelative(void *base) const & {
// Check for null.
if (Nullable && RelativeOffset == 0)
return nullptr;

// The value is addressed relative to `base`.
uintptr_t absolute = detail::applyRelativeOffset(base, RelativeOffset);
return reinterpret_cast<PointerTy>(absolute);
}

/// A zero relative offset encodes a null reference.
bool isNull() const & {
return RelativeOffset == 0;
Expand Down Expand Up @@ -476,6 +487,10 @@ class RelativeDirectPointer<T, Nullable, Offset,
return this->get();
}

const typename super::ValueTy* getRelative(void *base) const & {
return this->super::getRelative(base);
}

using super::isNull;
};

Expand Down
34 changes: 25 additions & 9 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,9 @@ class ReflectionContext
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.data(), strlen(Name.data())) != 0)
if (strncmp(S->sectname, Name.data(), sizeof(S->sectname)) != 0)
continue;

auto RemoteSecStart = S->addr + Slide;
auto LocalSectBuf =
this->getReader().readBytes(RemoteAddress(RemoteSecStart), S->size);
Expand All @@ -247,13 +248,16 @@ class ReflectionContext
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
auto ReflStrMdSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
auto ConformMdSec = findMachOSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));

if (FieldMdSec.first == nullptr &&
AssocTySec.first == nullptr &&
BuiltinTySec.first == nullptr &&
CaptureSec.first == nullptr &&
TypeRefMdSec.first == nullptr &&
ReflStrMdSec.first == nullptr)
ReflStrMdSec.first == nullptr &&
ConformMdSec.first == nullptr)
return false;

ReflectionInfo info = {
Expand All @@ -262,7 +266,8 @@ class ReflectionContext
{BuiltinTySec.first, BuiltinTySec.second},
{CaptureSec.first, CaptureSec.second},
{TypeRefMdSec.first, TypeRefMdSec.second},
{ReflStrMdSec.first, ReflStrMdSec.second}};
{ReflStrMdSec.first, ReflStrMdSec.second},
{ConformMdSec.first, ConformMdSec.second}};

this->addReflectionInfo(info);

Expand Down Expand Up @@ -365,13 +370,16 @@ class ReflectionContext
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
auto ReflStrMdSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
auto ConformMdSec = findCOFFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));

if (FieldMdSec.first == nullptr &&
AssocTySec.first == nullptr &&
BuiltinTySec.first == nullptr &&
CaptureSec.first == nullptr &&
TypeRefMdSec.first == nullptr &&
ReflStrMdSec.first == nullptr)
ReflStrMdSec.first == nullptr &&
ConformMdSec.first == nullptr)
return false;

ReflectionInfo Info = {
Expand All @@ -380,7 +388,8 @@ class ReflectionContext
{BuiltinTySec.first, BuiltinTySec.second},
{CaptureSec.first, CaptureSec.second},
{TypeRefMdSec.first, TypeRefMdSec.second},
{ReflStrMdSec.first, ReflStrMdSec.second}};
{ReflStrMdSec.first, ReflStrMdSec.second},
{ConformMdSec.first, ConformMdSec.second}};
this->addReflectionInfo(Info);
return true;
}
Expand Down Expand Up @@ -544,6 +553,8 @@ class ReflectionContext
ObjectFileFormat.getSectionName(ReflectionSectionKind::typeref));
auto ReflStrMdSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
auto ConformMdSec = findELFSectionByName(
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));

if (Error)
return false;
Expand All @@ -555,7 +566,8 @@ class ReflectionContext
BuiltinTySec.first == nullptr &&
CaptureSec.first == nullptr &&
TypeRefMdSec.first == nullptr &&
ReflStrMdSec.first == nullptr)
ReflStrMdSec.first == nullptr &&
ConformMdSec.first == nullptr)
return false;

ReflectionInfo info = {
Expand All @@ -564,7 +576,8 @@ class ReflectionContext
{BuiltinTySec.first, BuiltinTySec.second},
{CaptureSec.first, CaptureSec.second},
{TypeRefMdSec.first, TypeRefMdSec.second},
{ReflStrMdSec.first, ReflStrMdSec.second}};
{ReflStrMdSec.first, ReflStrMdSec.second},
{ConformMdSec.first, ConformMdSec.second}};

this->addReflectionInfo(info);
return true;
Expand Down Expand Up @@ -665,7 +678,9 @@ class ReflectionContext
auto Sections = {
ReflectionSectionKind::fieldmd, ReflectionSectionKind::assocty,
ReflectionSectionKind::builtin, ReflectionSectionKind::capture,
ReflectionSectionKind::typeref, ReflectionSectionKind::reflstr};
ReflectionSectionKind::typeref, ReflectionSectionKind::reflstr,
ReflectionSectionKind::conform
};

llvm::SmallVector<std::pair<RemoteRef<void>, uint64_t>, 6> Pairs;
for (auto Section : Sections) {
Expand All @@ -687,7 +702,8 @@ class ReflectionContext
ReflectionInfo Info = {
{Pairs[0].first, Pairs[0].second}, {Pairs[1].first, Pairs[1].second},
{Pairs[2].first, Pairs[2].second}, {Pairs[3].first, Pairs[3].second},
{Pairs[4].first, Pairs[4].second}, {Pairs[5].first, Pairs[5].second}};
{Pairs[4].first, Pairs[4].second}, {Pairs[5].first, Pairs[5].second},
{Pairs[6].first, Pairs[6].second}};
this->addReflectionInfo(Info);
return true;
}
Expand Down
Loading