diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 2eba9fcd8ae6e..ab964e25ceed8 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -278,6 +278,12 @@ def no_static_stdlib: Flag<["-"], "no-static-stdlib">, Flags<[HelpHidden]>, HelpText<"Don't statically link the Swift standard library">; +def static_executable : Flag<["-"], "static-executable">, + HelpText<"Statically link the executable">; +def no_static_executable : Flag<["-"], "no-static-executable">, + Flags<[HelpHidden]>, + HelpText<"Don't statically link the executable">; + def use_ld : Joined<["-"], "use-ld=">, Flags<[DoesNotAffectIncrementalBuild]>, HelpText<"Specifies the linker to be used">; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 285de54a2a067..6003e0908b967 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -948,6 +948,12 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job, assert(context.Output.getPrimaryOutputType() == types::TY_Image && "Invalid linker output type."); + if (context.Args.hasFlag(options::OPT_static_executable, + options::OPT_no_static_executable, + false)) { + llvm::report_fatal_error("-static-executable is not supported on Darwin"); + } + const Driver &D = getDriver(); const llvm::Triple &Triple = getTriple(); @@ -1353,9 +1359,38 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, // Link the standard library. Arguments.push_back("-L"); - if (context.Args.hasFlag(options::OPT_static_stdlib, - options::OPT_no_static_stdlib, - false)) { + if (context.Args.hasFlag(options::OPT_static_executable, + options::OPT_no_static_executable, + false)) { + SmallString<128> StaticRuntimeLibPath; + getRuntimeStaticLibraryPath(StaticRuntimeLibPath, context.Args, *this); + Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); + + SmallString<128> StaticStubObjectPath = StaticRuntimeLibPath; + llvm::sys::path::append(StaticStubObjectPath, "static_stub.o"); + auto ObjectPath = StaticStubObjectPath.str(); + + if (llvm::sys::fs::is_regular_file(ObjectPath)) { + // FIXME: It would be better if these were extracted from static_stub.o + // using `swift-autolink-extract' + Arguments.push_back(context.Args.MakeArgString(ObjectPath)); + Arguments.push_back("-static"); + Arguments.push_back("-Xlinker"); + Arguments.push_back("--defsym=__swift2_protocol_conformances_start=.swift2_protocol_conformances_start"); + Arguments.push_back("-Xlinker"); + Arguments.push_back("--defsym=__swift2_type_metadata_start=.swift2_type_metadata_start"); + Arguments.push_back("-lswiftCore"); + Arguments.push_back("-licui18n"); + Arguments.push_back("-licuuc"); + Arguments.push_back("-licudata"); + Arguments.push_back("-lpthread"); + } else { + llvm::report_fatal_error("-static-executable not supported on this platform"); + } + } + else if (context.Args.hasFlag(options::OPT_static_stdlib, + options::OPT_no_static_stdlib, + false)) { SmallString<128> StaticRuntimeLibPath; getRuntimeStaticLibraryPath(StaticRuntimeLibPath, context.Args, *this); Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 732013ad1c701..6f5f076969137 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -55,6 +55,7 @@ set(swift_runtime_sources ProtocolConformance.cpp ReflectionNative.cpp RuntimeEntrySymbols.cpp + SectionData.cpp SwiftObjectNative.cpp) # Acknowledge that the following sources are known. @@ -64,6 +65,7 @@ set(LLVM_OPTIONAL_SOURCES MutexPThread.cpp MutexWin32.cpp CygwinPort.cpp + static_stub.c ${swift_runtime_sources} ${swift_runtime_objc_sources} ${swift_runtime_leaks_sources}) @@ -130,3 +132,15 @@ foreach(sdk ${ELFISH_SDKS}) endforeach() add_custom_target(section_magic ALL DEPENDS ${object_target_list}) + +if(SWIFT_BUILD_STATIC_STDLIB) + foreach(sdk ${SWIFT_SDKS}) + if("${sdk}" STREQUAL "LINUX") + add_library(static_stub OBJECT static_stub.c) + swift_install_in_component(stdlib + FILES "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/static_stub.dir/static_stub.c${CMAKE_C_OUTPUT_EXTENSION}" + RENAME "static_stub.o" + DESTINATION "lib/swift_static/linux") + endif() + endforeach() +endif() diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index 5822a930520c0..0256ae89659e8 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -25,14 +25,8 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringExtras.h" #include "Private.h" +#include "SectionData.h" -#if defined(__APPLE__) && defined(__MACH__) -#include -#include -#elif defined(__ELF__) || defined(__ANDROID__) -#include -#include -#endif using namespace swift; using namespace Demangle; @@ -43,14 +37,6 @@ using namespace Demangle; #include #endif -#if defined(__APPLE__) && defined(__MACH__) -#define SWIFT_TYPE_METADATA_SECTION "__swift2_types" -#elif defined(__ELF__) -#define SWIFT_TYPE_METADATA_SECTION ".swift2_type_metadata_start" -#elif defined(__CYGWIN__) || defined(_MSC_VER) -#define SWIFT_TYPE_METADATA_SECTION ".sw2tymd" -#endif - // Type Metadata Cache. namespace { @@ -89,17 +75,22 @@ namespace { }; } -#if defined(__APPLE__) && defined(__MACH__) -static void _initializeCallbacksToInspectDylib(); -#else -namespace swift { - void _swift_initializeCallbacksToInspectDylib( - void (*fnAddImageBlock)(const uint8_t *, size_t), - const char *sectionName); -} - static void _addImageTypeMetadataRecordsBlock(const uint8_t *records, size_t recordsSize); + +static InspectArgs metadataSectionArgs = { + _addImageTypeMetadataRecordsBlock, + SWIFT_TYPE_METADATA_SECTION, +#if defined(SUPPORTS_STATIC_BINARIES) + &__swift2_type_metadata_start +#endif +}; + +#if defined(__APPLE__) && defined(__MACH__) +static void +_addImageTypeMetadataRecords(const mach_header *mh, intptr_t vmaddr_slide) { + _swift_readSectionData(mh, &metadataSectionArgs); +} #endif struct TypeMetadataState { @@ -110,14 +101,11 @@ struct TypeMetadataState { TypeMetadataState() { SectionsToScan.reserve(16); #if defined(__APPLE__) && defined(__MACH__) - _initializeCallbacksToInspectDylib(); + _swift_initializeCallbacksForSectionData(_addImageTypeMetadataRecords); #else - _swift_initializeCallbacksToInspectDylib( - _addImageTypeMetadataRecordsBlock, - SWIFT_TYPE_METADATA_SECTION); + _swift_initializeCallbacksForSectionData(&metadataSectionArgs); #endif } - }; static Lazy TypeMetadataRecords; @@ -147,36 +135,6 @@ static void _addImageTypeMetadataRecordsBlock(const uint8_t *records, recordsBegin, recordsEnd); } -#if defined(__APPLE__) && defined(__MACH__) -static void _addImageTypeMetadataRecords(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_types section. - unsigned long recordsSize; - const uint8_t *records = - getsectiondata(reinterpret_cast(mh), - SEG_TEXT, SWIFT_TYPE_METADATA_SECTION, - &recordsSize); - - if (!records) - return; - - _addImageTypeMetadataRecordsBlock(records, recordsSize); -} - -static void _initializeCallbacksToInspectDylib() { - // Install our dyld callback. - // Dyld will invoke this on our behalf for all images that have already - // been loaded. - _dyld_register_func_for_add_image(_addImageTypeMetadataRecords); -} -#endif void swift::swift_registerTypeMetadataRecords(const TypeMetadataRecord *begin, diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp index 4ac9ad976c339..f2ba73d75d9a2 100644 --- a/stdlib/public/runtime/ProtocolConformance.cpp +++ b/stdlib/public/runtime/ProtocolConformance.cpp @@ -20,22 +20,8 @@ #include "swift/Runtime/Metadata.h" #include "swift/Runtime/Mutex.h" #include "Private.h" +#include "SectionData.h" -#if defined(__APPLE__) && defined(__MACH__) -#include -#include -#elif defined(__ELF__) || defined(__ANDROID__) -#include -#include -#endif - -#if defined(_MSC_VER) -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include -#else -#include -#endif using namespace swift; @@ -146,13 +132,6 @@ const { } } -#if defined(__APPLE__) && defined(__MACH__) -#define SWIFT_PROTOCOL_CONFORMANCES_SECTION "__swift2_proto" -#elif defined(__ELF__) -#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".swift2_protocol_conformances_start" -#elif defined(__CYGWIN__) || defined(_MSC_VER) -#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".sw2prtc" -#endif namespace { struct ConformanceSection { @@ -232,17 +211,23 @@ namespace { } // Conformance Cache. -#if defined(__APPLE__) && defined(__MACH__) -static void _initializeCallbacksToInspectDylib(); -#else -namespace swift { - void _swift_initializeCallbacksToInspectDylib( - void (*fnAddImageBlock)(const uint8_t *, size_t), - const char *sectionName); -} static void _addImageProtocolConformancesBlock(const uint8_t *conformances, size_t conformancesSize); + +static InspectArgs conformanceSectionArgs = { + _addImageProtocolConformancesBlock, + SWIFT_PROTOCOL_CONFORMANCES_SECTION, +#if defined(SUPPORTS_STATIC_BINARIES) + &__swift2_protocol_conformances_start +#endif +}; + +#if defined(__APPLE__) && defined(__MACH__) +static void +_addImageProtocolConformances(const mach_header *mh, intptr_t vmaddr_slide) { + _swift_readSectionData(mh, &conformanceSectionArgs); +} #endif struct ConformanceState { @@ -253,11 +238,9 @@ struct ConformanceState { ConformanceState() { SectionsToScan.reserve(16); #if defined(__APPLE__) && defined(__MACH__) - _initializeCallbacksToInspectDylib(); + _swift_initializeCallbacksForSectionData(_addImageProtocolConformances); #else - _swift_initializeCallbacksToInspectDylib( - _addImageProtocolConformancesBlock, - SWIFT_PROTOCOL_CONFORMANCES_SECTION); + _swift_initializeCallbacksForSectionData(&conformanceSectionArgs); #endif } @@ -317,138 +300,6 @@ static void _addImageProtocolConformancesBlock(const uint8_t *conformances, recordsBegin, recordsEnd); } -#if !defined(__APPLE__) || !defined(__MACH__) -// Common Structure -struct InspectArgs { - void (*fnAddImageBlock)(const uint8_t *, size_t); - const char *sectionName; -}; -#endif - -#if defined(__APPLE__) && defined(__MACH__) -static void _addImageProtocolConformances(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 conformancesSize; - const uint8_t *conformances = - getsectiondata(reinterpret_cast(mh), - SEG_TEXT, SWIFT_PROTOCOL_CONFORMANCES_SECTION, - &conformancesSize); - - if (!conformances) - return; - - _addImageProtocolConformancesBlock(conformances, conformancesSize); -} - -static void _initializeCallbacksToInspectDylib() { - // Install our dyld callback. - // Dyld will invoke this on our behalf for all images that have already - // been loaded. - _dyld_register_func_for_add_image(_addImageProtocolConformances); -} - -#elif defined(__ELF__) || defined(__ANDROID__) -static int _addImageProtocolConformances(struct dl_phdr_info *info, - size_t size, void *data) { - // inspectArgs contains addImage*Block function and the section name - InspectArgs *inspectArgs = reinterpret_cast(data); - - 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); - - if (!handle) { - // Not a shared library. - return 0; - } - - auto conformances = reinterpret_cast( - dlsym(handle, inspectArgs->sectionName)); - - 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); - - inspectArgs->fnAddImageBlock(conformances, conformancesSize); - - dlclose(handle); - return 0; -} - -void swift::_swift_initializeCallbacksToInspectDylib( - void (*fnAddImageBlock)(const uint8_t *, size_t), - const char *sectionName) { - InspectArgs inspectArgs = {fnAddImageBlock, sectionName}; - - // 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, &inspectArgs); -} -#elif defined(__CYGWIN__) || defined(_MSC_VER) -static int _addImageProtocolConformances(struct dl_phdr_info *info, - size_t size, void *data) { - InspectArgs *inspectArgs = (InspectArgs *)data; - // inspectArgs contains addImage*Block function and the section name -#if defined(_MSC_VER) - HMODULE handle; - - if (!info->dlpi_name || info->dlpi_name[0] == '\0') - handle = GetModuleHandle(nullptr); - else - handle = GetModuleHandle(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); - -#if defined(_MSC_VER) - FreeLibrary(handle); -#else - dlclose(handle); -#endif - return 0; -} - -void swift::_swift_initializeCallbacksToInspectDylib( - void (*fnAddImageBlock)(const uint8_t *, size_t), - const char *sectionName) { - InspectArgs inspectArgs = {fnAddImageBlock, sectionName}; - - _swift_dl_iterate_phdr(_addImageProtocolConformances, &inspectArgs); -} -#else -# error No known mechanism to inspect dynamic libraries on this platform. -#endif - // This variable is used to signal when a cache was generated and // it is correct to avoid a new scan. static unsigned ConformanceCacheGeneration = 0; diff --git a/stdlib/public/runtime/SectionData.cpp b/stdlib/public/runtime/SectionData.cpp new file mode 100644 index 0000000000000..6e3f298d69cdd --- /dev/null +++ b/stdlib/public/runtime/SectionData.cpp @@ -0,0 +1,151 @@ +//===-- SectionData.cpp -----------------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include +#include "SectionData.h" + + +using namespace swift; + +#if defined(__APPLE__) && defined(__MACH__) +void +swift::_swift_readSectionData(const mach_header *mh, + InspectArgs *inspectArgs) { +#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 named section. + unsigned long dataSize = 0; + const uint8_t *data = + getsectiondata(reinterpret_cast(mh), + SEG_TEXT, inspectArgs->sectionName, + &dataSize); + + if (data) { + inspectArgs->fnAddImageBlock(data, dataSize); + } +} + +void +swift::_swift_initializeCallbacksForSectionData( + void (*func)(const mach_header*, intptr_t)) { + // Install our dyld callback. + // Dyld will invoke this on our behalf for all images that have already + // been loaded. + _dyld_register_func_for_add_image(func); +} +#elif defined(__ELF__) || defined(__ANDROID__) + +#if defined(SUPPORTS_STATIC_BINARIES) +// If creating a static binary using --static-executable, +// gold will set these to the data sections via --defsym +const void *__swift2_protocol_conformances_start = nullptr; +const void *__swift2_type_metadata_start = nullptr; +#endif // SUPPORTS_STATIC_BINARIES + +static int +_addImageSectionData(struct dl_phdr_info *info, size_t size, void *data) { + // inspectArgs contains addImage*Block function and the section name + InspectArgs *inspectArgs = reinterpret_cast(data); + 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); + + if (!handle) { + // Not a shared library. + return 0; + } + + auto imageBlock = reinterpret_cast( + dlsym(handle, inspectArgs->sectionName)); + + if (imageBlock) { + // Extract the size of the image data from the head of the section + auto imageBlockSize = *reinterpret_cast(imageBlock); + imageBlock += sizeof(imageBlockSize); + inspectArgs->fnAddImageBlock(imageBlock, imageBlockSize); + } + dlclose(handle); + return 0; +} + +void +swift::_swift_initializeCallbacksForSectionData(InspectArgs *inspectArgs) { +#if defined(SUPPORTS_STATIC_BINARIES) + const void **sectionDataAddr = inspectArgs->sectionDataAddr; + assert(sectionDataAddr != nullptr ); + if (*sectionDataAddr) { + auto blockAddr = reinterpret_cast(sectionDataAddr); + auto blockSize = *reinterpret_cast(blockAddr); + blockAddr += sizeof(blockSize); + inspectArgs->fnAddImageBlock(blockAddr, blockSize); + return; + } +#endif // SUPPORTS_STATIC_BINARIES + + // 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(_addImageSectionData, inspectArgs); +} + +#elif defined(__CYGWIN__) || defined(_MSC_VER) + +static int +_addImageSectionData(struct dl_phdr_info *info, size_t size, void *data) { + InspectArgs *inspectArgs = (InspectArgs *)data; + // inspectArgs contains addImage*Block function and the section name +#if defined(_MSC_VER) + HMODULE handle; + + if (!info->dlpi_name || info->dlpi_name[0] == '\0') + handle = GetModuleHandle(nullptr); + else + handle = GetModuleHandle(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 imageBlockSize; + const uint8_t *imageBlock = + _swift_getSectionDataPE(handle, inspectArgs->sectionName, + imageBlockSize); + + if (imageBlock) + inspectArgs->fnAddImageBlock(imageBlock, imageBlockSize); + +#if defined(_MSC_VER) + FreeLibrary(handle); +#else + dlclose(handle); +#endif + return 0; +} + +void +swift::_swift_initializeCallbacksForSectionData(InspectArgs *inspectArgs) { + _swift_dl_iterate_phdr(_addImageSectionData, inspectArgs); +} +#else +# error No known mechanism to inspect dynamic libraries on this platform. +#endif diff --git a/stdlib/public/runtime/SectionData.h b/stdlib/public/runtime/SectionData.h new file mode 100644 index 0000000000000..63fdd5a8302bc --- /dev/null +++ b/stdlib/public/runtime/SectionData.h @@ -0,0 +1,72 @@ +//===-- SectionData.h ------------------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_RUNTIME_SECTIONDATA_H +#define SWIFT_RUNTIME_SECTIONDATA_H + +#if defined(__APPLE__) && defined(__MACH__) +#include +#include +#elif defined(__ELF__) || defined(__ANDROID__) +#include +#include +#endif + +#if defined(_MSC_VER) +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include +#else +#include +#endif + + +#if defined(__APPLE__) && defined(__MACH__) +#define SWIFT_PROTOCOL_CONFORMANCES_SECTION "__swift2_proto" +#define SWIFT_TYPE_METADATA_SECTION "__swift2_types" +#elif defined(__ELF__) +#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".swift2_protocol_conformances_start" +#define SWIFT_TYPE_METADATA_SECTION ".swift2_type_metadata_start" + +#if defined(__linux__) +#define SUPPORTS_STATIC_BINARIES +// Add a declaration for each section +extern const void *__swift2_protocol_conformances_start; +extern const void *__swift2_type_metadata_start; +#endif // __linux__ + +#elif defined(__CYGWIN__) || defined(_MSC_VER) +#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".sw2prtc" +#define SWIFT_TYPE_METADATA_SECTION ".sw2tymd" +#endif + + +namespace swift { + // Common Structure + struct InspectArgs { + void (*fnAddImageBlock)(const uint8_t *, size_t); + const char *sectionName; +#if defined(SUPPORTS_STATIC_BINARIES) + const void **sectionDataAddr; +#endif + }; + +#if defined(__APPLE__) && defined(__MACH__) + void _swift_initializeCallbacksForSectionData(void (*func)(const mach_header*, + intptr_t)); + void _swift_readSectionData(const mach_header *mh, InspectArgs *inspectArgs); +#else + void _swift_initializeCallbacksForSectionData(InspectArgs *inspectArgs); +#endif +} + +#endif /* SWIFT_RUNTIME_SECTIONDATA_H */ diff --git a/stdlib/public/runtime/static_stub.c b/stdlib/public/runtime/static_stub.c new file mode 100644 index 0000000000000..366415c61345d --- /dev/null +++ b/stdlib/public/runtime/static_stub.c @@ -0,0 +1,33 @@ +#if defined(__LINUX__) && defined(__ELF__) +#error "This only works on Linux/ELF" // Needs testing on other ELF platforms +#else +#include +#include +#include + + +// This forces resolving of these weak symbols but keeps them hidden +// externally +const void *unused1 __attribute__ ((unused, visibility("internal"))) = pthread_self; +const void *unused2 __attribute__ ((unused, visibility("internal"))) = pthread_key_create; +const void *unused3 __attribute__ ((unused, visibility("internal"))) = pthread_once; + + +// linking libdl into static binaries produces this message: +// "warning: Using 'dlopen' in statically linked applications requires at +// runtime the shared libraries from the glibc version used for linking" +// +// Instead of letting the calls silently fail, show an error and quit. +// This is not actually needed, it is just to aid debugging + +#define UNSUPPORTED_FUNC(x) void x() { \ + fprintf(stderr, "Unsupported dynamic linker call: %s\n", __func__); \ + abort(); \ +} + +UNSUPPORTED_FUNC(dlopen) +UNSUPPORTED_FUNC(dlsym) +UNSUPPORTED_FUNC(dladdr) +UNSUPPORTED_FUNC(dlclose) + +#endif // linux && ELF