|
| 1 | +//===--- ImageInspectionCommon.cpp - Image inspection routines --*- C++ -*-===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift.org open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See https://swift.org/LICENSE.txt for license information |
| 9 | +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | +/// |
| 13 | +/// \file |
| 14 | +/// |
| 15 | +/// This file unifies common ELF and COFF image inspection routines |
| 16 | +/// |
| 17 | +//===----------------------------------------------------------------------===// |
| 18 | + |
| 19 | +#ifndef SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H |
| 20 | +#define SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H |
| 21 | + |
| 22 | +#if !defined(__MACH__) |
| 23 | + |
| 24 | +#include "../SwiftShims/Visibility.h" |
| 25 | +#include "../SwiftShims/MetadataSections.h" |
| 26 | +#include "ImageInspection.h" |
| 27 | + |
| 28 | + |
| 29 | +namespace swift { |
| 30 | + |
| 31 | +static swift::MetadataSections *registered = nullptr; |
| 32 | + |
| 33 | +void record(swift::MetadataSections *sections) { |
| 34 | + if (registered == nullptr) { |
| 35 | + registered = sections; |
| 36 | + sections->next = sections->prev = sections; |
| 37 | + } else { |
| 38 | + registered->prev->next = sections; |
| 39 | + sections->next = registered; |
| 40 | + sections->prev = registered->prev; |
| 41 | + registered->prev = sections; |
| 42 | + } |
| 43 | +} |
| 44 | +} |
| 45 | + |
| 46 | +SWIFT_RUNTIME_EXPORT |
| 47 | +void swift_addNewDSOImage(const void *addr) { |
| 48 | + const swift::MetadataSections *sections = |
| 49 | + static_cast<const swift::MetadataSections *>(addr); |
| 50 | + |
| 51 | + // We cast off the const in order to update the linked list |
| 52 | + // data structure. This is safe to do since we don't touch |
| 53 | + // any other fields. |
| 54 | + auto casted_sections = const_cast<swift::MetadataSections *>(sections); |
| 55 | + record(casted_sections); |
| 56 | + |
| 57 | + const auto &protocols_section = sections->swift5_protocols; |
| 58 | + const void *protocols = reinterpret_cast<void *>(protocols_section.start); |
| 59 | + if (protocols_section.length) |
| 60 | + swift::addImageProtocolsBlockCallback(protocols, protocols_section.length); |
| 61 | + |
| 62 | + const auto &protocol_conformances = sections->swift5_protocol_conformances; |
| 63 | + const void *conformances = |
| 64 | + reinterpret_cast<void *>(protocol_conformances.start); |
| 65 | + if (protocol_conformances.length) |
| 66 | + swift::addImageProtocolConformanceBlockCallback(conformances, |
| 67 | + protocol_conformances.length); |
| 68 | + |
| 69 | + const auto &type_metadata = sections->swift5_type_metadata; |
| 70 | + const void *metadata = reinterpret_cast<void *>(type_metadata.start); |
| 71 | + if (type_metadata.length) |
| 72 | + swift::addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length); |
| 73 | + |
| 74 | + const auto &dynamic_replacements = sections->swift5_replace; |
| 75 | + const auto *replacements = |
| 76 | + reinterpret_cast<void *>(dynamic_replacements.start); |
| 77 | + if (dynamic_replacements.length) { |
| 78 | + const auto &dynamic_replacements_some = sections->swift5_replac2; |
| 79 | + const auto *replacements_some = |
| 80 | + reinterpret_cast<void *>(dynamic_replacements_some.start); |
| 81 | + swift::addImageDynamicReplacementBlockCallback( |
| 82 | + replacements, dynamic_replacements.length, replacements_some, |
| 83 | + dynamic_replacements_some.length); |
| 84 | + } |
| 85 | +} |
| 86 | + |
| 87 | +void swift::initializeProtocolLookup() { |
| 88 | + const swift::MetadataSections *sections = registered; |
| 89 | + while (true) { |
| 90 | + const swift::MetadataSectionRange &protocols = |
| 91 | + sections->swift5_protocols; |
| 92 | + if (protocols.length) |
| 93 | + addImageProtocolsBlockCallbackUnsafe( |
| 94 | + reinterpret_cast<void *>(protocols.start), protocols.length); |
| 95 | + |
| 96 | + if (sections->next == registered) |
| 97 | + break; |
| 98 | + sections = sections->next; |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | +void swift::initializeProtocolConformanceLookup() { |
| 103 | + const swift::MetadataSections *sections = registered; |
| 104 | + while (true) { |
| 105 | + const swift::MetadataSectionRange &conformances = |
| 106 | + sections->swift5_protocol_conformances; |
| 107 | + if (conformances.length) |
| 108 | + addImageProtocolConformanceBlockCallbackUnsafe( |
| 109 | + reinterpret_cast<void *>(conformances.start), conformances.length); |
| 110 | + |
| 111 | + if (sections->next == registered) |
| 112 | + break; |
| 113 | + sections = sections->next; |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 117 | +void swift::initializeTypeMetadataRecordLookup() { |
| 118 | + const swift::MetadataSections *sections = registered; |
| 119 | + while (true) { |
| 120 | + const swift::MetadataSectionRange &type_metadata = |
| 121 | + sections->swift5_type_metadata; |
| 122 | + if (type_metadata.length) |
| 123 | + addImageTypeMetadataRecordBlockCallbackUnsafe( |
| 124 | + reinterpret_cast<void *>(type_metadata.start), type_metadata.length); |
| 125 | + |
| 126 | + if (sections->next == registered) |
| 127 | + break; |
| 128 | + sections = sections->next; |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +void swift::initializeDynamicReplacementLookup() { |
| 133 | +} |
| 134 | + |
| 135 | +// This is only used for backward deployment hooks, which we currently only support for |
| 136 | +// MachO. Add a stub here to make sure it still compiles. |
| 137 | +void *swift::lookupSection(const char *segment, const char *section, size_t *outSize) { |
| 138 | + return nullptr; |
| 139 | +} |
| 140 | + |
| 141 | +#endif // !defined(__MACH__) |
| 142 | + |
| 143 | +#endif // SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H |
0 commit comments