1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 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(__x86_64__) 17800b99b8Sopenharmony_ci#include "dfx_regs.h" 18800b99b8Sopenharmony_ci 19800b99b8Sopenharmony_ci#include <elf.h> 20800b99b8Sopenharmony_ci#include <securec.h> 21800b99b8Sopenharmony_ci#include <cstdint> 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 DfxRegsX86_64::SetFromUcontext(const ucontext_t &context) 33800b99b8Sopenharmony_ci{ 34800b99b8Sopenharmony_ci if (regsData_.size() < REG_LAST) { 35800b99b8Sopenharmony_ci return; 36800b99b8Sopenharmony_ci } 37800b99b8Sopenharmony_ci regsData_[REG_X86_64_RAX] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RAX]); 38800b99b8Sopenharmony_ci regsData_[REG_X86_64_RDX] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RDX]); 39800b99b8Sopenharmony_ci regsData_[REG_X86_64_RCX] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RCX]); 40800b99b8Sopenharmony_ci regsData_[REG_X86_64_RBX] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RBX]); 41800b99b8Sopenharmony_ci regsData_[REG_X86_64_RSI] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RSI]); 42800b99b8Sopenharmony_ci regsData_[REG_X86_64_RDI] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RDI]); 43800b99b8Sopenharmony_ci regsData_[REG_X86_64_RBP] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RBP]); 44800b99b8Sopenharmony_ci regsData_[REG_X86_64_RSP] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RSP]); 45800b99b8Sopenharmony_ci regsData_[REG_X86_64_R8] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R8]); 46800b99b8Sopenharmony_ci regsData_[REG_X86_64_R9] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R9]); 47800b99b8Sopenharmony_ci regsData_[REG_X86_64_R10] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R10]); 48800b99b8Sopenharmony_ci regsData_[REG_X86_64_R11] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R11]); 49800b99b8Sopenharmony_ci regsData_[REG_X86_64_R12] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R12]); 50800b99b8Sopenharmony_ci regsData_[REG_X86_64_R13] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R13]); 51800b99b8Sopenharmony_ci regsData_[REG_X86_64_R14] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R14]); 52800b99b8Sopenharmony_ci regsData_[REG_X86_64_R15] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_R15]); 53800b99b8Sopenharmony_ci regsData_[REG_X86_64_RIP] = static_cast<uintptr_t>(context.uc_mcontext.gregs[REG_RIP]); 54800b99b8Sopenharmony_ci} 55800b99b8Sopenharmony_ci 56800b99b8Sopenharmony_civoid DfxRegsX86_64::SetFromFpMiniRegs(const uintptr_t* regs, const size_t size) 57800b99b8Sopenharmony_ci{ 58800b99b8Sopenharmony_ci} 59800b99b8Sopenharmony_ci 60800b99b8Sopenharmony_civoid DfxRegsX86_64::SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) 61800b99b8Sopenharmony_ci{ 62800b99b8Sopenharmony_ci} 63800b99b8Sopenharmony_ci 64800b99b8Sopenharmony_cibool DfxRegsX86_64::SetPcFromReturnAddress(std::shared_ptr<DfxMemory> memory) 65800b99b8Sopenharmony_ci{ 66800b99b8Sopenharmony_ci uintptr_t newPc; 67800b99b8Sopenharmony_ci if (!memory->ReadUptr(regsData_[REG_SP], &newPc, false) || 68800b99b8Sopenharmony_ci newPc == regsData_[REG_PC]) { 69800b99b8Sopenharmony_ci return false; 70800b99b8Sopenharmony_ci } 71800b99b8Sopenharmony_ci regsData_[REG_PC] = newPc; 72800b99b8Sopenharmony_ci return true; 73800b99b8Sopenharmony_ci} 74800b99b8Sopenharmony_ci 75800b99b8Sopenharmony_cistd::string DfxRegsX86_64::PrintRegs() const 76800b99b8Sopenharmony_ci{ 77800b99b8Sopenharmony_ci char buf[REGS_PRINT_LEN] = {0}; 78800b99b8Sopenharmony_ci auto regs = GetRegsData(); 79800b99b8Sopenharmony_ci 80800b99b8Sopenharmony_ci BufferPrintf(buf, sizeof(buf), " rax:%016lx rdx:%016lx rcx:%016lx rbx:%016lx\n", \ 81800b99b8Sopenharmony_ci regs[REG_X86_64_RAX], regs[REG_X86_64_RDX], regs[REG_X86_64_RCX], regs[REG_X86_64_RBX]); 82800b99b8Sopenharmony_ci 83800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " rsi:%016lx rdi:%016lx rbp:%016lx rsp:%016lx\n", \ 84800b99b8Sopenharmony_ci regs[REG_X86_64_RSI], regs[REG_X86_64_RDI], regs[REG_X86_64_RBP], regs[REG_X86_64_RSP]); 85800b99b8Sopenharmony_ci 86800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " r8:%016lx r9:%016lx r10:%016lx r11:%016lx\n", \ 87800b99b8Sopenharmony_ci regs[REG_X86_64_R8], regs[REG_X86_64_R9], regs[REG_X86_64_R10], regs[REG_X86_64_R11]); 88800b99b8Sopenharmony_ci 89800b99b8Sopenharmony_ci BufferPrintf(buf + strlen(buf), sizeof(buf) - strlen(buf), \ 90800b99b8Sopenharmony_ci " r12:%016lx r13:%016lx r14:%016lx r15:%016lx rip:%016lx\n", \ 91800b99b8Sopenharmony_ci regs[REG_X86_64_R12], regs[REG_X86_64_R13], regs[REG_X86_64_R14], regs[REG_X86_64_R15], regs[REG_X86_64_RIP]); 92800b99b8Sopenharmony_ci 93800b99b8Sopenharmony_ci std::string regString = StringPrintf("Registers:\n%s", buf); 94800b99b8Sopenharmony_ci return regString; 95800b99b8Sopenharmony_ci} 96800b99b8Sopenharmony_ci 97800b99b8Sopenharmony_cibool DfxRegsX86_64::StepIfSignalFrame(uintptr_t pc, std::shared_ptr<DfxMemory> memory) 98800b99b8Sopenharmony_ci{ 99800b99b8Sopenharmony_ci uint64_t data; 100800b99b8Sopenharmony_ci if (!memory->ReadU64(pc, &data, false)) { 101800b99b8Sopenharmony_ci return false; 102800b99b8Sopenharmony_ci } 103800b99b8Sopenharmony_ci DFXLOGU("[%{public}d]: data: %{public}llx", __LINE__, data); 104800b99b8Sopenharmony_ci 105800b99b8Sopenharmony_ci // __restore_rt: 106800b99b8Sopenharmony_ci // 0x48 0xc7 0xc0 0x0f 0x00 0x00 0x00 mov $0xf,%rax 107800b99b8Sopenharmony_ci // 0x0f 0x05 syscall 108800b99b8Sopenharmony_ci // 0x0f nopl 0x0($rax) 109800b99b8Sopenharmony_ci if (data != 0x0f0000000fc0c748) { 110800b99b8Sopenharmony_ci return false; 111800b99b8Sopenharmony_ci } 112800b99b8Sopenharmony_ci 113800b99b8Sopenharmony_ci uint16_t data2; 114800b99b8Sopenharmony_ci pc += sizeof(uint64_t); 115800b99b8Sopenharmony_ci if (!memory->ReadU16(pc, &data2, false) || (data2 != 0x0f05)) { 116800b99b8Sopenharmony_ci DFXLOGU("data2: %{public}x", data2); 117800b99b8Sopenharmony_ci return false; 118800b99b8Sopenharmony_ci } 119800b99b8Sopenharmony_ci 120800b99b8Sopenharmony_ci // Read the mcontext data from the stack. 121800b99b8Sopenharmony_ci // sp points to the ucontext data structure, read only the mcontext part. 122800b99b8Sopenharmony_ci ucontext_t ucontext; 123800b99b8Sopenharmony_ci uintptr_t scAddr = regsData_[REG_SP] + 0x28; 124800b99b8Sopenharmony_ci DFXLOGU("[%{public}d]: scAddr: %{public}llx", __LINE__, scAddr); 125800b99b8Sopenharmony_ci memory->Read(scAddr, &ucontext.uc_mcontext, sizeof(ucontext.uc_mcontext), false); 126800b99b8Sopenharmony_ci SetFromUcontext(ucontext); 127800b99b8Sopenharmony_ci return true; 128800b99b8Sopenharmony_ci} 129800b99b8Sopenharmony_ci} // namespace HiviewDFX 130800b99b8Sopenharmony_ci} // namespace OHOS 131800b99b8Sopenharmony_ci#endif 132