@@ -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+
10941116ToolChain::InvocationInfo
10951117toolchains::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" );
0 commit comments