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