1800b99b8Sopenharmony_ci 2800b99b8Sopenharmony_ci/* 3800b99b8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 4800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 5800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 6800b99b8Sopenharmony_ci * You may obtain a copy of the License at 7800b99b8Sopenharmony_ci * 8800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 9800b99b8Sopenharmony_ci * 10800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 11800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 12800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 14800b99b8Sopenharmony_ci * limitations under the License. 15800b99b8Sopenharmony_ci */ 16800b99b8Sopenharmony_ci#ifndef DFX_DWARF_EXPRESSION_H 17800b99b8Sopenharmony_ci#define DFX_DWARF_EXPRESSION_H 18800b99b8Sopenharmony_ci 19800b99b8Sopenharmony_ci#include <cinttypes> 20800b99b8Sopenharmony_ci#include <deque> 21800b99b8Sopenharmony_ci#include <type_traits> 22800b99b8Sopenharmony_ci#include <memory> 23800b99b8Sopenharmony_ci#include "dfx_errors.h" 24800b99b8Sopenharmony_ci#include "dfx_instr_statistic.h" 25800b99b8Sopenharmony_ci#include "dfx_memory.h" 26800b99b8Sopenharmony_ci#include "dfx_regs.h" 27800b99b8Sopenharmony_ci#include "dfx_regs_qut.h" 28800b99b8Sopenharmony_ci#include "dwarf_cfa_instructions.h" 29800b99b8Sopenharmony_ci 30800b99b8Sopenharmony_cinamespace OHOS { 31800b99b8Sopenharmony_cinamespace HiviewDFX { 32800b99b8Sopenharmony_ci// DWARF expressions describe how to compute a value or specify a location. 33800b99b8Sopenharmony_ci// They 2 are expressed in terms of DWARF operations that operate on a stack of values 34800b99b8Sopenharmony_citemplate <typename AddressType> 35800b99b8Sopenharmony_ciclass DwarfOp { 36800b99b8Sopenharmony_ci using SignedType = typename std::make_signed<AddressType>::type; 37800b99b8Sopenharmony_ci using UnsignedType = typename std::make_unsigned<AddressType>::type; 38800b99b8Sopenharmony_ci 39800b99b8Sopenharmony_cipublic: 40800b99b8Sopenharmony_ci DwarfOp(std::shared_ptr<DfxMemory> memory) : memory_(memory) {}; 41800b99b8Sopenharmony_ci virtual ~DwarfOp() = default; 42800b99b8Sopenharmony_ci 43800b99b8Sopenharmony_ci AddressType Eval(DfxRegs& regs, AddressType initStackValue, AddressType startPtr); 44800b99b8Sopenharmony_ci 45800b99b8Sopenharmony_ciprotected: 46800b99b8Sopenharmony_ci bool Decode(DfxRegs& regs, uintptr_t& addr); 47800b99b8Sopenharmony_ci 48800b99b8Sopenharmony_ci inline void StackReset(AddressType initialStackValue) 49800b99b8Sopenharmony_ci { 50800b99b8Sopenharmony_ci stack_.clear(); 51800b99b8Sopenharmony_ci stack_.push_front(initialStackValue); 52800b99b8Sopenharmony_ci }; 53800b99b8Sopenharmony_ci 54800b99b8Sopenharmony_ci inline void StackPush(AddressType value) 55800b99b8Sopenharmony_ci { 56800b99b8Sopenharmony_ci stack_.push_front(value); 57800b99b8Sopenharmony_ci } 58800b99b8Sopenharmony_ci 59800b99b8Sopenharmony_ci inline AddressType StackPop() 60800b99b8Sopenharmony_ci { 61800b99b8Sopenharmony_ci AddressType value = stack_.front(); 62800b99b8Sopenharmony_ci stack_.pop_front(); 63800b99b8Sopenharmony_ci return value; 64800b99b8Sopenharmony_ci } 65800b99b8Sopenharmony_ci 66800b99b8Sopenharmony_ci inline AddressType StackAt(size_t index) { return stack_[index]; } 67800b99b8Sopenharmony_ci inline size_t StackSize() { return stack_.size(); } 68800b99b8Sopenharmony_ci 69800b99b8Sopenharmony_ci /* DW_OP_addr DW_OP_constXs DW_OP_constXu */ 70800b99b8Sopenharmony_ci template <typename T> 71800b99b8Sopenharmony_ci inline void OpPush(T value) 72800b99b8Sopenharmony_ci { 73800b99b8Sopenharmony_ci StackPush(static_cast<AddressType>(value)); 74800b99b8Sopenharmony_ci }; 75800b99b8Sopenharmony_ci 76800b99b8Sopenharmony_ci /* DW_OP_deref */ 77800b99b8Sopenharmony_ci inline void OpDeref() 78800b99b8Sopenharmony_ci { 79800b99b8Sopenharmony_ci auto addr = static_cast<uintptr_t>(StackPop()); 80800b99b8Sopenharmony_ci uintptr_t val; 81800b99b8Sopenharmony_ci memory_->ReadUptr(addr, &val); 82800b99b8Sopenharmony_ci StackPush(static_cast<AddressType>(val)); 83800b99b8Sopenharmony_ci }; 84800b99b8Sopenharmony_ci 85800b99b8Sopenharmony_ci /* DW_OP_deref_size */ 86800b99b8Sopenharmony_ci void OpDerefSize(AddressType& exprPtr) 87800b99b8Sopenharmony_ci { 88800b99b8Sopenharmony_ci auto addr = static_cast<uintptr_t>(StackPop()); 89800b99b8Sopenharmony_ci AddressType value = 0; 90800b99b8Sopenharmony_ci uint8_t operand; 91800b99b8Sopenharmony_ci memory_->ReadU8(exprPtr, &operand, true); 92800b99b8Sopenharmony_ci switch (operand) { 93800b99b8Sopenharmony_ci case 1: { // 1 : read one byte length 94800b99b8Sopenharmony_ci uint8_t u8; 95800b99b8Sopenharmony_ci memory_->ReadU8(addr, &u8, true); 96800b99b8Sopenharmony_ci value = static_cast<AddressType>(u8); 97800b99b8Sopenharmony_ci } 98800b99b8Sopenharmony_ci break; 99800b99b8Sopenharmony_ci case 2: { // 2 : read two bytes length 100800b99b8Sopenharmony_ci uint16_t u16; 101800b99b8Sopenharmony_ci memory_->ReadU16(addr, &u16, true); 102800b99b8Sopenharmony_ci value = static_cast<AddressType>(u16); 103800b99b8Sopenharmony_ci } 104800b99b8Sopenharmony_ci break; 105800b99b8Sopenharmony_ci case 3: // 3 : read four bytes length 106800b99b8Sopenharmony_ci case 4: { // 4 : read four bytes length 107800b99b8Sopenharmony_ci uint32_t u32; 108800b99b8Sopenharmony_ci memory_->ReadU32(addr, &u32, true); 109800b99b8Sopenharmony_ci value = static_cast<AddressType>(u32); 110800b99b8Sopenharmony_ci } 111800b99b8Sopenharmony_ci break; 112800b99b8Sopenharmony_ci case 5: // 5 : read eight bytes length 113800b99b8Sopenharmony_ci case 6: // 6 : read eight bytes length 114800b99b8Sopenharmony_ci case 7: // 7 : read eight bytes length 115800b99b8Sopenharmony_ci case 8: { // 8 : read eight bytes length 116800b99b8Sopenharmony_ci uint64_t u64; 117800b99b8Sopenharmony_ci memory_->ReadU64(addr, &u64, true); 118800b99b8Sopenharmony_ci value = static_cast<AddressType>(u64); 119800b99b8Sopenharmony_ci } 120800b99b8Sopenharmony_ci break; 121800b99b8Sopenharmony_ci default: 122800b99b8Sopenharmony_ci break; 123800b99b8Sopenharmony_ci } 124800b99b8Sopenharmony_ci StackPush(static_cast<UnsignedType>(value)); 125800b99b8Sopenharmony_ci }; 126800b99b8Sopenharmony_ci 127800b99b8Sopenharmony_ci /* DW_OP_dup */ 128800b99b8Sopenharmony_ci inline void OpDup() 129800b99b8Sopenharmony_ci { 130800b99b8Sopenharmony_ci StackPush(StackAt(0)); 131800b99b8Sopenharmony_ci }; 132800b99b8Sopenharmony_ci 133800b99b8Sopenharmony_ci /* DW_OP_drop */ 134800b99b8Sopenharmony_ci inline void OpDrop() 135800b99b8Sopenharmony_ci { 136800b99b8Sopenharmony_ci StackPop(); 137800b99b8Sopenharmony_ci }; 138800b99b8Sopenharmony_ci 139800b99b8Sopenharmony_ci /* DW_OP_over */ 140800b99b8Sopenharmony_ci inline void OpOver() 141800b99b8Sopenharmony_ci { 142800b99b8Sopenharmony_ci StackPush(StackAt(1)); 143800b99b8Sopenharmony_ci }; 144800b99b8Sopenharmony_ci 145800b99b8Sopenharmony_ci /* DW_OP_pick */ 146800b99b8Sopenharmony_ci inline void OpPick(AddressType& exprPtr) 147800b99b8Sopenharmony_ci { 148800b99b8Sopenharmony_ci uint8_t reg; 149800b99b8Sopenharmony_ci memory_->ReadU8(exprPtr, ®, true); 150800b99b8Sopenharmony_ci if (reg > StackSize()) { 151800b99b8Sopenharmony_ci return; 152800b99b8Sopenharmony_ci } 153800b99b8Sopenharmony_ci AddressType value = StackAt(reg); 154800b99b8Sopenharmony_ci StackPush(value); 155800b99b8Sopenharmony_ci }; 156800b99b8Sopenharmony_ci 157800b99b8Sopenharmony_ci /* DW_OP_swap */ 158800b99b8Sopenharmony_ci inline void OpSwap() 159800b99b8Sopenharmony_ci { 160800b99b8Sopenharmony_ci AddressType oldValue = stack_[0]; 161800b99b8Sopenharmony_ci stack_[0] = stack_[1]; 162800b99b8Sopenharmony_ci stack_[1] = oldValue; 163800b99b8Sopenharmony_ci } 164800b99b8Sopenharmony_ci 165800b99b8Sopenharmony_ci /* DW_OP_rot */ 166800b99b8Sopenharmony_ci inline void OpRot() 167800b99b8Sopenharmony_ci { 168800b99b8Sopenharmony_ci AddressType top = stack_[0]; 169800b99b8Sopenharmony_ci stack_[0] = stack_[1]; 170800b99b8Sopenharmony_ci stack_[1] = stack_[2]; // 2:the index of the array 171800b99b8Sopenharmony_ci stack_[2] = top; // 2:the index of the array 172800b99b8Sopenharmony_ci } 173800b99b8Sopenharmony_ci 174800b99b8Sopenharmony_ci /* DW_OP_abs */ 175800b99b8Sopenharmony_ci inline void OpAbs() 176800b99b8Sopenharmony_ci { 177800b99b8Sopenharmony_ci SignedType signedValue = static_cast<SignedType>(stack_[0]); 178800b99b8Sopenharmony_ci if (signedValue < 0) { 179800b99b8Sopenharmony_ci signedValue = -signedValue; 180800b99b8Sopenharmony_ci } 181800b99b8Sopenharmony_ci stack_[0] = static_cast<AddressType>(signedValue); 182800b99b8Sopenharmony_ci }; 183800b99b8Sopenharmony_ci 184800b99b8Sopenharmony_ci /* DW_OP_and */ 185800b99b8Sopenharmony_ci inline void OpAnd() 186800b99b8Sopenharmony_ci { 187800b99b8Sopenharmony_ci AddressType top = StackPop(); 188800b99b8Sopenharmony_ci stack_[0] &= top; 189800b99b8Sopenharmony_ci }; 190800b99b8Sopenharmony_ci 191800b99b8Sopenharmony_ci /* DW_OP_div */ 192800b99b8Sopenharmony_ci inline void OpDiv() 193800b99b8Sopenharmony_ci { 194800b99b8Sopenharmony_ci AddressType top = StackPop(); 195800b99b8Sopenharmony_ci if (top == 0) { 196800b99b8Sopenharmony_ci return; 197800b99b8Sopenharmony_ci } 198800b99b8Sopenharmony_ci SignedType signedDivisor = static_cast<SignedType>(top); 199800b99b8Sopenharmony_ci SignedType signedDividend = static_cast<SignedType>(stack_[0]); 200800b99b8Sopenharmony_ci stack_[0] = static_cast<AddressType>(signedDividend / signedDivisor); 201800b99b8Sopenharmony_ci }; 202800b99b8Sopenharmony_ci 203800b99b8Sopenharmony_ci /* DW_OP_minus */ 204800b99b8Sopenharmony_ci inline void OpMinus() 205800b99b8Sopenharmony_ci { 206800b99b8Sopenharmony_ci AddressType top = StackPop(); 207800b99b8Sopenharmony_ci stack_[0] -= top; 208800b99b8Sopenharmony_ci }; 209800b99b8Sopenharmony_ci 210800b99b8Sopenharmony_ci /* DW_OP_mod */ 211800b99b8Sopenharmony_ci inline void OpMod() 212800b99b8Sopenharmony_ci { 213800b99b8Sopenharmony_ci AddressType top = StackPop(); 214800b99b8Sopenharmony_ci if (top == 0) { 215800b99b8Sopenharmony_ci return; 216800b99b8Sopenharmony_ci } 217800b99b8Sopenharmony_ci stack_[0] %= top; 218800b99b8Sopenharmony_ci }; 219800b99b8Sopenharmony_ci 220800b99b8Sopenharmony_ci /* DW_OP_mul */ 221800b99b8Sopenharmony_ci inline void OpMul() 222800b99b8Sopenharmony_ci { 223800b99b8Sopenharmony_ci AddressType top = StackPop(); 224800b99b8Sopenharmony_ci stack_[0] *= top; 225800b99b8Sopenharmony_ci }; 226800b99b8Sopenharmony_ci 227800b99b8Sopenharmony_ci inline void OpNeg() 228800b99b8Sopenharmony_ci { 229800b99b8Sopenharmony_ci SignedType signedValue = static_cast<SignedType>(stack_[0]); 230800b99b8Sopenharmony_ci stack_[0] = static_cast<AddressType>(-signedValue); 231800b99b8Sopenharmony_ci }; 232800b99b8Sopenharmony_ci 233800b99b8Sopenharmony_ci inline void OpNot() 234800b99b8Sopenharmony_ci { 235800b99b8Sopenharmony_ci stack_[0] = ~stack_[0]; 236800b99b8Sopenharmony_ci }; 237800b99b8Sopenharmony_ci 238800b99b8Sopenharmony_ci inline void OpOr() 239800b99b8Sopenharmony_ci { 240800b99b8Sopenharmony_ci AddressType top = StackPop(); 241800b99b8Sopenharmony_ci stack_[0] |= top; 242800b99b8Sopenharmony_ci }; 243800b99b8Sopenharmony_ci 244800b99b8Sopenharmony_ci inline void OpPlus() 245800b99b8Sopenharmony_ci { 246800b99b8Sopenharmony_ci AddressType top = StackPop(); 247800b99b8Sopenharmony_ci stack_[0] += top; 248800b99b8Sopenharmony_ci }; 249800b99b8Sopenharmony_ci 250800b99b8Sopenharmony_ci inline void OpPlusULEBConst(AddressType& exprPtr) 251800b99b8Sopenharmony_ci { 252800b99b8Sopenharmony_ci stack_[0] += memory_->ReadUleb128(exprPtr); 253800b99b8Sopenharmony_ci }; 254800b99b8Sopenharmony_ci 255800b99b8Sopenharmony_ci inline void OpShl() 256800b99b8Sopenharmony_ci { 257800b99b8Sopenharmony_ci AddressType top = StackPop(); 258800b99b8Sopenharmony_ci stack_[0] <<= top; 259800b99b8Sopenharmony_ci }; 260800b99b8Sopenharmony_ci 261800b99b8Sopenharmony_ci inline void OpShr() 262800b99b8Sopenharmony_ci { 263800b99b8Sopenharmony_ci AddressType top = StackPop(); 264800b99b8Sopenharmony_ci stack_[0] >>= top; 265800b99b8Sopenharmony_ci }; 266800b99b8Sopenharmony_ci 267800b99b8Sopenharmony_ci inline void OpShra() 268800b99b8Sopenharmony_ci { 269800b99b8Sopenharmony_ci AddressType top = StackPop(); 270800b99b8Sopenharmony_ci SignedType signedValue = static_cast<SignedType>(stack_[0]) >> top; 271800b99b8Sopenharmony_ci stack_[0] = static_cast<AddressType>(signedValue); 272800b99b8Sopenharmony_ci }; 273800b99b8Sopenharmony_ci 274800b99b8Sopenharmony_ci inline void OpXor() 275800b99b8Sopenharmony_ci { 276800b99b8Sopenharmony_ci AddressType top = StackPop(); 277800b99b8Sopenharmony_ci stack_[0] ^= top; 278800b99b8Sopenharmony_ci }; 279800b99b8Sopenharmony_ci 280800b99b8Sopenharmony_ci inline void OpSkip(AddressType& exprPtr) 281800b99b8Sopenharmony_ci { 282800b99b8Sopenharmony_ci int16_t offset; 283800b99b8Sopenharmony_ci memory_->ReadS16(exprPtr, &offset, true); 284800b99b8Sopenharmony_ci exprPtr = static_cast<AddressType>(exprPtr + offset); 285800b99b8Sopenharmony_ci }; 286800b99b8Sopenharmony_ci 287800b99b8Sopenharmony_ci // DW_OP_bra 288800b99b8Sopenharmony_ci inline void OpBra(AddressType& exprPtr) 289800b99b8Sopenharmony_ci { 290800b99b8Sopenharmony_ci AddressType top = StackPop(); 291800b99b8Sopenharmony_ci int16_t offset; 292800b99b8Sopenharmony_ci memory_->ReadS16(exprPtr, &offset, true); 293800b99b8Sopenharmony_ci if (top != 0) { 294800b99b8Sopenharmony_ci exprPtr = exprPtr + offset; 295800b99b8Sopenharmony_ci } 296800b99b8Sopenharmony_ci }; 297800b99b8Sopenharmony_ci 298800b99b8Sopenharmony_ci inline void OpEQ() 299800b99b8Sopenharmony_ci { 300800b99b8Sopenharmony_ci AddressType top = StackPop(); 301800b99b8Sopenharmony_ci stack_[0] = ((stack_[0] == top) ? 1 : 0); 302800b99b8Sopenharmony_ci }; 303800b99b8Sopenharmony_ci 304800b99b8Sopenharmony_ci inline void OpGE() 305800b99b8Sopenharmony_ci { 306800b99b8Sopenharmony_ci AddressType top = StackPop(); 307800b99b8Sopenharmony_ci stack_[0] = ((stack_[0] >= top) ? 1 : 0); 308800b99b8Sopenharmony_ci }; 309800b99b8Sopenharmony_ci 310800b99b8Sopenharmony_ci inline void OpGT() 311800b99b8Sopenharmony_ci { 312800b99b8Sopenharmony_ci AddressType top = StackPop(); 313800b99b8Sopenharmony_ci stack_[0] = ((stack_[0] > top) ? 1 : 0); 314800b99b8Sopenharmony_ci }; 315800b99b8Sopenharmony_ci 316800b99b8Sopenharmony_ci inline void OpLE() 317800b99b8Sopenharmony_ci { 318800b99b8Sopenharmony_ci AddressType top = StackPop(); 319800b99b8Sopenharmony_ci stack_[0] = ((stack_[0] <= top) ? 1 : 0); 320800b99b8Sopenharmony_ci }; 321800b99b8Sopenharmony_ci 322800b99b8Sopenharmony_ci inline void OpLT() 323800b99b8Sopenharmony_ci { 324800b99b8Sopenharmony_ci AddressType top = StackPop(); 325800b99b8Sopenharmony_ci stack_[0] = ((stack_[0] < top) ? 1 : 0); 326800b99b8Sopenharmony_ci }; 327800b99b8Sopenharmony_ci 328800b99b8Sopenharmony_ci inline void OpNE() 329800b99b8Sopenharmony_ci { 330800b99b8Sopenharmony_ci AddressType top = StackPop(); 331800b99b8Sopenharmony_ci stack_[0] = ((stack_[0] != top) ? 1 : 0); 332800b99b8Sopenharmony_ci }; 333800b99b8Sopenharmony_ci 334800b99b8Sopenharmony_ci // DW_OP_litXX 335800b99b8Sopenharmony_ci inline void OpLit(uint8_t opcode) 336800b99b8Sopenharmony_ci { 337800b99b8Sopenharmony_ci stack_.push_front(opcode - DW_OP_lit0); 338800b99b8Sopenharmony_ci }; 339800b99b8Sopenharmony_ci 340800b99b8Sopenharmony_ci // DW_OP_regXX 341800b99b8Sopenharmony_ci inline void OpReg(uint8_t opcode, DfxRegs& regs) 342800b99b8Sopenharmony_ci { 343800b99b8Sopenharmony_ci auto reg = static_cast<UnsignedType>(opcode - DW_OP_reg0); 344800b99b8Sopenharmony_ci size_t qutIdx = 0; 345800b99b8Sopenharmony_ci if (!DfxRegsQut::IsQutReg(static_cast<uint16_t>(reg), qutIdx)) { 346800b99b8Sopenharmony_ci INSTR_STATISTIC(UnsupportedDwarfOp_Reg, reg, UNW_ERROR_UNSUPPORTED_QUT_REG); 347800b99b8Sopenharmony_ci return; 348800b99b8Sopenharmony_ci } 349800b99b8Sopenharmony_ci stack_.push_front(regs[reg]); 350800b99b8Sopenharmony_ci }; 351800b99b8Sopenharmony_ci 352800b99b8Sopenharmony_ci // DW_OP_regx 353800b99b8Sopenharmony_ci inline void OpRegx(AddressType& exprPtr, DfxRegs& regs) 354800b99b8Sopenharmony_ci { 355800b99b8Sopenharmony_ci auto reg = static_cast<uint32_t>(memory_->ReadUleb128(exprPtr)); 356800b99b8Sopenharmony_ci size_t qutIdx = 0; 357800b99b8Sopenharmony_ci if (!DfxRegsQut::IsQutReg(static_cast<uint16_t>(reg), qutIdx)) { 358800b99b8Sopenharmony_ci INSTR_STATISTIC(UnsupportedDwarfOp_Regx, reg, UNW_ERROR_UNSUPPORTED_QUT_REG); 359800b99b8Sopenharmony_ci return; 360800b99b8Sopenharmony_ci } 361800b99b8Sopenharmony_ci stack_.push_front(regs[reg]); 362800b99b8Sopenharmony_ci }; 363800b99b8Sopenharmony_ci 364800b99b8Sopenharmony_ci inline void OpBReg(uint8_t opcode, AddressType& exprPtr, DfxRegs& regs) 365800b99b8Sopenharmony_ci { 366800b99b8Sopenharmony_ci auto reg = static_cast<uint32_t>(opcode - DW_OP_breg0); 367800b99b8Sopenharmony_ci size_t qutIdx = 0; 368800b99b8Sopenharmony_ci if (!DfxRegsQut::IsQutReg(static_cast<uint16_t>(reg), qutIdx)) { 369800b99b8Sopenharmony_ci INSTR_STATISTIC(UnsupportedDwarfOp_Breg, reg, UNW_ERROR_UNSUPPORTED_QUT_REG); 370800b99b8Sopenharmony_ci return; 371800b99b8Sopenharmony_ci } 372800b99b8Sopenharmony_ci auto value = static_cast<SignedType>(memory_->ReadSleb128(exprPtr)); 373800b99b8Sopenharmony_ci value += static_cast<SignedType>(regs[reg]); 374800b99b8Sopenharmony_ci stack_.push_front(value); 375800b99b8Sopenharmony_ci }; 376800b99b8Sopenharmony_ci 377800b99b8Sopenharmony_ci inline void OpBRegx(AddressType& exprPtr, DfxRegs& regs) 378800b99b8Sopenharmony_ci { 379800b99b8Sopenharmony_ci auto reg = static_cast<uint32_t>(memory_->ReadUleb128(exprPtr)); 380800b99b8Sopenharmony_ci size_t qutIdx = 0; 381800b99b8Sopenharmony_ci if (!DfxRegsQut::IsQutReg(static_cast<uint16_t>(reg), qutIdx)) { 382800b99b8Sopenharmony_ci INSTR_STATISTIC(UnsupportedDwarfOp_Bregx, reg, UNW_ERROR_UNSUPPORTED_QUT_REG); 383800b99b8Sopenharmony_ci return; 384800b99b8Sopenharmony_ci } 385800b99b8Sopenharmony_ci auto value = static_cast<SignedType>(memory_->ReadSleb128(exprPtr)); 386800b99b8Sopenharmony_ci value += static_cast<SignedType>(regs[reg]); 387800b99b8Sopenharmony_ci stack_.push_front(value); 388800b99b8Sopenharmony_ci }; 389800b99b8Sopenharmony_ci 390800b99b8Sopenharmony_ci inline void OpNop(uint8_t opcode) 391800b99b8Sopenharmony_ci { 392800b99b8Sopenharmony_ci // log un-implemmented operate codes 393800b99b8Sopenharmony_ci }; 394800b99b8Sopenharmony_ci 395800b99b8Sopenharmony_ciprotected: 396800b99b8Sopenharmony_ci std::shared_ptr<DfxMemory> memory_; 397800b99b8Sopenharmony_ci std::deque<AddressType> stack_; 398800b99b8Sopenharmony_ci}; 399800b99b8Sopenharmony_ci} // nameapace HiviewDFX 400800b99b8Sopenharmony_ci} // nameapace OHOS 401800b99b8Sopenharmony_ci#endif