]> granicus.if.org Git - clang/commitdiff
[Driver] Export symbols needed to use profile runtime
authorVedant Kumar <vsk@apple.com>
Wed, 11 Oct 2017 21:54:09 +0000 (21:54 +0000)
committerVedant Kumar <vsk@apple.com>
Wed, 11 Oct 2017 21:54:09 +0000 (21:54 +0000)
Apple's API verification tool (tapi) checks that the symbols exported
from a program match a whitelist. When the program uses the profile
runtime, some additional symbols which are typically not part of the
regular whitelist must be exported.

If we're using symbol export directives along with the profile runtime
on Darwin, the driver needs to export the additional symbols to avoid
verification failures.

rdar://problem/30067753

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315518 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/ToolChains/Darwin.cpp
test/Driver/darwin-ld.c

index 78d7bf4b3dc7129d1e1003a4345572d3ea31b809..39c4525f84d45aaa7a6674543bfa85695b130b5a 100644 (file)
@@ -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,
index 4358d38af6dcf9170c52a64336f8ee0689ad8cf0..3ddba02a43e882f63324fd49fe74422f43e80d67 100644 (file)
 // 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"