dberris updated this revision to Diff 122229.
dberris added a comment.

- fixup: Use ASM macros for darwin assembly
- fixup: support weak symbols for Darwin linkage
- fixup: qualify symbols, use macros, limit weak symbols
- fixup: move test cases from Linux up one directory
- fixup: make clang link the needed runtime bits in osx
- fixup: update tests to run on x86_64 on both Darwin and Linux


https://reviews.llvm.org/D39114

Files:
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/Driver/ToolChains/Darwin.cpp
  clang/lib/Driver/XRayArgs.cpp
  compiler-rt/cmake/config-ix.cmake
  compiler-rt/lib/xray/CMakeLists.txt
  compiler-rt/lib/xray/tests/CMakeLists.txt
  compiler-rt/lib/xray/weak_symbols.txt
  compiler-rt/lib/xray/xray_init.cc
  compiler-rt/lib/xray/xray_trampoline_x86_64.S
  compiler-rt/test/xray/TestCases/Darwin/always-never-instrument.cc
  compiler-rt/test/xray/TestCases/Darwin/lit.local.cfg
  compiler-rt/test/xray/TestCases/Linux/always-never-instrument.cc
  compiler-rt/test/xray/TestCases/Linux/arg1-arg0-logging.cc
  compiler-rt/test/xray/TestCases/Linux/arg1-logger.cc
  compiler-rt/test/xray/TestCases/Linux/arg1-logging-implicit-this.cc
  compiler-rt/test/xray/TestCases/Linux/argv0-log-file-name.cc
  compiler-rt/test/xray/TestCases/Linux/coverage-sample.cc
  compiler-rt/test/xray/TestCases/Linux/custom-event-handler-alignment.cc
  compiler-rt/test/xray/TestCases/Linux/custom-event-logging.cc
  compiler-rt/test/xray/TestCases/Linux/fdr-mode.cc
  compiler-rt/test/xray/TestCases/Linux/fdr-single-thread.cc
  compiler-rt/test/xray/TestCases/Linux/fdr-thread-order.cc
  compiler-rt/test/xray/TestCases/Linux/fixedsize-logging.cc
  compiler-rt/test/xray/TestCases/Linux/func-id-utils.cc
  compiler-rt/test/xray/TestCases/Linux/optional-inmemory-log.cc
  compiler-rt/test/xray/TestCases/Linux/patching-unpatching.cc
  compiler-rt/test/xray/TestCases/Linux/pic_test.cc
  compiler-rt/test/xray/TestCases/Linux/quiet-start.cc
  compiler-rt/test/xray/TestCases/always-never-instrument.cc
  compiler-rt/test/xray/TestCases/arg1-arg0-logging.cc
  compiler-rt/test/xray/TestCases/arg1-logger.cc
  compiler-rt/test/xray/TestCases/arg1-logging-implicit-this.cc
  compiler-rt/test/xray/TestCases/argv0-log-file-name.cc
  compiler-rt/test/xray/TestCases/coverage-sample.cc
  compiler-rt/test/xray/TestCases/custom-event-handler-alignment.cc
  compiler-rt/test/xray/TestCases/custom-event-logging.cc
  compiler-rt/test/xray/TestCases/fdr-mode.cc
  compiler-rt/test/xray/TestCases/fdr-single-thread.cc
  compiler-rt/test/xray/TestCases/fdr-thread-order.cc
  compiler-rt/test/xray/TestCases/fixedsize-logging.cc
  compiler-rt/test/xray/TestCases/func-id-utils.cc
  compiler-rt/test/xray/TestCases/lit.local.cfg
  compiler-rt/test/xray/TestCases/optional-inmemory-log.cc
  compiler-rt/test/xray/TestCases/patching-unpatching.cc
  compiler-rt/test/xray/TestCases/pic_test.cc
  compiler-rt/test/xray/TestCases/quiet-start.cc
  compiler-rt/test/xray/lit.cfg

Index: compiler-rt/test/xray/lit.cfg
===================================================================
--- compiler-rt/test/xray/lit.cfg
+++ compiler-rt/test/xray/lit.cfg
@@ -40,7 +40,7 @@
 # Default test suffixes.
 config.suffixes = ['.c', '.cc', '.cpp']
 
-if config.host_os not in ['Linux']:
+if config.host_os not in ['Linux', 'Darwin']:
   config.unsupported = True
 elif '64' not in config.host_arch:
   if 'arm' in config.host_arch:
Index: compiler-rt/test/xray/TestCases/quiet-start.cc
===================================================================
--- compiler-rt/test/xray/TestCases/quiet-start.cc
+++ compiler-rt/test/xray/TestCases/quiet-start.cc
@@ -9,8 +9,8 @@
 // RUN: XRAY_OPTIONS="" %run %t 2>&1 | FileCheck %s --check-prefix DEFAULT
 //
 // FIXME: Understand how to make this work on other platforms
+// REQUIRES: x86_64
 // REQUIRES: built-in-llvm-tree
-// REQUIRES: x86_64-linux
 #include <iostream>
 
 using namespace std;
Index: compiler-rt/test/xray/TestCases/Linux/pic_test.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/pic_test.cc
@@ -1,36 +0,0 @@
-// Test to check if we handle pic code properly.
-
-// RUN: %clangxx_xray -fxray-instrument -std=c++11 -ffunction-sections \
-// RUN:     -fdata-sections -fpic -fpie -Wl,--gc-sections %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=pic-test-logging-" %run %t 2>&1 | FileCheck %s
-// After all that, clean up the output xray log.
-//
-// RUN: rm pic-test-logging-*
-
-// UNSUPPORTED: target-is-mips64,target-is-mips64el
-
-#include <cstdio>
-
-[[clang::xray_always_instrument]]
-unsigned short foo (unsigned b);
-
-[[clang::xray_always_instrument]]
-unsigned short bar (unsigned short a)
-{
-  printf("bar() is always instrumented!\n");
-  return foo(a);
-}
-
-unsigned short foo (unsigned b)
-{
-  printf("foo() is always instrumented!\n");
-  return b + b + 5;
-}
-
-int main ()
-{
-  // CHECK: XRay: Log file in 'pic-test-logging-{{.*}}'
-  bar(10);
-  // CHECK: bar() is always instrumented!
-  // CHECK-NEXT: foo() is always instrumented!
-}
Index: compiler-rt/test/xray/TestCases/Linux/patching-unpatching.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/patching-unpatching.cc
@@ -1,49 +0,0 @@
-// Check that we can patch and un-patch on demand, and that logging gets invoked
-// appropriately.
-//
-// RUN: %clangxx_xray -fxray-instrument -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=false" %run %t 2>&1 | FileCheck %s
-
-// UNSUPPORTED: target-is-mips64,target-is-mips64el
-
-#include "xray/xray_interface.h"
-
-#include <cstdio>
-
-bool called = false;
-
-void test_handler(int32_t fid, XRayEntryType type) {
-  printf("called: %d, type=%d\n", fid, static_cast<int32_t>(type));
-  called = true;
-}
-
-[[clang::xray_always_instrument]] void always_instrument() {
-  printf("always instrumented called\n");
-}
-
-int main() {
-  __xray_set_handler(test_handler);
-  always_instrument();
-  // CHECK: always instrumented called
-  auto status = __xray_patch();
-  printf("patching status: %d\n", static_cast<int32_t>(status));
-  // CHECK-NEXT: patching status: 1
-  always_instrument();
-  // CHECK-NEXT: called: {{.*}}, type=0
-  // CHECK-NEXT: always instrumented called
-  // CHECK-NEXT: called: {{.*}}, type=1
-  status = __xray_unpatch();
-  printf("patching status: %d\n", static_cast<int32_t>(status));
-  // CHECK-NEXT: patching status: 1
-  always_instrument();
-  // CHECK-NEXT: always instrumented called
-  status = __xray_patch();
-  printf("patching status: %d\n", static_cast<int32_t>(status));
-  // CHECK-NEXT: patching status: 1
-  __xray_remove_handler();
-  always_instrument();
-  // CHECK-NEXT: always instrumented called
-  status = __xray_unpatch();
-  printf("patching status: %d\n", static_cast<int32_t>(status));
-  // CHECK-NEXT: patching status: 1
-}
Index: compiler-rt/test/xray/TestCases/Linux/optional-inmemory-log.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/optional-inmemory-log.cc
@@ -1,23 +0,0 @@
-// Make sure that we don't get the inmemory logging implementation enabled when
-// we turn it off via options.
-
-// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_naive_log=false xray_logfile_base=optional-inmemory-log.xray-" %run %t 2>&1 | FileCheck %s
-//
-// Make sure we clean out the logs in case there was a bug.
-//
-// RUN: rm -f optional-inmemory-log.xray-*
-
-// UNSUPPORTED: target-is-mips64,target-is-mips64el
-
-#include <cstdio>
-
-[[clang::xray_always_instrument]] void foo() {
-  printf("foo() is always instrumented!");
-}
-
-int main() {
-  // CHECK-NOT: XRay: Log file in 'optional-inmemory-log.xray-{{.*}}'
-  foo();
-  // CHECK: foo() is always instrumented!
-}
Index: compiler-rt/test/xray/TestCases/lit.local.cfg
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+  if not config.parent:
+    return config
+  return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Linux', 'Darwin']:
+  config.unsupported = True
Index: compiler-rt/test/xray/TestCases/Linux/func-id-utils.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/func-id-utils.cc
@@ -1,44 +0,0 @@
-// Check that we can turn a function id to a function address, and also get the
-// maximum function id for the current binary.
-//
-// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false" %run %t
-
-// UNSUPPORTED: target-is-mips64,target-is-mips64el
-
-#include "xray/xray_interface.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdio>
-#include <iterator>
-#include <set>
-
-[[clang::xray_always_instrument]] void bar(){}
-
-[[clang::xray_always_instrument]] void foo() {
-  bar();
-}
-
-[[clang::xray_always_instrument]] int main(int argc, char *argv[]) {
-  assert(__xray_max_function_id() != 0 && "we need xray instrumentation!");
-  std::set<void *> must_be_instrumented = {reinterpret_cast<void *>(&foo),
-                                           reinterpret_cast<void *>(&bar),
-                                           reinterpret_cast<void *>(&main)};
-  std::set<void *> all_instrumented;
-  for (auto i = __xray_max_function_id(); i != 0; --i) {
-    auto addr = __xray_function_address(i);
-    all_instrumented.insert(reinterpret_cast<void *>(addr));
-  }
-  assert(all_instrumented.size() == __xray_max_function_id() &&
-         "each function id must be assigned to a unique function");
-
-  std::set<void *> not_instrumented;
-  std::set_difference(
-      must_be_instrumented.begin(), must_be_instrumented.end(),
-      all_instrumented.begin(), all_instrumented.end(),
-      std::inserter(not_instrumented, not_instrumented.begin()));
-  assert(
-      not_instrumented.empty() &&
-      "we should see all explicitly instrumented functions with function ids");
-  return not_instrumented.empty() ? 0 : 1;
-}
Index: compiler-rt/test/xray/TestCases/Linux/fixedsize-logging.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/fixedsize-logging.cc
@@ -1,22 +0,0 @@
-// Check to make sure that we have a log file with a fixed-size.
-
-// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=true xray_naive_log=true verbosity=1 xray_logfile_base=fixedsize-logging-" %run %t 2>&1 | FileCheck %s
-//
-// After all that, clean up the output xray log.
-//
-// RUN: rm fixedsize-logging-*
-
-// UNSUPPORTED: target-is-mips64,target-is-mips64el
-
-#include <cstdio>
-
-[[clang::xray_always_instrument]] void foo() {
-  printf("foo() is always instrumented!");
-}
-
-int main() {
-  // CHECK: XRay: Log file in 'fixedsize-logging-{{.*}}'
-  foo();
-  // CHECK: foo() is always instrumented!
-}
Index: compiler-rt/test/xray/TestCases/fdr-thread-order.cc
===================================================================
--- compiler-rt/test/xray/TestCases/fdr-thread-order.cc
+++ compiler-rt/test/xray/TestCases/fdr-thread-order.cc
@@ -11,7 +11,7 @@
 // RUN:    FileCheck %s --check-prefix TRACE
 // RUN: rm fdr-thread-order.*
 // FIXME: Make llvm-xray work on non-x86_64 as well.
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64
 // REQUIRES: built-in-llvm-tree
 
 #include "xray/xray_log_interface.h"
Index: compiler-rt/test/xray/TestCases/fdr-single-thread.cc
===================================================================
--- compiler-rt/test/xray/TestCases/fdr-single-thread.cc
+++ compiler-rt/test/xray/TestCases/fdr-single-thread.cc
@@ -8,7 +8,7 @@
 // RUN:   "`ls fdr-logging-1thr-* | head -n1`" | FileCheck %s
 // RUN: rm fdr-logging-1thr-*
 //
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64
 
 #include "xray/xray_log_interface.h"
 #include <cassert>
Index: compiler-rt/test/xray/TestCases/fdr-mode.cc
===================================================================
--- compiler-rt/test/xray/TestCases/fdr-mode.cc
+++ compiler-rt/test/xray/TestCases/fdr-mode.cc
@@ -8,7 +8,7 @@
 // RUN: rm fdr-logging-test-*
 // RUN: rm fdr-unwrite-test-*
 // FIXME: Make llvm-xray work on non-x86_64 as well.
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64
 // REQUIRES: built-in-llvm-tree
 
 #include "xray/xray_log_interface.h"
Index: compiler-rt/test/xray/TestCases/custom-event-logging.cc
===================================================================
--- compiler-rt/test/xray/TestCases/custom-event-logging.cc
+++ compiler-rt/test/xray/TestCases/custom-event-logging.cc
@@ -5,7 +5,7 @@
 // RUN: %clangxx_xray -std=c++11 -fpic -fpie %s -o %t
 // RUN: XRAY_OPTIONS="patch_premain=false verbosity=1 xray_naive_log=false xray_logfile_base=custom-event-logging.xray-" %run %t 2>&1 | FileCheck %s
 // FIXME: Support this in non-x86_64 as well
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64
 // REQUIRES: built-in-llvm-tree
 #include <cstdio>
 #include "xray/xray_interface.h"
Index: compiler-rt/test/xray/TestCases/custom-event-handler-alignment.cc
===================================================================
--- compiler-rt/test/xray/TestCases/custom-event-handler-alignment.cc
+++ compiler-rt/test/xray/TestCases/custom-event-handler-alignment.cc
@@ -4,7 +4,7 @@
 // RUN: %clangxx_xray -std=c++11 %s -o %t
 // RUN: XRAY_OPTIONS="patch_premain=false verbosity=1 xray_naive_log=false" \
 // RUN:     %run %t 2>&1
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64
 // REQUIRES: built-in-llvm-tree
 #include <xmmintrin.h>
 #include <stdio.h>
Index: compiler-rt/test/xray/TestCases/Linux/coverage-sample.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/coverage-sample.cc
@@ -1,90 +0,0 @@
-// Check that we can patch and unpatch specific function ids.
-//
-// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false" %run %t | FileCheck %s
-
-// UNSUPPORTED: target-is-mips64,target-is-mips64el
-
-#include "xray/xray_interface.h"
-
-#include <set>
-#include <cstdio>
-
-std::set<int32_t> function_ids;
-
-[[clang::xray_never_instrument]] void coverage_handler(int32_t fid,
-                                                       XRayEntryType) {
-  thread_local bool patching = false;
-  if (patching) return;
-  patching = true;
-  function_ids.insert(fid);
-  __xray_unpatch_function(fid);
-  patching = false;
-}
-
-[[clang::xray_always_instrument]] void baz() {
-  // do nothing!
-}
-
-[[clang::xray_always_instrument]] void bar() {
-  baz();
-}
-
-[[clang::xray_always_instrument]] void foo() {
-  bar();
-}
-
-[[clang::xray_always_instrument]] int main(int argc, char *argv[]) {
-  __xray_set_handler(coverage_handler);
-  __xray_patch();
-  foo();
-  __xray_unpatch();
-
-  // print out the function_ids.
-  printf("first pass.\n");
-  for (const auto id : function_ids)
-    printf("patched: %d\n", id);
-
-  // CHECK-LABEL: first pass.
-  // CHECK-DAG: patched: [[F1:.*]]
-  // CHECK-DAG: patched: [[F2:.*]]
-  // CHECK-DAG: patched: [[F3:.*]]
-
-  // make a copy of the function_ids, then patch them later.
-  auto called_fns = function_ids;
-
-  // clear the function_ids.
-  function_ids.clear();
-
-  // patch the functions we've called before.
-  for (const auto id : called_fns)
-    __xray_patch_function(id);
-
-  // then call them again.
-  foo();
-  __xray_unpatch();
-
-  // confirm that we've seen the same functions again.
-  printf("second pass.\n");
-  for (const auto id : function_ids)
-    printf("patched: %d\n", id);
-  // CHECK-LABEL: second pass.
-  // CHECK-DAG: patched: [[F1]]
-  // CHECK-DAG: patched: [[F2]]
-  // CHECK-DAG: patched: [[F3]]
-
-  // Now we want to make sure that if we unpatch one, that we're only going to
-  // see two calls of the coverage_handler.
-  function_ids.clear();
-  __xray_patch();
-  __xray_unpatch_function(1);
-  foo();
-  __xray_unpatch();
-
-  // confirm that we don't see function id one called anymore.
-  printf("missing 1.\n");
-  for (const auto id : function_ids)
-    printf("patched: %d\n", id);
-  // CHECK-LABEL: missing 1.
-  // CHECK-NOT: patched: 1
-}
Index: compiler-rt/test/xray/TestCases/Linux/argv0-log-file-name.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/argv0-log-file-name.cc
@@ -1,16 +0,0 @@
-// Check to make sure argv[0] is contained within the (randomised) XRay log file
-// name.
-
-// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=true xray_naive_log=true" %run %t > xray.log.file.name 2>&1
-// RUN: ls | FileCheck xray.log.file.name
-// RUN: rm xray-log.* xray.log.file.name
-
-// UNSUPPORTED: target-is-mips64,target-is-mips64el
-
-#include <cstdio>
-#include <libgen.h>
-
-[[clang::xray_always_instrument]] int main(int argc, char *argv[]) {
-  printf("// CHECK: xray-log.%s.{{.*}}\n", basename(argv[0]));
-}
Index: compiler-rt/test/xray/TestCases/Linux/arg1-logging-implicit-this.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/arg1-logging-implicit-this.cc
@@ -1,31 +0,0 @@
-// Intercept the implicit 'this' argument of class member functions.
-//
-// RUN: %clangxx_xray -g -std=c++11 %s -o %t
-// RUN: rm log-args-this-* || true
-// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=log-args-this-" %run %t
-//
-// XFAIL: arm || aarch64 || mips
-// UNSUPPORTED: powerpc64le
-#include "xray/xray_interface.h"
-#include <cassert>
-
-class A {
- public:
-  [[clang::xray_always_instrument, clang::xray_log_args(1)]] void f() {
-    // does nothing.
-  }
-};
-
-volatile uint64_t captured = 0;
-
-void handler(int32_t, XRayEntryType, uint64_t arg1) {
-  captured = arg1;
-}
-
-int main() {
-  __xray_set_handler_arg1(handler);
-  A instance;
-  instance.f();
-  __xray_remove_handler_arg1();
-  assert(captured == (uint64_t)&instance);
-}
Index: compiler-rt/test/xray/TestCases/Linux/arg1-logger.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/arg1-logger.cc
@@ -1,43 +0,0 @@
-// Check that we can get the first function argument logged
-// using a custom logging function.
-//
-// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=arg1-logger-" %run %t 2>&1 | FileCheck %s
-//
-// After all that, clean up the XRay log file.
-//
-// RUN: rm arg1-logger-*
-//
-// At the time of writing, the ARM trampolines weren't written yet.
-// XFAIL: arm || aarch64 || mips
-// See the mailing list discussion of r296998.
-// UNSUPPORTED: powerpc64le
-
-#include "xray/xray_interface.h"
-
-#include <cinttypes>
-#include <cstdio>
-
-void arg1logger(int32_t fn, XRayEntryType t, uint64_t a1) {
-  printf("Arg1: %" PRIx64 ", XRayEntryType %u\n", a1, t);
-}
-
-[[clang::xray_always_instrument, clang::xray_log_args(1)]] void foo(void *) {}
-
-int main() {
-  // CHECK: XRay: Log file in 'arg1-logger-{{.*}}'
-
-  __xray_set_handler_arg1(arg1logger);
-  foo(nullptr);
-  // CHECK: Arg1: 0, XRayEntryType 3
-
-  __xray_remove_handler_arg1();
-  foo((void *) 0xBADC0DE);
-  // nothing expected to see here
-
-  __xray_set_handler_arg1(arg1logger);
-  foo((void *) 0xDEADBEEFCAFE);
-  // CHECK-NEXT: Arg1: deadbeefcafe, XRayEntryType 3
-  foo((void *) -1);
-  // CHECK-NEXT: Arg1: ffffffffffffffff, XRayEntryType 3
-}
Index: compiler-rt/test/xray/TestCases/Linux/arg1-arg0-logging.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Linux/arg1-arg0-logging.cc
@@ -1,39 +0,0 @@
-// Allow having both the no-arg and arg1 logging implementation live together,
-// and be called in the correct cases.
-//
-// RUN: rm arg0-arg1-logging-* || true
-// RUN: %clangxx_xray -std=c++11 %s -o %t
-// RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=arg0-arg1-logging-" %run %t
-//
-// TODO: Support these in ARM and PPC
-// XFAIL: arm || aarch64 || mips
-// UNSUPPORTED: powerpc64le
-
-#include "xray/xray_interface.h"
-#include <cassert>
-#include <cstdio>
-
-using namespace std;
-
-bool arg0loggercalled = false;
-void arg0logger(int32_t, XRayEntryType) { arg0loggercalled = true; }
-
-[[clang::xray_always_instrument]] void arg0fn() { printf("hello, arg0!\n"); }
-
-bool arg1loggercalled = false;
-void arg1logger(int32_t, XRayEntryType, uint64_t) { arg1loggercalled = true; }
-
-[[ clang::xray_always_instrument, clang::xray_log_args(1) ]] void
-arg1fn(uint64_t arg1) {
-  printf("hello, arg1!\n");
-}
-
-int main(int argc, char *argv[]) {
-  __xray_set_handler(arg0logger);
-  __xray_set_handler_arg1(arg1logger);
-  arg0fn();
-  arg1fn(0xcafef00d);
-  __xray_remove_handler_arg1();
-  __xray_remove_handler();
-  assert(arg0loggercalled && arg1loggercalled);
-}
Index: compiler-rt/test/xray/TestCases/always-never-instrument.cc
===================================================================
--- compiler-rt/test/xray/TestCases/always-never-instrument.cc
+++ compiler-rt/test/xray/TestCases/always-never-instrument.cc
@@ -9,7 +9,7 @@
 // RUN:    FileCheck %s --check-prefix NOINSTR
 // RUN: %llvm_xray extract -symbolize %t | \
 // RUN:    FileCheck %s --check-prefix ALWAYSINSTR
-// REQUIRES: x86_64-linux
+// REQUIRES: x86_64
 // REQUIRES: built-in-llvm-tree
 
 // NOINSTR-NOT: {{.*__xray_NeverInstrumented.*}}
Index: compiler-rt/test/xray/TestCases/Darwin/lit.local.cfg
===================================================================
--- /dev/null
+++ compiler-rt/test/xray/TestCases/Darwin/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+  if not config.parent:
+    return config
+  return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Darwin']:
+  config.unsupported = True
Index: compiler-rt/lib/xray/xray_trampoline_x86_64.S
===================================================================
--- compiler-rt/lib/xray/xray_trampoline_x86_64.S
+++ compiler-rt/lib/xray/xray_trampoline_x86_64.S
@@ -14,10 +14,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "../builtins/assembly.h"
+#include "../sanitizer_common/sanitizer_asm.h"
+
+
 
 .macro SAVE_REGISTERS
 	subq $192, %rsp
-	.cfi_def_cfa_offset 200
+	CFI_DEF_CFA_OFFSET(200)
 	// At this point, the stack pointer should be aligned to an 8-byte boundary,
 	// because any call instructions that come after this will add another 8
 	// bytes and therefore align it to 16-bytes.
@@ -57,25 +60,28 @@
 	movq	8(%rsp), %r8
 	movq	0(%rsp), %r9
 	addq	$192, %rsp
-	.cfi_def_cfa_offset 8
+	CFI_DEF_CFA_OFFSET(8)
 .endm
 
-	.text
+#if !defined(__APPLE__)
+	.section .text
+#else
+	.section __TEXT,__text
+#endif
 	.file "xray_trampoline_x86.S"
 
 //===----------------------------------------------------------------------===//
 
-	.globl __xray_FunctionEntry
+	.globl ASM_TSAN_SYMBOL(__xray_FunctionEntry)
 	.align 16, 0x90
-	.type __xray_FunctionEntry,@function
-
-__xray_FunctionEntry:
-	.cfi_startproc
+	ASM_TYPE_FUNCTION(__xray_FunctionEntry)
+ASM_TSAN_SYMBOL(__xray_FunctionEntry):
+	CFI_STARTPROC
 	SAVE_REGISTERS
 
 	// This load has to be atomic, it's concurrent with __xray_patch().
 	// On x86/amd64, a simple (type-aligned) MOV instruction is enough.
-	movq	_ZN6__xray19XRayPatchedFunctionE(%rip), %rax
+	movq	ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
 	testq	%rax, %rax
 	je	.Ltmp0
 
@@ -86,28 +92,27 @@
 .Ltmp0:
 	RESTORE_REGISTERS
 	retq
-.Ltmp1:
-	.size __xray_FunctionEntry, .Ltmp1-__xray_FunctionEntry
-	.cfi_endproc
+	ASM_SIZE(__xray_FunctionEntry)
+	CFI_ENDPROC
 
 //===----------------------------------------------------------------------===//
 
-	.globl __xray_FunctionExit
+	.globl ASM_TSAN_SYMBOL(__xray_FunctionExit)
 	.align 16, 0x90
-	.type __xray_FunctionExit,@function
-__xray_FunctionExit:
-	.cfi_startproc
+	ASM_TYPE_FUNCTION(__xray_FunctionExit)
+ASM_TSAN_SYMBOL(__xray_FunctionExit):
+	CFI_STARTPROC
 	// Save the important registers first. Since we're assuming that this
 	// function is only jumped into, we only preserve the registers for
 	// returning.
 	subq	$56, %rsp
-	.cfi_def_cfa_offset 64
+	CFI_DEF_CFA_OFFSET(64)
 	movq  %rbp, 48(%rsp)
 	movupd	%xmm0, 32(%rsp)
 	movupd	%xmm1, 16(%rsp)
 	movq	%rax, 8(%rsp)
 	movq	%rdx, 0(%rsp)
-	movq	_ZN6__xray19XRayPatchedFunctionE(%rip), %rax
+	movq	ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
 	testq %rax,%rax
 	je	.Ltmp2
 
@@ -122,22 +127,21 @@
 	movq	8(%rsp), %rax
 	movq	0(%rsp), %rdx
 	addq	$56, %rsp
-	.cfi_def_cfa_offset 8
+	CFI_DEF_CFA_OFFSET(8)
 	retq
-.Ltmp3:
-	.size __xray_FunctionExit, .Ltmp3-__xray_FunctionExit
-	.cfi_endproc
+	ASM_SIZE(__xray_FunctionExit)
+	CFI_ENDPROC
 
 //===----------------------------------------------------------------------===//
 
-	.global __xray_FunctionTailExit
+	.globl ASM_TSAN_SYMBOL(__xray_FunctionTailExit)
 	.align 16, 0x90
-	.type __xray_FunctionTailExit,@function
-__xray_FunctionTailExit:
-	.cfi_startproc
+	ASM_TYPE_FUNCTION(__xray_FunctionTailExit)
+ASM_TSAN_SYMBOL(__xray_FunctionTailExit):
+	CFI_STARTPROC
 	SAVE_REGISTERS
 
-	movq	_ZN6__xray19XRayPatchedFunctionE(%rip), %rax
+	movq	ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
 	testq %rax,%rax
 	je	.Ltmp4
 
@@ -148,26 +152,25 @@
 .Ltmp4:
 	RESTORE_REGISTERS
 	retq
-.Ltmp5:
-	.size __xray_FunctionTailExit, .Ltmp5-__xray_FunctionTailExit
-	.cfi_endproc
+	ASM_SIZE(__xray_FunctionTailExit)
+	CFI_ENDPROC
 
 //===----------------------------------------------------------------------===//
 
-	.globl __xray_ArgLoggerEntry
+	.globl ASM_TSAN_SYMBOL(__xray_ArgLoggerEntry)
 	.align 16, 0x90
-	.type __xray_ArgLoggerEntry,@function
-__xray_ArgLoggerEntry:
-	.cfi_startproc
+	ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry)
+ASM_TSAN_SYMBOL(__xray_ArgLoggerEntry):
+	CFI_STARTPROC
 	SAVE_REGISTERS
 
 	// Again, these function pointer loads must be atomic; MOV is fine.
-	movq	_ZN6__xray13XRayArgLoggerE(%rip), %rax
+	movq	ASM_TSAN_SYMBOL(_ZN6__xray13XRayArgLoggerE)(%rip), %rax
 	testq	%rax, %rax
 	jne	.Larg1entryLog
 
 	// If [arg1 logging handler] not set, defer to no-arg logging.
-	movq	_ZN6__xray19XRayPatchedFunctionE(%rip), %rax
+	movq	ASM_TSAN_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax
 	testq	%rax, %rax
 	je	.Larg1entryFail
 
@@ -186,24 +189,22 @@
 .Larg1entryFail:
 	RESTORE_REGISTERS
 	retq
-
-.Larg1entryEnd:
-	.size __xray_ArgLoggerEntry, .Larg1entryEnd-__xray_ArgLoggerEntry
-	.cfi_endproc
+	ASM_SIZE(__xray_ArgLoggerEntry)
+	CFI_ENDPROC
 
 //===----------------------------------------------------------------------===//
 
-	.global __xray_CustomEvent
+	.global ASM_TSAN_SYMBOL(__xray_CustomEvent)
 	.align 16, 0x90
-	.type __xray_CustomEvent,@function
-__xray_CustomEvent:
-  .cfi_startproc
+	ASM_TYPE_FUNCTION(__xray_CustomEvent)
+ASM_TSAN_SYMBOL(__xray_CustomEvent):
+	CFI_STARTPROC
 	SAVE_REGISTERS
 
 	// We take two arguments to this trampoline, which should be in rdi	and rsi
 	// already. We also make sure that we stash %rax because we use that register
 	// to call the logging handler.
-	movq _ZN6__xray22XRayPatchedCustomEventE(%rip), %rax
+	movq ASM_TSAN_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)(%rip), %rax
 	testq %rax,%rax
 	je .LcustomEventCleanup
 
@@ -223,9 +224,7 @@
 .LcustomEventCleanup:
 	RESTORE_REGISTERS
 	retq
-
-.Ltmp8:
-	.size __xray_CustomEvent, .Ltmp8-__xray_CustomEvent
-	.cfi_endproc
+	ASM_SIZE(__xray_CustomEvent)
+	CFI_ENDPROC
 
 NO_EXEC_STACK_DIRECTIVE
Index: compiler-rt/lib/xray/xray_init.cc
===================================================================
--- compiler-rt/lib/xray/xray_init.cc
+++ compiler-rt/lib/xray/xray_init.cc
@@ -88,7 +88,8 @@
 #endif
 }
 
-#ifndef XRAY_NO_PREINIT
+// Only add the preinit array initialization if the sanitizers can.
+#if !defined(XRAY_NO_PREINIT) && SANITIZER_CAN_USE_PREINIT_ARRAY
 __attribute__((section(".preinit_array"),
                used)) void (*__local_xray_preinit)(void) = __xray_init;
 #endif
Index: compiler-rt/lib/xray/weak_symbols.txt
===================================================================
--- /dev/null
+++ compiler-rt/lib/xray/weak_symbols.txt
@@ -0,0 +1,4 @@
+___start_xray_fn_idx
+___start_xray_instr_map
+___stop_xray_fn_idx
+___stop_xray_instr_map
Index: compiler-rt/lib/xray/tests/CMakeLists.txt
===================================================================
--- compiler-rt/lib/xray/tests/CMakeLists.txt
+++ compiler-rt/lib/xray/tests/CMakeLists.txt
@@ -12,21 +12,50 @@
   -I${COMPILER_RT_SOURCE_DIR}/lib)
 
 set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH})
+set(XRAY_LINK_FLAGS)
+append_list_if(COMPILER_RT_HAS_LIBRT -lrt XRAY_LINK_FLAGS)
+append_list_if(COMPILER_RT_HAS_LIBM -lm XRAY_LINK_FLAGS)
+append_list_if(COMPILER_RT_HAS_LIBPTHREAD -lpthread XRAY_LINK_FLAGS)
+
+if (APPLE)
+  list(APPEND XRAY_LINK_FLAGS -lc++)
+  list(APPEND XRAY_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
+  set(XRAY_TEST_RUNTIME_OBJECTS
+    $<TARGET_OBJECTS:RTSanitizerCommon.osx>
+    $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
+    $<TARGET_OBJECTS:RTXray.osx>)
+  set(XRAY_TEST_RUNTIME RTXRayTest)
+  add_library(${XRAY_TEST_RUNTIME} STATIC ${XRAY_TEST_RUNTIME_OBJECTS})
+  set_target_properties(${XRAY_TEST_RUNTIME} PROPERTIES
+    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+    FOLDER "Compiler-RT Runtime tests")
+
+  darwin_filter_host_archs(XRAY_SUPPORTED_ARCH XRAY_TEST_ARCH)
+  list(APPEND XRAY_UNITTEST_CFLAGS ${DARWIN_osx_CFLAGS})
+  list(APPEND XRAY_LINK_FLAGS "-lc++")
+  list(APPEND XRAY_LINK_FLAGS "-fxray-instrument")
+  add_weak_symbols("sanitizer_common" XRAY_LINK_FLAGS)
+  add_weak_symbols("xray" XRAY_LINK_FLAGS)
+else()
+  append_list_if(COMPILER_RT_HAS_LIBSTDCXX lstdc++ XRAY_LINK_FLAGS)
+endif()
+
 macro(add_xray_unittest testname)
   cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN})
-  if(UNIX AND NOT APPLE)
+  if(UNIX)
     foreach(arch ${XRAY_TEST_ARCH})
       set(TEST_OBJECTS)
       generate_compiler_rt_tests(TEST_OBJECTS
         XRayUnitTests "${testname}-${arch}-Test" "${arch}"
         SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}
+        RUNTIME ${XRAY_TEST_RUNTIME}
+        COMPILE_DEPS ${TEST_HEADERS}
         DEPS gtest xray llvm-xray
         CFLAGS ${XRAY_UNITTEST_CFLAGS}
         LINK_FLAGS -fxray-instrument
           ${TARGET_LINK_FLAGS}
-          -lstdc++ -lm ${CMAKE_THREAD_LIBS_INIT}
-          -lpthread
-          -ldl -lrt)
+          ${CMAKE_THREAD_LIBS_INIT}
+          ${XRAY_LINK_FLAGS})
       set_target_properties(XRayUnitTests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
     endforeach()
   endif()
Index: compiler-rt/lib/xray/CMakeLists.txt
===================================================================
--- compiler-rt/lib/xray/CMakeLists.txt
+++ compiler-rt/lib/xray/CMakeLists.txt
@@ -65,19 +65,53 @@
 append_list_if(
   COMPILER_RT_BUILD_XRAY_NO_PREINIT XRAY_NO_PREINIT XRAY_COMMON_DEFINITIONS)
 
-add_compiler_rt_object_libraries(RTXray
-  ARCHS ${XRAY_SUPPORTED_ARCH}
-  SOURCES ${XRAY_SOURCES} CFLAGS ${XRAY_CFLAGS}
-  DEFS ${XRAY_COMMON_DEFINITIONS})
-
 add_compiler_rt_component(xray)
 
 set(XRAY_COMMON_RUNTIME_OBJECT_LIBS
+    RTXray
     RTSanitizerCommon
     RTSanitizerCommonLibc)
 
+if (APPLE)
+  set(XRAY_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})
+  set(XRAY_ASM_SOURCES xray_trampoline_x86_64.S)
+
+  if (${CMAKE_GENERATOR} STREQUAL "Xcode")
+    enable_language(ASM)
+  else()
+    set_source_files_properties(${XRAY_ASM_SOURCES} PROPERTIES LANGUAGE C)
+  endif()
+
+  add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
+  add_weak_symbols("xray" WEAK_SYMBOL_LINK_FLAGS)
+
+  add_compiler_rt_object_libraries(RTXray
+    OS ${XRAY_SUPPORTED_OS}
+    ARCHS ${XRAY_SUPPORTED_ARCH}
+    SOURCES ${x86_64_SOURCES}
+    CFLAGS ${XRAY_CFLAGS}
+    DEFS ${XRAY_COMMON_DEFINITIONS})
+
+  # We only support running on osx for now.
+  add_compiler_rt_runtime(clang_rt.xray
+    STATIC
+    OS ${XRAY_SUPPORTED_OS}
+    ARCHS ${XRAY_SUPPORTED_ARCH}
+    OBJECT_LIBS RTXray
+                RTSanitizerCommon
+                RTSanitizerCommonLibc
+    CFLAGS ${XRAY_CFLAGS}
+    DEFS ${XRAY_COMMON_DEFINITIONS}
+    LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
+    LINK_LIBS ${XRAY_LINK_LIBS}
+    PARENT_TARGET xray)
+else()
 foreach(arch ${XRAY_SUPPORTED_ARCH})
   if(CAN_TARGET_${arch})
+    add_compiler_rt_object_libraries(RTXray
+      ARCHS ${XRAY_SUPPORTED_ARCH}
+      SOURCES ${XRAY_SOURCES} CFLAGS ${XRAY_CFLAGS}
+      DEFS ${XRAY_COMMON_DEFINITIONS})
     add_compiler_rt_runtime(clang_rt.xray
      STATIC
      ARCHS ${arch}
@@ -88,6 +122,7 @@
      PARENT_TARGET xray)
   endif()
 endforeach()
+endif()
 
 if(COMPILER_RT_INCLUDE_TESTS)
   add_subdirectory(tests)
Index: compiler-rt/cmake/config-ix.cmake
===================================================================
--- compiler-rt/cmake/config-ix.cmake
+++ compiler-rt/cmake/config-ix.cmake
@@ -211,7 +211,11 @@
 set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64})
 set(ALL_ESAN_SUPPORTED_ARCH ${X86_64} ${MIPS64})
 set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64})
+if(APPLE)
+set(ALL_XRAY_SUPPORTED_ARCH ${X86_64})
+else()
 set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} powerpc64le)
+endif()
 
 if(APPLE)
   include(CompilerRTDarwinUtils)
@@ -256,6 +260,7 @@
   set(SANITIZER_COMMON_SUPPORTED_OS osx)
   set(PROFILE_SUPPORTED_OS osx)
   set(TSAN_SUPPORTED_OS osx)
+  set(XRAY_SUPPORTED_OS osx)
   if(NOT SANITIZER_MIN_OSX_VERSION)
     string(REGEX MATCH "-mmacosx-version-min=([.0-9]+)"
            MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}")
@@ -412,12 +417,12 @@
   list_intersect(SCUDO_SUPPORTED_ARCH
     ALL_SCUDO_SUPPORTED_ARCH
     SANITIZER_COMMON_SUPPORTED_ARCH)
-  list_intersect(XRAY_SUPPORTED_ARCH
-    ALL_XRAY_SUPPORTED_ARCH
-    SANITIZER_COMMON_SUPPORTED_ARCH)
   list_intersect(FUZZER_SUPPORTED_ARCH
     ALL_FUZZER_SUPPORTED_ARCH
     ALL_SANITIZER_COMMON_SUPPORTED_ARCH)
+  list_intersect(XRAY_SUPPORTED_ARCH
+    ALL_XRAY_SUPPORTED_ARCH
+    SANITIZER_COMMON_SUPPORTED_ARCH)
 
 else()
   # Architectures supported by compiler-rt libraries.
@@ -580,7 +585,7 @@
 endif()
 
 if (COMPILER_RT_HAS_SANITIZER_COMMON AND XRAY_SUPPORTED_ARCH AND
-    OS_NAME MATCHES "Linux")
+    OS_NAME MATCHES "Darwin|Linux")
   set(COMPILER_RT_HAS_XRAY TRUE)
 else()
   set(COMPILER_RT_HAS_XRAY FALSE)
Index: clang/lib/Driver/XRayArgs.cpp
===================================================================
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -51,6 +51,15 @@
         D.Diag(diag::err_drv_clang_unsupported)
             << (std::string(XRayInstrumentOption) + " on " + Triple.str());
       }
+    else if (Triple.getOS() == llvm::Triple::Darwin)
+      // Experimental support for macos.
+      switch (Triple.getArch()) {
+      case llvm::Triple::x86_64:
+        break;
+      default:
+        D.Diag(diag::err_drv_clang_unsupported)
+            << (std::string(XRayInstrumentOption) + " on " + Triple.str());
+      }
     else
       D.Diag(diag::err_drv_clang_unsupported)
           << (std::string(XRayInstrumentOption) + " on non-Linux target OS");
Index: clang/lib/Driver/ToolChains/Darwin.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Darwin.cpp
+++ clang/lib/Driver/ToolChains/Darwin.cpp
@@ -18,6 +18,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
+#include "clang/Driver/XRayArgs.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/Path.h"
@@ -1098,6 +1099,11 @@
   if (Sanitize.needsEsanRt())
     AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
 
+  const XRayArgs& XRay = getXRayArgs();
+  if (XRay.needsXRayRt() && isTargetMacOS()) {
+    AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.xray_osx.a", RLO_AlwaysLink);
+  }
+
   // Otherwise link libSystem, then the dynamic runtime library, and finally any
   // target specific static runtime library.
   CmdArgs.push_back("-lSystem");
Index: clang/include/clang/Driver/XRayArgs.h
===================================================================
--- clang/include/clang/Driver/XRayArgs.h
+++ clang/include/clang/Driver/XRayArgs.h
@@ -30,6 +30,7 @@
   XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
   void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
                llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
+  bool needsXRayRt() const { return XRayInstrument; }
 };
 
 } // namespace driver
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to