Skip to content

Commit db1882e

Browse files
authored
[SystemZ][XRay] XRay runtime support for SystemZ (#113252)
Adds the runtime support routines for XRay on SystemZ. Only function entry/exit is implemented.
1 parent 8b65973 commit db1882e

File tree

7 files changed

+302
-1
lines changed

7 files changed

+302
-1
lines changed

compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ if(APPLE)
102102
set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM64})
103103
else()
104104
set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64}
105-
powerpc64le ${HEXAGON} ${LOONGARCH64})
105+
powerpc64le ${HEXAGON} ${LOONGARCH64} ${S390X})
106106
endif()
107107
set(ALL_XRAY_DSO_SUPPORTED_ARCH ${X86_64})
108108
set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64})

compiler-rt/lib/xray/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ set(hexagon_SOURCES
9292
xray_trampoline_hexagon.S
9393
)
9494

95+
set(s390x_SOURCES
96+
xray_s390x.cpp
97+
xray_trampoline_s390x.S
98+
)
99+
# Enable vector instructions in the assembly file.
100+
set_source_files_properties(xray_trampoline_s390x.S PROPERTIES COMPILE_FLAGS -mvx)
101+
95102
set(XRAY_SOURCE_ARCHS
96103
arm
97104
armhf
@@ -102,6 +109,7 @@ set(XRAY_SOURCE_ARCHS
102109
mips64
103110
mips64el
104111
powerpc64le
112+
s390x
105113
x86_64
106114
)
107115

@@ -152,6 +160,7 @@ set(XRAY_ALL_SOURCE_FILES
152160
${mips64_SOURCES}
153161
${mips64el_SOURCES}
154162
${powerpc64le_SOURCES}
163+
${s390x_SOURCES}
155164
${XRAY_IMPL_HEADERS}
156165
)
157166
list(REMOVE_DUPLICATES XRAY_ALL_SOURCE_FILES)

compiler-rt/lib/xray/xray_interface.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ static const int16_t cSledLength = 64;
5757
static const int16_t cSledLength = 8;
5858
#elif defined(__hexagon__)
5959
static const int16_t cSledLength = 20;
60+
#elif defined(__s390x__)
61+
static const int16_t cSledLength = 18;
6062
#else
6163
#error "Unsupported CPU Architecture"
6264
#endif /* CPU architecture */

compiler-rt/lib/xray/xray_interface_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ extern void __xray_FunctionTailExit();
2929
extern void __xray_ArgLoggerEntry();
3030
extern void __xray_CustomEvent();
3131
extern void __xray_TypedEvent();
32+
#if defined(__s390x__)
33+
extern void __xray_FunctionEntryVec();
34+
extern void __xray_FunctionExitVec();
35+
#endif
3236
}
3337

3438
extern "C" {

compiler-rt/lib/xray/xray_s390x.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
20+
bool __xray::patchFunctionEntry(const bool Enable, uint32_t FuncId,
21+
const XRaySledEntry &Sled,
22+
void (*Trampoline)()) XRAY_NEVER_INSTRUMENT {
23+
uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address());
24+
if (Enable) {
25+
// The resulting code is:
26+
// stmg %r2, %r15, 16(%r15)
27+
// llilf %2, FuncID
28+
// brasl %r14, __xray_FunctionEntry@GOT
29+
// The FuncId and the stmg instruction must be written.
30+
31+
// Write FuncId into llilf.
32+
Address[2] = FuncId;
33+
// Write last part of stmg.
34+
reinterpret_cast<uint16_t *>(Address)[2] = 0x24;
35+
// Write first part of stmg.
36+
Address[0] = 0xeb2ff010;
37+
} else {
38+
// j +16 instructions.
39+
Address[0] = 0xa7f4000b;
40+
}
41+
return true;
42+
}
43+
44+
bool __xray::patchFunctionExit(const bool Enable, uint32_t FuncId,
45+
const XRaySledEntry &Sled)
46+
XRAY_NEVER_INSTRUMENT {
47+
uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address());
48+
if (Enable) {
49+
// The resulting code is:
50+
// stmg %r2, %r15, 24(%r15)
51+
// llilf %2,FuncID
52+
// j __xray_FunctionEntry@GOT
53+
// The FuncId and the stmg instruction must be written.
54+
55+
// Write FuncId into llilf.
56+
Address[2] = FuncId;
57+
// Write last part of of stmg.
58+
reinterpret_cast<uint16_t *>(Address)[2] = 0x24;
59+
// Write first part of stmg.
60+
Address[0] = 0xeb2ff010;
61+
} else {
62+
// br %14 instruction.
63+
reinterpret_cast<uint16_t *>(Address)[0] = 0x07fe;
64+
}
65+
return true;
66+
}
67+
68+
bool __xray::patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
69+
const XRaySledEntry &Sled)
70+
XRAY_NEVER_INSTRUMENT {
71+
return patchFunctionExit(Enable, FuncId, Sled);
72+
}
73+
74+
bool __xray::patchCustomEvent(const bool Enable, const uint32_t FuncId,
75+
const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
76+
// TODO Implement.
77+
return false;
78+
}
79+
80+
bool __xray::patchTypedEvent(const bool Enable, const uint32_t FuncId,
81+
const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
82+
// TODO Implement.
83+
return false;
84+
}
85+
86+
extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {
87+
// TODO this will have to be implemented in the trampoline assembly file.
88+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
//===-- xray_trampoline_s390x.s ---------------------------------*- ASM -*-===//
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+
// This implements the s390x-specific assembler for the trampolines.
12+
// 2 versions of the functions are provided: one which does not store the
13+
// vector registers, and one which does store them. The compiler decides
14+
// which to call based on the availability of the vector extension.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
.text
19+
20+
// Minimal stack frame size
21+
#define STACKSZ 160
22+
23+
// Minimal stack frame size (160) plus space for 8 vector registers a 16 bytes.
24+
#define STACKSZ_VEC 288
25+
26+
//===----------------------------------------------------------------------===//
27+
28+
.globl __xray_FunctionEntry
29+
.p2align 4
30+
.type __xray_FunctionEntry,@function
31+
__xray_FunctionEntry:
32+
# The registers r2-15 of the instrumented function are already saved in the
33+
# stack frame. On entry, r2 contains the function id, and %r14 the address
34+
# of the first instruction of the instrumented function.
35+
# Register r14 will be stored in the slot reserved for compiler use.
36+
stg %r14, 8(%r15)
37+
std %f0, 128(%r15)
38+
std %f2, 136(%r15)
39+
std %f4, 144(%r15)
40+
std %f6, 152(%r15)
41+
aghi %r15, -STACKSZ
42+
43+
lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT
44+
ltg %r1, 0(%r1)
45+
je .Lrestore0
46+
47+
# Set r3 to XRayEntryType::ENTRY = 0.
48+
# The FuncId is still stored in r2.
49+
lghi %r3, 0
50+
basr %r14, %r1
51+
52+
.Lrestore0:
53+
ld %f6, STACKSZ+152(%r15)
54+
ld %f4, STACKSZ+144(%r15)
55+
ld %f2, STACKSZ+136(%r15)
56+
ld %f0, STACKSZ+128(%r15)
57+
lmg %r1, %r15, STACKSZ+8(%r15)
58+
br %r1
59+
.Lfunc_end0:
60+
.size __xray_FunctionEntry, .Lfunc_end0-__xray_FunctionEntry
61+
62+
//===----------------------------------------------------------------------===//
63+
64+
.globl __xray_FunctionEntryVec
65+
.p2align 4
66+
.type __xray_FunctionEntryVec,@function
67+
__xray_FunctionEntryVec:
68+
# The registers r2-15 of the instrumented function are already saved in the
69+
# stack frame. On entry, r2 contains the function id, and %r14 the address
70+
# of the first instruction of the instrumented function.
71+
# Register r14 will be stored in the slot reserved for compiler use.
72+
stg %r14, 8(%r15)
73+
std %f0, 128(%r15)
74+
std %f2, 136(%r15)
75+
std %f4, 144(%r15)
76+
std %f6, 152(%r15)
77+
aghi %r15, -STACKSZ_VEC
78+
vstm %v24, %v31, 160(%r15)
79+
80+
lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT
81+
ltg %r1, 0(%r1)
82+
je .Lrestore1
83+
84+
# Set r3 to XRayEntryType::ENTRY = 0.
85+
# The FuncId is still stored in r2.
86+
lghi %r3, 0
87+
basr %r14, %r1
88+
89+
.Lrestore1:
90+
vlm %v24, %v31, 160(%r15)
91+
ld %f6, STACKSZ_VEC+152(%r15)
92+
ld %f4, STACKSZ_VEC+144(%r15)
93+
ld %f2, STACKSZ_VEC+136(%r15)
94+
ld %f0, STACKSZ_VEC+128(%r15)
95+
lmg %r1, %r15, STACKSZ_VEC+8(%r15)
96+
br %r1
97+
.Lfunc_end1:
98+
.size __xray_FunctionEntryVec, .Lfunc_end1-__xray_FunctionEntryVec
99+
100+
//===----------------------------------------------------------------------===//
101+
102+
.globl __xray_FunctionExit
103+
.p2align 4
104+
.type __xray_FunctionExit,@function
105+
__xray_FunctionExit:
106+
# The registers r2-15 of the instrumented function are already saved in the
107+
# stack frame. On entry, the register r2 contains the function id.
108+
# At the end, the function jumps to the address saved in the slot for r14,
109+
# which contains the return address into the caller of the instrumented
110+
# function.
111+
std %f0, 128(%r15)
112+
std %f2, 136(%r15)
113+
std %f4, 144(%r15)
114+
std %f6, 152(%r15)
115+
aghi %r15, -STACKSZ
116+
117+
lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT
118+
ltg %r1, 0(%r1)
119+
je .Lrestore2
120+
121+
# Set r3 to XRayEntryType::EXIT = 1.
122+
# The FuncId is still stored in r2.
123+
lghi %r3, 1
124+
basr %r14, %r1
125+
126+
.Lrestore2:
127+
ld %f6, STACKSZ+152(%r15)
128+
ld %f4, STACKSZ+144(%r15)
129+
ld %f2, STACKSZ+136(%r15)
130+
ld %f0, STACKSZ+128(%r15)
131+
lmg %r2, %r15, STACKSZ+16(%r15)
132+
br %r14
133+
.Lfunc_end2:
134+
.size __xray_FunctionExit, .Lfunc_end2-__xray_FunctionExit
135+
136+
//===----------------------------------------------------------------------===//
137+
138+
.globl __xray_FunctionExitVec
139+
.p2align 4
140+
.type __xray_FunctionExitVec,@function
141+
__xray_FunctionExitVec:
142+
# The registers r2-15 of the instrumented function are already saved in the
143+
# stack frame. On entry, the register r2 contains the function id.
144+
# At the end, the function jumps to the address saved in the slot for r14,
145+
# which contains the return address into the caller of the instrumented
146+
# function.
147+
std %f0, 128(%r15)
148+
std %f2, 136(%r15)
149+
std %f4, 144(%r15)
150+
std %f6, 152(%r15)
151+
aghi %r15, -STACKSZ_VEC
152+
vstm %v24, %v31, 160(%r15)
153+
154+
lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT
155+
ltg %r1, 0(%r1)
156+
je .Lrestore3
157+
158+
# Set r3 to XRayEntryType::EXIT = 1.
159+
# The FuncId is still stored in r2.
160+
lghi %r3, 1
161+
basr %r14, %r1
162+
163+
.Lrestore3:
164+
vlm %v24, %v31, 160(%r15)
165+
ld %f6, STACKSZ_VEC+152(%r15)
166+
ld %f4, STACKSZ_VEC+144(%r15)
167+
ld %f2, STACKSZ_VEC+136(%r15)
168+
ld %f0, STACKSZ_VEC+128(%r15)
169+
lmg %r2, %r15, STACKSZ_VEC+16(%r15)
170+
br %r14
171+
.Lfunc_end3:
172+
.size __xray_FunctionExit, .Lfunc_end3-__xray_FunctionExit
173+
174+
//===----------------------------------------------------------------------===//
175+
176+
.section ".note.GNU-stack","",@progbits

compiler-rt/lib/xray/xray_tsc.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,28 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
8383

8484
} // namespace __xray
8585

86+
#elif defined(__s390x__)
87+
#include "sanitizer_common/sanitizer_common.h"
88+
#include "sanitizer_common/sanitizer_internal_defs.h"
89+
#include "xray_defs.h"
90+
#include <cerrno>
91+
#include <cstdint>
92+
#include <time.h>
93+
94+
namespace __xray {
95+
96+
inline bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; }
97+
98+
ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
99+
return __builtin_readcyclecounter();
100+
}
101+
102+
inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
103+
return NanosecondsPerSecond;
104+
}
105+
106+
} // namespace __xray
107+
86108
#else
87109
#error Target architecture is not supported.
88110
#endif // CPU architecture

0 commit comments

Comments
 (0)