1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright 2024 Institute of Software, Chinese Academy of Sciences. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 17800b99b8Sopenharmony_ci#include "dfx_regs.h" 18800b99b8Sopenharmony_ci 19800b99b8Sopenharmony_ci#include <elf.h> 20800b99b8Sopenharmony_ci#include <securec.h> 21800b99b8Sopenharmony_ci#include <stdint.h> 22800b99b8Sopenharmony_ci#include <sys/ptrace.h> 23800b99b8Sopenharmony_ci#include <sys/uio.h> 24800b99b8Sopenharmony_ci 25800b99b8Sopenharmony_ci#include "dfx_define.h" 26800b99b8Sopenharmony_ci#include "dfx_log.h" 27800b99b8Sopenharmony_ci#include "dfx_elf.h" 28800b99b8Sopenharmony_ci#include "string_printf.h" 29800b99b8Sopenharmony_ci 30800b99b8Sopenharmony_cinamespace OHOS { 31800b99b8Sopenharmony_cinamespace HiviewDFX { 32800b99b8Sopenharmony_civoid DfxRegsRiscv64::SetFromUcontext(const ucontext_t &context) 33800b99b8Sopenharmony_ci{ 34800b99b8Sopenharmony_ci if (regsData_.size() < REG_LAST) { 35800b99b8Sopenharmony_ci return; 36800b99b8Sopenharmony_ci } 37800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X0] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X0]); 38800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X1] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X1]); 39800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X2] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X2]); 40800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X3] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X3]); 41800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X4] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X4]); 42800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X5] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X5]); 43800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X6] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X6]); 44800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X7] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X7]); 45800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X8] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X8]); 46800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X9] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X9]); 47800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X10] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X10]); 48800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X11] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X11]); 49800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X12] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X12]); 50800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X13] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X13]); 51800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X14] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X14]); 52800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X15] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X15]); 53800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X16] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X16]); 54800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X17] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X17]); 55800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X18] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X18]); 56800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X19] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X19]); 57800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X20] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X20]); 58800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X21] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X21]); 59800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X22] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X22]); 60800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X23] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X23]); 61800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X24] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X24]); 62800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X25] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X25]); 63800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X26] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X26]); 64800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X27] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X27]); 65800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X28] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X28]); 66800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X29] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X29]); 67800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X30] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X30]); 68800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X31] = static_cast<uintptr_t>(context.uc_mcontext.__gregs[REG_RISCV64_X31]); 69800b99b8Sopenharmony_ci} 70800b99b8Sopenharmony_ci 71800b99b8Sopenharmony_civoid DfxRegsRiscv64::SetFromFpMiniRegs(const uintptr_t* regs, const size_t size) 72800b99b8Sopenharmony_ci{ 73800b99b8Sopenharmony_ci if (size < FP_MINI_REGS_SIZE) { 74800b99b8Sopenharmony_ci return; 75800b99b8Sopenharmony_ci } 76800b99b8Sopenharmony_ci regsData_[REG_FP] = regs[0]; // 0 : fp offset 77800b99b8Sopenharmony_ci regsData_[REG_LR] = regs[1]; // 1 : lr offset 78800b99b8Sopenharmony_ci regsData_[REG_SP] = regs[2]; // 2 : sp offset 79800b99b8Sopenharmony_ci regsData_[REG_PC] = regs[3]; // 3 : pc offset 80800b99b8Sopenharmony_ci} 81800b99b8Sopenharmony_ci 82800b99b8Sopenharmony_civoid DfxRegsRiscv64::SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) 83800b99b8Sopenharmony_ci{ 84800b99b8Sopenharmony_ci if (size < QUT_MINI_REGS_SIZE) { 85800b99b8Sopenharmony_ci return; 86800b99b8Sopenharmony_ci } 87800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X20] = regs[1]; // 1 : X20 offset 88800b99b8Sopenharmony_ci regsData_[REG_RISCV64_X28] = regs[2]; // 2 : X28 offset 89800b99b8Sopenharmony_ci regsData_[REG_FP] = regs[3]; // 3 : fp offset 90800b99b8Sopenharmony_ci regsData_[REG_SP] = regs[4]; // 4 : sp offset 91800b99b8Sopenharmony_ci regsData_[REG_PC] = regs[5]; // 5 : pc offset 92800b99b8Sopenharmony_ci regsData_[REG_LR] = regs[6]; // 6 : lr offset 93800b99b8Sopenharmony_ci} 94800b99b8Sopenharmony_ci 95800b99b8Sopenharmony_cibool DfxRegsRiscv64::SetPcFromReturnAddress(MAYBE_UNUSED std::shared_ptr<DfxMemory> memory) 96800b99b8Sopenharmony_ci{ 97800b99b8Sopenharmony_ci uintptr_t lr = regsData_[REG_LR]; 98800b99b8Sopenharmony_ci if (regsData_[REG_PC] == lr) { 99800b99b8Sopenharmony_ci return false; 100800b99b8Sopenharmony_ci } 101800b99b8Sopenharmony_ci regsData_[REG_PC] = lr; 102800b99b8Sopenharmony_ci return true; 103800b99b8Sopenharmony_ci} 104800b99b8Sopenharmony_ci 105800b99b8Sopenharmony_cistd::string DfxRegsRiscv64::PrintRegs() const 106800b99b8Sopenharmony_ci{ 107800b99b8Sopenharmony_ci char buf[REGS_PRINT_LEN] = {0}; 108800b99b8Sopenharmony_ci auto regs = GetRegsData(); 109800b99b8Sopenharmony_ci 110800b99b8Sopenharmony_ci BufferPrintf(buf, sizeof(buf), "x0:%016lx x1:%016lx x2:%016lx x3:%016lx\n", \ 111800b99b8Sopenharmony_ci regs[REG_RISCV64_X0], regs[REG_RISCV64_X1], regs[REG_RISCV64_X2], regs[REG_RISCV64_X3]); 112800b99b8Sopenharmony_ci 113800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "x4:%016lx x5:%016lx x6:%016lx x7:%016lx\n", \ 114800b99b8Sopenharmony_ci regs[REG_RISCV64_X4], regs[REG_RISCV64_X5], regs[REG_RISCV64_X6], regs[REG_RISCV64_X7]); 115800b99b8Sopenharmony_ci 116800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "x8:%016lx x9:%016lx x10:%016lx x11:%016lx\n", \ 117800b99b8Sopenharmony_ci regs[REG_RISCV64_X8], regs[REG_RISCV64_X9], regs[REG_RISCV64_X10], regs[REG_RISCV64_X11]); 118800b99b8Sopenharmony_ci 119800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "x12:%016lx x13:%016lx x14:%016lx x15:%016lx\n", \ 120800b99b8Sopenharmony_ci regs[REG_RISCV64_X12], regs[REG_RISCV64_X13], regs[REG_RISCV64_X14], regs[REG_RISCV64_X15]); 121800b99b8Sopenharmony_ci 122800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "x16:%016lx x17:%016lx x18:%016lx x19:%016lx\n", \ 123800b99b8Sopenharmony_ci regs[REG_RISCV64_X16], regs[REG_RISCV64_X17], regs[REG_RISCV64_X18], regs[REG_RISCV64_X19]); 124800b99b8Sopenharmony_ci 125800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "x20:%016lx x21:%016lx x22:%016lx x23:%016lx\n", \ 126800b99b8Sopenharmony_ci regs[REG_RISCV64_X20], regs[REG_RISCV64_X21], regs[REG_RISCV64_X22], regs[REG_RISCV64_X23]); 127800b99b8Sopenharmony_ci 128800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "x24:%016lx x25:%016lx x26:%016lx x27:%016lx\n", \ 129800b99b8Sopenharmony_ci regs[REG_RISCV64_X24], regs[REG_RISCV64_X25], regs[REG_RISCV64_X26], regs[REG_RISCV64_X27]); 130800b99b8Sopenharmony_ci 131800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "x28:%016lx x29:%016lx\n", \ 132800b99b8Sopenharmony_ci regs[REG_RISCV64_X28], regs[REG_RISCV64_X29]); 133800b99b8Sopenharmony_ci 134800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "lr:%016lx sp:%016lx pc:%016lx\n", \ 135800b99b8Sopenharmony_ci regs[REG_RISCV64_X30], regs[REG_SP], regs[REG_PC]); 136800b99b8Sopenharmony_ci 137800b99b8Sopenharmony_ci std::string regString = StringPrintf("Registers:\n%s", buf); 138800b99b8Sopenharmony_ci return regString; 139800b99b8Sopenharmony_ci} 140800b99b8Sopenharmony_ci 141800b99b8Sopenharmony_cibool DfxRegsRiscv64::StepIfSignalFrame(uintptr_t pc, std::shared_ptr<DfxMemory> memory) 142800b99b8Sopenharmony_ci{ 143800b99b8Sopenharmony_ci uint64_t data; 144800b99b8Sopenharmony_ci if (!memory->ReadU64(pc, &data, false)) { 145800b99b8Sopenharmony_ci return false; 146800b99b8Sopenharmony_ci } 147800b99b8Sopenharmony_ci DFXLOGU("[%{public}d]: data: %{public}llx", __LINE__, data); 148800b99b8Sopenharmony_ci 149800b99b8Sopenharmony_ci // Look for the kernel sigreturn function. 150800b99b8Sopenharmony_ci // __kernel_rt_sigreturn: 151800b99b8Sopenharmony_ci // li a7, __NR_rt_sigreturn 152800b99b8Sopenharmony_ci // scall 153800b99b8Sopenharmony_ci const int scallSize = 8; 154800b99b8Sopenharmony_ci const uint8_t liScall[] = {0x93, 0x08, 0xb0, 0x08, 0x73, 0x00, 0x00, 0x00}; 155800b99b8Sopenharmony_ci if (memcmp(&data, &liScall, scallSize) != 0) { 156800b99b8Sopenharmony_ci return false; 157800b99b8Sopenharmony_ci } 158800b99b8Sopenharmony_ci // SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset. 159800b99b8Sopenharmony_ci uintptr_t scAddr = regsData_[REG_SP] + sizeof(siginfo_t) + 0xb0 + 0x00; 160800b99b8Sopenharmony_ci DFXLOGU("[%{public}d]: scAddr: %{public}llx", __LINE__, scAddr); 161800b99b8Sopenharmony_ci memory->Read(scAddr, regsData_.data(), sizeof(uint64_t) * REG_LAST, false); 162800b99b8Sopenharmony_ci return true; 163800b99b8Sopenharmony_ci} 164800b99b8Sopenharmony_ci} // namespace HiviewDFX 165800b99b8Sopenharmony_ci} // namespace OHOS 166800b99b8Sopenharmony_ci#endif 167