1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_DFX_STACKINFO_JS_STACKINFO_TEST_H 17 #define ECMASCRIPT_DFX_STACKINFO_JS_STACKINFO_TEST_H 18 19 #include <cstdio> 20 #include <cstdint> 21 22 #define E_OK 0 23 #define E_INVAL (-1) 24 25 #define LAZY_DEOPT_FLAG_BIT1 30 26 27 #define mask_of_frame_type(frame_type) (1UL << (frame_type)) 28 #define build_frame_type_mask0 0 29 #define build_frame_type_mask1(frame_type) mask_of_frame_type(frame_type) 30 #define build_frame_type_mask2(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask1(__VA_ARGS__) 31 #define build_frame_type_mask3(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask2(__VA_ARGS__) 32 #define build_frame_type_mask4(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask3(__VA_ARGS__) 33 #define build_frame_type_mask5(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask4(__VA_ARGS__) 34 #define build_frame_type_mask6(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask5(__VA_ARGS__) 35 #define build_frame_type_mask7(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask6(__VA_ARGS__) 36 #define build_frame_type_mask8(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask7(__VA_ARGS__) 37 #define build_frame_type_mask9(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask8(__VA_ARGS__) 38 #define build_frame_type_mask10(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask9(__VA_ARGS__) 39 #define build_frame_type_mask11(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask10(__VA_ARGS__) 40 #define build_frame_type_mask12(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask11(__VA_ARGS__) 41 #define build_frame_type_mask13(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask12(__VA_ARGS__) 42 #define build_frame_type_mask14(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask13(__VA_ARGS__) 43 #define build_frame_type_mask15(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask14(__VA_ARGS__) 44 #define build_frame_type_mask16(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask15(__VA_ARGS__) 45 #define build_frame_type_mask17(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask16(__VA_ARGS__) 46 #define build_frame_type_mask18(frame_type, ...) mask_of_frame_type(frame_type) | build_frame_type_mask17(__VA_ARGS__) 47 48 #define VA_ARGS_NUM(...) VA_ARGS_NUM_IMPL(__VA_ARGS__, 18, 17, 16, 15, 14, 13, 12, \ 49 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 50 #define VA_ARGS_NUM_IMPL(x, y, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, count, ...) count 51 52 #define __build_frame_type_mask(n, ...) (build_frame_type_mask##n(__VA_ARGS__)) 53 #define build_frame_type_mask(n, ...) __build_frame_type_mask(n, __VA_ARGS__) 54 #define is_frame_type(frame_type, max_frame_type, ...) (((frame_type) <= (max_frame_type)) \ 55 && ((mask_of_frame_type(frame_type) & \ 56 build_frame_type_mask(VA_ARGS_NUM(__VA_ARGS__), __VA_ARGS__)) != 0UL)) 57 58 struct unwind_user_context_s { 59 int count; read_memunwind_user_context_s60 int read_mem(unwind_user_context_s *ctx, uintptr_t addr, uintptr_t *value, [[maybe_unused]] size_t size) 61 { 62 if (count == -1) { // -1: means no check 63 *value = *reinterpret_cast<uintptr_t *>(addr); 64 return E_OK; 65 } else if (count == 0) { 66 return E_INVAL; 67 } else { 68 *value = *reinterpret_cast<uintptr_t *>(addr); 69 count--; 70 return E_OK; 71 } 72 } 73 }; 74 75 void unwind_user_finish(unwind_user_context_s *ctx); 76 77 struct unwind_stack_frame_s { 78 uintptr_t fp; 79 uintptr_t pc; 80 }; 81 82 void mem_zero_s(unwind_stack_frame_s &frame); 83 84 #define UNWIND_FRAME_EMPTY { 0, 0 } 85 86 enum arkts_frame_type { 87 OPTIMIZED_FRAME = 0, 88 OPTIMIZED_ENTRY_FRAME, 89 OPTIMIZED_JS_FUNCTION_FRAME, 90 OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME, 91 FASTJIT_FUNCTION_FRAME, 92 FASTJIT_FAST_CALL_FUNCTION_FRAME, 93 ASM_BRIDGE_FRAME, 94 LEAVE_FRAME, 95 LEAVE_FRAME_WITH_ARGV, 96 BUILTIN_CALL_LEAVE_FRAME, 97 INTERPRETER_FRAME, 98 ASM_INTERPRETER_FRAME, 99 INTERPRETER_CONSTRUCTOR_FRAME, 100 BUILTIN_FRAME, 101 BUILTIN_FRAME_WITH_ARGV, 102 BUILTIN_ENTRY_FRAME, 103 INTERPRETER_BUILTIN_FRAME, 104 INTERPRETER_FAST_NEW_FRAME, 105 INTERPRETER_ENTRY_FRAME, 106 ASM_INTERPRETER_ENTRY_FRAME, 107 ASM_INTERPRETER_BRIDGE_FRAME, 108 OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME, 109 OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME, 110 BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME, 111 BASELINE_BUILTIN_FRAME, 112 FRAME_TYPE_MAX, 113 114 FRAME_TYPE_FIRST = OPTIMIZED_FRAME, 115 FRAME_TYPE_LAST = OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME, 116 INTERPRETER_FIRST = INTERPRETER_FRAME, 117 INTERPRETER_LAST = INTERPRETER_FAST_NEW_FRAME, 118 BUILTIN_FIRST = BUILTIN_FRAME, 119 BUILTIN_LAST = BUILTIN_ENTRY_FRAME, 120 }; 121 122 struct frame_offset_s { 123 int type_offset; 124 int fp_offset; 125 int pc_offset; 126 }; 127 128 #define define_offset(__type, __type_offset, __fp_offset, __pc_offset) \ 129 [__type] = \ 130 { \ 131 .type_offset = (__type_offset), \ 132 .fp_offset = (__fp_offset), \ 133 .pc_offset = (__pc_offset), \ 134 } 135 136 static frame_offset_s frame_offset_table64[] = { 137 define_offset(OPTIMIZED_FRAME, 0, 8, 16), 138 define_offset(OPTIMIZED_ENTRY_FRAME, 8, 0, -1), 139 define_offset(OPTIMIZED_JS_FUNCTION_FRAME, 8, 16, 24), 140 define_offset(OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME, 8, 16, 24), 141 define_offset(FASTJIT_FUNCTION_FRAME, 16, 24, 0), 142 define_offset(FASTJIT_FAST_CALL_FUNCTION_FRAME, 16, 24, 0), 143 define_offset(ASM_BRIDGE_FRAME, 0, 8, 16), 144 define_offset(LEAVE_FRAME, 0, 8, 16), 145 define_offset(LEAVE_FRAME_WITH_ARGV, 0, 8, 16), 146 define_offset(BUILTIN_CALL_LEAVE_FRAME, 0, 8, 16), 147 define_offset(INTERPRETER_FRAME, 64, 56, 48), 148 define_offset(ASM_INTERPRETER_FRAME, 64, 56, 48), 149 define_offset(INTERPRETER_CONSTRUCTOR_FRAME, 64, 56, 48), 150 define_offset(BUILTIN_FRAME, 0, 8, 16), 151 define_offset(BUILTIN_FRAME_WITH_ARGV, 0, 8, 16), 152 define_offset(BUILTIN_ENTRY_FRAME, 0, 8, 16), 153 define_offset(INTERPRETER_BUILTIN_FRAME, 24, 16, -1), 154 define_offset(INTERPRETER_FAST_NEW_FRAME, 64, 56, 48), 155 define_offset(INTERPRETER_ENTRY_FRAME, 16, 8, -1), 156 define_offset(ASM_INTERPRETER_ENTRY_FRAME, 16, 8, -1), 157 define_offset(ASM_INTERPRETER_BRIDGE_FRAME, 16, 8, 24), 158 define_offset(OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME, 8, 16, 24), 159 define_offset(OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME, 8, 16, 24), 160 define_offset(BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME, 0, 8, 16), 161 define_offset(BASELINE_BUILTIN_FRAME, 0, 8, 16), 162 }; 163 164 bool is_entry_frame(unsigned int frame_type); 165 bool is_js_function_frame(unsigned int frame_type); 166 bool is_native_function_frame(unsigned int frame_type); 167 uintptr_t calc_pc_addr_from_fp_addr(uintptr_t fp_addr, unsigned int frame_type); 168 uintptr_t calc_fp_addr_from_fp_addr(uintptr_t fp_addr, unsigned int frame_type); 169 uintptr_t clear_lazy_deopt_flag(uintptr_t frame_type_raw); 170 int next_ark_frame(unwind_user_context_s *ctx, uintptr_t fp_addr, unsigned int curr_frame_type, 171 unwind_stack_frame_s *frame, bool *ret_frame_avail); 172 int next_ark_frame(unwind_user_context_s *ctx, uintptr_t fp_addr, 173 unwind_stack_frame_s *frame, unsigned int *ret_frame_type); 174 unwind_stack_frame_s step_ark_frame(unwind_user_context_s *ctx, 175 const unwind_stack_frame_s *cur_frame); 176 unwind_stack_frame_s unwind_arkts(unwind_user_context_s *context, 177 const unwind_stack_frame_s *cur_frame); 178 179 #endif // ECMASCRIPT_DFX_STACKINFO_JS_STACKINFO_TEST_H