1 //===-- xray_interface_internal.h -------------------------------*- 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 the API functions. See also include/xray/xray_interface.h. 12 // 13 //===----------------------------------------------------------------------===// 14 #ifndef XRAY_INTERFACE_INTERNAL_H 15 #define XRAY_INTERFACE_INTERNAL_H 16 17 #include "sanitizer_common/sanitizer_platform.h" 18 #include "xray/xray_interface.h" 19 #include <cstddef> 20 #include <cstdint> 21 #include <utility> 22 23 extern "C" { 24 // The following functions have to be defined in assembler, on a per-platform 25 // basis. See xray_trampoline_*.S files for implementations. 26 extern void __xray_FunctionEntry(); 27 extern void __xray_FunctionExit(); 28 extern void __xray_FunctionTailExit(); 29 extern void __xray_ArgLoggerEntry(); 30 extern void __xray_CustomEvent(); 31 extern void __xray_TypedEvent(); 32 } 33 34 extern "C" { 35 36 struct XRaySledEntry { 37 #if SANITIZER_WORDSIZE == 64 38 uint64_t Address; 39 uint64_t Function; 40 unsigned char Kind; 41 unsigned char AlwaysInstrument; 42 unsigned char Version; 43 unsigned char Padding[13]; // Need 32 bytes 44 uint64_t function() const { 45 // The target address is relative to the location of the Function variable. 46 return reinterpret_cast<uint64_t>(&Function) + Function; 47 } 48 uint64_t address() const { 49 // The target address is relative to the location of the Address variable. 50 return reinterpret_cast<uint64_t>(&Address) + Address; 51 } 52 #elif SANITIZER_WORDSIZE == 32 53 uint32_t Address; 54 uint32_t Function; 55 unsigned char Kind; 56 unsigned char AlwaysInstrument; 57 unsigned char Version; 58 unsigned char Padding[5]; // Need 16 bytes 59 uint32_t function() const { 60 // The target address is relative to the location of the Function variable. 61 return reinterpret_cast<uint32_t>(&Function) + Function; 62 } 63 uint32_t address() const { 64 // The target address is relative to the location of the Address variable. 65 return reinterpret_cast<uint32_t>(&Address) + Address; 66 } 67 #else 68 #error "Unsupported word size." 69 #endif 70 }; 71 72 struct XRayFunctionSledIndex { 73 const XRaySledEntry *Begin; 74 size_t Size; 75 // For an entry in the xray_fn_idx section, the address is relative to the 76 // location of the Begin variable. 77 const XRaySledEntry *fromPCRelative() const { 78 return reinterpret_cast<const XRaySledEntry *>(uintptr_t(&Begin) + 79 uintptr_t(Begin)); 80 } 81 }; 82 83 struct XRayTrampolines { 84 void (*EntryTrampoline)(); 85 void (*ExitTrampoline)(); 86 void (*TailExitTrampoline)(); 87 void (*LogArgsTrampoline)(); 88 89 XRayTrampolines() { 90 // These resolve to the definitions in the respective executable or DSO. 91 EntryTrampoline = __xray_FunctionEntry; 92 ExitTrampoline = __xray_FunctionExit; 93 TailExitTrampoline = __xray_FunctionTailExit; 94 LogArgsTrampoline = __xray_ArgLoggerEntry; 95 } 96 }; 97 98 extern int32_t __xray_register_dso(const XRaySledEntry *SledsBegin, 99 const XRaySledEntry *SledsEnd, 100 const XRayFunctionSledIndex *FnIndexBegin, 101 const XRayFunctionSledIndex *FnIndexEnd, 102 XRayTrampolines Trampolines); 103 104 extern bool __xray_deregister_dso(int32_t ObjId); 105 } 106 107 namespace __xray { 108 109 constexpr uint32_t XRayNFnBits = 24; 110 constexpr uint32_t XRayNObjBits = 8; 111 112 constexpr uint32_t XRayFnBitMask = 0x00FFFFFF; 113 constexpr uint32_t XRayObjBitMask = 0xFF000000; 114 115 constexpr size_t XRayMaxFunctions = 1 << XRayNFnBits; 116 constexpr size_t XRayMaxObjects = 1 << XRayNObjBits; 117 118 inline int32_t MakePackedId(int32_t FnId, int32_t ObjId) { 119 return ((ObjId << XRayNFnBits) & XRayObjBitMask) | (FnId & XRayFnBitMask); 120 } 121 122 inline std::pair<int32_t, int32_t> UnpackId(int32_t PackedId) { 123 uint32_t ObjId = (PackedId & XRayObjBitMask) >> XRayNFnBits; 124 uint32_t FnId = PackedId & XRayFnBitMask; 125 return {ObjId, FnId}; 126 } 127 128 struct XRaySledMap { 129 const XRaySledEntry *Sleds; 130 size_t Entries; 131 const XRayFunctionSledIndex *SledsIndex; 132 size_t Functions; 133 XRayTrampolines Trampolines; 134 bool FromDSO; 135 bool Loaded; 136 }; 137 138 bool patchFunctionEntry(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled, 139 const XRayTrampolines &Trampolines, bool LogArgs); 140 bool patchFunctionExit(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled, 141 const XRayTrampolines &Trampolines); 142 bool patchFunctionTailExit(bool Enable, uint32_t FuncId, 143 const XRaySledEntry &Sled, 144 const XRayTrampolines &Trampolines); 145 bool patchCustomEvent(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); 146 bool patchTypedEvent(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); 147 148 } // namespace __xray 149 150 #endif 151