diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 78d7bf4b3dc71..39c4525f84d45 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -986,6 +986,25 @@ StringRef Darwin::getOSLibraryNameSuffix() const { llvm_unreachable("Unsupported platform"); } +/// Check if the link command contains a symbol export directive. +static bool hasExportSymbolDirective(const ArgList &Args) { + for (Arg *A : Args) { + if (!A->getOption().matches(options::OPT_Wl_COMMA) && + !A->getOption().matches(options::OPT_Xlinker)) + continue; + if (A->containsValue("-exported_symbols_list") || + A->containsValue("-exported_symbol")) + return true; + } + return false; +} + +/// Add an export directive for \p Symbol to the link command. +static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol) { + CmdArgs.push_back("-exported_symbol"); + CmdArgs.push_back(Symbol); +} + void Darwin::addProfileRTLibs(const ArgList &Args, ArgStringList &CmdArgs) const { if (!needsProfileRT(Args)) return; @@ -994,6 +1013,16 @@ void Darwin::addProfileRTLibs(const ArgList &Args, Args, CmdArgs, (Twine("libclang_rt.profile_") + getOSLibraryNameSuffix() + ".a").str(), RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink)); + + // If we have a symbol export directive and we're linking in the profile + // runtime, automatically export symbols necessary to implement some of the + // runtime's functionality. + if (hasExportSymbolDirective(Args)) { + addExportedSymbol(CmdArgs, "_VPMergeHook"); + addExportedSymbol(CmdArgs, "___llvm_profile_filename"); + addExportedSymbol(CmdArgs, "___llvm_profile_raw_version"); + addExportedSymbol(CmdArgs, "_lprofCurFilename"); + } } void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, diff --git a/clang/test/Driver/darwin-ld.c b/clang/test/Driver/darwin-ld.c index 4358d38af6dcf..3ddba02a43e88 100644 --- a/clang/test/Driver/darwin-ld.c +++ b/clang/test/Driver/darwin-ld.c @@ -351,3 +351,17 @@ // RUN: %clang -target arm64-apple-ios5.0 -miphoneos-version-min=5.0 -fprofile-instr-generate -### %t.o 2> %t.log // RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log // LINK_PROFILE_FIRST: {{ld(.exe)?"}} "{{[^"]+}}libclang_rt.profile_{{[a-z]+}}.a" + +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Wl,-exported_symbols_list,/dev/null -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Wl,-exported_symbol,foo -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Xlinker -exported_symbol -Xlinker foo -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Xlinker -exported_symbols_list -Xlinker /dev/null -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log +// PROFILE_EXPORT: "-exported_symbol" "_VPMergeHook" "-exported_symbol" "___llvm_profile_filename" "-exported_symbol" "___llvm_profile_raw_version" "-exported_symbol" "_lprofCurFilename" +// +// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=NO_PROFILE_EXPORT %s < %t.log +// NO_PROFILE_EXPORT-NOT: "-exported_symbol"