Add a new (hidden) option -autolink-force-load.

This option puts a special symbol into the generated object files that other
object files can reference to force the library to be loaded.

The next commit will modify the way we serialize autolinking information so
that importers of this module will always emit a reference to this symbol.
This means the library will be linked into the final binary even if no other
symbols are used (which happens for some of our overlays that just add
category methods to Objective-C classes).

Part of <rdar://problem/16829587>

Swift SVN r17750
This commit is contained in:
Jordan Rose
2014-05-09 01:07:07 +00:00
parent 4f0776936a
commit 41700b03da
5 changed files with 37 additions and 1 deletions

View File

@@ -59,6 +59,10 @@ public:
/// The libraries and frameworks specified on the command line. /// The libraries and frameworks specified on the command line.
SmallVector<LinkLibrary, 4> LinkLibraries; SmallVector<LinkLibrary, 4> LinkLibraries;
/// If non-empty, the (unmangled) name of a dummy symbol to emit that can be
/// used to force-load this module.
std::string ForceLoadSymbolName;
/// The kind of compilation we should do. /// The kind of compilation we should do.
IRGenOutputKind OutputKind : 3; IRGenOutputKind OutputKind : 3;
@@ -87,7 +91,7 @@ public:
/// \brief Whether we should omit dynamic safety checks from the emitted IR. /// \brief Whether we should omit dynamic safety checks from the emitted IR.
unsigned DisableAllRuntimeChecks : 1; unsigned DisableAllRuntimeChecks : 1;
// Disable frame pointer elimination? /// Disable frame pointer elimination?
unsigned DisableFPElim : 1; unsigned DisableFPElim : 1;
IRGenOptions() : OutputKind(IRGenOutputKind::LLVMAssembly), Verify(true), IRGenOptions() : OutputKind(IRGenOutputKind::LLVMAssembly), Verify(true),

View File

@@ -151,6 +151,9 @@ def module_link_name : Separate<["-"], "module-link-name">,
HelpText<"Library to link against when using this module">; HelpText<"Library to link against when using this module">;
def module_link_name_EQ : Joined<["-"], "module-link-name=">, def module_link_name_EQ : Joined<["-"], "module-link-name=">,
Flags<[FrontendOption]>, Alias<module_link_name>; Flags<[FrontendOption]>, Alias<module_link_name>;
def autolink_force_load : Flag<["-"], "autolink-force-load">,
Flags<[FrontendOption, HelpHidden]>,
HelpText<"Force ld to link against this module even if no symbols are used">;
def emit_module : Flag<["-"], "emit-module">, Flags<[FrontendOption]>, def emit_module : Flag<["-"], "emit-module">, Flags<[FrontendOption]>,
HelpText<"Emit an importable module">; HelpText<"Emit an importable module">;

View File

@@ -263,6 +263,9 @@ Job *Swift::constructJob(const JobAction &JA, std::unique_ptr<JobList> Inputs,
Args.AddLastArg(Arguments, options::OPT_module_link_name); Args.AddLastArg(Arguments, options::OPT_module_link_name);
Args.AddLastArg(Arguments, options::OPT_import_underlying_module); Args.AddLastArg(Arguments, options::OPT_import_underlying_module);
// FIXME: Warn if -module-link-name is not present.
Args.AddLastArg(Arguments, options::OPT_autolink_force_load);
Args.AddLastArg(Arguments, options::OPT_split_objc_selectors); Args.AddLastArg(Arguments, options::OPT_split_objc_selectors);
Args.AddLastArg(Arguments, options::OPT_implicit_objc_with); Args.AddLastArg(Arguments, options::OPT_implicit_objc_with);
Args.AddLastArg(Arguments, options::OPT_strict_keyword_arguments); Args.AddLastArg(Arguments, options::OPT_strict_keyword_arguments);

View File

@@ -858,6 +858,9 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Opts.EnableDynamicValueTypeLayout = true; Opts.EnableDynamicValueTypeLayout = true;
} }
if (Args.hasArg(OPT_autolink_force_load))
Opts.ForceLoadSymbolName = Args.getLastArgValue(OPT_module_link_name);
if (const Arg *A = Args.getLastArg(OPT_target)) { if (const Arg *A = Args.getLastArg(OPT_target)) {
Opts.Triple = llvm::Triple::normalize(A->getValue()); Opts.Triple = llvm::Triple::normalize(A->getValue());
} }

View File

@@ -20,6 +20,7 @@
#include "swift/AST/IRGenOptions.h" #include "swift/AST/IRGenOptions.h"
#include "swift/ClangImporter/ClangImporter.h" #include "swift/ClangImporter/ClangImporter.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CodeGenABITypes.h" #include "clang/CodeGen/CodeGenABITypes.h"
#include "clang/CodeGen/ModuleBuilder.h" #include "clang/CodeGen/ModuleBuilder.h"
@@ -424,6 +425,19 @@ static int pointerPODSortComparator(T * const *lhs, T * const *rhs) {
return 0; return 0;
} }
static StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
StringRef name) {
llvm::raw_svector_ostream os{buf};
os << "_swift_FORCE_LOAD_$";
if (clang::isValidIdentifier(name)) {
os << "_" << name;
} else {
for (auto c : name)
os.write_hex(static_cast<uint8_t>(c));
}
return os.str();
}
void IRGenModule::emitAutolinkInfo() { void IRGenModule::emitAutolinkInfo() {
// FIXME: This constant should be vended by LLVM somewhere. // FIXME: This constant should be vended by LLVM somewhere.
static const char * const LinkerOptionsFlagName = "Linker Options"; static const char * const LinkerOptionsFlagName = "Linker Options";
@@ -437,6 +451,15 @@ void IRGenModule::emitAutolinkInfo() {
llvm::LLVMContext &ctx = Module.getContext(); llvm::LLVMContext &ctx = Module.getContext();
Module.addModuleFlag(llvm::Module::AppendUnique, LinkerOptionsFlagName, Module.addModuleFlag(llvm::Module::AppendUnique, LinkerOptionsFlagName,
llvm::MDNode::get(ctx, AutolinkEntries)); llvm::MDNode::get(ctx, AutolinkEntries));
if (!Opts.ForceLoadSymbolName.empty()) {
llvm::SmallString<64> buf;
encodeForceLoadSymbolName(buf, Opts.ForceLoadSymbolName);
(void)new llvm::GlobalVariable(Module, Int1Ty, /*constant=*/true,
llvm::GlobalVariable::LinkOnceAnyLinkage,
llvm::Constant::getNullValue(Int1Ty),
buf.str());
}
} }
void IRGenModule::finalize() { void IRGenModule::finalize() {