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, &reg, 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