• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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