1 1.1 kamil //===-- xray_powerpc64.cc ---------------------------------------*- C++ -*-===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // 10 1.1 kamil // This file is a part of XRay, a dynamic runtime instrumentation system. 11 1.1 kamil // 12 1.1 kamil // Implementation of powerpc64 and powerpc64le routines. 13 1.1 kamil // 14 1.1 kamil //===----------------------------------------------------------------------===// 15 1.1 kamil #include "sanitizer_common/sanitizer_common.h" 16 1.1 kamil #include "xray_defs.h" 17 1.1 kamil #include "xray_interface_internal.h" 18 1.1 kamil #include "xray_utils.h" 19 1.1 kamil #include <atomic> 20 1.1 kamil #include <cassert> 21 1.1 kamil #include <cstring> 22 1.1 kamil 23 1.1 kamil #ifndef __LITTLE_ENDIAN__ 24 1.1 kamil #error powerpc64 big endian is not supported for now. 25 1.1 kamil #endif 26 1.1 kamil 27 1.1 kamil namespace { 28 1.1 kamil 29 1.1 kamil constexpr unsigned long long JumpOverInstNum = 7; 30 1.1 kamil 31 1.1 kamil void clearCache(void *Addr, size_t Len) { 32 1.1 kamil const size_t LineSize = 32; 33 1.1 kamil 34 1.1 kamil const intptr_t Mask = ~(LineSize - 1); 35 1.1 kamil const intptr_t StartLine = ((intptr_t)Addr) & Mask; 36 1.1 kamil const intptr_t EndLine = ((intptr_t)Addr + Len + LineSize - 1) & Mask; 37 1.1 kamil 38 1.1 kamil for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize) 39 1.1 kamil asm volatile("dcbf 0, %0" : : "r"(Line)); 40 1.1 kamil asm volatile("sync"); 41 1.1 kamil 42 1.1 kamil for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize) 43 1.1 kamil asm volatile("icbi 0, %0" : : "r"(Line)); 44 1.1 kamil asm volatile("isync"); 45 1.1 kamil } 46 1.1 kamil 47 1.1 kamil } // namespace 48 1.1 kamil 49 1.1 kamil extern "C" void __clear_cache(void *start, void *end); 50 1.1 kamil 51 1.1 kamil namespace __xray { 52 1.1 kamil 53 1.1 kamil bool patchFunctionEntry(const bool Enable, uint32_t FuncId, 54 1.1 kamil const XRaySledEntry &Sled, 55 1.1 kamil void (*Trampoline)()) XRAY_NEVER_INSTRUMENT { 56 1.1 kamil if (Enable) { 57 1.1 kamil // lis 0, FuncId[16..32] 58 1.1 kamil // li 0, FuncId[0..15] 59 1.1 kamil *reinterpret_cast<uint64_t *>(Sled.Address) = 60 1.1 kamil (0x3c000000ull + (FuncId >> 16)) + 61 1.1 kamil ((0x60000000ull + (FuncId & 0xffff)) << 32); 62 1.1 kamil } else { 63 1.1 kamil // b +JumpOverInstNum instructions. 64 1.1 kamil *reinterpret_cast<uint32_t *>(Sled.Address) = 65 1.1 kamil 0x48000000ull + (JumpOverInstNum << 2); 66 1.1 kamil } 67 1.1 kamil clearCache(reinterpret_cast<void *>(Sled.Address), 8); 68 1.1 kamil return true; 69 1.1 kamil } 70 1.1 kamil 71 1.1 kamil bool patchFunctionExit(const bool Enable, uint32_t FuncId, 72 1.1 kamil const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { 73 1.1 kamil if (Enable) { 74 1.1 kamil // lis 0, FuncId[16..32] 75 1.1 kamil // li 0, FuncId[0..15] 76 1.1 kamil *reinterpret_cast<uint64_t *>(Sled.Address) = 77 1.1 kamil (0x3c000000ull + (FuncId >> 16)) + 78 1.1 kamil ((0x60000000ull + (FuncId & 0xffff)) << 32); 79 1.1 kamil } else { 80 1.1 kamil // Copy the blr/b instruction after JumpOverInstNum instructions. 81 1.1 kamil *reinterpret_cast<uint32_t *>(Sled.Address) = 82 1.1 kamil *(reinterpret_cast<uint32_t *>(Sled.Address) + JumpOverInstNum); 83 1.1 kamil } 84 1.1 kamil clearCache(reinterpret_cast<void *>(Sled.Address), 8); 85 1.1 kamil return true; 86 1.1 kamil } 87 1.1 kamil 88 1.1 kamil bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, 89 1.1 kamil const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { 90 1.1 kamil return patchFunctionExit(Enable, FuncId, Sled); 91 1.1 kamil } 92 1.1 kamil 93 1.1 kamil // FIXME: Maybe implement this better? 94 1.1 kamil bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; } 95 1.1 kamil 96 1.1 kamil bool patchCustomEvent(const bool Enable, const uint32_t FuncId, 97 1.1 kamil const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { 98 1.1 kamil // FIXME: Implement in powerpc64? 99 1.1 kamil return false; 100 1.1 kamil } 101 1.1 kamil 102 1.1 kamil bool patchTypedEvent(const bool Enable, const uint32_t FuncId, 103 1.1 kamil const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { 104 1.1 kamil // FIXME: Implement in powerpc64? 105 1.1 kamil return false; 106 1.1 kamil } 107 1.1 kamil 108 1.1 kamil } // namespace __xray 109 1.1 kamil 110 1.1 kamil extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT { 111 1.1 kamil // FIXME: this will have to be implemented in the trampoline assembly file 112 1.1 kamil } 113