From db18deaf91556d1baf85a257b81a320b581b51c9 Mon Sep 17 00:00:00 2001 From: "Kuba (Brecka) Mracek" Date: Tue, 18 Aug 2020 11:46:42 -0700 Subject: [PATCH] Add a SWIFT_RUNTIME_MACHO_NO_DYLD stdlib mode that doesn't dynamically look up sections in modules, and only assumes a single static module (#33441) --- stdlib/CMakeLists.txt | 4 + stdlib/cmake/modules/AddSwiftStdlib.cmake | 4 + stdlib/public/runtime/CMakeLists.txt | 1 + stdlib/public/runtime/Errors.cpp | 2 +- stdlib/public/runtime/ImageInspectionCommon.h | 22 +++++- .../public/runtime/ImageInspectionMachO.cpp | 31 ++++---- .../public/runtime/ImageInspectionStatic.cpp | 77 +++++++++++++++++++ utils/build-presets.ini | 1 + utils/build-script-impl | 2 + 9 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 stdlib/public/runtime/ImageInspectionStatic.cpp diff --git a/stdlib/CMakeLists.txt b/stdlib/CMakeLists.txt index 70d45d3821c..2e82392b6e2 100644 --- a/stdlib/CMakeLists.txt +++ b/stdlib/CMakeLists.txt @@ -17,6 +17,10 @@ option(SWIFT_ENABLE_COMPATIBILITY_OVERRIDES "Support back-deploying compatibility fixes for newer apps running on older runtimes." TRUE) +option(SWIFT_RUNTIME_MACHO_NO_DYLD + "Build stdlib assuming the runtime environment uses Mach-O but does not support dynamic modules." + FALSE) + # # End of user-configurable options. # diff --git a/stdlib/cmake/modules/AddSwiftStdlib.cmake b/stdlib/cmake/modules/AddSwiftStdlib.cmake index a751a1da805..34d5d417d42 100644 --- a/stdlib/cmake/modules/AddSwiftStdlib.cmake +++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake @@ -302,6 +302,10 @@ function(_add_target_variant_c_compile_flags) list(APPEND result "-DSWIFT_RUNTIME_NO_COMPATIBILITY_OVERRIDES") endif() + if(SWIFT_RUNTIME_MACHO_NO_DYLD) + list(APPEND result "-DSWIFT_RUNTIME_MACHO_NO_DYLD") + endif() + set("${CFLAGS_RESULT_VAR_NAME}" "${result}" PARENT_SCOPE) endfunction() diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index ed72fba6bf0..bb5cfe990cb 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -50,6 +50,7 @@ set(swift_runtime_sources ImageInspectionMachO.cpp ImageInspectionELF.cpp ImageInspectionCOFF.cpp + ImageInspectionStatic.cpp KeyPaths.cpp KnownMetadata.cpp Metadata.cpp diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp index 6e0dd53758b..b5a5e467388 100644 --- a/stdlib/public/runtime/Errors.cpp +++ b/stdlib/public/runtime/Errors.cpp @@ -137,7 +137,7 @@ static bool getSymbolNameAddr(llvm::StringRef libraryName, void swift::dumpStackTraceEntry(unsigned index, void *framePC, bool shortOutput) { -#if SWIFT_SUPPORTS_BACKTRACE_REPORTING +#if SWIFT_SUPPORTS_BACKTRACE_REPORTING && !defined(SWIFT_RUNTIME_MACHO_NO_DYLD) SymbolInfo syminfo; // 0 is failure for lookupSymbol diff --git a/stdlib/public/runtime/ImageInspectionCommon.h b/stdlib/public/runtime/ImageInspectionCommon.h index 4166adcf1c9..b18f9c48cda 100644 --- a/stdlib/public/runtime/ImageInspectionCommon.h +++ b/stdlib/public/runtime/ImageInspectionCommon.h @@ -19,7 +19,27 @@ #ifndef SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H #define SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H -#if !defined(__MACH__) +#if defined(__MACH__) + +#include + +/// The Mach-O section name for the section containing protocol descriptor +/// references. This lives within SEG_TEXT. +#define MachOProtocolsSection "__swift5_protos" +/// The Mach-O section name for the section containing protocol conformances. +/// This lives within SEG_TEXT. +#define MachOProtocolConformancesSection "__swift5_proto" +/// The Mach-O section name for the section containing type references. +/// This lives within SEG_TEXT. +#define MachOTypeMetadataRecordSection "__swift5_types" +/// The Mach-O section name for the section containing dynamic replacements. +/// This lives within SEG_TEXT. +#define MachODynamicReplacementSection "__swift5_replace" +#define MachODynamicReplacementSomeSection "__swift5_replac2" + +#define MachOTextSegment "__TEXT" + +#else #if defined(__ELF__) #define SWIFT_REFLECTION_METADATA_ELF_NOTE_MAGIC_STRING "swift_reflection_metadata_magic_string" diff --git a/stdlib/public/runtime/ImageInspectionMachO.cpp b/stdlib/public/runtime/ImageInspectionMachO.cpp index 643cd665898..54c4d17a52a 100644 --- a/stdlib/public/runtime/ImageInspectionMachO.cpp +++ b/stdlib/public/runtime/ImageInspectionMachO.cpp @@ -18,9 +18,11 @@ /// //===----------------------------------------------------------------------===// -#if defined(__APPLE__) && defined(__MACH__) +#if defined(__APPLE__) && defined(__MACH__) && \ + !defined(SWIFT_RUNTIME_MACHO_NO_DYLD) #include "ImageInspection.h" +#include "ImageInspectionCommon.h" #include "swift/Runtime/Config.h" #include #include @@ -31,21 +33,17 @@ using namespace swift; namespace { -/// The Mach-O section name for the section containing protocol descriptor -/// references. This lives within SEG_TEXT. -constexpr const char ProtocolsSection[] = "__swift5_protos"; -/// The Mach-O section name for the section containing protocol conformances. -/// This lives within SEG_TEXT. -constexpr const char ProtocolConformancesSection[] = "__swift5_proto"; -/// The Mach-O section name for the section containing type references. -/// This lives within SEG_TEXT. -constexpr const char TypeMetadataRecordSection[] = "__swift5_types"; -/// The Mach-O section name for the section containing dynamic replacements. -/// This lives within SEG_TEXT. -constexpr const char DynamicReplacementSection[] = "__swift5_replace"; -constexpr const char DynamicReplacementSomeSection[] = "__swift5_replac2"; -constexpr const char TextSegment[] = SEG_TEXT; +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; @@ -182,4 +180,5 @@ void *swift::lookupSection(const char *segment, const char *section, size_t *out #endif // #ifndef SWIFT_RUNTIME_NO_COMPATIBILITY_OVERRIDES -#endif // defined(__APPLE__) && defined(__MACH__) +#endif // defined(__APPLE__) && defined(__MACH__) && + // !defined(SWIFT_RUNTIME_MACHO_NO_DYLD) diff --git a/stdlib/public/runtime/ImageInspectionStatic.cpp b/stdlib/public/runtime/ImageInspectionStatic.cpp new file mode 100644 index 00000000000..8c0d42253c6 --- /dev/null +++ b/stdlib/public/runtime/ImageInspectionStatic.cpp @@ -0,0 +1,77 @@ +//===--- ImageInspectionStatic.cpp - image inspection for static stdlib ---===// +// +// 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 +/// +/// Implementation of ImageInspection for static stdlib (no dynamic loader +/// present) environments. Assumes that only a single image exists in memory. +/// +//===----------------------------------------------------------------------===// + +#if defined(__MACH__) && defined(SWIFT_RUNTIME_MACHO_NO_DYLD) + +#include "ImageInspection.h" +#include "ImageInspectionCommon.h" + +using namespace swift; + +#define GET_SECTION_START_AND_SIZE(start, size, _seg, _sec) \ + extern void *__s##_seg##_sec __asm("section$start$" _seg "$" _sec); \ + extern void *__e##_seg##_sec __asm("section$end$" _seg "$" _sec); \ + start = &__s##_seg##_sec; \ + size = (char *)&__e##_seg##_sec - (char *)&__s##_seg##_sec; + +void swift::initializeProtocolLookup() { + void *start; + uintptr_t size; + GET_SECTION_START_AND_SIZE(start, size, TextSegment, ProtocolsSection); + if (start == nullptr || size == 0) + return; + addImageProtocolsBlockCallbackUnsafe(start, size); +} + +void swift::initializeProtocolConformanceLookup() { + void *start; + uintptr_t size; + GET_SECTION_START_AND_SIZE(start, size, TextSegment, + ProtocolConformancesSection); + if (start == nullptr || size == 0) + return; + addImageProtocolConformanceBlockCallbackUnsafe(start, size); +} +void swift::initializeTypeMetadataRecordLookup() { + void *start; + uintptr_t size; + GET_SECTION_START_AND_SIZE(start, size, TextSegment, + TypeMetadataRecordSection); + if (start == nullptr || size == 0) + return; + addImageTypeMetadataRecordBlockCallbackUnsafe(start, size); +} + +void swift::initializeDynamicReplacementLookup() { + void *start1; + uintptr_t size1; + GET_SECTION_START_AND_SIZE(start1, size1, TextSegment, + DynamicReplacementSection); + if (start1 == nullptr || size1 == 0) + return; + void *start2; + uintptr_t size2; + GET_SECTION_START_AND_SIZE(start2, size2, TextSegment, + DynamicReplacementSection); + if (start2 == nullptr || size2 == 0) + return; + addImageDynamicReplacementBlockCallback(start1, size1, start2, size2); +} + +#endif // defined(__MACH__) && defined(SWIFT_RUNTIME_MACHO_NO_DYLD) diff --git a/utils/build-presets.ini b/utils/build-presets.ini index e8231a2e942..ed50414e787 100644 --- a/utils/build-presets.ini +++ b/utils/build-presets.ini @@ -2425,6 +2425,7 @@ build-swift-dynamic-stdlib=0 build-swift-static-stdlib=1 swift-objc-interop=0 swift-enable-compatibility-overrides=0 +swift-runtime-macho-no-dyld=1 [preset: stdlib_S_standalone_minimal_macho_x86_64,build] mixin-preset= diff --git a/utils/build-script-impl b/utils/build-script-impl index 572f6c20a00..6e471f191c3 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -194,6 +194,7 @@ KNOWN_SETTINGS=( stdlib-deployment-targets "" "space-separated list of targets to configure the Swift standard library to be compiled or cross-compiled for" swift-objc-interop "" "whether to enable interoperability with Objective-C, default is 1 on Apple platfors, 0 otherwise" swift-enable-compatibility-overrides "1" "whether to support back-deploying compatibility fixes for newer apps running on older runtimes" + swift-runtime-macho-no-dyld "0" "whether to build stdlib assuming the runtime environment does not support dynamic modules" ## FREESTANDING Stdlib Options swift-freestanding-sdk "" "which SDK to use when building the FREESTANDING stdlib" @@ -1762,6 +1763,7 @@ for host in "${ALL_HOSTS[@]}"; do -DSWIFT_STDLIB_USE_NONATOMIC_RC:BOOL=$(true_false "${SWIFT_STDLIB_USE_NONATOMIC_RC}") -DSWIFT_ENABLE_COMPATIBILITY_OVERRIDES:BOOL=$(true_false "${SWIFT_ENABLE_COMPATIBILITY_OVERRIDES}") -DSWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS:BOOL=$(true_false "${SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS}") + -DSWIFT_RUNTIME_MACHO_NO_DYLD:BOOL=$(true_false "${SWIFT_RUNTIME_MACHO_NO_DYLD}") -DSWIFT_NATIVE_LLVM_TOOLS_PATH:STRING="${native_llvm_tools_path}" -DSWIFT_NATIVE_CLANG_TOOLS_PATH:STRING="${native_clang_tools_path}" -DSWIFT_NATIVE_SWIFT_TOOLS_PATH:STRING="${native_swift_tools_path}"