Merge pull request #13211 from compnerd/COFF-registration

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 3f604b5..7be0a1c 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2391,7 +2391,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 "
@@ -2414,7 +2414,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 *>(&sectionHeader[8]);
-    uint32_t virtualAddress =
-        *reinterpret_cast<const uint32_t *>(&sectionHeader[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(&sections);
+}
+
+__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"