[compiler-rt] r325240 - Add Xray instrumentation support to FreeBSD
Kamil Rytarowski via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 15 06:17:16 PST 2018
Author: kamil
Date: Thu Feb 15 06:17:15 2018
New Revision: 325240
URL: http://llvm.org/viewvc/llvm-project?rev=325240&view=rev
Log:
Add Xray instrumentation support to FreeBSD
Summary:
- Enabling the build.
- Using assembly for the cpuid parts.
- Using thr_self FreeBSD call to get the thread id
Patch by: David CARLIER
Reviewers: dberris, rnk, krytarowski
Reviewed By: dberris, krytarowski
Subscribers: emaste, stevecheckoway, nglevin, srhines, kubamracek, dberris, mgorny, krytarowski, llvm-commits, #sanitizers
Differential Revision: https://reviews.llvm.org/D43278
Modified:
compiler-rt/trunk/cmake/config-ix.cmake
compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
compiler-rt/trunk/lib/xray/tests/CMakeLists.txt
compiler-rt/trunk/lib/xray/tests/unit/fdr_logging_test.cc
compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h
compiler-rt/trunk/lib/xray/xray_flags.inc
compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
compiler-rt/trunk/lib/xray/xray_x86_64.cc
compiler-rt/trunk/lib/xray/xray_x86_64.inc
compiler-rt/trunk/test/xray/lit.cfg
Modified: compiler-rt/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake (original)
+++ compiler-rt/trunk/cmake/config-ix.cmake Thu Feb 15 06:17:15 2018
@@ -597,7 +597,7 @@ else()
endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND XRAY_SUPPORTED_ARCH AND
- OS_NAME MATCHES "Darwin|Linux")
+ OS_NAME MATCHES "Darwin|Linux|FreeBSD")
set(COMPILER_RT_HAS_XRAY TRUE)
else()
set(COMPILER_RT_HAS_XRAY FALSE)
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h Thu Feb 15 06:17:15 2018
@@ -98,7 +98,8 @@
// We can use .preinit_array section on Linux to call sanitizer initialization
// functions very early in the process startup (unless PIC macro is defined).
// FIXME: do we have anything like this on Mac?
-#if SANITIZER_LINUX && !SANITIZER_ANDROID && !defined(PIC)
+#if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || \
+ SANITIZER_FREEBSD) && !defined(PIC)
# define SANITIZER_CAN_USE_PREINIT_ARRAY 1
// Before Solaris 11.4, .preinit_array is fully supported only with GNU ld.
// FIXME: Check for those conditions.
Modified: compiler-rt/trunk/lib/xray/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/tests/CMakeLists.txt?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/xray/tests/CMakeLists.txt Thu Feb 15 06:17:15 2018
@@ -15,6 +15,10 @@ set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH
macro(add_xray_unittest testname)
cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN})
if(UNIX AND NOT APPLE)
+ set(CMAKE_DL_LIBS_INIT "")
+ foreach(lib ${CMAKE_DL_LIBS})
+ list(APPEND CMAKE_DL_LIBS_INIT -l${lib})
+ endforeach()
foreach(arch ${XRAY_TEST_ARCH})
set(TEST_OBJECTS)
generate_compiler_rt_tests(TEST_OBJECTS
@@ -25,8 +29,7 @@ macro(add_xray_unittest testname)
LINK_FLAGS -fxray-instrument
${TARGET_LINK_FLAGS}
-lstdc++ -lm ${CMAKE_THREAD_LIBS_INIT}
- -lpthread
- -ldl -lrt)
+ ${CMAKE_DL_LIBS_INIT} -lrt)
set_target_properties(XRayUnitTests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endforeach()
endif()
Modified: compiler-rt/trunk/lib/xray/tests/unit/fdr_logging_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/tests/unit/fdr_logging_test.cc?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/tests/unit/fdr_logging_test.cc (original)
+++ compiler-rt/trunk/lib/xray/tests/unit/fdr_logging_test.cc Thu Feb 15 06:17:15 2018
@@ -10,6 +10,7 @@
// This file is a part of XRay, a function call tracing system.
//
//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common.h"
#include "xray_fdr_logging.h"
#include "gtest/gtest.h"
@@ -154,12 +155,12 @@ TEST(FDRLoggingTest, MultiThreadedCyclin
// Now we want to create one thread, do some logging, then create another one,
// in succession and making sure that we're able to get thread records from
// the latest thread (effectively being able to recycle buffers).
- std::array<pid_t, 2> Threads;
+ std::array<tid_t, 2> Threads;
for (uint64_t I = 0; I < 2; ++I) {
std::thread t{[I, &Threads] {
fdrLoggingHandleArg0(I + 1, XRayEntryType::ENTRY);
fdrLoggingHandleArg0(I + 1, XRayEntryType::EXIT);
- Threads[I] = syscall(SYS_gettid);
+ Threads[I] = __sanitizer::GetTid();
}};
t.join();
}
@@ -192,9 +193,9 @@ TEST(FDRLoggingTest, MultiThreadedCyclin
ASSERT_EQ(MDR0.RecordKind,
uint8_t(MetadataRecord::RecordKinds::BufferExtents));
ASSERT_EQ(MDR1.RecordKind, uint8_t(MetadataRecord::RecordKinds::NewBuffer));
- pid_t Latest = 0;
- memcpy(&Latest, MDR1.Data, sizeof(pid_t));
- ASSERT_EQ(Latest, Threads[1]);
+ int32_t Latest = 0;
+ memcpy(&Latest, MDR1.Data, sizeof(int32_t));
+ ASSERT_EQ(Latest, static_cast<int32_t>(Threads[1]));
}
} // namespace
Modified: compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h (original)
+++ compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h Thu Feb 15 06:17:15 2018
@@ -54,7 +54,7 @@ namespace __xray_fdr_internal {
/// Writes the new buffer record and wallclock time that begin a buffer for the
/// current thread.
-static void writeNewBufferPreamble(pid_t Tid, timespec TS);
+static void writeNewBufferPreamble(tid_t Tid, timespec TS);
/// Writes a Function Record to the buffer associated with the current thread.
static void writeFunctionRecord(int FuncId, uint32_t TSCDelta,
@@ -185,7 +185,7 @@ public:
} // namespace
-static void writeNewBufferPreamble(pid_t Tid,
+static void writeNewBufferPreamble(tid_t Tid,
timespec TS) XRAY_NEVER_INSTRUMENT {
static constexpr int InitRecordsCount = 2;
auto &TLD = getThreadLocalData();
@@ -195,11 +195,12 @@ static void writeNewBufferPreamble(pid_t
// buffer, associated with a particular thread, with a new CPU. For the
// data, we have 15 bytes to squeeze as much information as we can. At this
// point we only write down the following bytes:
- // - Thread ID (pid_t, 4 bytes)
+ // - Thread ID (tid_t, cast to 4 bytes type due to Darwin being 8 bytes)
auto &NewBuffer = Metadata[0];
NewBuffer.Type = uint8_t(RecordType::Metadata);
NewBuffer.RecordKind = uint8_t(MetadataRecord::RecordKinds::NewBuffer);
- std::memcpy(&NewBuffer.Data, &Tid, sizeof(pid_t));
+ int32_t tid = static_cast<int32_t>(Tid);
+ std::memcpy(&NewBuffer.Data, &tid, sizeof(tid));
}
// Also write the WalltimeMarker record.
@@ -236,7 +237,7 @@ inline void setupNewBuffer(int (*wall_cl
auto &TLD = getThreadLocalData();
auto &B = TLD.Buffer;
TLD.RecordPtr = static_cast<char *>(B.Data);
- pid_t Tid = syscall(SYS_gettid);
+ tid_t Tid = __sanitizer::GetTid();
timespec TS{0, 0};
// This is typically clock_gettime, but callers have injection ability.
wall_clock_reader(CLOCK_MONOTONIC, &TS);
Modified: compiler-rt/trunk/lib/xray/xray_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_flags.inc?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_flags.inc (original)
+++ compiler-rt/trunk/lib/xray/xray_flags.inc Thu Feb 15 06:17:15 2018
@@ -31,7 +31,7 @@ XRAY_FLAG(int, xray_naive_log_func_durat
"microseconds than this threshold.")
XRAY_FLAG(int, xray_naive_log_max_stack_depth, 64,
"Naive logging will keep track of at most this deep a call stack, "
- "any more and the recordings will be droppped.")
+ "any more and the recordings will be dropped.")
XRAY_FLAG(int, xray_naive_log_thread_buffer_size, 1024,
"The number of entries to keep on a per-thread buffer.")
Modified: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_inmemory_log.cc?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc Thu Feb 15 06:17:15 2018
@@ -60,7 +60,7 @@ struct alignas(64) ThreadLocalData {
size_t StackSize = 0;
size_t StackEntries = 0;
int Fd = -1;
- pid_t TID = 0;
+ tid_t TID = 0;
};
static pthread_key_t PThreadKey;
Modified: compiler-rt/trunk/lib/xray/xray_x86_64.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_x86_64.cc?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_x86_64.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_x86_64.cc Thu Feb 15 06:17:15 2018
@@ -3,6 +3,10 @@
#include "xray_defs.h"
#include "xray_interface_internal.h"
+#if SANITIZER_FREEBSD
+#include <sys/sysctl.h>
+#endif
+
#include <atomic>
#include <cstdint>
#include <errno.h>
@@ -14,6 +18,7 @@
namespace __xray {
+#if SANITIZER_LINUX
static std::pair<ssize_t, bool>
retryingReadSome(int Fd, char *Begin, char *End) XRAY_NEVER_INSTRUMENT {
auto BytesToRead = std::distance(Begin, End);
@@ -71,6 +76,24 @@ uint64_t getTSCFrequency() XRAY_NEVER_IN
}
return TSCFrequency == -1 ? 0 : static_cast<uint64_t>(TSCFrequency);
}
+#elif SANITIZER_FREEBSD
+uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
+ long long TSCFrequency = -1;
+ size_t tscfreqsz = sizeof(TSCFrequency);
+
+ if (sysctlbyname("machdep.tsc_freq", &TSCFrequency, &tscfreqsz,
+ NULL, 0) != -1) {
+ return static_cast<uint64_t>(TSCFrequency);
+ } else {
+ Report("Unable to determine CPU frequency for TSC accounting.\n");
+ }
+
+ return 0;
+
+}
+#else
+#error "Platform not supported"
+#endif
static constexpr uint8_t CallOpCode = 0xe8;
static constexpr uint16_t MovR10Seq = 0xba41;
@@ -259,7 +282,8 @@ bool probeRequiredCPUFeatures() XRAY_NEV
// We check whether rdtscp support is enabled. According to the x86_64 manual,
// level should be set at 0x80000001, and we should have a look at bit 27 in
// EDX. That's 0x8000000 (or 1u << 27).
- __get_cpuid(0x80000001, &EAX, &EBX, &ECX, &EDX);
+ __asm__ __volatile__("cpuid" : "=a"(EAX), "=b"(EBX), "=c"(ECX), "=d"(EDX)
+ : "0"(0x80000001));
if (!(EDX & (1u << 27))) {
Report("Missing rdtscp support.\n");
return false;
Modified: compiler-rt/trunk/lib/xray/xray_x86_64.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_x86_64.inc?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_x86_64.inc (original)
+++ compiler-rt/trunk/lib/xray/xray_x86_64.inc Thu Feb 15 06:17:15 2018
@@ -21,9 +21,10 @@ namespace __xray {
ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
unsigned LongCPU;
- uint64_t TSC = __rdtscp(&LongCPU);
+ unsigned long Rax, Rdx;
+ __asm__ __volatile__("rdtscp\n" : "=a"(Rax), "=d"(Rdx), "=c"(LongCPU) ::);
CPU = LongCPU;
- return TSC;
+ return (Rdx << 32) + Rax;
}
uint64_t getTSCFrequency();
Modified: compiler-rt/trunk/test/xray/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/lit.cfg?rev=325240&r1=325239&r2=325240&view=diff
==============================================================================
--- compiler-rt/trunk/test/xray/lit.cfg (original)
+++ compiler-rt/trunk/test/xray/lit.cfg Thu Feb 15 06:17:15 2018
@@ -20,6 +20,13 @@ def build_invocation(compile_flags):
llvm_xray = os.path.join(config.llvm_tools_dir, 'llvm-xray')
# Setup substitutions.
+xraylib_flags = '-lm -pthread -lrt'
+if config.host_os == 'Linux':
+ xraylib_flags += ' -ldl'
+
+xraylib_flags += ' -L%s -Wl,-whole-archive -lclang_rt.xray-%s '
+'-Wl,-no-whole-archive'
+
config.substitutions.append(
('%clang ', build_invocation([config.target_cflags])))
config.substitutions.append(
@@ -33,14 +40,13 @@ config.substitutions.append(
('%llvm_xray', llvm_xray))
config.substitutions.append(
('%xraylib',
- ('-lm -lpthread -ldl -lrt -L%s '
- '-Wl,-whole-archive -lclang_rt.xray-%s -Wl,-no-whole-archive')
+ (xraylib_flags)
% (config.compiler_rt_libdir, config.host_arch)))
# Default test suffixes.
config.suffixes = ['.c', '.cc', '.cpp']
-if config.host_os not in ['Linux']:
+if config.host_os not in ['Linux', 'FreeBSD']:
config.unsupported = True
elif '64' not in config.host_arch:
if 'arm' in config.host_arch:
More information about the llvm-commits
mailing list