• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 The hook mode has 3 kinds which can be set by command "param set":
3 (1) param set libc.hook_mode "startup:\"prog1 \""
4 (2) param set libc.hook_mode startup:program1
5 (3) param set libc.hook_mode step
6 (4) param set libc.hook_mode direct
7 
8 Case 1 represents "startup" mode, and the hooked process is "prog1 ",
9 which loads hooking shared library when the program starts up.
10 The path is added with two quotation marks because a quotation mark is a special charcter,
11 which need be escaped.
12 (2) is similar with (1), but no escaped character, so quotation marks doesn't need.
13 (3) represents "step" mode, which loads hooking shared library by some steps.
14 (4) represetnt  "direct" mode, which loads hooking shared library by a step.
15 */
16 
17 #ifdef HOOK_ENABLE
18 #include <unistd.h>
19 #include <signal.h>
20 #include "musl_malloc_dispatch_table.h"
21 #include "musl_malloc.h"
22 #include "memory_tag.h"
23 #include "musl_preinit_common.h"
24 #ifdef OHOS_ENABLE_PARAMETER
25 #include "sys_param.h"
26 #endif
27 #include <pthread.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <dlfcn.h>
31 #include <errno.h>
32 #include <stdatomic.h>
33 #include <ctype.h>
34 #include <assert.h>
35 #include <string.h>
36 #include <malloc.h>
37 
38 void* ohos_malloc_hook_init_function(size_t bytes);
39 
40 static struct MallocDispatchType __ohos_malloc_hook_init_dispatch = {
41 	.malloc = ohos_malloc_hook_init_function,
42 	.free = MuslMalloc(free),
43 	.mmap = MuslMalloc(mmap),
44 	.munmap = MuslMalloc(munmap),
45 	.calloc = MuslMalloc(calloc),
46 	.realloc = MuslMalloc(realloc),
47 };
48 #define MAX_SYM_NAME_SIZE 1000
49 #define MAX_PROC_NAME_SIZE 256
50 #define ADDR_NATIVE_ENABLE (1<<4)
51 #define ADDR_NATIVE_DISABLE (1<<5)
52 #define ADDR_NATIVE_SAVE (1<<6)
53 #define ADDR_NATIVE_CLEAR (1<<7)
54 static char *__malloc_hook_shared_lib = "libnative_hook.z.so";
55 static char *__malloc_hook_function_prefix = "ohos_malloc_hook";
56 volatile atomic_llong ohos_malloc_hook_shared_library;
57 static char *kMemTrackSharedLib = "libmemleak_tracker.so";
58 static char *kMemTrackPrefix = "track";
59 static char *kMemTrackPropertyEnable = "const.hiview.memleak_tracker.enable";
60 static char *kMemTrackSign = "true";
61 bool checkLoadMallocMemTrack = false;
62 unsigned int memLeakTypeContent = 0;
63 volatile atomic_llong memleak_ever_shared_library_handle;
64 volatile atomic_llong ohos_malloc_ever_shared_library_handle;
65 void* function_of_shared_lib[LAST_FUNCTION];
66 void* function_of_ohos_malloc_shared_lib[LAST_FUNCTION];
67 void* function_of_memleak_shared_lib[LAST_FUNCTION];
68 static enum EnumHookMode __hook_mode = STEP_HOOK_MODE;
69 
get_native_hook_param(char * buf,unsigned int buf_len)70 static void  get_native_hook_param(char *buf, unsigned int buf_len)
71 {
72 #ifdef OHOS_ENABLE_PARAMETER
73 	const char *key =  MUSL_HOOK_PARAM_NAME;
74 	unsigned int len = buf_len;
75 	(void)SystemReadParam(key, buf, &len);
76 #else
77 	return;
78 #endif
79 }
80 
get_memleak_hook_param()81 static void  get_memleak_hook_param()
82 {
83 #ifdef OHOS_ENABLE_PARAMETER
84 	const char *key =  kMemTrackPropertyEnable;
85 	unsigned int len = OHOS_PARAM_MAX_SIZE;
86 	char memleak_param_value[OHOS_PARAM_MAX_SIZE + 1] = {0};
87 	(void)SystemReadParam(key, memleak_param_value, &len);
88 	if (strncmp(memleak_param_value, kMemTrackSign, strlen(kMemTrackSign)) == 0) {
89 		checkLoadMallocMemTrack = true;
90 	}
91 #else
92 	return;
93 #endif
94 }
95 
parse_hook_variable(enum EnumHookMode * mode,char * path,int size)96 static int parse_hook_variable(enum EnumHookMode* mode, char* path, int size)
97 {
98 	if (!mode || !path || size <= 0) {
99 		return -1;
100 	}
101 	char hook_param_value[OHOS_PARAM_MAX_SIZE + 1] = {0};
102 	unsigned int len = OHOS_PARAM_MAX_SIZE;
103 	get_native_hook_param(hook_param_value, len);
104 	if (hook_param_value[0] == '\0') {
105 		*mode = STEP_HOOK_MODE;
106 		path[0] = '\0';
107 	} else {
108 		char* ptr = hook_param_value;
109 		while (*ptr && *ptr != ':') {
110 			++ptr;
111 		}
112 
113 		if (*ptr == ':') {
114 			*ptr = '\0';
115 			++ptr;
116 		}
117 
118 		if (strcmp(hook_param_value, "startup") == 0) {
119 			*mode = STARTUP_HOOK_MODE;
120 		} else if (strcmp(hook_param_value, "direct") == 0) {
121 			*mode = DIRECT_HOOK_MODE;
122 		} else if (strcmp(hook_param_value, "step") == 0) {
123 			*mode = STEP_HOOK_MODE;
124 		} else {
125 			*mode = STEP_HOOK_MODE;
126 		}
127 		if (*mode == STARTUP_HOOK_MODE) {
128 			if (*ptr == '\"') {
129 				++ptr;
130 				int idx = 0;
131 				while (idx < size - 1 && *ptr && *ptr != '\"') {
132 					path[idx++] = *ptr++;
133 				}
134 				path[idx] = '\0';
135 			} else {
136 				int idx = 0;
137 				while (idx < size - 1 && *ptr) {
138 					path[idx++] = *ptr++;
139 				}
140 				path[idx] = '\0';
141 			}
142 		}
143 	}
144 	return 0;
145 }
146 
get_proc_name(pid_t pid,char * buf,unsigned int buf_len)147 static bool get_proc_name(pid_t pid, char *buf, unsigned int buf_len)
148 {
149 	if (pid <= 0) {
150 		return false;
151 	}
152 	char target_file[FILE_NAME_MAX_SIZE] = {0};
153 	(void)snprintf(target_file, sizeof(target_file), "/proc/%d/cmdline", pid);
154 	FILE *f = fopen(target_file, "r");
155 	if (f == NULL) {
156 		return false;
157 	}
158 	if (fgets(buf, buf_len, f) == NULL) {
159 		(void)fclose(f);
160 		return false;
161 	}
162 	(void)fclose(f);
163 	return true;
164 }
165 
init_malloc_function(void * malloc_shared_library_handler,MallocMallocType * func,const char * prefix)166 static bool init_malloc_function(void* malloc_shared_library_handler, MallocMallocType* func, const char* prefix)
167 {
168 	char symbol[MAX_SYM_NAME_SIZE];
169 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc");
170 	*func = (MallocMallocType)(dlsym(malloc_shared_library_handler, symbol));
171 	if (*func == NULL) {
172 		return false;
173 	}
174 	return true;
175 }
176 
init_free_function(void * malloc_shared_library_handler,MallocFreeType * func,const char * prefix)177 static bool init_free_function(void* malloc_shared_library_handler, MallocFreeType* func, const char* prefix)
178 {
179 	char symbol[MAX_SYM_NAME_SIZE];
180 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "free");
181 	*func = (MallocFreeType)(dlsym(malloc_shared_library_handler, symbol));
182 	if (*func == NULL) {
183 		return false;
184 	}
185 	return true;
186 }
187 
init_mmap_function(void * malloc_shared_library_handler,MallocMmapType * func,const char * prefix)188 static bool init_mmap_function(void* malloc_shared_library_handler, MallocMmapType* func, const char* prefix)
189 {
190 	char symbol[MAX_SYM_NAME_SIZE];
191 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "mmap");
192 	*func = (MallocMmapType)(dlsym(malloc_shared_library_handler, symbol));
193 	if (*func == NULL) {
194 		return false;
195 	}
196 	return true;
197 }
198 
init_munmap_function(void * malloc_shared_library_handler,MallocMunmapType * func,const char * prefix)199 static bool init_munmap_function(void* malloc_shared_library_handler, MallocMunmapType* func, const char* prefix)
200 {
201 	char symbol[MAX_SYM_NAME_SIZE];
202 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "munmap");
203 	*func = (MallocMunmapType)(dlsym(malloc_shared_library_handler, symbol));
204 	if (*func == NULL) {
205 		return false;
206 	}
207 	return true;
208 }
209 
init_memorytag_function(void * malloc_shared_library_handler,const char * prefix)210 static bool init_memorytag_function(void* malloc_shared_library_handler, const char* prefix)
211 {
212 	char symbol[MAX_SYM_NAME_SIZE];
213 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "memtag");
214 	__mem_typeset = (mtypeset)(dlsym(malloc_shared_library_handler, symbol));
215 
216 	if (__mem_typeset == NULL) {
217 		return false;
218 	}
219 	return true;
220 }
221 
init_calloc_function(void * malloc_shared_library_handler,MallocCallocType * func,const char * prefix)222 static bool init_calloc_function(void* malloc_shared_library_handler, MallocCallocType* func, const char* prefix)
223 {
224 	char symbol[MAX_SYM_NAME_SIZE];
225 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "calloc");
226 	*func = (MallocCallocType)(dlsym(malloc_shared_library_handler, symbol));
227 	if (*func == NULL) {
228 		return false;
229 	}
230 	return true;
231 }
232 
init_realloc_function(void * malloc_shared_library_handler,MallocReallocType * func,const char * prefix)233 static bool init_realloc_function(void* malloc_shared_library_handler, MallocReallocType* func, const char* prefix)
234 {
235 	char symbol[MAX_SYM_NAME_SIZE];
236 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "realloc");
237 	*func = (MallocReallocType)(dlsym(malloc_shared_library_handler, symbol));
238 	if (*func == NULL) {
239 		return false;
240 	}
241 	return true;
242 }
243 
init_malloc_usable_size_function(void * malloc_shared_library_handler,MallocMallocUsableSizeType * func,const char * prefix)244 static bool init_malloc_usable_size_function(void* malloc_shared_library_handler, MallocMallocUsableSizeType* func, const char* prefix)
245 {
246 	char symbol[MAX_SYM_NAME_SIZE];
247 	snprintf(symbol, sizeof(symbol), "%s_%s", prefix, "malloc_usable_size");
248 	*func = (MallocMallocUsableSizeType)(dlsym(malloc_shared_library_handler, symbol));
249 	if (*func == NULL) {
250 		return false;
251 	}
252 	return true;
253 }
254 
init_hook_functions(void * shared_library_handler,struct MallocDispatchType * table,const char * prefix)255 static bool init_hook_functions(void* shared_library_handler, struct MallocDispatchType* table, const char* prefix)
256 {
257 	if (!init_malloc_function(shared_library_handler, &table->malloc, prefix)) {
258 		return false;
259 	}
260 	if (!init_free_function(shared_library_handler, &table->free, prefix)) {
261 		return false;
262 	}
263 	if (!init_mmap_function(shared_library_handler, &table->mmap, prefix)) {
264 		return false;
265 	}
266 	if (!init_munmap_function(shared_library_handler, &table->munmap, prefix)) {
267 		return false;
268 	}
269 	if (!init_calloc_function(shared_library_handler, &table->calloc, prefix)) {
270 		return false;
271 	}
272 	if (!init_realloc_function(shared_library_handler, &table->realloc, prefix)) {
273 		return false;
274 	}
275 	if (!init_memorytag_function(shared_library_handler, prefix)) {
276 		return false;
277 	}
278 	if (!init_malloc_usable_size_function(shared_library_handler, &table->malloc_usable_size, prefix)) {
279 		return false;
280 	}
281 	return true;
282 }
283 
clear_function_table()284 static void clear_function_table()
285 {
286 	for (size_t i = 0; i < LAST_FUNCTION; i++) {
287 		function_of_shared_lib[i] = NULL;
288 		if (__get_memleak_hook_flag()) {
289 			function_of_memleak_shared_lib[i] = NULL;
290 		} else if (__get_global_hook_flag()) {
291 			function_of_ohos_malloc_shared_lib[i] = NULL;
292 		}
293 	}
294 }
295 
init_malloc_hook_shared_library(void * shared_library_handle,const char * shared_lib,const char * prefix,struct MallocDispatchType * dispatch_table)296 bool init_malloc_hook_shared_library(void* shared_library_handle, const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
297 {
298 	static const char* names[] = {
299 		"initialize",
300 		"finalize",
301 		"get_hook_flag",
302 		"set_hook_flag",
303 		"on_start",
304 		"on_end",
305 	};
306 
307 	for (int i = 0; i < LAST_FUNCTION; i++) {
308 		char symbol[MAX_SYM_NAME_SIZE];
309 		snprintf(symbol, sizeof(symbol), "%s_%s", prefix, names[i]);
310 		function_of_shared_lib[i] = dlsym(shared_library_handle, symbol);
311 		if (__get_memleak_hook_flag()) {
312 			function_of_memleak_shared_lib[i] = function_of_shared_lib[i];
313 		} else if (__get_global_hook_flag()) {
314 			function_of_ohos_malloc_shared_lib[i] = function_of_shared_lib[i];
315 		}
316 		if (function_of_shared_lib[i] == NULL) {
317 			// __musl_log(__MUSL_LOG_ERROR, "%s: %s routine not found in %s\n", getprogname(), symbol, shared_lib);
318 			clear_function_table();
319 			return false;
320 		}
321 	}
322 
323 	if (!init_hook_functions(shared_library_handle, dispatch_table, prefix)) {
324 		clear_function_table();
325 		return false;
326 	}
327 
328 	return true;
329 }
330 
load_malloc_hook_shared_library(const char * shared_lib,const char * prefix,struct MallocDispatchType * dispatch_table)331 void* load_malloc_hook_shared_library(const char* shared_lib, const char* prefix, struct MallocDispatchType* dispatch_table)
332 {
333 	void* shared_library_handle = NULL;
334 
335 	shared_library_handle = dlopen(shared_lib, RTLD_NOW | RTLD_LOCAL);
336 
337 	if (shared_library_handle == NULL) {
338 		printf("Unable to open shared library %s: %s\n", shared_lib, dlerror());
339 		return NULL;
340 	}
341 
342 	if (!init_malloc_hook_shared_library(shared_library_handle, shared_lib, prefix, dispatch_table)) {
343 		dlclose(shared_library_handle);
344 		shared_library_handle = NULL;
345 	}
346 	// printf("load_malloc_hook_shared_library success new version test\n");
347 	return shared_library_handle;
348 }
349 
350 typedef void (*finalize_func_t)();
351 typedef bool (*init_func_t)(const struct MallocDispatchType*, bool*, const char*);
352 typedef bool (*on_start_func_t)();
353 typedef bool (*on_end_func_t)();
354 
malloc_finalize()355 static void malloc_finalize()
356 {
357 	__set_hook_flag(false);
358 	((finalize_func_t)function_of_shared_lib[FINALIZE_FUNCTION])();
359 
360 	fclose(stdin);
361 	fclose(stdout);
362 	fclose(stderr);
363 }
364 
finish_install_ohos_malloc_hooks(struct musl_libc_globals * globals,const char * options,const char * prefix)365 bool finish_install_ohos_malloc_hooks(struct musl_libc_globals* globals, const char* options, const char* prefix)
366 {
367 	init_func_t init_func = (init_func_t)(function_of_shared_lib[INITIALIZE_FUNCTION]);
368 	if (!init_func(&__libc_malloc_default_dispatch, NULL, options)) {
369 		// __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc %s\n", getprogname(), prefix);
370 		clear_function_table();
371 		return false;
372 	}
373 	on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
374 	if (__get_global_hook_flag()) {
375 		if (!start_func()) {
376 			// __musl_log(__MUSL_LOG_ERROR, "%s: failed to start %s\n", getprogname(), prefix);
377 			clear_function_table();
378 			return false;
379 		}
380 		atomic_store_explicit(&__musl_libc_globals.so_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
381 		atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->malloc_dispatch_table, memory_order_seq_cst);
382 	}
383 	if (__get_memleak_hook_flag() && checkLoadMallocMemTrack) {
384 		if (!start_func(memLeakTypeContent)) {
385 			clear_function_table();
386 			return false;
387 		}
388 		atomic_store_explicit(&__musl_libc_globals.memleak_tracker_so_dispatch_table, (volatile long long)&globals->memleak_tracker_malloc_dispatch_table, memory_order_seq_cst);
389 		atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)&globals->memleak_tracker_malloc_dispatch_table, memory_order_seq_cst);
390 	}
391 	int ret_value = atexit(malloc_finalize);
392 	if (ret_value != 0) {
393 		// __musl_log(__MUSL_LOG_ERROR, "failed to set atexit cleanup function: %d\n", ret_value);
394 	}
395 	return true;
396 }
397 
is_empty_string(const char * str)398 static bool is_empty_string(const char* str)
399 {
400 	while (*str) {
401 		if (!isspace((unsigned char)(*str))) {
402 			return false;
403 		}
404 	}
405 	return true;
406 }
407 
install_ohos_malloc_hook(struct musl_libc_globals * globals,const char * shared_lib,const char * prefix)408 static void install_ohos_malloc_hook(struct musl_libc_globals* globals, const char* shared_lib, const char* prefix)
409 {
410 	volatile void* shared_library_handle = (volatile void *)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
411 	assert(shared_library_handle == NULL || shared_library_handle == (volatile void*)-1);
412 	if (__get_memleak_hook_flag()) {
413 		shared_library_handle = (volatile void*)load_malloc_hook_shared_library(shared_lib, prefix, &globals->memleak_tracker_malloc_dispatch_table);
414 	} else if (__get_global_hook_flag()) {
415 		shared_library_handle = (volatile void*)load_malloc_hook_shared_library(shared_lib, prefix, &globals->malloc_dispatch_table);
416 	}
417 	if (shared_library_handle == NULL) {
418 		// __musl_log(__MUSL_LOG_ERROR, "Can't load shared library '%s'\n", __malloc_hook_shared_lib);
419 		return;
420 	}
421 
422 	if (finish_install_ohos_malloc_hooks(globals, NULL, prefix)) {
423 		atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)shared_library_handle, memory_order_seq_cst);
424 		if (strncmp(__malloc_hook_function_prefix, prefix, strlen(prefix)) == 0) {
425 			atomic_store_explicit(&ohos_malloc_ever_shared_library_handle, (volatile long long)shared_library_handle, memory_order_seq_cst);
426 		} else {
427 			atomic_store_explicit(&memleak_ever_shared_library_handle, (volatile long long)shared_library_handle, memory_order_seq_cst);
428 		}
429 	} else {
430 		// __musl_log(__MUSL_LOG_ERROR, "finish_install_ohos_malloc_hooks failed\n");
431 		dlclose((void *)shared_library_handle);
432 		atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst);
433 	}
434 }
435 
init_ohos_malloc_hook()436 static void* init_ohos_malloc_hook()
437 {
438 	if (__get_memleak_hook_flag()) {
439 		get_memleak_hook_param();
440 		if (checkLoadMallocMemTrack) {
441 			install_ohos_malloc_hook(&__musl_libc_globals, kMemTrackSharedLib, kMemTrackPrefix);
442 		}
443 	}
444 	if (__get_global_hook_flag()) {
445 		install_ohos_malloc_hook(&__musl_libc_globals, __malloc_hook_shared_lib, __malloc_hook_function_prefix);
446 	}
447 	return NULL;
448 }
449 
ohos_malloc_hook_init_function(size_t bytes)450 void* ohos_malloc_hook_init_function(size_t bytes)
451 {
452 	if (atomic_exchange(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL)) {
453 		pthread_t thread_id;
454 		if (pthread_create(&thread_id, NULL, init_ohos_malloc_hook, NULL) != 0) {
455 			// __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_create\n", getprogname());
456 		} else if (pthread_detach(thread_id) != 0) {
457 			// __musl_log(__MUSL_LOG_ERROR, "%s: ohos_malloc_hook: failed to pthread_detach\n", getprogname());
458 		}
459 	}
460 	void*ptr = MuslMalloc(malloc)(bytes);
461 	return ptr;
462 
463 }
464 
__set_default_malloc()465 static void __set_default_malloc()
466 {
467 	atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)NULL, memory_order_seq_cst);
468 }
469 
__restore_hook_function_table()470 static void __restore_hook_function_table()
471 {
472 	for (size_t i = 0; i < LAST_FUNCTION; i++) {
473 		if (__get_memleak_hook_flag()) {
474 			function_of_shared_lib[i] = function_of_memleak_shared_lib[i];
475 		} else if (__get_global_hook_flag()) {
476 			function_of_shared_lib[i] = function_of_ohos_malloc_shared_lib[i];
477 		}
478 	}
479 }
480 
__install_malloc_hook()481 static void __install_malloc_hook()
482 {
483 	if (__get_memleak_hook_flag()) {
484 		return;
485 	}
486 	atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
487 	volatile void* ohos_malloc_ever_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_ever_shared_library_handle, memory_order_acquire);
488 	if (ohos_malloc_ever_handle != NULL) {
489 		atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)ohos_malloc_ever_handle, memory_order_seq_cst);
490 	} else {
491 		atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst);
492 	}
493 	volatile void* shared_library_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
494 	if (shared_library_handle == NULL) {
495 		if (__hook_mode == STEP_HOOK_MODE) {
496 			atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst);
497 			atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)-1, memory_order_seq_cst);
498 		} else {
499 			init_ohos_malloc_hook();
500 		}
501 	} else if (shared_library_handle != (void*)-1) {
502 		__restore_hook_function_table();
503 		volatile const struct MallocDispatchType* so_dispatch_value = (volatile const struct MallocDispatchType* )atomic_load_explicit(&__musl_libc_globals.so_dispatch_table, memory_order_acquire);
504 		atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)so_dispatch_value, memory_order_seq_cst);
505 		on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
506 		if (start_func && !start_func()) {
507 			// __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname());
508 		}
509 
510 	}
511 }
512 
__uninstal_malloc_hook()513 static void __uninstal_malloc_hook()
514 {
515 	if (__get_memleak_hook_flag()) {
516 		return;
517 	}
518 	atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
519 	bool flag = __set_hook_flag(false);
520 	__set_default_malloc();
521 	on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]);
522 	if (end_func) {
523 		end_func();
524 	}
525 }
526 
__install_memleak_tracker_hook(int32_t sigNum,siginfo_t * info,void * ptr)527 static void __install_memleak_tracker_hook(int32_t sigNum, siginfo_t *info, void *ptr)
528 {
529 	if (__get_global_hook_flag()) {
530 		return;
531 	}
532 	atomic_store_explicit(&__memleak_hook_flag, (volatile bool)true, memory_order_seq_cst);
533 	volatile void* memleak_ever_handle = (volatile void* )atomic_load_explicit(&memleak_ever_shared_library_handle, memory_order_acquire);
534 	if (memleak_ever_handle != NULL) {
535 		atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)memleak_ever_handle, memory_order_seq_cst);
536 	} else {
537 		atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)0, memory_order_seq_cst);
538 	}
539 	volatile void* shared_library_handle = (volatile void* )atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
540 	memLeakTypeContent = (unsigned int)(siginfo_t *)((info)->si_addr);
541 	if (shared_library_handle == NULL) {
542 		if (__hook_mode == STEP_HOOK_MODE) {
543 			if (memLeakTypeContent & ADDR_NATIVE_ENABLE) {
544 				atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile const long long)&__ohos_malloc_hook_init_dispatch, memory_order_seq_cst);
545 				atomic_store_explicit(&ohos_malloc_hook_shared_library, (volatile long long)-1, memory_order_seq_cst);
546 			}
547 		} else {
548 			init_ohos_malloc_hook();
549 		}
550 	} else if (shared_library_handle != (void*)-1) {
551 		if (checkLoadMallocMemTrack) {
552 			__restore_hook_function_table();
553 			on_start_func_t start_func = (on_start_func_t)(function_of_shared_lib[ON_START_FUNCTION]);
554 			if (memLeakTypeContent & ADDR_NATIVE_ENABLE) {
555 				volatile const struct MallocDispatchType* memleak_tracker_so_dispatch_value = (volatile const struct MallocDispatchType* )atomic_load_explicit(&__musl_libc_globals.memleak_tracker_so_dispatch_table, memory_order_acquire);
556 				atomic_store_explicit(&__musl_libc_globals.current_dispatch_table, (volatile long long)memleak_tracker_so_dispatch_value, memory_order_seq_cst);
557 			}
558 			if (start_func && !start_func(memLeakTypeContent)) {
559 				// __musl_log(__MUSL_LOG_ERROR, "%s: failed to enable malloc\n", getprogname());
560 				clear_function_table();
561 			}
562 			if (memLeakTypeContent & ADDR_NATIVE_CLEAR) {
563 				atomic_store_explicit(&__memleak_hook_flag, (volatile bool)false, memory_order_seq_cst);
564 				bool flag = __set_hook_flag(false);
565 				__set_default_malloc();
566 				on_end_func_t end_func = (on_end_func_t)(function_of_shared_lib[ON_END_FUNCTION]);
567 				if (end_func) {
568 					end_func();
569 				}
570 				memLeakTypeContent = 0;
571 			}
572 		}
573 	}
574 }
575 
576 
__install_malloc_hook_signal_handler()577 static void __install_malloc_hook_signal_handler()
578 {
579 	struct sigaction actionInstallHook = {};
580 	actionInstallHook.sa_handler = __install_malloc_hook;
581 	sigemptyset(&actionInstallHook.sa_mask);
582 	sigaddset(&actionInstallHook.sa_mask, MUSL_SIGNAL_UNHOOK);
583 	sigaction(MUSL_SIGNAL_HOOK, &actionInstallHook, NULL);
584 
585 	struct sigaction actionDef = {};
586 	actionDef.sa_handler = __uninstal_malloc_hook;
587 	sigemptyset(&actionDef.sa_mask);
588 	sigaddset(&actionDef.sa_mask, MUSL_SIGNAL_HOOK);
589 	sigaction(MUSL_SIGNAL_UNHOOK, &actionDef, NULL);
590 
591 	struct sigaction actionInstallMemleakHook = {};
592 	actionInstallMemleakHook.sa_handler = NULL;
593 	actionInstallMemleakHook.sa_sigaction = __install_memleak_tracker_hook;
594 	sigemptyset(&actionInstallMemleakHook.sa_mask);
595 	sigaddset(&actionInstallMemleakHook.sa_mask, MUSL_SIGNAL_MEMCHECK);
596 	actionInstallMemleakHook.sa_flags = SA_SIGINFO;
597 	actionInstallMemleakHook.sa_restorer = NULL;
598 	sigaction(MUSL_SIGNAL_MEMCHECK, &actionInstallMemleakHook, NULL);
599 }
600 
__initialize_malloc()601 static void __initialize_malloc()
602 {
603 	__install_malloc_hook_signal_handler();
604 }
605 
__musl_initialize()606 __attribute__((constructor(1))) static void __musl_initialize()
607 {
608 	atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)false, memory_order_seq_cst);
609 	atomic_store_explicit(&__memleak_hook_flag, (volatile bool)false, memory_order_seq_cst);
610 	__set_default_malloc();
611 	char hook_process_path[MAX_PROC_NAME_SIZE + 1] = {0};
612 	parse_hook_variable(&__hook_mode, hook_process_path, sizeof(hook_process_path) - 1);
613 	if (__hook_mode == STARTUP_HOOK_MODE) {
614 		char proc_name[MAX_PROC_NAME_SIZE + 1] = {0};
615 		if (get_proc_name(getpid(), proc_name, sizeof(proc_name) - 1)) {
616 			const char *pos = strrchr(proc_name, '/');
617 			const char* file_name;
618 			if (pos != NULL) {
619 				file_name = pos + 1;
620 			} else {
621 				file_name = proc_name;
622 			}
623 			if (strncmp(file_name, hook_process_path, strlen(hook_process_path)) == 0) {
624 				atomic_store_explicit(&__hook_enable_hook_flag, (volatile bool)true, memory_order_seq_cst);
625 				init_ohos_malloc_hook();
626 			} else {
627 				__hook_mode = STEP_HOOK_MODE;
628 			}
629 		} else {
630 			__hook_mode = STEP_HOOK_MODE;
631 		}
632 	}
633 	__initialize_malloc();
634 	errno = 0;
635 }
636 #endif
637