Loading...
--- dyld/dyld-1162/common/SwiftVisitor.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
- *
- * Copyright (c) 2014 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <TargetConditionals.h>
-
-#if !TARGET_OS_EXCLAVEKIT
-
-#include "SwiftVisitor.h"
-
-#if SUPPORT_VM_LAYOUT
-#include "MachOAnalyzer.h"
-#endif
-
-#include <assert.h>
-
-using namespace metadata_visitor;
-
-//
-// MARK: --- SwiftVisitor methods ---
-//
-
-void SwiftVisitor::forEachProtocolConformance(void (^callback)(const SwiftConformance& swiftConformance,
- bool& stopConformance)) const
-{
- SwiftConformanceList swiftConformanceList = this->getSwiftConformances();
-
- for ( uint32_t i = 0, e = swiftConformanceList.numConformances(); i != e; ++i ) {
- SwiftConformance swiftConformance = swiftConformanceList.getConformance(*this, i);
-
- bool stop = false;
- callback(swiftConformance, stop);
- if ( stop )
- break;
- }
-}
-
-SwiftConformanceList SwiftVisitor::getSwiftConformances() const
-{
- std::optional<SectionContent> protoListSection = findTextSection("__swift5_proto");
- if ( !protoListSection.has_value() )
- return SwiftConformanceList(std::nullopt, 0);
-
- assert((protoListSection->sectSize % 4) == 0);
- uint64_t numElements = protoListSection->sectSize / 4;
- const ResolvedValue& sectionValue = protoListSection->sectionBase;
- return SwiftConformanceList(sectionValue, (uint32_t)numElements);
-}
-
-std::optional<SwiftVisitor::SectionContent> SwiftVisitor::findTextSection(const char *sectionName) const
-{
-#if SUPPORT_VM_LAYOUT
- const dyld3::MachOFile* mf = this->dylibMA;
-#else
- const dyld3::MachOFile* mf = this->dylibMF;
-#endif
-
- __block std::optional<SwiftVisitor::SectionContent> sectionContent;
- mf->forEachSection(^(const dyld3::MachOFile::SectionInfo& sectInfo, bool malformedSectionRange, bool& stop) {
- if ( (strcmp(sectInfo.segInfo.segName, "__TEXT") != 0) )
- return;
- if ( strcmp(sectInfo.sectName, sectionName) != 0 )
- return;
-
-#if SUPPORT_VM_LAYOUT
- const void* targetValue = (const void*)(sectInfo.sectAddr + this->dylibMA->getSlide());
- ResolvedValue target(targetValue, VMAddress(sectInfo.sectAddr));
-#else
- VMOffset offsetInSegment(sectInfo.sectAddr - sectInfo.segInfo.vmAddr);
- ResolvedValue target(this->segments[sectInfo.segInfo.segIndex], offsetInSegment);
-#endif
- sectionContent.emplace(std::move(target));
- sectionContent->sectSize = sectInfo.sectSize;
-
- stop = true;
- });
- return sectionContent;
-}
-
-//
-// MARK: --- SwiftConformanceList methods ---
-//
-
-SwiftConformance SwiftConformanceList::getConformance(const Visitor &swiftVisitor, uint32_t i) const
-{
- // Protocol conformances are a 32-bit offset from the list entry
- const uint8_t* fieldPos = (const uint8_t*)this->conformanceListPos->value() + (i * sizeof(int32_t));
-
- int64_t relativeOffsetFromField = (int64_t)*(int32_t*)fieldPos;
- VMOffset relativeOffsetFromList((uint64_t)relativeOffsetFromField + (i * 4));
-
- VMAddress listVMAddr = this->conformanceListPos->vmAddress();
- VMAddress conformanceVMAddr = listVMAddr + relativeOffsetFromList;
-
- ResolvedValue conformanceValue = swiftVisitor.getValueFor(conformanceVMAddr);
- return SwiftConformance(conformanceValue);
-}
-
-uint32_t SwiftConformanceList::numConformances() const
-{
- return this->numElements;
-}
-
-//
-// MARK: --- SwiftConformance methods ---
-//
-
-std::optional<VMAddress> SwiftConformance::getProtocolVMAddr(const SwiftVisitor& swiftVisitor) const
-{
- const conformance_t* rawConformance = (const conformance_t*)this->getLocation();
-
- // The protocol is found via the relative pointer
- const relative_pointer_t* relativePtr = &rawConformance->protocolRelativePointer;
- ResolvedValue relativePtrField = swiftVisitor.getField(this->conformancePos, relativePtr);
- return SwiftRelativePointer(relativePtrField).getTargetVMAddr(swiftVisitor);
-}
-
-SwiftPointer SwiftConformance::getProtocolPointer(const SwiftVisitor& swiftVisitor) const
-{
- const conformance_t* rawConformance = (const conformance_t*)this->getLocation();
-
- // The protocol is found via the relative pointer
- const relative_pointer_t* relativePtr = &rawConformance->protocolRelativePointer;
- ResolvedValue relativePtrField = swiftVisitor.getField(this->conformancePos, relativePtr);
- return SwiftRelativePointer(relativePtrField).getTargetPointer(swiftVisitor);
-}
-
-SwiftConformance::SwiftProtocolConformanceFlags
-SwiftConformance::getProtocolConformanceFlags(const SwiftVisitor& swiftVisitor) const
-{
- const conformance_t* rawConformance = (const conformance_t*)this->getLocation();
-
- const protocol_conformance_flags_t* flagsPtr = &rawConformance->flags;
- ResolvedValue flagsField = swiftVisitor.getField(this->conformancePos, flagsPtr);
- return SwiftProtocolConformanceFlags(flagsField);
-}
-
-SwiftConformance::SwiftTypeRefPointer
-SwiftConformance::getTypeRef(const SwiftVisitor& swiftVisitor) const
-{
- const conformance_t* rawConformance = (const conformance_t*)this->getLocation();
-
- // The typeref is found via the relative pointer
- const typeref_pointer_t* relativePtr = &rawConformance->typeRef;
- ResolvedValue relativePtrField = swiftVisitor.getField(this->conformancePos, relativePtr);
-
- auto kind = getProtocolConformanceFlags(swiftVisitor).typeReferenceKind();
- return SwiftTypeRefPointer(relativePtrField, kind);
-}
-
-bool SwiftConformance::isNull() const
-{
- const conformance_t* rawConformance = (const conformance_t*)this->getLocation();
- uint8_t emptyConformance[sizeof(conformance_t)] = { 0 };
- return memcmp(rawConformance, emptyConformance, sizeof(conformance_t)) == 0;
-}
-
-VMAddress SwiftConformance::getVMAddress() const
-{
- return this->conformancePos.vmAddress();
-}
-
-const void* SwiftConformance::getLocation() const
-{
- return this->conformancePos.value();
-}
-
-//
-// MARK: --- SwiftConformance::SwiftRelativePointer methods ---
-//
-
-std::optional<VMAddress> SwiftConformance::SwiftRelativePointer::getTargetVMAddr(const SwiftVisitor &swiftVisitor) const
-{
- const relative_pointer_t* relativePtr = (const relative_pointer_t*)this->pos.value();
- int32_t relativeOffset = relativePtr->relativeOffset;
- if ( (relativeOffset & 0x1) == 0 ) {
- // Relative offset directly to the target value
- int64_t offset64 = (int64_t)relativeOffset;
- VMAddress targetVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- return targetVMAddr;
- } else {
- // Relative offset to a pointer. The pointer contains the target value
- int32_t offset = relativeOffset & ~0x1ULL;
- int64_t offset64 = (int64_t)offset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- ResolvedValue pointerValue = swiftVisitor.getValueFor(pointerVMAddr);
-
- // Dereference the pointer to get the final target
- return swiftVisitor.resolveOptionalRebaseToVMAddress(pointerValue);
- }
-}
-
-SwiftPointer SwiftConformance::SwiftRelativePointer::getTargetPointer(const SwiftVisitor &swiftVisitor) const
-{
- const relative_pointer_t* relativePtr = (const relative_pointer_t*)this->pos.value();
- int32_t relativeOffset = relativePtr->relativeOffset;
- if ( (relativeOffset & 0x1) == 0 ) {
- // Relative offset directly to the target value
- int64_t offset64 = (int64_t)relativeOffset;
- VMAddress targetVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- return { true, swiftVisitor.getValueFor(targetVMAddr) };
- } else {
- // Relative offset to a pointer. The pointer contains the target value
- int32_t offset = relativeOffset & ~0x1ULL;
- int64_t offset64 = (int64_t)offset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- return { false, swiftVisitor.getValueFor(pointerVMAddr) };
- }
-}
-
-//
-// MARK: --- SwiftConformance::SwiftProtocolConformanceFlags methods ---
-//
-
-SwiftConformance::SwiftProtocolConformanceFlags::TypeReferenceKind
-SwiftConformance::SwiftProtocolConformanceFlags::typeReferenceKind() const
-{
- const protocol_conformance_flags_t* flagsPtr = (const protocol_conformance_flags_t*)this->pos.value();
- uint32_t flags = flagsPtr->flags;
- return (TypeReferenceKind)((flags & (uint32_t)TypeMetadataKind::mask) >> (uint32_t)TypeMetadataKind::shift);
-}
-
-//
-// MARK: --- SwiftConformance::SwiftProtocolConformanceFlags methods ---
-//
-
-std::optional<ResolvedValue>
-SwiftConformance::SwiftTypeRefPointer::getTypeDescriptor(const SwiftVisitor &swiftVisitor) const
-{
- assert((this->kind == SwiftProtocolConformanceFlags::TypeReferenceKind::directTypeDescriptor)
- || (this->kind == SwiftProtocolConformanceFlags::TypeReferenceKind::indirectTypeDescriptor));
-
- if ( this->kind == SwiftProtocolConformanceFlags::TypeReferenceKind::directTypeDescriptor ) {
- // Relative offset directly to the target value
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int64_t offset64 = (int64_t)relativeOffset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
-
- return swiftVisitor.getValueFor(pointerVMAddr);
- }
-
- if ( this->kind == SwiftProtocolConformanceFlags::TypeReferenceKind::indirectTypeDescriptor ) {
- // Relative offset to a pointer. The pointer contains the target value
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int32_t offset = relativeOffset & ~0x1ULL;
- int64_t offset64 = (int64_t)offset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- ResolvedValue pointerValue = swiftVisitor.getValueFor(pointerVMAddr);
-
- // Dereference the pointer to get the final target
- return swiftVisitor.resolveOptionalRebase(pointerValue);
- }
- return { };
-}
-
-const char*
-SwiftConformance::SwiftTypeRefPointer::getClassName(const SwiftVisitor &swiftVisitor) const
-{
- assert(this->kind == SwiftProtocolConformanceFlags::TypeReferenceKind::directObjCClassName);
-
- // Relative offset directly to the class name string
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int64_t offset64 = (int64_t)relativeOffset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
-
- ResolvedValue pointerValue = swiftVisitor.getValueFor(pointerVMAddr);
- return (const char*)pointerValue.value();
-}
-
-std::optional<ResolvedValue>
-SwiftConformance::SwiftTypeRefPointer::getClass(const SwiftVisitor &swiftVisitor) const
-{
- assert(this->kind == SwiftProtocolConformanceFlags::TypeReferenceKind::indirectObjCClass);
-
- // Relative offset to a pointer. The pointer contains the target value
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int32_t offset = relativeOffset & ~0x1ULL;
- int64_t offset64 = (int64_t)offset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- ResolvedValue pointerValue = swiftVisitor.getValueFor(pointerVMAddr);
-
- // Dereference the pointer to get the final target
- return swiftVisitor.resolveOptionalRebase(pointerValue);
-}
-
-SwiftPointer SwiftConformance::SwiftTypeRefPointer::getTargetPointer(const SwiftVisitor &swiftVisitor) const
-{
- switch ( this->kind ) {
- case SwiftProtocolConformanceFlags::TypeReferenceKind::directTypeDescriptor: {
- // Relative offset directly to the target value
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int64_t offset64 = (int64_t)relativeOffset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- return { true, swiftVisitor.getValueFor(pointerVMAddr) };
- }
- case SwiftProtocolConformanceFlags::TypeReferenceKind::indirectTypeDescriptor: {
- // Relative offset to a pointer. The pointer contains the target value
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int32_t offset = relativeOffset & ~0x1ULL;
- int64_t offset64 = (int64_t)offset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- return { false, swiftVisitor.getValueFor(pointerVMAddr) };
- }
- case SwiftProtocolConformanceFlags::TypeReferenceKind::directObjCClassName: {
- // Relative offset directly to the class name string
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int64_t offset64 = (int64_t)relativeOffset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- return { true, swiftVisitor.getValueFor(pointerVMAddr) };
- }
- case SwiftProtocolConformanceFlags::TypeReferenceKind::indirectObjCClass: {
- // Relative offset to a pointer. The pointer contains the target value
- int32_t relativeOffset = *(int32_t*)this->pos.value();
- int32_t offset = relativeOffset & ~0x1ULL;
- int64_t offset64 = (int64_t)offset;
- VMAddress pointerVMAddr = this->pos.vmAddress() + VMOffset((uint64_t)offset64);
- return { false, swiftVisitor.getValueFor(pointerVMAddr) };
- }
- }
-}
-
-//
-// MARK: --- SwiftConformance::TypeContextDescriptor methods ---
-//
-
-// The most significant two bytes of the flags word, which can have
-// kind-specific meaning.
-uint16_t SwiftConformance::TypeContextDescriptor::getKindSpecificFlags() const {
- const type_context_descriptor_t* context = (type_context_descriptor_t*)this->pos.value();
- return (context->flags >> 16u) & 0xFFFFu;
-}
-
-bool SwiftConformance::TypeContextDescriptor::isForeignMetadata() const
-{
- // The botton 2 bits have the flags
- return (this->getKindSpecificFlags() & 0x3) == ForeignMetadataInitialization;
-}
-
-bool SwiftConformance::TypeContextDescriptor::hasImportInfo() const
-{
- // Bit 2 tells us if we have import info, ie, a name containing NULLs
- return (this->getKindSpecificFlags() & (1 << 2)) != 0;
-}
-
-ResolvedValue SwiftConformance::TypeContextDescriptor::getName(const SwiftVisitor& swiftVisitor) const
-{
- // The name is found via a relative offset
- const type_context_descriptor_t* context = (type_context_descriptor_t*)this->pos.value();
- ResolvedValue nameField = swiftVisitor.getField(this->pos, &context->name.relativeOffset);
-
- // Add the offset to the field to get the target value
- int32_t nameOffset = *(int32_t*)nameField.value();
- int64_t nameOffset64 = (int64_t)nameOffset;
- VMOffset offsetFromNameField((uint64_t)nameOffset64);
- VMAddress targetVMAddr = nameField.vmAddress() + offsetFromNameField;
- return swiftVisitor.getValueFor(targetVMAddr);
-}
-
-#endif // !TARGET_OS_EXCLAVEKIT