[compiler-rt] r311524 - [XRay][compiler-rt] Support sled versioning for custom event sleds
Dean Michael Berris via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 22 21:42:37 PDT 2017
Author: dberris
Date: Tue Aug 22 21:42:37 2017
New Revision: 311524
URL: http://llvm.org/viewvc/llvm-project?rev=311524&view=rev
Log:
[XRay][compiler-rt] Support sled versioning for custom event sleds
Summary:
This change introduces versions to the instrumentation map entries we
emit for XRay instrumentaiton points. The status quo for the version is
currently set to 0 (as emitted by the LLVM back-end), and versions will
count up to 255 (unsigned char).
This change is in preparation for supporting the newer version of the
custom event sleds that will be emitted by the LLVM compiler.
While we're here, we take the opportunity to stash more registers and
align the stack properly in the __xray_CustomEvent trampoline.
Reviewers: kpw, pcc, dblaikie
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36816
Added:
compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-handler-alignment.cc
Modified:
compiler-rt/trunk/lib/xray/xray_interface_internal.h
compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S
compiler-rt/trunk/lib/xray/xray_x86_64.cc
compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-logging.cc
Modified: compiler-rt/trunk/lib/xray/xray_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_interface_internal.h?rev=311524&r1=311523&r2=311524&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_interface_internal.h (original)
+++ compiler-rt/trunk/lib/xray/xray_interface_internal.h Tue Aug 22 21:42:37 2017
@@ -28,13 +28,15 @@ struct XRaySledEntry {
uint64_t Function;
unsigned char Kind;
unsigned char AlwaysInstrument;
- unsigned char Padding[14]; // Need 32 bytes
+ unsigned char Version;
+ unsigned char Padding[13]; // Need 32 bytes
#elif SANITIZER_WORDSIZE == 32
uint32_t Address;
uint32_t Function;
unsigned char Kind;
unsigned char AlwaysInstrument;
- unsigned char Padding[6]; // Need 16 bytes
+ unsigned char Version;
+ unsigned char Padding[5]; // Need 16 bytes
#else
#error "Unsupported word size."
#endif
Modified: compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S?rev=311524&r1=311523&r2=311524&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S (original)
+++ compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S Tue Aug 22 21:42:37 2017
@@ -202,10 +202,7 @@ __xray_ArgLoggerEntry:
.type __xray_CustomEvent, at function
__xray_CustomEvent:
.cfi_startproc
- subq $16, %rsp
- .cfi_def_cfa_offset 24
- movq %rbp, 8(%rsp)
- movq %rax, 0(%rsp)
+ 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
@@ -215,14 +212,20 @@ __xray_CustomEvent:
je .LcustomEventCleanup
// At this point we know that rcx and rdx already has the data, so we just
- // call the logging handler.
+ // call the logging handler, after aligning the stack to a 16-byte boundary.
+ // The approach we're taking here uses additional stack space to stash the
+ // stack pointer twice before aligning the pointer to 16-bytes. If the stack
+ // was 8-byte aligned, it will become 16-byte aligned -- when restoring the
+ // pointer, we can always look -8 bytes from the current position to get
+ // either of the values we've stashed in the first place.
+ pushq %rsp
+ pushq (%rsp)
+ andq $-0x10, %rsp
callq *%rax
+ movq 8(%rsp), %rsp
.LcustomEventCleanup:
- movq 0(%rsp), %rax
- movq 8(%rsp), %rbp
- addq $16, %rsp
- .cfi_def_cfa_offset 8
+ RESTORE_REGISTERS
retq
.Ltmp8:
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=311524&r1=311523&r2=311524&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_x86_64.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_x86_64.cc Tue Aug 22 21:42:37 2017
@@ -76,6 +76,7 @@ static constexpr uint8_t CallOpCode = 0x
static constexpr uint16_t MovR10Seq = 0xba41;
static constexpr uint16_t Jmp9Seq = 0x09eb;
static constexpr uint16_t Jmp20Seq = 0x14eb;
+static constexpr uint16_t Jmp15Seq = 0x0feb;
static constexpr uint8_t JmpOpCode = 0xe9;
static constexpr uint8_t RetOpCode = 0xc3;
static constexpr uint16_t NopwSeq = 0x9066;
@@ -207,8 +208,10 @@ bool patchCustomEvent(const bool Enable,
const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
// Here we do the dance of replacing the following sled:
//
+ // In Version 0:
+ //
// xray_sled_n:
- // jmp +19 // 2 bytes
+ // jmp +20 // 2 bytes
// ...
//
// With the following:
@@ -216,24 +219,35 @@ bool patchCustomEvent(const bool Enable,
// nopw // 2 bytes*
// ...
//
- // We need to do this in the following order:
//
- // 1. Overwrite the 5-byte nop with the call (relative), where (relative) is
- // the relative offset to the __xray_CustomEvent trampoline.
- // 2. Do a two-byte atomic write over the 'jmp +24' to turn it into a 'nopw'.
- // This allows us to "enable" this code once the changes have committed.
+ // The "unpatch" should just turn the 'nopw' back to a 'jmp +20'.
+ //
+ // ---
+ //
+ // In Version 1:
//
- // The "unpatch" should just turn the 'nopw' back to a 'jmp +24'.
+ // The jump offset is now 15 bytes (0x0f), so when restoring the nopw back
+ // to a jmp, use 15 bytes instead.
//
if (Enable) {
std::atomic_store_explicit(
reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), NopwSeq,
std::memory_order_release);
} else {
- std::atomic_store_explicit(
- reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp20Seq,
- std::memory_order_release);
- }
+ switch (Sled.Version) {
+ case 1:
+ std::atomic_store_explicit(
+ reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp15Seq,
+ std::memory_order_release);
+ break;
+ case 0:
+ default:
+ std::atomic_store_explicit(
+ reinterpret_cast<std::atomic<uint16_t> *>(Sled.Address), Jmp20Seq,
+ std::memory_order_release);
+ break;
+ }
+ }
return false;
}
Added: compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-handler-alignment.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-handler-alignment.cc?rev=311524&view=auto
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-handler-alignment.cc (added)
+++ compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-handler-alignment.cc Tue Aug 22 21:42:37 2017
@@ -0,0 +1,42 @@
+// Make sure we're aligning the stack properly when lowering the custom event
+// calls.
+//
+// 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: built-in-llvm-tree
+#include <xmmintrin.h>
+#include <stdio.h>
+#include "xray/xray_interface.h"
+
+[[clang::xray_never_instrument]] __attribute__((weak)) __m128 f(__m128 *i) {
+ return *i;
+}
+
+[[clang::xray_always_instrument]] void foo() {
+ __xray_customevent(0, 0);
+ __m128 v = {};
+ f(&v);
+}
+
+[[clang::xray_always_instrument]] void bar() {
+ __xray_customevent(0, 0);
+}
+
+void printer(void* ptr, size_t size) {
+ printf("handler called\n");
+ __m128 v = {};
+ f(&v);
+}
+
+int main(int argc, char* argv[]) {
+ __xray_set_customevent_handler(printer);
+ __xray_patch();
+ foo(); // CHECK: handler called
+ bar(); // CHECK: handler called
+ __xray_unpatch();
+ __xray_remove_customevent_handler();
+ foo();
+ bar();
+}
Modified: compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-logging.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-logging.cc?rev=311524&r1=311523&r2=311524&view=diff
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-logging.cc (original)
+++ compiler-rt/trunk/test/xray/TestCases/Linux/custom-event-logging.cc Tue Aug 22 21:42:37 2017
@@ -2,6 +2,8 @@
//
// RUN: %clangxx_xray -std=c++11 %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
+// 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: built-in-llvm-tree
More information about the llvm-commits
mailing list