• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "dfx_ark.h"
17 
18 #include <algorithm>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <dlfcn.h>
22 #include <pthread.h>
23 
24 #include "dfx_define.h"
25 #include "dfx_log.h"
26 #include "string_util.h"
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 #undef LOG_DOMAIN
32 #undef LOG_TAG
33 #define LOG_DOMAIN 0xD002D11
34 #define LOG_TAG "DfxArk"
35 
36 const char ARK_LIB_NAME[] = "libark_jsruntime.so";
37 
38 void* g_handle = nullptr;
39 pthread_mutex_t g_mutex;
40 int (*g_getArkNativeFrameInfoFn)(int, uintptr_t*, uintptr_t*, uintptr_t*, JsFrame*, size_t&);
41 int (*g_stepArkFn)(void*, OHOS::HiviewDFX::ReadMemFunc, uintptr_t*, uintptr_t*, uintptr_t*, uintptr_t*, bool*);
42 int (*g_stepArkWithJitFn)(OHOS::HiviewDFX::ArkUnwindParam*);
43 int (*g_jitCodeWriteFileFn)(void*, OHOS::HiviewDFX::ReadMemFunc, int, const uintptr_t* const, const size_t);
44 int (*g_parseArkFileInfoFn)(uintptr_t, uintptr_t, uintptr_t, const char*, uintptr_t, JsFunction*);
45 int (*g_parseArkFrameInfoLocalFn)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, JsFunction*);
46 int (*g_parseArkFrameInfoFn)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uint8_t*, uint64_t, uintptr_t, JsFunction*);
47 int (*g_translateArkFrameInfoFn)(uint8_t*, uint64_t, JsFunction*);
48 int (*g_arkCreateJsSymbolExtractorFn)(uintptr_t*);
49 int (*g_arkDestoryJsSymbolExtractorFn)(uintptr_t);
50 
GetLibArkHandle()51 bool GetLibArkHandle()
52 {
53     if (g_handle != nullptr) {
54         return true;
55     }
56     g_handle = dlopen(ARK_LIB_NAME, RTLD_LAZY);
57     if (g_handle == nullptr) {
58         LOGU("Failed to load library(%s).", dlerror());
59         return false;
60     }
61     return true;
62 }
63 }
64 
65 #define DLSYM_ARK_FUNC(FuncName, DlsymFuncName) { \
66     pthread_mutex_lock(&g_mutex); \
67     do { \
68         if ((DlsymFuncName) != nullptr) { \
69             break; \
70         } \
71         if (!GetLibArkHandle()) { \
72             break; \
73         } \
74         *(void**)(&(DlsymFuncName)) = dlsym(g_handle, (FuncName)); \
75         if ((DlsymFuncName) == NULL) { \
76             LOGE("Failed to dlsym(%s), error: %s", (FuncName), dlerror()); \
77             break; \
78         } \
79     } while (false); \
80     pthread_mutex_unlock(&g_mutex); \
81 }
82 
ArkCreateJsSymbolExtractor(uintptr_t * extractorPtr)83 int DfxArk::ArkCreateJsSymbolExtractor(uintptr_t* extractorPtr)
84 {
85     if (g_arkCreateJsSymbolExtractorFn != nullptr) {
86         return g_arkCreateJsSymbolExtractorFn(extractorPtr);
87     }
88 
89     const char* arkFuncName = "ark_create_js_symbol_extractor";
90     DLSYM_ARK_FUNC(arkFuncName, g_arkCreateJsSymbolExtractorFn)
91 
92     if (g_arkCreateJsSymbolExtractorFn != nullptr) {
93         return g_arkCreateJsSymbolExtractorFn(extractorPtr);
94     }
95     return -1;
96 }
97 
ArkDestoryJsSymbolExtractor(uintptr_t extractorPtr)98 int DfxArk::ArkDestoryJsSymbolExtractor(uintptr_t extractorPtr)
99 {
100     if (g_arkDestoryJsSymbolExtractorFn != nullptr) {
101         return g_arkDestoryJsSymbolExtractorFn(extractorPtr);
102     }
103 
104     const char* arkFuncName = "ark_destory_js_symbol_extractor";
105     DLSYM_ARK_FUNC(arkFuncName, g_arkDestoryJsSymbolExtractorFn)
106 
107     if (g_arkDestoryJsSymbolExtractorFn != nullptr) {
108         return g_arkDestoryJsSymbolExtractorFn(extractorPtr);
109     }
110     return -1;
111 }
112 
ParseArkFileInfo(uintptr_t byteCodePc,uintptr_t methodid,uintptr_t mapBase,const char * name,uintptr_t extractorPtr,JsFunction * jsFunction)113 int DfxArk::ParseArkFileInfo(uintptr_t byteCodePc, uintptr_t methodid, uintptr_t mapBase, const char* name,
114     uintptr_t extractorPtr, JsFunction *jsFunction)
115 {
116     if (g_parseArkFileInfoFn != nullptr) {
117         return g_parseArkFileInfoFn(byteCodePc, methodid, mapBase, name, extractorPtr, jsFunction);
118     }
119 
120     const char* arkFuncName = "ark_parse_js_file_info";
121     DLSYM_ARK_FUNC(arkFuncName, g_parseArkFileInfoFn)
122 
123     if (g_parseArkFileInfoFn != nullptr) {
124         return g_parseArkFileInfoFn(byteCodePc, methodid, mapBase, name, extractorPtr, jsFunction);
125     }
126     return -1;
127 }
128 
ParseArkFrameInfoLocal(uintptr_t byteCodePc,uintptr_t methodid,uintptr_t mapBase,uintptr_t offset,JsFunction * jsFunction)129 int DfxArk::ParseArkFrameInfoLocal(uintptr_t byteCodePc, uintptr_t methodid, uintptr_t mapBase,
130     uintptr_t offset, JsFunction *jsFunction)
131 {
132     if (g_parseArkFrameInfoLocalFn != nullptr) {
133         return g_parseArkFrameInfoLocalFn(byteCodePc, methodid, mapBase, offset, jsFunction);
134     }
135 
136     const char* arkFuncName = "ark_parse_js_frame_info_local";
137     DLSYM_ARK_FUNC(arkFuncName, g_parseArkFrameInfoLocalFn)
138 
139     if (g_parseArkFrameInfoLocalFn != nullptr) {
140         return g_parseArkFrameInfoLocalFn(byteCodePc, methodid, mapBase, offset, jsFunction);
141     }
142     return -1;
143 }
144 
ParseArkFrameInfo(uintptr_t byteCodePc,uintptr_t mapBase,uintptr_t loadOffset,uint8_t * data,uint64_t dataSize,uintptr_t extractorPtr,JsFunction * jsFunction)145 int DfxArk::ParseArkFrameInfo(uintptr_t byteCodePc, uintptr_t mapBase, uintptr_t loadOffset,
146     uint8_t *data, uint64_t dataSize, uintptr_t extractorPtr, JsFunction *jsFunction)
147 {
148     return ParseArkFrameInfo(byteCodePc, 0, mapBase, loadOffset, data, dataSize, extractorPtr, jsFunction);
149 }
150 
ParseArkFrameInfo(uintptr_t byteCodePc,uintptr_t methodid,uintptr_t mapBase,uintptr_t loadOffset,uint8_t * data,uint64_t dataSize,uintptr_t extractorPtr,JsFunction * jsFunction)151 int DfxArk::ParseArkFrameInfo(uintptr_t byteCodePc, uintptr_t methodid, uintptr_t mapBase, uintptr_t loadOffset,
152     uint8_t *data, uint64_t dataSize, uintptr_t extractorPtr, JsFunction *jsFunction)
153 {
154     if (g_parseArkFrameInfoFn != nullptr) {
155         return g_parseArkFrameInfoFn(byteCodePc, methodid, mapBase, loadOffset, data, dataSize,
156             extractorPtr, jsFunction);
157     }
158 
159     const char* arkFuncName = "ark_parse_js_frame_info";
160     DLSYM_ARK_FUNC(arkFuncName, g_parseArkFrameInfoFn)
161 
162     if (g_parseArkFrameInfoFn != nullptr) {
163         return g_parseArkFrameInfoFn(byteCodePc, methodid, mapBase, loadOffset, data, dataSize,
164             extractorPtr, jsFunction);
165     }
166     return -1;
167 }
168 
TranslateArkFrameInfo(uint8_t * data,uint64_t dataSize,JsFunction * jsFunction)169 int DfxArk::TranslateArkFrameInfo(uint8_t *data, uint64_t dataSize, JsFunction *jsFunction)
170 {
171     if (g_translateArkFrameInfoFn != nullptr) {
172         return g_translateArkFrameInfoFn(data, dataSize, jsFunction);
173     }
174 
175     const char* arkFuncName = "ark_translate_js_frame_info";
176     DLSYM_ARK_FUNC(arkFuncName, g_translateArkFrameInfoFn)
177 
178     if (g_translateArkFrameInfoFn != nullptr) {
179         return g_translateArkFrameInfoFn(data, dataSize, jsFunction);
180     }
181     return -1;
182 }
183 
StepArkFrame(void * obj,OHOS::HiviewDFX::ReadMemFunc readMemFn,uintptr_t * fp,uintptr_t * sp,uintptr_t * pc,uintptr_t * methodid,bool * isJsFrame)184 int DfxArk::StepArkFrame(void *obj, OHOS::HiviewDFX::ReadMemFunc readMemFn,
185     uintptr_t *fp, uintptr_t *sp, uintptr_t *pc, uintptr_t* methodid, bool *isJsFrame)
186 {
187     if (g_stepArkFn != nullptr) {
188         return g_stepArkFn(obj, readMemFn, fp, sp, pc, methodid, isJsFrame);
189     }
190 
191     const char* arkFuncName = "step_ark";
192     DLSYM_ARK_FUNC(arkFuncName, g_stepArkFn)
193 
194     if (g_stepArkFn != nullptr) {
195         return g_stepArkFn(obj, readMemFn, fp, sp, pc, methodid, isJsFrame);
196     }
197     return -1;
198 }
199 
StepArkFrameWithJit(OHOS::HiviewDFX::ArkUnwindParam * arkPrama)200 int DfxArk::StepArkFrameWithJit(OHOS::HiviewDFX::ArkUnwindParam* arkPrama)
201 {
202     if (g_stepArkWithJitFn != nullptr) {
203         return g_stepArkWithJitFn(arkPrama);
204     }
205 
206     const char* const arkFuncName = "step_ark_with_record_jit";
207     DLSYM_ARK_FUNC(arkFuncName, g_stepArkWithJitFn)
208 
209     if (g_stepArkWithJitFn != nullptr) {
210         return g_stepArkWithJitFn(arkPrama);
211     }
212     return -1;
213 }
214 
JitCodeWriteFile(void * ctx,OHOS::HiviewDFX::ReadMemFunc readMemFn,int fd,const uintptr_t * const jitCodeArray,const size_t jitSize)215 int DfxArk::JitCodeWriteFile(void* ctx, OHOS::HiviewDFX::ReadMemFunc readMemFn, int fd,
216     const uintptr_t* const jitCodeArray, const size_t jitSize)
217 {
218     if (g_jitCodeWriteFileFn != nullptr) {
219         return g_jitCodeWriteFileFn(ctx, readMemFn, fd, jitCodeArray, jitSize);
220     }
221 
222     const char* const arkFuncName = "ark_write_jit_code";
223     DLSYM_ARK_FUNC(arkFuncName, g_jitCodeWriteFileFn)
224 
225     if (g_jitCodeWriteFileFn != nullptr) {
226         return g_jitCodeWriteFileFn(ctx, readMemFn, fd, jitCodeArray, jitSize);
227     }
228     return -1;
229 }
230 
GetArkNativeFrameInfo(int pid,uintptr_t & pc,uintptr_t & fp,uintptr_t & sp,JsFrame * frames,size_t & size)231 int DfxArk::GetArkNativeFrameInfo(int pid, uintptr_t& pc, uintptr_t& fp, uintptr_t& sp, JsFrame* frames, size_t& size)
232 {
233     if (g_getArkNativeFrameInfoFn != nullptr) {
234         return g_getArkNativeFrameInfoFn(pid, &pc, &fp, &sp, frames, size);
235     }
236 
237     const char* arkFuncName = "get_ark_native_frame_info";
238     DLSYM_ARK_FUNC(arkFuncName, g_getArkNativeFrameInfoFn)
239 
240     if (g_getArkNativeFrameInfoFn != nullptr) {
241         return g_getArkNativeFrameInfoFn(pid, &pc, &fp, &sp, frames, size);
242     }
243     return -1;
244 }
245 } // namespace HiviewDFX
246 } // namespace OHOS
247