//===--- ImageInspectionMachO.cpp - Mach-O image inspection ---------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// /// /// \file /// /// This file includes routines that interact with dyld on Mach-O-based /// platforms to extract runtime metadata embedded in images generated by the /// Swift compiler. /// //===----------------------------------------------------------------------===// #if defined(__APPLE__) && defined(__MACH__) && \ !defined(SWIFT_RUNTIME_MACHO_NO_DYLD) #include "ImageInspection.h" #include "ImageInspectionCommon.h" #include "swift/Runtime/Config.h" #include #include #include #include #include using namespace swift; namespace { constexpr const char ProtocolsSection[] = MachOProtocolsSection; constexpr const char ProtocolConformancesSection[] = MachOProtocolConformancesSection; constexpr const char TypeMetadataRecordSection[] = MachOTypeMetadataRecordSection; constexpr const char DynamicReplacementSection[] = MachODynamicReplacementSection; constexpr const char DynamicReplacementSomeSection[] = MachODynamicReplacementSomeSection; constexpr const char TextSegment[] = MachOTextSegment; #if __POINTER_WIDTH__ == 64 using mach_header_platform = mach_header_64; #else using mach_header_platform = mach_header; #endif extern "C" void *_NSGetMachExecuteHeader(); template void addImageCallback(const mach_header *mh) { #if __POINTER_WIDTH__ == 64 assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!"); #endif // Look for a __swift5_proto section. unsigned long size; const uint8_t *section = getsectiondata(reinterpret_cast(mh), SEGMENT_NAME, SECTION_NAME, &size); if (!section) return; CONSUME_BLOCK(section, size); } template void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) { addImageCallback(mh); } template void addImageCallback2Sections(const mach_header *mh) { #if __POINTER_WIDTH__ == 64 assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!"); #endif // Look for a section. unsigned long size; const uint8_t *section = getsectiondata(reinterpret_cast(mh), SEGMENT_NAME, SECTION_NAME, &size); if (!section) return; // Look for another section. unsigned long size2; const uint8_t *section2 = getsectiondata(reinterpret_cast(mh), SEGMENT_NAME2, SECTION_NAME2, &size2); if (!section2) size2 = 0; CONSUME_BLOCK(section, size, section2, size2); } template void addImageCallback2Sections(const mach_header *mh, intptr_t vmaddr_slide) { addImageCallback2Sections(mh); } } // end anonymous namespace #if OBJC_ADDLOADIMAGEFUNC_DEFINED && SWIFT_OBJC_INTEROP #define REGISTER_FUNC(...) \ if (__builtin_available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)) { \ objc_addLoadImageFunc(__VA_ARGS__); \ } else { \ _dyld_register_func_for_add_image(__VA_ARGS__); \ } #else #define REGISTER_FUNC(...) _dyld_register_func_for_add_image(__VA_ARGS__) #endif void swift::initializeProtocolLookup() { REGISTER_FUNC(addImageCallback); } void swift::initializeProtocolConformanceLookup() { REGISTER_FUNC( addImageCallback); } void swift::initializeTypeMetadataRecordLookup() { REGISTER_FUNC( addImageCallback); } void swift::initializeDynamicReplacementLookup() { REGISTER_FUNC( addImageCallback2Sections); } int swift::lookupSymbol(const void *address, SymbolInfo *info) { Dl_info dlinfo; if (dladdr(address, &dlinfo) == 0) { return 0; } info->fileName = dlinfo.dli_fname; info->baseAddress = dlinfo.dli_fbase; info->symbolName.reset(dlinfo.dli_sname); info->symbolAddress = dlinfo.dli_saddr; return 1; } #ifndef SWIFT_RUNTIME_NO_COMPATIBILITY_OVERRIDES void *swift::lookupSection(const char *segment, const char *section, size_t *outSize) { unsigned long size; auto *executableHeader = static_cast(_NSGetMachExecuteHeader()); uint8_t *data = getsectiondata(executableHeader, segment, section, &size); if (outSize != nullptr && data != nullptr) *outSize = size; return static_cast(data); } #endif // #ifndef SWIFT_RUNTIME_NO_COMPATIBILITY_OVERRIDES #endif // defined(__APPLE__) && defined(__MACH__) && // !defined(SWIFT_RUNTIME_MACHO_NO_DYLD)