//===-- 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 #include bool __xray::patchFunctionEntry(const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled, const XRayTrampolines &Trampolines, bool LogArgs) XRAY_NEVER_INSTRUMENT { uint32_t *Address = reinterpret_cast(Sled.address()); // TODO: Trampoline addresses are currently inserted at compile-time, using // __xray_FunctionEntry and __xray_FunctionExit only. // To support DSO instrumentation, trampolines have to be written during // patching (see implementation on X86_64, e.g.). 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. Address[2] = FuncId; // Write last part of stmg. reinterpret_cast(Address)[2] = 0x24; // Write first part of stmg. Address[0] = 0xeb2ff010; } else { // j +16 instructions. Address[0] = 0xa7f4000b; } return true; } bool __xray::patchFunctionExit( const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled, const XRayTrampolines &Trampolines) XRAY_NEVER_INSTRUMENT { uint32_t *Address = reinterpret_cast(Sled.address()); // TODO: Trampoline addresses are currently inserted at compile-time, using // __xray_FunctionEntry and __xray_FunctionExit only. // To support DSO instrumentation, trampolines have to be written during // patching (see implementation on X86_64, e.g.). 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. Address[2] = FuncId; // Write last part of of stmg. reinterpret_cast(Address)[2] = 0x24; // Write first part of stmg. Address[0] = 0xeb2ff010; } else { // br %14 instruction. reinterpret_cast(Address)[0] = 0x07fe; } return true; } bool __xray::patchFunctionTailExit( const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled, const XRayTrampolines &Trampolines) XRAY_NEVER_INSTRUMENT { return patchFunctionExit(Enable, FuncId, Sled, Trampolines); } bool __xray::patchCustomEvent(const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { // TODO Implement. return false; } bool __xray::patchTypedEvent(const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { // TODO Implement. return false; } extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT { // TODO this will have to be implemented in the trampoline assembly file. } extern "C" void __xray_FunctionTailExit() XRAY_NEVER_INSTRUMENT { // For PowerPC, calls to __xray_FunctionEntry and __xray_FunctionExit // are statically inserted into the sled. Tail exits are handled like normal // function exits. This trampoline is therefore not implemented. // This stub is placed here to avoid linking issues. }