xref: /freebsd/contrib/llvm-project/compiler-rt/lib/xray/xray_s390x.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- xray_s390x.cpp ------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of XRay, a dynamic runtime instrumentation system.
10 //
11 // Implementation of s390x routines.
12 //
13 //===----------------------------------------------------------------------===//
14 #include "sanitizer_common/sanitizer_common.h"
15 #include "xray_defs.h"
16 #include "xray_interface_internal.h"
17 #include <cassert>
18 #include <cstring>
19 
patchFunctionEntry(const bool Enable,const uint32_t FuncId,const XRaySledEntry & Sled,const XRayTrampolines & Trampolines,bool LogArgs)20 bool __xray::patchFunctionEntry(const bool Enable, const uint32_t FuncId,
21                                 const XRaySledEntry &Sled,
22                                 const XRayTrampolines &Trampolines,
23                                 bool LogArgs) XRAY_NEVER_INSTRUMENT {
24   uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address());
25   // TODO: Trampoline addresses are currently inserted at compile-time, using
26   //       __xray_FunctionEntry and __xray_FunctionExit only.
27   //       To support DSO instrumentation, trampolines have to be written during
28   //       patching (see implementation on X86_64, e.g.).
29   if (Enable) {
30     // The resulting code is:
31     //   stmg    %r2, %r15, 16(%r15)
32     //   llilf   %2, FuncID
33     //   brasl   %r14, __xray_FunctionEntry@GOT
34     // The FuncId and the stmg instruction must be written.
35 
36     // Write FuncId into llilf.
37     Address[2] = FuncId;
38     // Write last part of stmg.
39     reinterpret_cast<uint16_t *>(Address)[2] = 0x24;
40     // Write first part of stmg.
41     Address[0] = 0xeb2ff010;
42   } else {
43     // j +16 instructions.
44     Address[0] = 0xa7f4000b;
45   }
46   return true;
47 }
48 
patchFunctionExit(const bool Enable,const uint32_t FuncId,const XRaySledEntry & Sled,const XRayTrampolines & Trampolines)49 bool __xray::patchFunctionExit(
50     const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled,
51     const XRayTrampolines &Trampolines) XRAY_NEVER_INSTRUMENT {
52   uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address());
53   // TODO: Trampoline addresses are currently inserted at compile-time, using
54   //       __xray_FunctionEntry and __xray_FunctionExit only.
55   //       To support DSO instrumentation, trampolines have to be written during
56   //       patching (see implementation on X86_64, e.g.).
57   if (Enable) {
58     // The resulting code is:
59     //   stmg    %r2, %r15, 24(%r15)
60     //   llilf   %2,FuncID
61     //   j       __xray_FunctionEntry@GOT
62     // The FuncId and the stmg instruction must be written.
63 
64     // Write FuncId into llilf.
65     Address[2] = FuncId;
66     // Write last part of of stmg.
67     reinterpret_cast<uint16_t *>(Address)[2] = 0x24;
68     // Write first part of stmg.
69     Address[0] = 0xeb2ff010;
70   } else {
71     // br %14 instruction.
72     reinterpret_cast<uint16_t *>(Address)[0] = 0x07fe;
73   }
74   return true;
75 }
76 
patchFunctionTailExit(const bool Enable,const uint32_t FuncId,const XRaySledEntry & Sled,const XRayTrampolines & Trampolines)77 bool __xray::patchFunctionTailExit(
78     const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled,
79     const XRayTrampolines &Trampolines) XRAY_NEVER_INSTRUMENT {
80   return patchFunctionExit(Enable, FuncId, Sled, Trampolines);
81 }
82 
patchCustomEvent(const bool Enable,const uint32_t FuncId,const XRaySledEntry & Sled)83 bool __xray::patchCustomEvent(const bool Enable, const uint32_t FuncId,
84                               const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
85   // TODO Implement.
86   return false;
87 }
88 
patchTypedEvent(const bool Enable,const uint32_t FuncId,const XRaySledEntry & Sled)89 bool __xray::patchTypedEvent(const bool Enable, const uint32_t FuncId,
90                              const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
91   // TODO Implement.
92   return false;
93 }
94 
__xray_ArgLoggerEntry()95 extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {
96   // TODO this will have to be implemented in the trampoline assembly file.
97 }
98 
__xray_FunctionTailExit()99 extern "C" void __xray_FunctionTailExit() XRAY_NEVER_INSTRUMENT {
100   // For PowerPC, calls to __xray_FunctionEntry and __xray_FunctionExit
101   // are statically inserted into the sled. Tail exits are handled like normal
102   // function exits. This trampoline is therefore not implemented.
103   // This stub is placed here to avoid linking issues.
104 }
105