COFF: restructure metadata registration
Restructure the COFF metadata handling to use the linker section
grouping to emit section start/stop markers in the appropriate location.
This allows us to lookup the sections statically without having to the
walk the entire image structure.
Introduce a constructor for PE/COFF binaries. This will ensure that the
registration occurs for all modules appropriately. This should resolve
rdar://problem/19045112. The registration should occur prior to
`DllMain` being invoked from `DllMainCRTStartup`.
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index c55badb..ce84b9b 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -607,7 +607,7 @@
set(SWIFTLIB_SINGLE_options
SHARED STATIC OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE IS_SDK_OVERLAY
TARGET_LIBRARY FORCE_BUILD_FOR_HOST_SDK
- API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE FORCE_BUILD_OPTIMIZED)
+ API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE FORCE_BUILD_OPTIMIZED NOSWIFTRT)
cmake_parse_arguments(SWIFTLIB_SINGLE
"${SWIFTLIB_SINGLE_options}"
"MODULE_TARGET;SDK;ARCHITECTURE;INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS"
@@ -819,11 +819,15 @@
${SWIFTLIB_SINGLE_EXTERNAL_SOURCES}
${INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS}
${SWIFTLIB_SINGLE_XCODE_WORKAROUND_SOURCES})
- if("${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF" AND SWIFTLIB_TARGET_LIBRARY)
- if("${libkind}" STREQUAL "SHARED")
+ if(("${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF" OR
+ "${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "COFF") AND
+ SWIFTLIB_TARGET_LIBRARY)
+ if("${libkind}" STREQUAL "SHARED" AND NOT SWIFTLIB_SINGLE_NOSWIFTRT)
# TODO(compnerd) switch to the generator expression when cmake is upgraded
# to a version which supports it.
- # target_sources(${target} PRIVATE $<TARGET_OBJECTS:swiftImageRegistrationObject-${SWIFT_SDK_${sdk}_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE}>)
+ # target_sources(${target}
+ # PRIVATE
+ # $<TARGET_OBJECTS:swiftImageRegistrationObject${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}-${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}-${SWIFTLIB_SINGLE_ARCHITECTURE}>)
target_sources(${target}
PRIVATE
"${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swiftrt${CMAKE_C_OUTPUT_EXTENSION}")
@@ -1350,7 +1354,8 @@
set(SWIFTLIB_options
SHARED STATIC OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE IS_SDK_OVERLAY
TARGET_LIBRARY FORCE_BUILD_FOR_HOST_SDK
- API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE HAS_SWIFT_CONTENT FORCE_BUILD_OPTIMIZED)
+ API_NOTES_NON_OVERLAY DONT_EMBED_BITCODE HAS_SWIFT_CONTENT
+ FORCE_BUILD_OPTIMIZED NOSWIFTRT)
cmake_parse_arguments(SWIFTLIB
"${SWIFTLIB_options}"
"INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS"
@@ -1623,6 +1628,7 @@
${SWIFTLIB_TARGET_LIBRARY_keyword}
${SWIFTLIB_FORCE_BUILD_FOR_HOST_SDK_keyword}
${SWIFTLIB_FORCE_BUILD_OPTIMIZED_keyword}
+ ${SWIFTLIB_NOSWIFTRT_keyword}
INSTALL_IN_COMPONENT "${SWIFTLIB_INSTALL_IN_COMPONENT}"
DEPLOYMENT_VERSION_OSX "${SWIFTLIB_DEPLOYMENT_VERSION_OSX}"
DEPLOYMENT_VERSION_IOS "${SWIFTLIB_DEPLOYMENT_VERSION_IOS}"
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 5ce97a6..340e18c 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2389,7 +2389,7 @@
sectionName = "swift2_protocol_conformances";
break;
case llvm::Triple::COFF:
- sectionName = ".sw2prtc";
+ sectionName = ".sw2prtc$B";
break;
default:
llvm_unreachable("Don't know how to emit protocol conformances for "
@@ -2412,7 +2412,7 @@
sectionName = "swift2_type_metadata";
break;
case llvm::Triple::COFF:
- sectionName = ".sw2tymd";
+ sectionName = ".sw2tymd$B";
break;
default:
llvm_unreachable("Don't know how to emit type metadata table for "
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index a93a908..52bfd36 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -766,7 +766,7 @@
case llvm::Triple::COFF:
assert(FourCC.size() <= 4 &&
"COFF section name length must be <= 8 characters");
- OS << ".sw3" << FourCC;
+ OS << ".sw3" << FourCC << "$B";
break;
case llvm::Triple::ELF:
OS << "swift3_" << LongName;
diff --git a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
index 6aa7709..bacdf0d 100644
--- a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
+++ b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
@@ -4,7 +4,7 @@
# libswiftRemoteMirror.dylib should not have runtime dependencies; it's
# always built as a shared library.
if(SWIFT_BUILD_DYNAMIC_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR)
- add_swift_library(swiftRemoteMirror SHARED TARGET_LIBRARY DONT_EMBED_BITCODE
+ add_swift_library(swiftRemoteMirror SHARED TARGET_LIBRARY DONT_EMBED_BITCODE NOSWIFTRT
SwiftRemoteMirror.cpp
LINK_LIBRARIES swiftReflection
C_COMPILE_FLAGS ${SWIFT_RUNTIME_CXX_FLAGS}
diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt
index 56ae09c..44dff74 100644
--- a/stdlib/public/runtime/CMakeLists.txt
+++ b/stdlib/public/runtime/CMakeLists.txt
@@ -45,7 +45,7 @@
HeapObject.cpp
ImageInspectionMachO.cpp
ImageInspectionELF.cpp
- ImageInspectionWin32.cpp
+ ImageInspectionCOFF.cpp
KnownMetadata.cpp
Metadata.cpp
MetadataLookup.cpp
@@ -71,6 +71,7 @@
CygwinPort.cpp
ImageInspectionELF.cpp
StaticBinaryELF.cpp
+ SwiftRT-COFF.cpp
SwiftRT-ELF.cpp
${swift_runtime_sources}
${swift_runtime_objc_sources}
@@ -128,30 +129,41 @@
INSTALL_IN_COMPONENT never_install)
set(ELFISH_SDKS)
+set(COFF_SDKS)
foreach(sdk ${SWIFT_CONFIGURED_SDKS})
if("${SWIFT_SDK_${sdk}_OBJECT_FORMAT}" STREQUAL "ELF")
list(APPEND ELFISH_SDKS ${sdk})
+ elseif("${SWIFT_SDK_${sdk}_OBJECT_FORMAT}" STREQUAL "COFF")
+ list(APPEND COFF_SDKS ${sdk})
endif()
endforeach()
-add_swift_library(swiftImageRegistrationObject
+add_swift_library(swiftImageRegistrationObjectELF
OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE
SwiftRT-ELF.cpp
C_COMPILE_FLAGS ${SWIFT_RUNTIME_CORE_CXX_FLAGS}
LINK_FLAGS ${SWIFT_RUNTIME_CORE_LINK_FLAGS}
TARGET_SDKS ${ELFISH_SDKS}
INSTALL_IN_COMPONENT none)
+add_swift_library(swiftImageRegistrationObjectCOFF
+ OBJECT_LIBRARY IS_STDLIB IS_STDLIB_CORE
+ SwiftRT-COFF.cpp
+ C_COMPILE_FLAGS ${SWIFT_RUNTIME_CORE_CXX_FLAGS}
+ LINK_FLAGS ${SWIFT_RUNTIME_CORE_LINK_FLAGS}
+ TARGET_SDKS ${COFF_SDKS}
+ INSTALL_IN_COMPONENT none)
foreach(sdk ${SWIFT_CONFIGURED_SDKS})
foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES})
set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}")
set(arch_suffix "${SWIFT_SDK_${sdk}_LIB_SUBDIR}-${arch}")
- if("${SWIFT_SDK_${sdk}_OBJECT_FORMAT}" STREQUAL "ELF")
+ if("${SWIFT_SDK_${sdk}_OBJECT_FORMAT}" STREQUAL "ELF" OR
+ "${SWIFT_SDK_${sdk}_OBJECT_FORMAT}" STREQUAL "COFF")
# TODO(compnerd) switch to the generator expression when cmake is upgraded
# to a version which supports it.
- # set(swiftrtObject "$<TARGET_OBJECTS:swiftImageRegistrationObject-${arch_suffix}>")
- set(swiftrtObject ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/swiftImageRegistrationObject-${arch_suffix}.dir/SwiftRT-ELF.cpp${CMAKE_C_OUTPUT_EXTENSION})
+ # set(swiftrtObject "$<TARGET_OBJECTS:swiftImageRegistrationObject${SWIFT_SDK_${sdk}_OBJECT_FORMAT}-${arch_suffix}>")
+ set(swiftrtObject ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/swiftImageRegistrationObject${SWIFT_SDK_${sdk}_OBJECT_FORMAT}-${arch_suffix}.dir/SwiftRT-${SWIFT_SDK_${sdk}_OBJECT_FORMAT}.cpp${CMAKE_C_OUTPUT_EXTENSION})
set(swiftrtPath "${SWIFTLIB_DIR}/${arch_subdir}/swiftrt${CMAKE_C_OUTPUT_EXTENSION}")
add_custom_command_target(swiftImageRegistration-${arch_suffix}
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.cpp b/stdlib/public/runtime/ImageInspectionCOFF.cpp
new file mode 100644
index 0000000..7f8b6c0
--- /dev/null
+++ b/stdlib/public/runtime/ImageInspectionCOFF.cpp
@@ -0,0 +1,107 @@
+//===--- ImageInspectionWin32.cpp - Win32 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
+//
+//===----------------------------------------------------------------------===//
+
+#if !defined(__ELF__) && !defined(__MACH__)
+
+#include "ImageInspection.h"
+#include "ImageInspectionCOFF.h"
+
+#if defined(__CYGWIN__)
+#include <dlfcn.h>
+#endif
+
+using namespace swift;
+
+namespace {
+static const swift::MetadataSections *registered = nullptr;
+
+void record(const swift::MetadataSections *sections) {
+ if (registered == nullptr) {
+ registered = sections;
+ sections->next = sections->prev = sections;
+ } else {
+ registered->prev->next = sections;
+ sections->next = registered;
+ sections->prev = registered->prev;
+ registered->prev = sections;
+ }
+}
+}
+
+void swift::initializeProtocolConformanceLookup() {
+ const swift::MetadataSections *sections = registered;
+ while (true) {
+ const swift::MetadataSections::Range &conformances =
+ sections->swift2_protocol_conformances;
+ if (conformances.length)
+ addImageProtocolConformanceBlockCallback(reinterpret_cast<void *>(conformances.start),
+ conformances.length);
+
+ if (sections->next == registered)
+ break;
+ sections = sections->next;
+ }
+}
+
+void swift::initializeTypeMetadataRecordLookup() {
+ const swift::MetadataSections *sections = registered;
+ while (true) {
+ const swift::MetadataSections::Range &type_metadata =
+ sections->swift2_type_metadata;
+ if (type_metadata.length)
+ addImageTypeMetadataRecordBlockCallback(reinterpret_cast<void *>(type_metadata.start),
+ type_metadata.length);
+
+ if (sections->next == registered)
+ break;
+ sections = sections->next;
+ }
+}
+
+SWIFT_RUNTIME_EXPORT
+void swift_addNewDSOImage(const void *addr) {
+ const swift::MetadataSections *sections =
+ static_cast<const swift::MetadataSections *>(addr);
+
+ record(sections);
+
+ const auto &protocol_conformances = sections->swift2_protocol_conformances;
+ const void *conformances =
+ reinterpret_cast<void *>(protocol_conformances.start);
+ if (protocol_conformances.length)
+ addImageProtocolConformanceBlockCallback(conformances,
+ protocol_conformances.length);
+
+ const auto &type_metadata = sections->swift2_type_metadata;
+ const void *metadata = reinterpret_cast<void *>(type_metadata.start);
+ if (type_metadata.length)
+ addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
+}
+
+int swift::lookupSymbol(const void *address, SymbolInfo *info) {
+#if defined(__CYGWIN__)
+ Dl_info dlinfo;
+ if (dladdr(address, &dlinfo) == 0) {
+ return 0;
+ }
+
+ info->fileName = dlinfo.dli_fname;
+ info->baseAddress = dlinfo.dli_fbase;
+ info->symbolName = dli_info.dli_sname;
+ info->symbolAddress = dli_saddr;
+ return 1;
+#else
+ return 0;
+#endif // __CYGWIN__
+}
+
+#endif // !defined(__ELF__) && !defined(__MACH__)
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.h b/stdlib/public/runtime/ImageInspectionCOFF.h
new file mode 100644
index 0000000..bc63f9f
--- /dev/null
+++ b/stdlib/public/runtime/ImageInspectionCOFF.h
@@ -0,0 +1,63 @@
+//===--- ImageInspectionELF.h -----------------------------------*- C++ -*-===//
+//
+// 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
+///
+/// COFF specific image inspection routines.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_RUNTIME_IMAGEINSPECTIONCOFF_H
+#define SWIFT_RUNTIME_IMAGEINSPECTIONCOFF_H
+
+#if !defined(__ELF__) && !defined(__MACH__)
+
+#include "../SwiftShims/Visibility.h"
+#include <cstdint>
+#include <cstddef>
+
+namespace swift {
+struct SectionInfo {
+ uint64_t size;
+ const char *data;
+};
+
+static constexpr const uintptr_t CurrentSectionMetadataVersion = 1;
+
+struct MetadataSections {
+ uintptr_t version;
+ uintptr_t reserved;
+
+ mutable const MetadataSections *next;
+ mutable const MetadataSections *prev;
+
+ struct Range {
+ uintptr_t start;
+ size_t length;
+ };
+
+ Range swift2_protocol_conformances;
+ Range swift2_type_metadata;
+ Range swift3_typeref;
+ Range swift3_reflstr;
+ Range swift3_fieldmd;
+ Range swift3_assocty;
+};
+} // namespace swift
+
+// Called by injected constructors when a dynamic library is loaded.
+SWIFT_RUNTIME_EXPORT
+void swift_addNewDSOImage(const void *addr);
+
+#endif // !defined(__ELF__) && !defined(__MACH__)
+
+#endif // SWIFT_RUNTIME_IMAGEINSPECTIONCOFF_H
diff --git a/stdlib/public/runtime/ImageInspectionWin32.cpp b/stdlib/public/runtime/ImageInspectionWin32.cpp
deleted file mode 100644
index a590b3d..0000000
--- a/stdlib/public/runtime/ImageInspectionWin32.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-//===--- ImageInspectionWin32.cpp - Win32 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file includes routines that interact with the Win32 API on
-// Windows platforms to extract runtime metadata embedded in executables and
-// DLLs generated by the Swift compiler.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(_WIN32) || defined(__CYGWIN__)
-
-#include "ImageInspection.h"
-#include "swift/Runtime/Debug.h"
-#include <cstdlib>
-#include <cstring>
-#include <vector>
-
-#define WIN32_LEAN_AND_MEAN
-#define NOMINMAX
-#include <windows.h>
-#include <psapi.h>
-
-#if defined(__CYGWIN__)
-#include <dlfcn.h>
-#endif
-
-using namespace swift;
-
-/// PE section name for the section that contains protocol conformance records.
-static const char ProtocolConformancesSection[] = ".sw2prtc";
-/// PE section name for the section that contains type metadata records.
-static const char TypeMetadataRecordsSection[] = ".sw2tymd";
-
-/// Context information passed down from _swift_dl_iterate_phdr to the
-/// callback function.
-struct InspectArgs {
- void (*fnAddImageBlock)(const void *, uintptr_t);
- const char *sectionName;
-};
-
-struct _swift_dl_phdr_info {
- void *dlpi_addr;
- const char *dlpi_name;
-};
-
-static int _swift_dl_iterate_phdr(int (*Callback)(struct _swift_dl_phdr_info *info,
- size_t size, const void *data),
- const void *data) {
- DWORD procId = GetCurrentProcessId();
- HANDLE procHandle =
- OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, procId);
- if (!procHandle) {
- swift::fatalError(/* flags = */ 0, "OpenProcess() failed");
- return 0;
- }
-
- int lastRet = 0;
-
- std::vector<HMODULE> modules(1024);
- DWORD neededSize;
-
- BOOL ret = EnumProcessModules(procHandle, modules.data(),
- modules.size() * sizeof(HMODULE), &neededSize);
-
- if (!ret) {
- swift::fatalError(/* flags = */ 0, "EnumProcessModules() failed");
- return 0;
- }
-
- if (modules.size() * sizeof(HMODULE) < neededSize) {
- modules.resize(neededSize / sizeof(HMODULE));
- ret = EnumProcessModules(procHandle, modules.data(),
- modules.size() * sizeof(HMODULE), &neededSize);
- }
-
- if (!ret) {
- swift::fatalError(/* flags = */ 0, "EnumProcessModules() failed");
- return 0;
- }
-
- for (unsigned i = 0; i < neededSize / sizeof(HMODULE); i++) {
- char modName[MAX_PATH];
-
- if (!GetModuleFileNameExA(procHandle, modules[i], modName,
- sizeof(modName))) {
- swift::fatalError(/* flags = */ 0, "GetModuleFileNameExA() failed");
- }
-
- _swift_dl_phdr_info hdr;
- hdr.dlpi_name = modName;
- hdr.dlpi_addr = modules[i];
-
- lastRet = Callback(&hdr, sizeof(hdr), data);
- if (lastRet != 0)
- break;
- }
-
- CloseHandle(procHandle);
-
- return lastRet;
-}
-
-static uint8_t *_swift_getSectionDataPE(const void *handle,
- const char *sectionName,
- unsigned long *sectionSize) {
- // In Cygwin, dlopen() returns PE/COFF image pointer.
- // This is relying on undocumented feature of Windows API LoadLibrary().
- const unsigned char *peStart = static_cast<const unsigned char *>(handle);
-
- const int kLocationOfNtHeaderOffset = 0x3C;
- int ntHeadersOffset =
- *reinterpret_cast<const int32_t *>(peStart + kLocationOfNtHeaderOffset);
-
- bool assert1 =
- peStart[ntHeadersOffset] == 'P' && peStart[ntHeadersOffset + 1] == 'E';
- if (!assert1) {
- swift::fatalError(/* flags = */ 0, "_swift_getSectionDataPE()'s finding PE failed");
- }
-
- const unsigned char *coff = peStart + ntHeadersOffset + 4;
-
- int16_t numberOfSections = *reinterpret_cast<const int16_t *>(coff + 2);
-
- // SizeOfOptionalHeader
- int16_t sizeOfOptionalHeader = *reinterpret_cast<const int16_t *>(coff + 16);
-
- const int kCoffFileHeaderSize = 20;
- const unsigned char *sectionTableBase =
- coff + kCoffFileHeaderSize + sizeOfOptionalHeader;
-
- // Section Header Record
- const int kSectionRecordSize = 40;
-
- const unsigned char *sectionHeader = sectionTableBase;
- for (int i = 0; i < numberOfSections; i++) {
- uint32_t virtualSize =
- *reinterpret_cast<const uint32_t *>(§ionHeader[8]);
- uint32_t virtualAddress =
- *reinterpret_cast<const uint32_t *>(§ionHeader[12]);
-
- char nameOfThisSection[9];
- memcpy(nameOfThisSection, sectionHeader, 8);
- nameOfThisSection[8] = '\0';
-
- if (strcmp(sectionName, nameOfThisSection) == 0) {
- *sectionSize = virtualSize;
- return const_cast<uint8_t *>(peStart + virtualAddress);
- }
- sectionHeader += kSectionRecordSize;
- }
-
- return nullptr;
-}
-
-static int _addImageCallback(struct _swift_dl_phdr_info *info,
- size_t size, const void *data) {
- const InspectArgs *inspectArgs = static_cast<const InspectArgs *>(data);
- // inspectArgs contains addImage*Block function and the section name
-#if defined(_WIN32)
- HMODULE handle;
-
- if (!info->dlpi_name || info->dlpi_name[0] == '\0')
- handle = GetModuleHandle(nullptr);
- else
- handle = GetModuleHandleA(info->dlpi_name);
-#else
- void *handle;
- if (!info->dlpi_name || info->dlpi_name[0] == '\0')
- handle = dlopen(nullptr, RTLD_LAZY);
- else
- handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
-#endif
-
- unsigned long conformancesSize;
- const uint8_t *conformances =
- _swift_getSectionDataPE(handle, inspectArgs->sectionName,
- &conformancesSize);
-
- if (conformances)
- inspectArgs->fnAddImageBlock(conformances, conformancesSize);
-
- // There is no close function or free function for GetModuleHandle(),
- // especially we should not pass a handle returned by GetModuleHandle to the
- // FreeLibrary function.
-#if defined(__CYGWIN__)
- dlclose(handle);
-#endif
- return 0;
-}
-
-void swift::initializeProtocolConformanceLookup() {
- // Search the loaded dls. This only searches the already
- // loaded ones.
- // FIXME: Find a way to have this continue to happen for dlopen-ed images.
- // rdar://problem/19045112
- const InspectArgs ProtocolConformancesArgs = {
- addImageProtocolConformanceBlockCallback,
- ProtocolConformancesSection,
- };
- _swift_dl_iterate_phdr(_addImageCallback, &ProtocolConformancesArgs);
-}
-
-void swift::initializeTypeMetadataRecordLookup() {
- // Search the loaded dls. This only searches the already
- // loaded ones.
- // FIXME: Find a way to have this continue to happen for dlopen-ed images.
- // rdar://problem/19045112
- const InspectArgs TypeMetadataRecordsArgs = {
- addImageTypeMetadataRecordBlockCallback,
- TypeMetadataRecordsSection,
- };
- _swift_dl_iterate_phdr(_addImageCallback, &TypeMetadataRecordsArgs);
-}
-
-
-int swift::lookupSymbol(const void *address, SymbolInfo *info) {
-#if defined(__CYGWIN__)
- Dl_info dlinfo;
- if (dladdr(address, &dlinfo) == 0) {
- return 0;
- }
-
- info->fileName = dlinfo.dli_fname;
- info->baseAddress = dlinfo.dli_fbase;
- info->symbolName = dli_info.dli_sname;
- info->symbolAddress = dli_saddr;
- return 1;
-#else
- return 0;
-#endif // __CYGWIN__
-}
-
-#endif // defined(_WIN32) || defined(__CYGWIN__)
diff --git a/stdlib/public/runtime/SwiftRT-COFF.cpp b/stdlib/public/runtime/SwiftRT-COFF.cpp
new file mode 100644
index 0000000..77b5b04
--- /dev/null
+++ b/stdlib/public/runtime/SwiftRT-COFF.cpp
@@ -0,0 +1,79 @@
+//===--- SwiftRT-COFF.cpp -------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "ImageInspectionCOFF.h"
+
+#include <cstdint>
+
+#define PASTE_EXPANDED(a,b) a##b
+#define PASTE(a,b) PASTE_EXPANDED(a,b)
+
+#define STRING_EXPANDED(string) #string
+#define STRING(string) STRING_EXPANDED(string)
+
+#define C_LABEL(name) PASTE(__USER_LABEL_PREFIX__,name)
+
+#define PRAGMA(pragma) _Pragma(#pragma)
+
+#define DECLARE_SWIFT_SECTION(name) \
+ PRAGMA(section("." #name "$A", long, read, write)) \
+ __declspec(allocate("." #name "$A")) \
+ static uintptr_t __start_##name = 0; \
+ \
+ PRAGMA(section("." #name "$C", long, read, write)) \
+ __declspec(allocate("." #name "$C")) \
+ static uintptr_t __stop_##name = 0;
+
+extern "C" {
+DECLARE_SWIFT_SECTION(sw2prtc)
+DECLARE_SWIFT_SECTION(sw2tymd)
+
+DECLARE_SWIFT_SECTION(sw3tyrf)
+DECLARE_SWIFT_SECTION(sw3rfst)
+DECLARE_SWIFT_SECTION(sw3flmd)
+DECLARE_SWIFT_SECTION(sw3asty)
+}
+
+namespace {
+static swift::MetadataSections sections{};
+}
+
+static void swift_image_constructor() {
+#define SWIFT_SECTION_RANGE(name) \
+ { reinterpret_cast<uintptr_t>(&__start_##name) + sizeof(__start_##name), \
+ reinterpret_cast<uintptr_t>(&__stop_##name) - reinterpret_cast<uintptr_t>(&__start_##name) - sizeof(__start_##name) }
+
+ sections = {
+ swift::CurrentSectionMetadataVersion,
+ 0,
+
+ nullptr,
+ nullptr,
+
+ SWIFT_SECTION_RANGE(sw2prtc),
+ SWIFT_SECTION_RANGE(sw2tymd),
+
+ SWIFT_SECTION_RANGE(sw3tyrf),
+ SWIFT_SECTION_RANGE(sw3rfst),
+ SWIFT_SECTION_RANGE(sw3flmd),
+ SWIFT_SECTION_RANGE(sw3asty),
+ };
+
+#undef SWIFT_SECTION_RANGE
+
+ swift_addNewDSOImage(§ions);
+}
+
+__declspec(allocate(".CRT$XCIS"))
+extern "C" void (*pSwiftImageConstructor)(void) = &swift_image_constructor;
+#pragma comment(linker, "/include:" STRING(C_LABEL(pSwiftImageConstructor)))
+
diff --git a/test/IRGen/swift3-metadata-coff.swift b/test/IRGen/swift3-metadata-coff.swift
index 90e5428..9e1bc83 100644
--- a/test/IRGen/swift3-metadata-coff.swift
+++ b/test/IRGen/swift3-metadata-coff.swift
@@ -25,11 +25,11 @@
return { gg = s }
}
-// CHECK-DAG: @"\01l__swift3_reflection_descriptor" = private constant {{.*}}, section ".sw3cptr"
-// CHECK-DAG: @{{[0-9]+}} = private constant [3 x i8] c"Sq\00", section ".sw3tyrf"
-// CHECK-DAG: @{{[0-9]+}} = private constant [5 x i8] c"none\00", section ".sw3rfst"
-// CHECK-DAG: @{{[0-9]+}} = private constant [5 x i8] c"some\00", section ".sw3rfst"
-// CHECK-DAG: @_T0SqMF = internal constant {{.*}}, section ".sw3flmd"
-// CHECK-DAG: @_T0s1SVs1PsMA = internal constant {{.*}}, section ".sw3asty"
-// CHECK-DAG: @_T0BoMB = internal constant {{.*}}, section ".sw3bltn"
+// CHECK-DAG: @"\01l__swift3_reflection_descriptor" = private constant {{.*}}, section ".sw3cptr$B"
+// CHECK-DAG: @{{[0-9]+}} = private constant [3 x i8] c"Sq\00", section ".sw3tyrf$B"
+// CHECK-DAG: @{{[0-9]+}} = private constant [5 x i8] c"none\00", section ".sw3rfst$B"
+// CHECK-DAG: @{{[0-9]+}} = private constant [5 x i8] c"some\00", section ".sw3rfst$B"
+// CHECK-DAG: @_T0SqMF = internal constant {{.*}}, section ".sw3flmd$B"
+// CHECK-DAG: @_T0s1SVs1PsMA = internal constant {{.*}}, section ".sw3asty$B"
+// CHECK-DAG: @_T0BoMB = internal constant {{.*}}, section ".sw3bltn$B"