diff --git a/CMakeLists.txt b/CMakeLists.txt index 263b8679a1c..b5c3bff8844 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1161,13 +1161,6 @@ macro(add_swift_library name) set(SWIFTLIB_DEFAULT_LINK_FLAGS "-Xlinker -segalign -Xlinker 0x4000") endif() - # On linux add the linker script that coalesces protocol conformance - # sections. This wouldn't be necessary if the link was done by the swift - # binary: rdar://problem/19007002 - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(SWIFTLIB_DEFAULT_LINK_FLAGS - "${SWIFTLIB_DEFAULT_LINK_FLAGS} -Xlinker -Tswift.ld") - endif() # If we're supposed to build this library for the target... if(SWIFTLIB_TARGET_LIBRARY AND SWIFT_SDKS) diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 0d39ca82eae..228707d8dd0 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -669,10 +669,6 @@ Job *linux::Linker::constructJob(const JobAction &JA, Arguments.push_back("-lswiftCore"); - // Add the linker script that coalesces protocol conformance sections. - Arguments.push_back("-Xlinker"); - Arguments.push_back("-Tswift.ld"); - // This should be the last option, for convenience in checking output. Arguments.push_back("-o"); Arguments.push_back(Output->getPrimaryOutputFilename().c_str()); diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index a26d408643d..f68710c2b94 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -1729,17 +1729,7 @@ namespace { ? Twine("_$_") + CategoryName.str() : Twine())); var->setAlignment(IGM.getPointerAlignment().getValue()); - switch (IGM.TargetInfo.OutputObjectFormat) { - case llvm::Triple::MachO: - var->setSection("__DATA, __objc_const"); - break; - case llvm::Triple::ELF: - var->setSection(".data"); - break; - default: - llvm_unreachable("Don't know how to emit private global constants for " - "the selected object format."); - } + var->setSection("__DATA, __objc_const"); return var; } diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index a5128908b46..cb073f3ca2c 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -454,27 +454,6 @@ emitGlobalList(IRGenModule &IGM, ArrayRef handles, return var; } -/// Emit the protocol conformance list and return it -llvm::Constant *IRGenModule::emitProtocolConformances() { - std::string sectionName; - switch (TargetInfo.OutputObjectFormat) { - case llvm::Triple::MachO: - sectionName = "__DATA, __swift1_proto, regular, no_dead_strip"; - break; - case llvm::Triple::ELF: - sectionName = ".swift1_protocol_conformances"; - break; - default: - llvm_unreachable("Don't know how to emit protocol conformances for " - "the selected object format."); - } - - return emitGlobalList(*this, ProtocolConformanceRecords, - "protocol_conformances", sectionName, - llvm::GlobalValue::InternalLinkage, - ProtocolConformanceRecordTy, true); -} - void IRGenModule::emitRuntimeRegistration() { // Duck out early if we have nothing to register. if (ProtocolConformanceRecords.empty() @@ -579,9 +558,13 @@ void IRGenModule::emitRuntimeRegistration() { } // Register Swift protocol conformances if we added any. if (!ProtocolConformanceRecords.empty()) { - - llvm::Constant *conformances = emitProtocolConformances(); - + llvm::Constant *conformances + = emitGlobalList(*this, ProtocolConformanceRecords, + "protocol_conformances", + "__DATA, __swift1_proto, regular, no_dead_strip", + llvm::GlobalValue::InternalLinkage, + ProtocolConformanceRecordTy, + true); llvm::Constant *beginIndices[] = { llvm::ConstantInt::get(Int32Ty, 0), llvm::ConstantInt::get(Int32Ty, 0), @@ -619,37 +602,37 @@ void IRGenModule::addProtocolConformanceRecord(llvm::Constant *conformanceRec) { } void IRGenModule::emitGlobalLists() { - if (ObjCInterop) { - assert(TargetInfo.OutputObjectFormat == llvm::Triple::MachO); - // Objective-C class references go in a variable with a meaningless - // name but a magic section. - emitGlobalList(*this, ObjCClasses, "objc_classes", - "__DATA, __objc_classlist, regular, no_dead_strip", - llvm::GlobalValue::InternalLinkage, - Int8PtrTy, - false); - // So do categories. - emitGlobalList(*this, ObjCCategories, "objc_categories", - "__DATA, __objc_catlist, regular, no_dead_strip", - llvm::GlobalValue::InternalLinkage, - Int8PtrTy, - false); + // Objective-C class references go in a variable with a meaningless + // name but a magic section. + emitGlobalList(*this, ObjCClasses, "objc_classes", + "__DATA, __objc_classlist, regular, no_dead_strip", + llvm::GlobalValue::InternalLinkage, + Int8PtrTy, + false); + // So do categories. + emitGlobalList(*this, ObjCCategories, "objc_categories", + "__DATA, __objc_catlist, regular, no_dead_strip", + llvm::GlobalValue::InternalLinkage, + Int8PtrTy, + false); - // Emit nonlazily realized class references in a second magic section to make - // sure they are realized by the Objective-C runtime before any instances - // are allocated. - emitGlobalList(*this, ObjCNonLazyClasses, "objc_non_lazy_classes", - "__DATA, __objc_nlclslist, regular, no_dead_strip", - llvm::GlobalValue::InternalLinkage, - Int8PtrTy, - false); - } + // Emit nonlazily realized class references in a second magic section to make + // sure they are realized by the Objective-C runtime before any instances + // are allocated. + emitGlobalList(*this, ObjCNonLazyClasses, "objc_non_lazy_classes", + "__DATA, __objc_nlclslist, regular, no_dead_strip", + llvm::GlobalValue::InternalLinkage, + Int8PtrTy, + false); // Emit protocol conformances into a section we can recognize at runtime. // In JIT mode we need to manually register these conformances later. - if (!Opts.UseJIT) { - emitProtocolConformances(); - } + if (!Opts.UseJIT) + emitGlobalList(*this, ProtocolConformanceRecords, "protocol_conformances", + "__DATA, __swift1_proto, regular, no_dead_strip", + llvm::GlobalValue::InternalLinkage, + ProtocolConformanceRecordTy, + true); // @llvm.used assert(std::all_of(LLVMUsed.begin(), LLVMUsed.end(), diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index dda7c675fb0..55f13726061 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -369,7 +369,6 @@ private: ObjCProtocolPair getObjCProtocolGlobalVars(ProtocolDecl *proto); - llvm::Constant *emitProtocolConformances(); void emitGlobalLists(); void emitAutolinkInfo(); diff --git a/stdlib/runtime/CMakeLists.txt b/stdlib/runtime/CMakeLists.txt index 3ea00c49087..5c66a3de500 100644 --- a/stdlib/runtime/CMakeLists.txt +++ b/stdlib/runtime/CMakeLists.txt @@ -47,10 +47,6 @@ add_swift_library(swiftRuntime FRAMEWORK_DEPENDS ${FRAMEWORKS}) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - # FIXME: This is probably not flexible enough to deal with 32bit builds, - # but SWIFTLIB_DIR isn't available in this cmake file and duplicating - # the logic seems wrong. rdar://problem/19035586 - configure_file(swift.ld ${CMAKE_BINARY_DIR}/lib/swift/swift.ld COPYONLY) target_link_libraries(swiftRuntime "-lpthread" "-ldl") endif() diff --git a/stdlib/runtime/Casting.cpp b/stdlib/runtime/Casting.cpp index 6ddd7dbf388..1b98b5276be 100644 --- a/stdlib/runtime/Casting.cpp +++ b/stdlib/runtime/Casting.cpp @@ -28,19 +28,16 @@ #include "../shims/RuntimeShims.h" #include "stddef.h" -#if defined(__APPLE__) && defined(__MACH__) +#ifdef __APPLE__ #include #include -#elif defined(__ELF__) -#include -#include +#include #endif #include #include #include #include -#include #include #include @@ -1659,17 +1656,14 @@ const { } } -#if defined(__APPLE__) && defined(__MACH__) +// TODO: Implement protocol conformance lookup for non-Apple environments +#ifdef __APPLE__ + #define SWIFT_PROTOCOL_CONFORMANCES_SECTION "__swift1_proto" -#elif defined(__ELF__) -#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".swift1_protocol_conformances_start" -#endif -// FIXME: Implement this callback on non-apple platforms. - -// std:once_flag token to install the dyld callback to enqueue images for +// dispatch_once token to install the dyld callback to enqueue images for // protocol conformance lookup. -static std::once_flag InstallProtocolConformanceAddImageCallbackOnce; +static dispatch_once_t InstallProtocolConformanceAddImageCallbackOnce = 0; // Monotonic generation number that is increased when we load an image with // new protocol conformances. @@ -1817,21 +1811,6 @@ swift::swift_registerProtocolConformances(const ProtocolConformanceRecord *begin pthread_mutex_unlock(&SectionsToScanLock); } -static void _addImageProtocolConformancesBlock(const uint8_t *conformances, - size_t conformancesSize) { - assert(conformancesSize % sizeof(ProtocolConformanceRecord) == 0 - && "weird-sized conformances section?!"); - - // If we have a section, enqueue the conformances for lookup. - auto recordsBegin - = reinterpret_cast(conformances); - auto recordsEnd - = reinterpret_cast - (conformances + conformancesSize); - swift_registerProtocolConformances(recordsBegin, recordsEnd); -} - -#if defined(__APPLE__) && defined(__MACH__) static void _addImageProtocolConformances(const mach_header *mh, intptr_t vmaddr_slide) { #ifdef __LP64__ @@ -1851,57 +1830,29 @@ static void _addImageProtocolConformances(const mach_header *mh, if (!conformances) return; - _addImageProtocolConformancesBlock(conformances, conformancesSize); + assert(conformancesSize % sizeof(ProtocolConformanceRecord) == 0 + && "weird-sized conformances section?!"); + + // If we have a section, enqueue the conformances for lookup. + auto recordsBegin + = reinterpret_cast(conformances); + auto recordsEnd + = reinterpret_cast + (conformances + conformancesSize); + swift_registerProtocolConformances(recordsBegin, recordsEnd); } -#elif defined(__ELF__) -static int _addImageProtocolConformances(struct dl_phdr_info *info, - size_t size, void * /*data*/) { - // Skip the executable and ld-linux.so, which both have a null or empty name. - if (!info->dlpi_name || info->dlpi_name[0] == '\0') - return 0; - - void *handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD); - auto conformances = reinterpret_cast( - dlsym(handle, SWIFT_PROTOCOL_CONFORMANCES_SECTION)); - - if (!conformances) { - // if there are no conformances, don't hold this handle open. - dlclose(handle); - return 0; - } - - // Extract the size of the conformances block from the head of the section - auto conformancesSize = *reinterpret_cast(conformances); - conformances += sizeof(conformancesSize); - - _addImageProtocolConformancesBlock(conformances, conformancesSize); - - dlclose(handle); - return 0; -} -#endif const WitnessTable *swift::swift_conformsToProtocol(const Metadata *type, const ProtocolDescriptor *protocol){ // TODO: Generic types, subclasses, foreign classes - std::call_once(InstallProtocolConformanceAddImageCallbackOnce, [](){ -#if defined(__APPLE__) && defined(__MACH__) - // Install our dyld callback if we haven't already. - // Dyld will invoke this on our behalf for all images that have already been - // loaded. + // Install our dyld callback if we haven't already. + // Dyld will invoke this on our behalf for all images that have already been + // loaded. + dispatch_once(&InstallProtocolConformanceAddImageCallbackOnce, ^(void){ _dyld_register_func_for_add_image(_addImageProtocolConformances); -#elif defined(__ELF__) - // Search the loaded dls. Unlike the above, this only searches the already - // loaded ones. - // FIXME: Find a way to have this continue to happen after. - // rdar://problem/19045112 - dl_iterate_phdr(_addImageProtocolConformances, nullptr); -#else -#error No known mechanism to inspect loaded dynamic libraries on this platform. -#endif }); - + auto origType = type; recur: @@ -2018,6 +1969,16 @@ recur_inside_cache_lock: goto recur; } +#else // if !__APPLE__ + +const WitnessTable *swift::swift_conformsToProtocol(const Metadata *type, + const ProtocolDescriptor *protocol){ + // Not implemented for non-Apple platforms. + return nullptr; +} + +#endif // __APPLE__ + // The return type is incorrect. It is only important that it is // passed using 'sret'. extern "C" OpaqueExistentialContainer diff --git a/stdlib/runtime/swift.ld b/stdlib/runtime/swift.ld deleted file mode 100644 index f775ec0b963..00000000000 --- a/stdlib/runtime/swift.ld +++ /dev/null @@ -1,10 +0,0 @@ -SECTIONS -{ - .swift1_protocol_conformances : - { - .swift1_protocol_conformances_start = . ; - QUAD(SIZEOF(.swift1_protocol_conformances) - 8) ; - *(.swift1_protocol_conformances) ; - } -} -INSERT AFTER .dtors diff --git a/test/Driver/linker.swift b/test/Driver/linker.swift index 777942cbf20..252a640de85 100644 --- a/test/Driver/linker.swift +++ b/test/Driver/linker.swift @@ -63,7 +63,6 @@ // LINUX-DAG: -lswiftCore // LINUX-DAG: -L [[STDLIB_PATH:[^ ]+/lib/swift]] // LINUX-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]] -// LINUX-DAG: -Xlinker -Tswift.ld // LINUX-DAG: -F foo // LINUX-DAG: -framework bar // LINUX-DAG: -L baz