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
20bool __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
49bool __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
77bool __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
83bool __xray::patchCustomEvent(const bool Enable, const uint32_t FuncId,
84 const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
85 // TODO Implement.
86 return false;
87}
88
89bool __xray::patchTypedEvent(const bool Enable, const uint32_t FuncId,
90 const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
91 // TODO Implement.
92 return false;
93}
94
95extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {
96 // TODO this will have to be implemented in the trampoline assembly file.
97}
98
99extern "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

source code of compiler-rt/lib/xray/xray_s390x.cpp