10b57cec5SDimitry Andric //===-- xray_interface_internal.h -------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file is a part of XRay, a dynamic runtime instrumentation system. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric // Implementation of the API functions. See also include/xray/xray_interface.h. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric #ifndef XRAY_INTERFACE_INTERNAL_H 150b57cec5SDimitry Andric #define XRAY_INTERFACE_INTERNAL_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_platform.h" 180b57cec5SDimitry Andric #include "xray/xray_interface.h" 190b57cec5SDimitry Andric #include <cstddef> 200b57cec5SDimitry Andric #include <cstdint> 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric extern "C" { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric struct XRaySledEntry { 250b57cec5SDimitry Andric #if SANITIZER_WORDSIZE == 64 260b57cec5SDimitry Andric uint64_t Address; 270b57cec5SDimitry Andric uint64_t Function; 280b57cec5SDimitry Andric unsigned char Kind; 290b57cec5SDimitry Andric unsigned char AlwaysInstrument; 300b57cec5SDimitry Andric unsigned char Version; 310b57cec5SDimitry Andric unsigned char Padding[13]; // Need 32 bytes functionXRaySledEntry325ffd83dbSDimitry Andric uint64_t function() const { 335ffd83dbSDimitry Andric // The target address is relative to the location of the Function variable. 345ffd83dbSDimitry Andric return reinterpret_cast<uint64_t>(&Function) + Function; 355ffd83dbSDimitry Andric } addressXRaySledEntry365ffd83dbSDimitry Andric uint64_t address() const { 375ffd83dbSDimitry Andric // The target address is relative to the location of the Address variable. 385ffd83dbSDimitry Andric return reinterpret_cast<uint64_t>(&Address) + Address; 395ffd83dbSDimitry Andric } 400b57cec5SDimitry Andric #elif SANITIZER_WORDSIZE == 32 410b57cec5SDimitry Andric uint32_t Address; 420b57cec5SDimitry Andric uint32_t Function; 430b57cec5SDimitry Andric unsigned char Kind; 440b57cec5SDimitry Andric unsigned char AlwaysInstrument; 450b57cec5SDimitry Andric unsigned char Version; 460b57cec5SDimitry Andric unsigned char Padding[5]; // Need 16 bytes 475ffd83dbSDimitry Andric uint32_t function() const { 485ffd83dbSDimitry Andric // The target address is relative to the location of the Function variable. 495ffd83dbSDimitry Andric return reinterpret_cast<uint32_t>(&Function) + Function; 505ffd83dbSDimitry Andric } 515ffd83dbSDimitry Andric uint32_t address() const { 525ffd83dbSDimitry Andric // The target address is relative to the location of the Address variable. 535ffd83dbSDimitry Andric return reinterpret_cast<uint32_t>(&Address) + Address; 545ffd83dbSDimitry Andric } 550b57cec5SDimitry Andric #else 560b57cec5SDimitry Andric #error "Unsupported word size." 570b57cec5SDimitry Andric #endif 580b57cec5SDimitry Andric }; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric struct XRayFunctionSledIndex { 610b57cec5SDimitry Andric const XRaySledEntry *Begin; 62*06c3fb27SDimitry Andric size_t Size; 63*06c3fb27SDimitry Andric // For an entry in the xray_fn_idx section, the address is relative to the 64*06c3fb27SDimitry Andric // location of the Begin variable. fromPCRelativeXRayFunctionSledIndex65*06c3fb27SDimitry Andric const XRaySledEntry *fromPCRelative() const { 66*06c3fb27SDimitry Andric return reinterpret_cast<const XRaySledEntry *>(uintptr_t(&Begin) + 67*06c3fb27SDimitry Andric uintptr_t(Begin)); 68*06c3fb27SDimitry Andric } 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric namespace __xray { 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric struct XRaySledMap { 750b57cec5SDimitry Andric const XRaySledEntry *Sleds; 760b57cec5SDimitry Andric size_t Entries; 770b57cec5SDimitry Andric const XRayFunctionSledIndex *SledsIndex; 780b57cec5SDimitry Andric size_t Functions; 790b57cec5SDimitry Andric }; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric bool patchFunctionEntry(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled, 820b57cec5SDimitry Andric void (*Trampoline)()); 830b57cec5SDimitry Andric bool patchFunctionExit(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); 840b57cec5SDimitry Andric bool patchFunctionTailExit(bool Enable, uint32_t FuncId, 850b57cec5SDimitry Andric const XRaySledEntry &Sled); 860b57cec5SDimitry Andric bool patchCustomEvent(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); 870b57cec5SDimitry Andric bool patchTypedEvent(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric } // namespace __xray 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric extern "C" { 920b57cec5SDimitry Andric // The following functions have to be defined in assembler, on a per-platform 930b57cec5SDimitry Andric // basis. See xray_trampoline_*.S files for implementations. 940b57cec5SDimitry Andric extern void __xray_FunctionEntry(); 950b57cec5SDimitry Andric extern void __xray_FunctionExit(); 960b57cec5SDimitry Andric extern void __xray_FunctionTailExit(); 970b57cec5SDimitry Andric extern void __xray_ArgLoggerEntry(); 980b57cec5SDimitry Andric extern void __xray_CustomEvent(); 990b57cec5SDimitry Andric extern void __xray_TypedEvent(); 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric #endif 103