-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SystemZ][XRay] XRay runtime support for SystemZ #113252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-xray @llvm/pr-subscribers-backend-systemz Author: Kai Nacke (redstar) ChangesAdds the runtime support routines for XRay on SystemZ. Only function entry/exit is implemented. Full diff: https://github.com/llvm/llvm-project/pull/113252.diff 6 Files Affected:
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 809e9277156912..bd51db766faab9 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -102,7 +102,7 @@ if(APPLE)
set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM64})
else()
set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64}
- powerpc64le ${HEXAGON} ${LOONGARCH64})
+ powerpc64le ${HEXAGON} ${LOONGARCH64} ${S390X})
endif()
set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64})
diff --git a/compiler-rt/lib/xray/CMakeLists.txt b/compiler-rt/lib/xray/CMakeLists.txt
index cf7b5062aae32d..8e1ef2db2873a8 100644
--- a/compiler-rt/lib/xray/CMakeLists.txt
+++ b/compiler-rt/lib/xray/CMakeLists.txt
@@ -83,6 +83,11 @@ set(hexagon_SOURCES
xray_trampoline_hexagon.S
)
+set(s390x_SOURCES
+ xray_s390x.cpp
+ xray_trampoline_s390x.S
+ )
+
set(XRAY_SOURCE_ARCHS
arm
armhf
@@ -93,6 +98,7 @@ set(XRAY_SOURCE_ARCHS
mips64
mips64el
powerpc64le
+ s390x
x86_64
)
@@ -141,6 +147,7 @@ set(XRAY_ALL_SOURCE_FILES
${mips64_SOURCES}
${mips64el_SOURCES}
${powerpc64le_SOURCES}
+ ${s390x_SOURCES}
${XRAY_IMPL_HEADERS}
)
list(REMOVE_DUPLICATES XRAY_ALL_SOURCE_FILES)
diff --git a/compiler-rt/lib/xray/xray_interface.cpp b/compiler-rt/lib/xray/xray_interface.cpp
index 5839043fcb93a8..fee7dccf695ca0 100644
--- a/compiler-rt/lib/xray/xray_interface.cpp
+++ b/compiler-rt/lib/xray/xray_interface.cpp
@@ -56,6 +56,8 @@ static const int16_t cSledLength = 64;
static const int16_t cSledLength = 8;
#elif defined(__hexagon__)
static const int16_t cSledLength = 20;
+#elif defined(__s390x__)
+static const int16_t cSledLength = 18;
#else
#error "Unsupported CPU Architecture"
#endif /* CPU architecture */
diff --git a/compiler-rt/lib/xray/xray_s390x.cpp b/compiler-rt/lib/xray/xray_s390x.cpp
new file mode 100644
index 00000000000000..135994e54a2d7a
--- /dev/null
+++ b/compiler-rt/lib/xray/xray_s390x.cpp
@@ -0,0 +1,90 @@
+//===-- xray_s390x.cpp ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// Implementation of s390x routines.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
+#include "xray_interface_internal.h"
+#include <cassert>
+#include <cstring>
+
+namespace __xray {
+
+bool patchFunctionEntry(const bool Enable, uint32_t FuncId,
+ const XRaySledEntry &Sled,
+ void (*Trampoline)()) XRAY_NEVER_INSTRUMENT {
+ const uint64_t Address = Sled.address();
+ if (Enable) {
+ // The resulting code is:
+ // stmg %r2, %r15, 16(%r15)
+ // llilf %2, FuncID
+ // brasl %r14, __xray_FunctionEntry@GOT
+ // The FuncId and the stmg instruction must be written.
+
+ // Write FuncId into llilf.
+ reinterpret_cast<uint32_t *>(Address)[2] = FuncId;
+ // Write last part of stmg.
+ reinterpret_cast<uint16_t *>(Address)[2] = 0x24;
+ // Write first part of stmg.
+ reinterpret_cast<uint32_t *>(Address)[0] = 0xeb2ff010;
+ } else {
+ // j +16 instructions.
+ *reinterpret_cast<uint32_t *>(Address) = 0xa7f4000b;
+ }
+ return true;
+}
+
+bool patchFunctionExit(const bool Enable, uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ const uint64_t Address = Sled.address();
+ if (Enable) {
+ // The resulting code is:
+ // stmg %r2, %r15, 24(%r15)
+ // llilf %2,FuncID
+ // j __xray_FunctionEntry@GOT
+ // The FuncId and the stmg instruction must be written.
+
+ // Write FuncId into llilf.
+ reinterpret_cast<uint32_t *>(Address)[2] = FuncId;
+ // Write last part of of stmg.
+ reinterpret_cast<uint16_t *>(Address)[2] = 0x24;
+ // Write first part of stmg.
+ reinterpret_cast<uint32_t *>(Address)[0] = 0xeb2ff010;
+ } else {
+ // br %14 instruction.
+ *reinterpret_cast<uint16_t *>(Address) = 0x07fe;
+ }
+ return true;
+}
+
+bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ return patchFunctionExit(Enable, FuncId, Sled);
+}
+
+bool patchCustomEvent(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ // FIXME: Implement.
+ return false;
+}
+
+bool patchTypedEvent(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ // FIXME: Implement.
+ return false;
+}
+
+} // namespace __xray
+
+extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {
+ // FIXME: this will have to be implemented in the trampoline assembly file.
+}
diff --git a/compiler-rt/lib/xray/xray_trampoline_s390x.S b/compiler-rt/lib/xray/xray_trampoline_s390x.S
new file mode 100644
index 00000000000000..49a290ceb11f0a
--- /dev/null
+++ b/compiler-rt/lib/xray/xray_trampoline_s390x.S
@@ -0,0 +1,111 @@
+//===-- xray_trampoline_s390x.s ---------------------------------*- ASM -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// This implements the s390x-specific assembler for the trampolines.
+//
+//===----------------------------------------------------------------------===//
+
+ .text
+
+#if __VX__
+// Minimal stack frame size (160) plus space for 8 vector registers a 16 bytes.
+#define STACKSZ 288
+#else
+// Minimal stack frame size
+#define STACKSZ 160
+#endif
+
+//===----------------------------------------------------------------------===//
+
+ .globl __xray_FunctionEntry
+ .p2align 4
+ .type __xray_FunctionEntry,@function
+__xray_FunctionEntry:
+ # The registers r2-15 of the instrumented function are already saved in the
+ # stack frame. On entry, r2 contains the function id, and %r14 the address
+ # of the first instruction of the instrumented function.
+ # Register r14 will be stored in the slot reserved for compiler use.
+ stg %r14, 8(%r15)
+ std %f0, 128(%r15)
+ std %f2, 136(%r15)
+ std %f4, 144(%r15)
+ std %f6, 152(%r15)
+ aghi %r15, -STACKSZ
+#if __VX__
+ vstm %v24, %v31, 160(%r15)
+#endif
+
+ lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT
+ ltg %r1, 0(%r1)
+ je .Lrestore1
+
+ # Set r3 to XRayEntryType::ENTRY = 0.
+ # The FuncId is still stored in r2.
+ lghi %r3, 0
+ basr %r14, %r1
+
+.Lrestore1:
+#if __VX__
+ vlm %v24, %v31, 160(%r15)
+#endif
+ ld %f6, STACKSZ+152(%r15)
+ ld %f4, STACKSZ+144(%r15)
+ ld %f2, STACKSZ+136(%r15)
+ ld %f0, STACKSZ+128(%r15)
+ lmg %r1, %r15, STACKSZ+8(%r15)
+ br %r1
+.Lfunc_end0:
+ .size __xray_FunctionEntry, .Lfunc_end0-__xray_FunctionEntry
+
+//===----------------------------------------------------------------------===//
+
+ .globl __xray_FunctionExit
+ .p2align 4
+ .type __xray_FunctionExit,@function
+__xray_FunctionExit:
+ # The registers r2-15 of the instrumented function are already saved in the
+ # stack frame. On entry, the register r2 contains the function id.
+ # At the end, the function jumps to the address saved in the slot for r14,
+ # which contains the return address into the caller of the instrumented
+ # function.
+ std %f0, 128(%r15)
+ std %f2, 136(%r15)
+ std %f4, 144(%r15)
+ std %f6, 152(%r15)
+ aghi %r15, -STACKSZ
+#if __VX__
+ vstm %v24, %v31, 160(%r15)
+#endif
+
+ lgrl %r1, _ZN6__xray19XRayPatchedFunctionE@GOT
+ ltg %r1, 0(%r1)
+ je .Lrestore2
+
+ # Set r3 to XRayEntryType::EXIT = 1.
+ # The FuncId is still stored in r2.
+ lghi %r3, 1
+ basr %r14, %r1
+
+.Lrestore2:
+#if __VX__
+ vlm %v24, %v31, 160(%r15)
+#endif
+ ld %f6, STACKSZ+152(%r15)
+ ld %f4, STACKSZ+144(%r15)
+ ld %f2, STACKSZ+136(%r15)
+ ld %f0, STACKSZ+128(%r15)
+ lmg %r2, %r15, STACKSZ+16(%r15)
+ br %r14
+.Lfunc_end1:
+ .size __xray_FunctionExit, .Lfunc_end1-__xray_FunctionExit
+
+//===----------------------------------------------------------------------===//
+
+ .section ".note.GNU-stack","",@progbits
diff --git a/compiler-rt/lib/xray/xray_tsc.h b/compiler-rt/lib/xray/xray_tsc.h
index e1cafe1bf11d2d..5b2ba49b85f5d6 100644
--- a/compiler-rt/lib/xray/xray_tsc.h
+++ b/compiler-rt/lib/xray/xray_tsc.h
@@ -83,6 +83,28 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
} // namespace __xray
+#elif defined(__s390x__)
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
+#include "xray_defs.h"
+#include <cerrno>
+#include <cstdint>
+#include <time.h>
+
+namespace __xray {
+
+inline bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; }
+
+ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
+ return __builtin_readcyclecounter();
+}
+
+inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT {
+ return NanosecondsPerSecond;
+}
+
+} // namespace __xray
+
#else
#error Target architecture is not supported.
#endif // CPU architecture
|
compiler-rt/lib/xray/xray_s390x.cpp
Outdated
return false; | ||
} | ||
|
||
} // namespace __xray |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO instead of FIXME
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
compiler-rt/lib/xray/xray_s390x.cpp
Outdated
|
||
namespace __xray { | ||
|
||
bool patchFunctionEntry(const bool Enable, uint32_t FuncId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer __xray::patchFunctionEntry
https://llvm.org/docs/CodingStandards.html#use-namespace-qualifiers-to-implement-previously-declared-functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
compiler-rt/lib/xray/xray_s390x.cpp
Outdated
bool __xray::patchFunctionEntry(const bool Enable, uint32_t FuncId, | ||
const XRaySledEntry &Sled, | ||
void (*Trampoline)()) XRAY_NEVER_INSTRUMENT { | ||
const uint64_t Address = Sled.address(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Easier to cast Address to uint32_t * here to avoid reinterpret_cast below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed, thanks!
std %f4, 144(%r15) | ||
std %f6, 152(%r15) | ||
aghi %r15, -STACKSZ | ||
#if __VX__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit concerned about this #if. As I understand, the vector argument registers need to be saved if they're live during the call (i.e. caller and callee were built with vector support, and at least one of the arguments is of vector type), and the XRay library routine being called below might clobber the vector registers - this can happen if either itself or a routine it calls are built with vector support.
The #if here checks whether this trampoline is built with vector support. This may not match whether or not caller and callee are built with vector support. While it would typically match whether the XRay library routine is built with vector support (generally, the whole support library is built with the same flags), it might not necessarily match all routines called by the support library - e.g. they might call memcpy
from a glibc that is built for vector support and uses vector registers.
I'm not sure if there is some way to ensure the called support routine never uses vector registers. Maybe an alternative would be to provide two copies of the trampoline, one that saves VRs and one that does not, and then emit calls to the version that matches how the instrumented code is being compiled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a good point. Spontaneously I think the decision must depend at runtime on the availability of the vector extension. A decision at application build time does not help if e.g. glibc is build with different settings.
Is there somewhere a flag to check for the vector extension?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Runtime check would be possible, but I'd try to avoid this. As I mentioned, if the function call that is being intercepted was compiled to use the vector feature (i.e. actually passes arguments in vector registers), then we can assume that the vector feature must be available at runtime, or else the call would have already crashed. So if we know at instrumentation time that this call uses the vector feature, the instrumentation can choose to use the variant of the trampoline that saves and restores vector registers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I'll put in a 2nd set of trampoline functions, and change #113253 accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a 2nd, vector-enabled version of the functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try building this with a host compiler that supports z10 by default? I'm afraid the vstm / vlm instructions would cause a compile error there. It might be best to either force -march=z13 when compiling this file, or hard-code the instructions via .insn or the like ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise this all LGTM now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I tried. I added the -mvx
option to the assembly file, to make sure it compiles. See the change in the CMake file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, excellent. Sorry I missed that. All LGTM now.
6d21673
to
e9b6161
Compare
Adds the runtime support routines for XRay on SystemZ. Only function entry/exit is implemented.
e9b6161
to
6359fba
Compare
sorry, i had to revert it for causing: |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/42/builds/1784 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/136/builds/1528 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/64/builds/1388 Here is the relevant piece of the build log for the reference
|
Adds the runtime support routines for XRay on SystemZ. Only function entry/exit is implemented.