Path: blob/main/contrib/llvm-project/compiler-rt/lib/xray/xray_powerpc64.cpp
35265 views
//===-- xray_powerpc64.cpp --------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of XRay, a dynamic runtime instrumentation system.9//10// Implementation of powerpc64 and powerpc64le routines.11//12//===----------------------------------------------------------------------===//13#include "sanitizer_common/sanitizer_common.h"14#include "xray_defs.h"15#include "xray_interface_internal.h"16#include "xray_utils.h"17#include <atomic>18#include <cassert>19#include <cstring>2021#ifndef __LITTLE_ENDIAN__22#error powerpc64 big endian is not supported for now.23#endif2425namespace {2627constexpr unsigned long long JumpOverInstNum = 7;2829void clearCache(void *Addr, size_t Len) {30const size_t LineSize = 32;3132const intptr_t Mask = ~(LineSize - 1);33const intptr_t StartLine = ((intptr_t)Addr) & Mask;34const intptr_t EndLine = ((intptr_t)Addr + Len + LineSize - 1) & Mask;3536for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)37asm volatile("dcbf 0, %0" : : "r"(Line));38asm volatile("sync");3940for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)41asm volatile("icbi 0, %0" : : "r"(Line));42asm volatile("isync");43}4445} // namespace4647extern "C" void __clear_cache(void *start, void *end);4849namespace __xray {5051bool patchFunctionEntry(const bool Enable, uint32_t FuncId,52const XRaySledEntry &Sled,53void (*Trampoline)()) XRAY_NEVER_INSTRUMENT {54const uint64_t Address = Sled.address();55if (Enable) {56// lis 0, FuncId[16..32]57// li 0, FuncId[0..15]58*reinterpret_cast<uint64_t *>(Address) =59(0x3c000000ull + (FuncId >> 16)) +60((0x60000000ull + (FuncId & 0xffff)) << 32);61} else {62// b +JumpOverInstNum instructions.63*reinterpret_cast<uint32_t *>(Address) =640x48000000ull + (JumpOverInstNum << 2);65}66clearCache(reinterpret_cast<void *>(Address), 8);67return true;68}6970bool patchFunctionExit(const bool Enable, uint32_t FuncId,71const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {72const uint64_t Address = Sled.address();73if (Enable) {74// lis 0, FuncId[16..32]75// li 0, FuncId[0..15]76*reinterpret_cast<uint64_t *>(Address) =77(0x3c000000ull + (FuncId >> 16)) +78((0x60000000ull + (FuncId & 0xffff)) << 32);79} else {80// Copy the blr/b instruction after JumpOverInstNum instructions.81*reinterpret_cast<uint32_t *>(Address) =82*(reinterpret_cast<uint32_t *>(Address) + JumpOverInstNum);83}84clearCache(reinterpret_cast<void *>(Address), 8);85return true;86}8788bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,89const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {90return patchFunctionExit(Enable, FuncId, Sled);91}9293// FIXME: Maybe implement this better?94bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; }9596bool patchCustomEvent(const bool Enable, const uint32_t FuncId,97const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {98// FIXME: Implement in powerpc64?99return false;100}101102bool patchTypedEvent(const bool Enable, const uint32_t FuncId,103const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {104// FIXME: Implement in powerpc64?105return false;106}107108} // namespace __xray109110extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {111// FIXME: this will have to be implemented in the trampoline assembly file112}113114115