[compiler-rt] r295166 - [Compiler-rt][XRAY][MIPS] Support xray on mips/mipsel/mips64/mips64el

Sagar Thakur via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 15 02:54:09 PST 2017


Author: slthakur
Date: Wed Feb 15 04:54:09 2017
New Revision: 295166

URL: http://llvm.org/viewvc/llvm-project?rev=295166&view=rev
Log:
[Compiler-rt][XRAY][MIPS] Support xray on mips/mipsel/mips64/mips64el

Summary: Adds support for xray on mips/mipsel/mips64/mips64el.

Reviewed by sdardis, dberris
Differential: D27699

Added:
    compiler-rt/trunk/lib/xray/xray_mips.cc
    compiler-rt/trunk/lib/xray/xray_mips64.cc
    compiler-rt/trunk/lib/xray/xray_trampoline_mips.S
    compiler-rt/trunk/lib/xray/xray_trampoline_mips64.S
    compiler-rt/trunk/test/xray/TestCases/Linux/pic_test.cc
Modified:
    compiler-rt/trunk/cmake/config-ix.cmake
    compiler-rt/trunk/lib/xray/CMakeLists.txt
    compiler-rt/trunk/lib/xray/tests/CMakeLists.txt
    compiler-rt/trunk/lib/xray/xray_interface.cc
    compiler-rt/trunk/lib/xray/xray_tsc.h

Modified: compiler-rt/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=295166&r1=295165&r2=295166&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake (original)
+++ compiler-rt/trunk/cmake/config-ix.cmake Wed Feb 15 04:54:09 2017
@@ -183,7 +183,7 @@ set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86}
 set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64})
 set(ALL_ESAN_SUPPORTED_ARCH ${X86_64} ${MIPS64})
 set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64})
-set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64})
+set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64})
 
 if(APPLE)
   include(CompilerRTDarwinUtils)

Modified: compiler-rt/trunk/lib/xray/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/CMakeLists.txt?rev=295166&r1=295165&r2=295166&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/xray/CMakeLists.txt Wed Feb 15 04:54:09 2017
@@ -29,6 +29,26 @@ set(aarch64_SOURCES
   xray_trampoline_AArch64.S
   ${XRAY_SOURCES})
 
+set(mips_SOURCES
+    xray_mips.cc
+    xray_trampoline_mips.S
+    ${XRAY_SOURCES})
+
+set(mipsel_SOURCES
+    xray_mips.cc
+    xray_trampoline_mips.S
+    ${XRAY_SOURCES})
+
+set(mips64_SOURCES
+    xray_mips64.cc
+    xray_trampoline_mips64.S
+    ${XRAY_SOURCES})
+
+set(mips64el_SOURCES
+    xray_mips64.cc
+    xray_trampoline_mips64.S
+    ${XRAY_SOURCES})
+
 include_directories(..)
 include_directories(../../include)
 

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=295166&r1=295165&r2=295166&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/xray/tests/CMakeLists.txt Wed Feb 15 04:54:09 2017
@@ -42,7 +42,7 @@ macro(add_xray_unittest testname)
         list(APPEND TEST_DEPS gtest_main xray)
       endif()
       if(NOT APPLE)
-        add_compiler_rt_test(XRayUnitTests ${testname}
+        add_compiler_rt_test(XRayUnitTests ${testname}-${arch}
           OBJECTS ${TEST_OBJECTS}
           DEPS ${TEST_DEPS}
           LINK_FLAGS ${TARGET_LINK_FLAGS}

Modified: compiler-rt/trunk/lib/xray/xray_interface.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_interface.cc?rev=295166&r1=295165&r2=295166&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_interface.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_interface.cc Wed Feb 15 04:54:09 2017
@@ -35,6 +35,10 @@ static const int16_t cSledLength = 12;
 static const int16_t cSledLength = 32;
 #elif defined(__arm__)
 static const int16_t cSledLength = 28;
+#elif SANITIZER_MIPS32
+static const int16_t cSledLength = 48;
+#elif SANITIZER_MIPS64
+static const int16_t cSledLength = 64;
 #else
 #error "Unsupported CPU Architecture"
 #endif /* CPU architecture */

Added: compiler-rt/trunk/lib/xray/xray_mips.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_mips.cc?rev=295166&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_mips.cc (added)
+++ compiler-rt/trunk/lib/xray/xray_mips.cc Wed Feb 15 04:54:09 2017
@@ -0,0 +1,153 @@
+//===-- xray_mips.cc --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// Implementation of MIPS-specific routines (32-bit).
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
+#include "xray_interface_internal.h"
+#include <atomic>
+
+namespace __xray {
+
+// The machine codes for some instructions used in runtime patching.
+enum PatchOpcodes : uint32_t {
+  PO_ADDIU = 0x24000000, // addiu rt, rs, imm
+  PO_SW = 0xAC000000,    // sw rt, offset(sp)
+  PO_LUI = 0x3C000000,   // lui rs, %hi(address)
+  PO_ORI = 0x34000000,   // ori rt, rs, %lo(address)
+  PO_JALR = 0x0000F809,  // jalr rs
+  PO_LW = 0x8C000000,    // lw rt, offset(address)
+  PO_B44 = 0x1000000b,   // b #44
+  PO_NOP = 0x0,          // nop
+};
+
+enum RegNum : uint32_t {
+  RN_T0 = 0x8,
+  RN_T9 = 0x19,
+  RN_RA = 0x1F,
+  RN_SP = 0x1D,
+};
+
+inline static uint32_t encodeInstruction(uint32_t Opcode, uint32_t Rs,
+                                         uint32_t Rt,
+                                         uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+  return (Opcode | Rs << 21 | Rt << 16 | Imm);
+}
+
+inline static uint32_t
+encodeSpecialInstruction(uint32_t Opcode, uint32_t Rs, uint32_t Rt, uint32_t Rd,
+                         uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+  return (Rs << 21 | Rt << 16 | Rd << 11 | Imm << 6 | Opcode);
+}
+
+inline static bool patchSled(const bool Enable, const uint32_t FuncId,
+                             const XRaySledEntry &Sled,
+                             void (*TracingHook)()) XRAY_NEVER_INSTRUMENT {
+  // When |Enable| == true,
+  // We replace the following compile-time stub (sled):
+  //
+  // xray_sled_n:
+  //	B .tmpN
+  //	11 NOPs (44 bytes)
+  //	.tmpN
+  //	ADDIU T9, T9, 44
+  //
+  // With the following runtime patch:
+  //
+  // xray_sled_n (32-bit):
+  //    addiu sp, sp, -8                        ;create stack frame
+  //    nop
+  //    sw ra, 4(sp)                            ;save return address
+  //    sw t9, 0(sp)                            ;save register t9
+  //    lui t9, %hi(__xray_FunctionEntry/Exit)
+  //    ori t9, t9, %lo(__xray_FunctionEntry/Exit)
+  //    lui t0, %hi(function_id)
+  //    jalr t9                                 ;call Tracing hook
+  //    ori t0, t0, %lo(function_id)            ;pass function id (delay slot)
+  //    lw t9, 0(sp)                            ;restore register t9
+  //    lw ra, 4(sp)                            ;restore return address
+  //    addiu sp, sp, 8                         ;delete stack frame
+  //
+  // We add 44 bytes to t9 because we want to adjust the function pointer to
+  // the actual start of function i.e. the address just after the noop sled.
+  // We do this because gp displacement relocation is emitted at the start of
+  // of the function i.e after the nop sled and to correctly calculate the
+  // global offset table address, t9 must hold the address of the instruction
+  // containing the gp displacement relocation.
+  // FIXME: Is this correct for the static relocation model?
+  //
+  // Replacement of the first 4-byte instruction should be the last and atomic
+  // operation, so that the user code which reaches the sled concurrently
+  // either jumps over the whole sled, or executes the whole sled when the
+  // latter is ready.
+  //
+  // When |Enable|==false, we set back the first instruction in the sled to be
+  //   B #44
+
+  if (Enable) {
+    uint32_t LoTracingHookAddr = reinterpret_cast<int32_t>(TracingHook) & 0xffff;
+    uint32_t HiTracingHookAddr =
+        (reinterpret_cast<int32_t>(TracingHook) >> 16) & 0xffff;
+    uint32_t LoFunctionID = FuncId & 0xffff;
+    uint32_t HiFunctionID = (FuncId >> 16) & 0xffff;
+    *reinterpret_cast<uint32_t *>(Sled.Address + 8) = encodeInstruction(
+        PatchOpcodes::PO_SW, RegNum::RN_SP, RegNum::RN_RA, 0x4);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 12) = encodeInstruction(
+        PatchOpcodes::PO_SW, RegNum::RN_SP, RegNum::RN_T9, 0x0);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 16) = encodeInstruction(
+        PatchOpcodes::PO_LUI, 0x0, RegNum::RN_T9, HiTracingHookAddr);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 20) = encodeInstruction(
+        PatchOpcodes::PO_ORI, RegNum::RN_T9, RegNum::RN_T9, LoTracingHookAddr);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 24) = encodeInstruction(
+        PatchOpcodes::PO_LUI, 0x0, RegNum::RN_T0, HiFunctionID);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 28) = encodeSpecialInstruction(
+        PatchOpcodes::PO_JALR, RegNum::RN_T9, 0x0, RegNum::RN_RA, 0X0);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 32) = encodeInstruction(
+        PatchOpcodes::PO_ORI, RegNum::RN_T0, RegNum::RN_T0, LoFunctionID);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 36) = encodeInstruction(
+        PatchOpcodes::PO_LW, RegNum::RN_SP, RegNum::RN_T9, 0x0);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 40) = encodeInstruction(
+        PatchOpcodes::PO_LW, RegNum::RN_SP, RegNum::RN_RA, 0x4);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 44) = encodeInstruction(
+        PatchOpcodes::PO_ADDIU, RegNum::RN_SP, RegNum::RN_SP, 0x8);
+    uint32_t CreateStackSpaceInstr = encodeInstruction(
+        PatchOpcodes::PO_ADDIU, RegNum::RN_SP, RegNum::RN_SP, 0xFFF8);
+    std::atomic_store_explicit(
+        reinterpret_cast<std::atomic<uint32_t> *>(Sled.Address),
+        uint32_t(CreateStackSpaceInstr), std::memory_order_release);
+  } else {
+    std::atomic_store_explicit(
+        reinterpret_cast<std::atomic<uint32_t> *>(Sled.Address),
+        uint32_t(PatchOpcodes::PO_B44), std::memory_order_release);
+  }
+  return true;
+}
+
+bool patchFunctionEntry(const bool Enable, const uint32_t FuncId,
+                        const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionEntry);
+}
+
+bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
+                       const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
+                           const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  // FIXME: In the future we'd need to distinguish between non-tail exits and
+  // tail exits for better information preservation.
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+} // namespace __xray

Added: compiler-rt/trunk/lib/xray/xray_mips64.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_mips64.cc?rev=295166&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_mips64.cc (added)
+++ compiler-rt/trunk/lib/xray/xray_mips64.cc Wed Feb 15 04:54:09 2017
@@ -0,0 +1,162 @@
+//===-- xray_mips64.cc ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// Implementation of MIPS64-specific routines.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
+#include "xray_interface_internal.h"
+#include <atomic>
+
+namespace __xray {
+
+// The machine codes for some instructions used in runtime patching.
+enum PatchOpcodes : uint32_t {
+  PO_DADDIU = 0x64000000, // daddiu rt, rs, imm
+  PO_SD = 0xFC000000,     // sd rt, base(offset)
+  PO_LUI = 0x3C000000,    // lui rt, imm
+  PO_ORI = 0x34000000,    // ori rt, rs, imm
+  PO_DSLL = 0x00000038,   // dsll rd, rt, sa
+  PO_JALR = 0x00000009,   // jalr rs
+  PO_LD = 0xDC000000,     // ld rt, base(offset)
+  PO_B60 = 0x1000000f,    // b #60
+  PO_NOP = 0x0,           // nop
+};
+
+enum RegNum : uint32_t {
+  RN_T0 = 0xC,
+  RN_T9 = 0x19,
+  RN_RA = 0x1F,
+  RN_SP = 0x1D,
+};
+
+inline static uint32_t encodeInstruction(uint32_t Opcode, uint32_t Rs,
+                                         uint32_t Rt,
+                                         uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+  return (Opcode | Rs << 21 | Rt << 16 | Imm);
+}
+
+inline static uint32_t
+encodeSpecialInstruction(uint32_t Opcode, uint32_t Rs, uint32_t Rt, uint32_t Rd,
+                         uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+  return (Rs << 21 | Rt << 16 | Rd << 11 | Imm << 6 | Opcode);
+}
+
+inline static bool patchSled(const bool Enable, const uint32_t FuncId,
+                             const XRaySledEntry &Sled,
+                             void (*TracingHook)()) XRAY_NEVER_INSTRUMENT {
+  // When |Enable| == true,
+  // We replace the following compile-time stub (sled):
+  //
+  // xray_sled_n:
+  //	B .tmpN
+  //	15 NOPs (60 bytes)
+  //	.tmpN
+  //
+  // With the following runtime patch:
+  //
+  // xray_sled_n (64-bit):
+  //    daddiu sp, sp, -16                      ;create stack frame
+  //    nop
+  //    sd ra, 8(sp)                            ;save return address
+  //    sd t9, 0(sp)                            ;save register t9
+  //    lui t9, %highest(__xray_FunctionEntry/Exit)
+  //    ori t9, t9, %higher(__xray_FunctionEntry/Exit)
+  //    dsll t9, t9, 16
+  //    ori t9, t9, %hi(__xray_FunctionEntry/Exit)
+  //    dsll t9, t9, 16
+  //    ori t9, t9, %lo(__xray_FunctionEntry/Exit)
+  //    lui t0, %hi(function_id)
+  //    jalr t9                                 ;call Tracing hook
+  //    ori t0, t0, %lo(function_id)            ;pass function id (delay slot)
+  //    ld t9, 0(sp)                            ;restore register t9
+  //    ld ra, 8(sp)                            ;restore return address
+  //    daddiu sp, sp, 16                       ;delete stack frame
+  //
+  // Replacement of the first 4-byte instruction should be the last and atomic
+  // operation, so that the user code which reaches the sled concurrently
+  // either jumps over the whole sled, or executes the whole sled when the
+  // latter is ready.
+  //
+  // When |Enable|==false, we set back the first instruction in the sled to be
+  //   B #60
+
+  if (Enable) {
+    uint32_t LoTracingHookAddr =
+        reinterpret_cast<int64_t>(TracingHook) & 0xffff;
+    uint32_t HiTracingHookAddr = (reinterpret_cast<int64_t>(TracingHook) >> 16) & 0xffff;
+    uint32_t HigherTracingHookAddr =
+        (reinterpret_cast<int64_t>(TracingHook) >> 32) & 0xffff;
+    uint32_t HighestTracingHookAddr =
+        (reinterpret_cast<int64_t>(TracingHook) >> 48) & 0xffff;
+    uint32_t LoFunctionID = FuncId & 0xffff;
+    uint32_t HiFunctionID = (FuncId >> 16) & 0xffff;
+    *reinterpret_cast<uint32_t *>(Sled.Address + 8) = encodeInstruction(
+        PatchOpcodes::PO_SD, RegNum::RN_SP, RegNum::RN_RA, 0x8);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 12) = encodeInstruction(
+        PatchOpcodes::PO_SD, RegNum::RN_SP, RegNum::RN_T9, 0x0);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 16) = encodeInstruction(
+        PatchOpcodes::PO_LUI, 0x0, RegNum::RN_T9, HighestTracingHookAddr);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 20) =
+        encodeInstruction(PatchOpcodes::PO_ORI, RegNum::RN_T9, RegNum::RN_T9,
+                          HigherTracingHookAddr);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 24) = encodeSpecialInstruction(
+        PatchOpcodes::PO_DSLL, 0x0, RegNum::RN_T9, RegNum::RN_T9, 0x10);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 28) = encodeInstruction(
+        PatchOpcodes::PO_ORI, RegNum::RN_T9, RegNum::RN_T9, HiTracingHookAddr);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 32) = encodeSpecialInstruction(
+        PatchOpcodes::PO_DSLL, 0x0, RegNum::RN_T9, RegNum::RN_T9, 0x10);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 36) = encodeInstruction(
+        PatchOpcodes::PO_ORI, RegNum::RN_T9, RegNum::RN_T9, LoTracingHookAddr);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 40) = encodeInstruction(
+        PatchOpcodes::PO_LUI, 0x0, RegNum::RN_T0, HiFunctionID);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 44) = encodeSpecialInstruction(
+        PatchOpcodes::PO_JALR, RegNum::RN_T9, 0x0, RegNum::RN_RA, 0X0);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 48) = encodeInstruction(
+        PatchOpcodes::PO_ORI, RegNum::RN_T0, RegNum::RN_T0, LoFunctionID);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 52) = encodeInstruction(
+        PatchOpcodes::PO_LD, RegNum::RN_SP, RegNum::RN_T9, 0x0);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 56) = encodeInstruction(
+        PatchOpcodes::PO_LD, RegNum::RN_SP, RegNum::RN_RA, 0x8);
+    *reinterpret_cast<uint32_t *>(Sled.Address + 60) = encodeInstruction(
+        PatchOpcodes::PO_DADDIU, RegNum::RN_SP, RegNum::RN_SP, 0x10);
+    uint32_t CreateStackSpace = encodeInstruction(
+        PatchOpcodes::PO_DADDIU, RegNum::RN_SP, RegNum::RN_SP, 0xfff0);
+    std::atomic_store_explicit(
+        reinterpret_cast<std::atomic<uint32_t> *>(Sled.Address),
+        CreateStackSpace, std::memory_order_release);
+  } else {
+    std::atomic_store_explicit(
+        reinterpret_cast<std::atomic<uint32_t> *>(Sled.Address),
+        uint32_t(PatchOpcodes::PO_B60), std::memory_order_release);
+  }
+  return true;
+}
+
+bool patchFunctionEntry(const bool Enable, const uint32_t FuncId,
+                        const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionEntry);
+}
+
+bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
+                       const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
+                           const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+  // FIXME: In the future we'd need to distinguish between non-tail exits and
+  // tail exits for better information preservation.
+  return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+} // namespace __xray

Added: compiler-rt/trunk/lib/xray/xray_trampoline_mips.S
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_trampoline_mips.S?rev=295166&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_trampoline_mips.S (added)
+++ compiler-rt/trunk/lib/xray/xray_trampoline_mips.S Wed Feb 15 04:54:09 2017
@@ -0,0 +1,110 @@
+//===-- xray_trampoline_mips.s ----------------------------------*- ASM -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// This implements the MIPS-specific assembler for the trampolines.
+//
+//===----------------------------------------------------------------------===//
+
+  .text
+  .file "xray_trampoline_mips.S"
+  .globl __xray_FunctionEntry
+  .p2align 2
+  .type __xray_FunctionEntry, at function
+__xray_FunctionEntry:
+  .cfi_startproc
+  .set noreorder
+  .cpload $t9
+  .set reorder
+  // Save argument registers before doing any actual work
+  .cfi_def_cfa_offset 36
+  addiu  $sp, $sp, -36
+  sw     $ra, 32($sp)
+  .cfi_offset 31, -4
+  sw     $a3, 28($sp)
+  sw     $a2, 24($sp)
+  sw     $a1, 20($sp)
+  sw     $a0, 16($sp)
+  sdc1	 $f14, 8($sp)
+  sdc1	 $f12, 0($sp)
+
+  la     $t9, _ZN6__xray19XRayPatchedFunctionE
+  lw     $t9, 0($t9)
+
+  beqz   $t9, FunctionEntry_restore
+
+  // a1=0 means that we are tracing an entry event
+  move   $a1, $zero
+  // Function ID is in t0 (the first parameter).
+  move   $a0, $t0
+  jalr   $t9
+
+FunctionEntry_restore:
+  // Restore argument registers
+  ldc1   $f12, 0($sp)
+  ldc1   $f14, 8($sp)
+  lw     $a0, 16($sp)
+  lw     $a1, 20($sp)
+  lw     $a2, 24($sp)
+  lw     $a3, 28($sp)
+  lw     $ra, 32($sp)
+  addiu	 $sp, $sp, 36
+  jr     $ra
+FunctionEntry_end:
+  .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry
+  .cfi_endproc
+
+  .text
+  .globl __xray_FunctionExit
+  .p2align 2
+  .type __xray_FunctionExit, at function
+__xray_FunctionExit:
+  .cfi_startproc
+  .set noreorder
+  .cpload $t9
+  .set reorder
+  // Save return registers before doing any actual work.
+  .cfi_def_cfa_offset 36
+  addiu  $sp, $sp, -36
+  sw     $ra, 32($sp)
+  .cfi_offset 31, -4
+  sw     $a1, 28($sp)
+  sw     $a0, 24($sp)
+  sw     $v1, 20($sp)
+  sw     $v0, 16($sp)
+  sdc1   $f2, 8($sp)
+  sdc1   $f0, 0($sp)
+
+  la     $t9, _ZN6__xray19XRayPatchedFunctionE
+  lw     $t9, 0($t9)
+
+  beqz	 $t9, FunctionExit_restore
+
+  // a1=1 means that we are tracing an exit event
+  li     $a1, 1
+  // Function ID is in t0 (the first parameter).
+  move   $a0, $t0
+  jalr   $t9
+
+FunctionExit_restore:
+  // Restore return registers
+  ldc1   $f0, 0($sp)
+  ldc1   $f2, 8($sp)
+  lw     $v0, 16($sp)
+  lw     $v1, 20($sp)
+  lw     $a0, 24($sp)
+  lw     $a1, 28($sp)
+  lw     $ra, 32($sp)
+  addiu  $sp, $sp, 36
+  jr     $ra
+
+FunctionExit_end:
+  .size __xray_FunctionExit, FunctionExit_end-__xray_FunctionExit
+  .cfi_endproc

Added: compiler-rt/trunk/lib/xray/xray_trampoline_mips64.S
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_trampoline_mips64.S?rev=295166&view=auto
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_trampoline_mips64.S (added)
+++ compiler-rt/trunk/lib/xray/xray_trampoline_mips64.S Wed Feb 15 04:54:09 2017
@@ -0,0 +1,136 @@
+//===-- xray_trampoline_mips64.s --------------------------------*- ASM -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// This implements the MIPS64-specific assembler for the trampolines.
+//
+//===----------------------------------------------------------------------===//
+
+  .text
+  .file "xray_trampoline_mips64.S"
+  .globl __xray_FunctionEntry
+  .p2align 2
+  .type __xray_FunctionEntry, at function
+__xray_FunctionEntry:
+  .cfi_startproc
+  // Save argument registers before doing any actual work.
+  .cfi_def_cfa_offset 144
+  daddiu  $sp, $sp, -144
+  sd      $ra, 136($sp)
+  .cfi_offset 31, -8
+  sd      $gp, 128($sp)
+  sd      $a7, 120($sp)
+  sd      $a6, 112($sp)
+  sd      $a5, 104($sp)
+  sd      $a4, 96($sp)
+  sd      $a3, 88($sp)
+  sd      $a2, 80($sp)
+  sd      $a1, 72($sp)
+  sd      $a0, 64($sp)
+  sdc1    $f19, 56($sp)
+  sdc1    $f18, 48($sp)
+  sdc1    $f17, 40($sp)
+  sdc1    $f16, 32($sp)
+  sdc1    $f15, 24($sp)
+  sdc1    $f14, 16($sp)
+  sdc1    $f13, 8($sp)
+  sdc1    $f12, 0($sp)
+
+  lui     $gp, %hi(%neg(%gp_rel(__xray_FunctionEntry)))
+  daddu   $gp, $gp, $t9
+  daddiu  $gp ,$gp, %lo(%neg(%gp_rel(__xray_FunctionEntry)))
+
+  dla     $t9, _ZN6__xray19XRayPatchedFunctionE
+  ld      $t9, 0($t9)
+
+  beqz    $t9, FunctionEntry_restore
+
+  // a1=0 means that we are tracing an entry event
+  move    $a1, $zero
+  // Function ID is in t0 (the first parameter).
+  move    $a0, $t0
+  jalr    $t9
+
+FunctionEntry_restore:
+  // Restore argument registers
+  ldc1    $f12, 0($sp)
+  ldc1    $f13, 8($sp)
+  ldc1    $f14, 16($sp)
+  ldc1    $f15, 24($sp)
+  ldc1    $f16, 32($sp)
+  ldc1    $f17, 40($sp)
+  ldc1    $f18, 48($sp)
+  ldc1    $f19, 56($sp)
+  ld      $a0, 64($sp)
+  ld      $a1, 72($sp)
+  ld      $a2, 80($sp)
+  ld      $a3, 88($sp)
+  ld      $a4, 96($sp)
+  ld      $a5, 104($sp)
+  ld      $a6, 112($sp)
+  ld      $a7, 120($sp)
+  ld      $gp, 128($sp)
+  ld      $ra, 136($sp)
+  daddiu  $sp, $sp, 144
+  jr      $ra
+FunctionEntry_end:
+  .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry
+  .cfi_endproc
+
+  .text
+  .globl __xray_FunctionExit
+  .p2align 2
+  .type __xray_FunctionExit, at function
+__xray_FunctionExit:
+  .cfi_startproc
+  // Save return registers before doing any actual work.
+  .cfi_def_cfa_offset 64
+  daddiu  $sp, $sp, -64
+  sd      $ra, 56($sp)
+  .cfi_offset 31, -8
+  sd      $gp, 48($sp)
+  sd      $a0, 40($sp)
+  sd      $v1, 32($sp)
+  sd      $v0, 24($sp)
+  sdc1    $f2, 16($sp)
+  sdc1    $f1, 8($sp)
+  sdc1    $f0, 0($sp)
+
+  lui     $gp, %hi(%neg(%gp_rel(__xray_FunctionExit)))
+  daddu   $gp, $gp, $t9
+  daddiu  $gp ,$gp, %lo(%neg(%gp_rel(__xray_FunctionExit)))
+
+  dla     $t9, _ZN6__xray19XRayPatchedFunctionE
+  ld      $t9, 0($t9)
+
+  beqz    $t9, FunctionExit_restore
+
+  // a1=1 means that we are tracing an exit event
+  li      $a1, 1
+  // Function ID is in t0 (the first parameter).
+  move    $a0, $t0
+  jalr    $t9
+
+FunctionExit_restore:
+  // Restore return registers
+  ldc1    $f0, 0($sp)
+  ldc1    $f1, 8($sp)
+  ldc1    $f2, 16($sp)
+  ld      $v0, 24($sp)
+  ld      $v1, 32($sp)
+  ld      $a0, 40($sp)
+  ld      $gp, 48($sp)
+  ld      $ra, 56($sp)
+  daddiu  $sp, $sp, 64
+  jr      $ra
+
+FunctionExit_end:
+  .size __xray_FunctionExit, FunctionExit_end-__xray_FunctionExit
+  .cfi_endproc

Modified: compiler-rt/trunk/lib/xray/xray_tsc.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_tsc.h?rev=295166&r1=295165&r2=295166&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_tsc.h (original)
+++ compiler-rt/trunk/lib/xray/xray_tsc.h Wed Feb 15 04:54:09 2017
@@ -15,7 +15,7 @@
 
 #if defined(__x86_64__)
 #include "xray_x86_64.inc"
-#elif defined(__arm__) || defined(__aarch64__)
+#elif defined(__arm__) || defined(__aarch64__) || defined(__mips__)
 // Emulated TSC.
 // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does
 //   not have a constant frequency like TSC on x86(_64), it may go faster

Added: compiler-rt/trunk/test/xray/TestCases/Linux/pic_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Linux/pic_test.cc?rev=295166&view=auto
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Linux/pic_test.cc (added)
+++ compiler-rt/trunk/test/xray/TestCases/Linux/pic_test.cc Wed Feb 15 04:54:09 2017
@@ -0,0 +1,33 @@
+// Test to check if we handle pic code properly.
+
+// RUN: %clangxx_xray -fxray-instrument -std=c++11 -fpic %s -o %t
+// RUN: XRAY_OPTIONS="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-*
+
+#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!
+}




More information about the llvm-commits mailing list