| //===--- 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__) |
| |
| #include "ImageInspection.h" |
| #include <mach-o/dyld.h> |
| #include <mach-o/getsect.h> |
| #include <assert.h> |
| #include <dlfcn.h> |
| |
| using namespace swift; |
| |
| namespace { |
| /// The Mach-O section name for the section containing protocol conformances. |
| /// This lives within SEG_TEXT. |
| constexpr const char ProtocolConformancesSection[] = "__swift2_proto"; |
| /// The Mach-O section name for the section containing type references. |
| /// This lives within SEG_TEXT. |
| constexpr const char TypeMetadataRecordSection[] = "__swift2_types"; |
| |
| template<const char *SECTION_NAME, |
| void CONSUME_BLOCK(const void *start, uintptr_t size)> |
| void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) { |
| #ifdef __LP64__ |
| using mach_header_platform = mach_header_64; |
| assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!"); |
| #else |
| using mach_header_platform = mach_header; |
| #endif |
| |
| // Look for a __swift2_proto section. |
| unsigned long size; |
| const uint8_t *section = |
| getsectiondata(reinterpret_cast<const mach_header_platform *>(mh), |
| SEG_TEXT, SECTION_NAME, |
| &size); |
| |
| if (!section) |
| return; |
| |
| CONSUME_BLOCK(section, size); |
| } |
| |
| } // end anonymous namespace |
| |
| void swift::initializeProtocolConformanceLookup() { |
| _dyld_register_func_for_add_image( |
| addImageCallback<ProtocolConformancesSection, |
| addImageProtocolConformanceBlockCallback>); |
| } |
| void swift::initializeTypeMetadataRecordLookup() { |
| _dyld_register_func_for_add_image( |
| addImageCallback<TypeMetadataRecordSection, |
| addImageTypeMetadataRecordBlockCallback>); |
| |
| } |
| |
| 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 = dlinfo.dli_sname; |
| info->symbolAddress = dlinfo.dli_saddr; |
| return 1; |
| } |
| |
| #endif // defined(__APPLE__) && defined(__MACH__) |