Skip to content

Commit 220a2b9

Browse files
committed
Merge pull request #1157 from hpux735/gold
Discard swift.ld in favor of portable solution and support gold linker in Swift
2 parents 62fa71d + d0d9b1d commit 220a2b9

File tree

14 files changed

+287
-111
lines changed

14 files changed

+287
-111
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
221221
endif()
222222

223223
if(SWIFT_BUILT_STANDALONE)
224-
project(Swift)
224+
project(Swift C CXX ASM)
225225
endif()
226226

227227
if("${CMAKE_SYSTEM_NAME}" STREQUAL "")

cmake/modules/AddSwift.cmake

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -173,15 +173,9 @@ function(_add_variant_link_flags
173173
result)
174174

175175
if("${sdk}" STREQUAL "LINUX")
176-
if("${arch}" STREQUAL "armv7")
177-
list(APPEND result "-lpthread" "-ldl" "-Wl,-Bsymbolic")
178-
elseif("${arch}" STREQUAL "armv6")
179-
list(APPEND result "-lpthread" "-ldl" "-Wl,-Bsymbolic")
180-
else()
181-
list(APPEND result "-lpthread" "-ldl")
182-
endif()
176+
list(APPEND result "-lpthread" "-ldl")
183177
elseif("${sdk}" STREQUAL "FREEBSD")
184-
list(APPEND result "-lpthread" "-Wl,-Bsymbolic")
178+
list(APPEND result "-lpthread")
185179
else()
186180
list(APPEND result "-lobjc")
187181
endif()
@@ -856,6 +850,22 @@ function(_add_swift_library_single target name)
856850
set(SWIFTLIB_SINGLE_API_NOTES "${module_name}")
857851
endif()
858852

853+
# On platforms that use ELF binaries (for now that is Linux and FreeBSD)
854+
# we add markers for metadata sections in the shared libraries using
855+
# these object files. This wouldn't be necessary if the link was done by
856+
# the swift binary: rdar://problem/19007002
857+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR
858+
"${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
859+
860+
if("${libkind}" STREQUAL "SHARED")
861+
set(arch_subdir "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}")
862+
863+
set(SWIFT_SECTIONS_OBJECT_BEGIN "${arch_subdir}/swift_begin.o")
864+
set(SWIFT_SECTIONS_OBJECT_END "${arch_subdir}/swift_end.o")
865+
endif()
866+
867+
endif()
868+
859869
# FIXME: don't actually depend on the libraries in SWIFTLIB_SINGLE_LINK_LIBRARIES,
860870
# just any swiftmodule files that are associated with them.
861871
handle_swift_sources(
@@ -877,8 +887,21 @@ function(_add_swift_library_single target name)
877887
INSTALL_IN_COMPONENT "${SWIFTLIB_INSTALL_IN_COMPONENT}")
878888

879889
add_library("${target}" ${libkind}
890+
${SWIFT_SECTIONS_OBJECT_BEGIN}
880891
${SWIFTLIB_SINGLE_SOURCES}
881-
${SWIFTLIB_SINGLE_EXTERNAL_SOURCES})
892+
${SWIFTLIB_SINGLE_EXTERNAL_SOURCES}
893+
${SWIFT_SECTIONS_OBJECT_END})
894+
895+
# The section metadata objects are generated sources, and we need to tell CMake
896+
# not to expect to find them prior to their generation.
897+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR
898+
"${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
899+
if("${libkind}" STREQUAL "SHARED")
900+
set_source_files_properties(${SWIFT_SECTIONS_OBJECT_BEGIN} PROPERTIES GENERATED 1)
901+
set_source_files_properties(${SWIFT_SECTIONS_OBJECT_END} PROPERTIES GENERATED 1)
902+
add_dependencies("${target}" section_magic)
903+
endif()
904+
endif()
882905

883906
if (dtrace_dependency_targets)
884907
add_dependencies("${target}" ${dtrace_dependency_targets})
@@ -1089,16 +1112,8 @@ function(_add_swift_library_single target name)
10891112
"${analyze_code_coverage}"
10901113
link_flags)
10911114

1092-
# Handle gold linker flags for shared libraries.
1093-
if(SWIFT_ENABLE_GOLD_LINKER AND SWIFTLIB_SINGLE_SHARED)
1094-
if("${SWIFTLIB_SINGLE_SDK}" STREQUAL "LINUX")
1095-
# Extend the link_flags for the gold linker so long as this
1096-
# isn't the standard library. The standard library uses a
1097-
# linker script that isn't supported by the gold linker.
1098-
if(NOT SWIFTLIB_SINGLE_IS_STDLIB)
1099-
list(APPEND link_flags "-fuse-ld=gold")
1100-
endif()
1101-
endif()
1115+
if(SWIFT_ENABLE_GOLD_LINKER)
1116+
list(APPEND link_flags "-fuse-ld=gold")
11021117
endif()
11031118

11041119
# Configure plist creation for OS X.
@@ -1133,16 +1148,6 @@ function(_add_swift_library_single target name)
11331148
set(PLIST_INFO_BUILD_VERSION)
11341149
endif()
11351150

1136-
# On Linux and FreeBSD add the linker script that coalesces protocol
1137-
# conformance sections. This wouldn't be necessary if the link was done by
1138-
# the swift binary: rdar://problem/19007002
1139-
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR
1140-
"${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
1141-
list(APPEND link_flags
1142-
"-Xlinker" "-T"
1143-
"-Xlinker" "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swift.ld")
1144-
endif()
1145-
11461151
# Convert variables to space-separated strings.
11471152
_list_escape_for_shell("${c_compile_flags}" c_compile_flags)
11481153
_list_escape_for_shell("${link_flags}" link_flags)

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ def no_link_objc_runtime : Flag<["-"], "no-link-objc-runtime">,
254254
Flags<[HelpHidden, DoesNotAffectIncrementalBuild]>,
255255
HelpText<"Don't link in additions to the Objective-C runtime">;
256256

257+
def use_ld : Joined<["-"], "use-ld=">,
258+
Flags<[DoesNotAffectIncrementalBuild]>,
259+
HelpText<"Specifies the linker to be used">;
260+
257261
def Xlinker : Separate<["-"], "Xlinker">,
258262
Flags<[DoesNotAffectIncrementalBuild]>,
259263
HelpText<"Specifies an option which should be passed to the linker">;

lib/Driver/Driver.cpp

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,24 +2009,7 @@ void Driver::printHelp(bool ShowHidden) const {
20092009
}
20102010

20112011
static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple) {
2012-
llvm::Triple triple = llvm::Triple(DefaultTargetTriple);
2013-
2014-
// armv6l and armv7l (which come from linux) are mapped to armv6 and
2015-
// armv7 (respectively) within llvm. When a Triple is created by llvm,
2016-
// the string is preserved, which keeps the 'l'. This extra character
2017-
// causes problems later down the line.
2018-
// By explicitly setting the architecture to the subtype that it aliases to,
2019-
// we remove that extra character while not introducing other side effects.
2020-
if (triple.getOS() == llvm::Triple::Linux) {
2021-
if (triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v7) {
2022-
triple.setArchName("armv7");
2023-
}
2024-
if (triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6) {
2025-
triple.setArchName("armv6");
2026-
}
2027-
}
2028-
2029-
return triple;
2012+
return llvm::Triple(DefaultTargetTriple);
20302013
}
20312014

20322015
const ToolChain *Driver::getToolChain(const ArgList &Args) const {

lib/Driver/ToolChains.cpp

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,28 @@ toolchains::GenericUnix::constructInvocation(const AutolinkExtractJobAction &job
10911091
return {"swift-autolink-extract", Arguments};
10921092
}
10931093

1094+
// This function maps triples to the architecture component of the path
1095+
// where the swift_begin.o and swift_end.o objects can be found. This
1096+
// is a stop-gap until full Triple support (ala Clang) exists within swiftc.
1097+
StringRef
1098+
getSectionMagicArch(const llvm::Triple &Triple) {
1099+
if (Triple.isOSLinux()) {
1100+
switch(Triple.getSubArch()) {
1101+
default:
1102+
return Triple.getArchName();
1103+
break;
1104+
case llvm::Triple::SubArchType::ARMSubArch_v7:
1105+
return "armv7";
1106+
break;
1107+
case llvm::Triple::SubArchType::ARMSubArch_v6:
1108+
return "armv6";
1109+
break;
1110+
}
1111+
} else {
1112+
return Triple.getArchName();
1113+
}
1114+
}
1115+
10941116
ToolChain::InvocationInfo
10951117
toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
10961118
const JobContext &context) const {
@@ -1109,25 +1131,32 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
11091131
break;
11101132
case LinkKind::DynamicLibrary:
11111133
Arguments.push_back("-shared");
1112-
if (getTriple().getOS() == llvm::Triple::Linux) {
1113-
if (getTriple().getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v7 ||
1114-
getTriple().getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6) {
1115-
Arguments.push_back("-Wl,-Bsymbolic");
1116-
}
1117-
}
11181134
break;
11191135
}
11201136

1121-
addPrimaryInputsOfType(Arguments, context.Inputs, types::TY_Object);
1122-
addInputsOfType(Arguments, context.InputActions, types::TY_Object);
1137+
// Select the linker to use
1138+
StringRef Linker;
11231139

1124-
context.Args.AddAllArgs(Arguments, options::OPT_Xlinker);
1125-
context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group);
1126-
context.Args.AddAllArgs(Arguments, options::OPT_F);
1140+
if (const Arg *A = context.Args.getLastArg(options::OPT_use_ld)) {
1141+
Linker = A->getValue();
1142+
} else {
1143+
switch(getTriple().getArch()) {
1144+
default:
1145+
break;
1146+
case llvm::Triple::arm:
1147+
case llvm::Triple::armeb:
1148+
case llvm::Triple::thumb:
1149+
case llvm::Triple::thumbeb:
1150+
// BFD linker has issues wrt relocation of the protocol conformance
1151+
// section on these targets, it also generates COPY relocations for
1152+
// final executables, as such, unless specified, we default to gold
1153+
// linker.
1154+
Linker = "gold";
1155+
}
1156+
}
11271157

1128-
if (!context.OI.SDKPath.empty()) {
1129-
Arguments.push_back("--sysroot");
1130-
Arguments.push_back(context.Args.MakeArgString(context.OI.SDKPath));
1158+
if (!Linker.empty()) {
1159+
Arguments.push_back(context.Args.MakeArgString("-fuse-ld=" + Linker));
11311160
}
11321161

11331162
// Add the runtime library link path, which is platform-specific and found
@@ -1147,9 +1176,27 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
11471176
}
11481177
llvm::sys::path::append(RuntimeLibPath,
11491178
getPlatformNameForTriple(getTriple()));
1179+
1180+
// On Linux and FreeBSD (really, ELF binaries) we need to add objects
1181+
// to provide markers and size for the metadata sections.
1182+
Arguments.push_back(context.Args.MakeArgString(
1183+
Twine(RuntimeLibPath) + "/" + getSectionMagicArch(getTriple()) + "/swift_begin.o"));
1184+
addPrimaryInputsOfType(Arguments, context.Inputs, types::TY_Object);
1185+
addInputsOfType(Arguments, context.InputActions, types::TY_Object);
1186+
1187+
context.Args.AddAllArgs(Arguments, options::OPT_Xlinker);
1188+
context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group);
1189+
context.Args.AddAllArgs(Arguments, options::OPT_F);
1190+
1191+
if (!context.OI.SDKPath.empty()) {
1192+
Arguments.push_back("--sysroot");
1193+
Arguments.push_back(context.Args.MakeArgString(context.OI.SDKPath));
1194+
}
1195+
11501196
Arguments.push_back("-L");
11511197
Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath));
11521198

1199+
// Explicitly pass the target to the linker
11531200
Arguments.push_back(context.Args.MakeArgString("--target=" + getTriple().str()));
11541201

11551202
if (context.Args.hasArg(options::OPT_profile_generate)) {
@@ -1182,13 +1229,10 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
11821229
Twine("@") + OutputInfo.getPrimaryOutputFilename()));
11831230
}
11841231

1185-
// Add the linker script that coalesces protocol conformance sections.
1186-
Arguments.push_back("-Xlinker");
1187-
Arguments.push_back("-T");
1188-
1189-
// FIXME: This should also query the abi type (i.e. gnueabihf)
1232+
// It is important that swift_end.o be the last object on the link line
1233+
// therefore, it is included just before the output filename.
11901234
Arguments.push_back(context.Args.MakeArgString(
1191-
Twine(RuntimeLibPath) + "/" + getTriple().getArchName() + "/swift.ld"));
1235+
Twine(RuntimeLibPath) + "/" + getSectionMagicArch(getTriple()) + "/swift_end.o"));
11921236

11931237
// This should be the last option, for convenience in checking output.
11941238
Arguments.push_back("-o");

lib/Frontend/CompilerInvocation.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,27 @@ static void updateRuntimeLibraryPath(SearchPathOptions &SearchPathOpts,
4747
llvm::sys::path::append(LibPath, getPlatformNameForTriple(Triple));
4848
SearchPathOpts.RuntimeLibraryPath = LibPath.str();
4949

50-
llvm::sys::path::append(LibPath, Triple.getArchName());
50+
// The linux provided triple for ARM contains a trailing 'l'
51+
// denoting little-endian. This is not used in the path for
52+
// libraries. LLVM matches these SubArchTypes to the generic
53+
// ARMSubArch_v7 (for example) type. If that is the case,
54+
// use the base of the architecture type in the library path.
55+
if (Triple.isOSLinux()) {
56+
switch(Triple.getSubArch()) {
57+
default:
58+
llvm::sys::path::append(LibPath, Triple.getArchName());
59+
break;
60+
case llvm::Triple::SubArchType::ARMSubArch_v7:
61+
llvm::sys::path::append(LibPath, "armv7");
62+
break;
63+
case llvm::Triple::SubArchType::ARMSubArch_v6:
64+
llvm::sys::path::append(LibPath, "armv6");
65+
break;
66+
}
67+
} else {
68+
llvm::sys::path::append(LibPath, Triple.getArchName());
69+
}
70+
5171
SearchPathOpts.RuntimeLibraryImportPath = LibPath.str();
5272
}
5373

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ add_swift_library(swiftCore SHARED IS_STDLIB IS_STDLIB_CORE
180180
# and the generated directory as dependencies.
181181
FILE_DEPENDS
182182
copy_shim_headers "${SWIFTLIB_DIR}/shims"
183+
section_magic
183184
LINK_FLAGS ${swift_core_link_flags}
184185
PRIVATE_LINK_LIBRARIES ${swift_core_private_link_libraries}
185186
FRAMEWORK_DEPENDS ${swift_core_framework_depends}

stdlib/public/runtime/CMakeLists.txt

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ endif()
1919

2020
# Acknowledge that the following sources are known.
2121
set(LLVM_OPTIONAL_SOURCES
22-
Remangle.cpp)
22+
Remangle.cpp
23+
swift_sections.S)
2324

2425
set(swift_runtime_objc_sources)
2526
set(swift_runtime_unicode_normalization_sources)
@@ -52,20 +53,40 @@ add_swift_library(swiftRuntime IS_STDLIB IS_STDLIB_CORE
5253
C_COMPILE_FLAGS ${swift_runtime_compile_flags}
5354
INSTALL_IN_COMPONENT stdlib)
5455

56+
set(object_target_list)
5557
foreach(sdk ${SWIFT_CONFIGURED_SDKS})
5658
if("${sdk}" STREQUAL "LINUX" OR "${sdk}" STREQUAL "FREEBSD")
5759
foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES})
5860
set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}")
5961

60-
# FIXME: We will need a different linker script for 32-bit builds.
61-
configure_file(
62-
"swift.ld" "${SWIFTLIB_DIR}/${arch_subdir}/swift.ld" COPYONLY)
62+
set(section_magic_begin_name "section_magic_begin_${SWIFT_SDK_${sdk}_ARCH_${arch}_TRIPLE}")
63+
set(section_magic_end_name "section_magic_end_${SWIFT_SDK_${sdk}_ARCH_${arch}_TRIPLE}")
64+
65+
add_library(${section_magic_begin_name} STATIC swift_sections.S)
66+
set_target_properties(${section_magic_begin_name} PROPERTIES COMPILE_FLAGS "-DSWIFT_BEGIN")
67+
68+
add_library(${section_magic_end_name} STATIC swift_sections.S)
69+
set_target_properties(${section_magic_end_name} PROPERTIES COMPILE_FLAGS "-DSWIFT_END")
70+
71+
add_custom_command_target(${section_magic_begin_name}_begin
72+
OUTPUT "${SWIFTLIB_DIR}/${arch_subdir}/swift_begin.o"
73+
COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${section_magic_begin_name}.dir/swift_sections.S${CMAKE_C_OUTPUT_EXTENSION}" "${SWIFTLIB_DIR}/${arch_subdir}/swift_begin.o"
74+
DEPENDS ${section_magic_begin_name})
75+
76+
add_custom_command_target(${section_magic_begin_name}_end
77+
OUTPUT "${SWIFTLIB_DIR}/${arch_subdir}/swift_end.o"
78+
COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${section_magic_end_name}.dir/swift_sections.S${CMAKE_C_OUTPUT_EXTENSION}" "${SWIFTLIB_DIR}/${arch_subdir}/swift_end.o"
79+
DEPENDS ${section_magic_end_name})
80+
81+
list(APPEND object_target_list "${SWIFTLIB_DIR}/${arch_subdir}/swift_begin.o" "${SWIFTLIB_DIR}/${arch_subdir}/swift_end.o")
6382

6483
swift_install_in_component(compiler
65-
FILES "swift.ld"
84+
FILES "${SWIFTLIB_DIR}/${arch_subdir}/swift_begin.o" "${SWIFTLIB_DIR}/${arch_subdir}/swift_end.o"
6685
DESTINATION "lib/swift/${arch_subdir}")
6786

6887
endforeach()
6988
endif()
7089
endforeach()
7190

91+
add_custom_target(section_magic ALL DEPENDS ${object_target_list})
92+

stdlib/public/runtime/swift.ld

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)