1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci *
4570af302Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
5570af302Sopenharmony_ci * of this software and associated documentation files (the "Software"), to
6570af302Sopenharmony_ci * deal in the Software without restriction, including without limitation the
7570af302Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8570af302Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
9570af302Sopenharmony_ci * furnished to do so, subject to the following conditions:
10570af302Sopenharmony_ci *
11570af302Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
12570af302Sopenharmony_ci * all copies or substantial portions of the Software.
13570af302Sopenharmony_ci *
14570af302Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15570af302Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16570af302Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17570af302Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18570af302Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19570af302Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20570af302Sopenharmony_ci * IN THE SOFTWARE.
21570af302Sopenharmony_ci */
22570af302Sopenharmony_ci
23570af302Sopenharmony_ci#ifndef _MUSL_PREINIT_COMMON_H
24570af302Sopenharmony_ci#define _MUSL_PREINIT_COMMON_H
25570af302Sopenharmony_ci
26570af302Sopenharmony_ci#include <stdatomic.h>
27570af302Sopenharmony_ci#include "musl_malloc_dispatch_table.h"
28570af302Sopenharmony_ci#include "musl_malloc_dispatch.h"
29570af302Sopenharmony_ci
30570af302Sopenharmony_ciextern struct musl_libc_globals __musl_libc_globals;
31570af302Sopenharmony_ci
32570af302Sopenharmony_ciextern struct MallocDispatchType __libc_malloc_default_dispatch;
33570af302Sopenharmony_ci
34570af302Sopenharmony_ciextern volatile atomic_bool __hook_enable_hook_flag;
35570af302Sopenharmony_ci
36570af302Sopenharmony_ciextern volatile atomic_bool __memleak_hook_flag;
37570af302Sopenharmony_ciextern bool checkLoadMallocMemTrack;
38570af302Sopenharmony_ci
39570af302Sopenharmony_cienum EnumFunc {
40570af302Sopenharmony_ci	INITIALIZE_FUNCTION,
41570af302Sopenharmony_ci	FINALIZE_FUNCTION,
42570af302Sopenharmony_ci	GET_HOOK_FLAG_FUNCTION,
43570af302Sopenharmony_ci	SET_HOOK_FLAG_FUNCTION,
44570af302Sopenharmony_ci	ON_START_FUNCTION,
45570af302Sopenharmony_ci	ON_END_FUNCTION,
46570af302Sopenharmony_ci	SEND_HOOK_MISC_DATA,
47570af302Sopenharmony_ci	GET_HOOK_CONFIG,
48570af302Sopenharmony_ci	LAST_FUNCTION,
49570af302Sopenharmony_ci};
50570af302Sopenharmony_ci
51570af302Sopenharmony_cienum EnumHookMode {
52570af302Sopenharmony_ci	STARTUP_HOOK_MODE,
53570af302Sopenharmony_ci	DIRECT_HOOK_MODE,
54570af302Sopenharmony_ci	STEP_HOOK_MODE,
55570af302Sopenharmony_ci};
56570af302Sopenharmony_ci
57570af302Sopenharmony_ci#ifdef HOOK_ENABLE
58570af302Sopenharmony_ciextern void* function_of_shared_lib[];
59570af302Sopenharmony_ciextern volatile atomic_llong ohos_malloc_hook_shared_library;
60570af302Sopenharmony_ci#endif // HOOK_ENABLE
61570af302Sopenharmony_ci
62570af302Sopenharmony_ci#ifdef __cplusplus
63570af302Sopenharmony_ciextern "C" {
64570af302Sopenharmony_ci#endif
65570af302Sopenharmony_ci
66570af302Sopenharmony_ci__attribute__((always_inline))
67570af302Sopenharmony_ciinline bool __get_global_hook_flag()
68570af302Sopenharmony_ci{
69570af302Sopenharmony_ci#ifdef HOOK_ENABLE
70570af302Sopenharmony_ci	volatile bool g_flag = atomic_load_explicit(&__hook_enable_hook_flag, memory_order_acquire);
71570af302Sopenharmony_ci	return g_flag;
72570af302Sopenharmony_ci#else
73570af302Sopenharmony_ci	return false;
74570af302Sopenharmony_ci#endif // HOOK_ENABLE
75570af302Sopenharmony_ci}
76570af302Sopenharmony_ci
77570af302Sopenharmony_ci__attribute__((always_inline))
78570af302Sopenharmony_ciinline bool __get_memleak_hook_flag()
79570af302Sopenharmony_ci{
80570af302Sopenharmony_ci#ifdef HOOK_ENABLE
81570af302Sopenharmony_ci	volatile bool memleak_flag = atomic_load_explicit(&__memleak_hook_flag, memory_order_acquire);
82570af302Sopenharmony_ci	return memleak_flag;
83570af302Sopenharmony_ci#else
84570af302Sopenharmony_ci	return false;
85570af302Sopenharmony_ci#endif // HOOK_ENABLE
86570af302Sopenharmony_ci}
87570af302Sopenharmony_ci
88570af302Sopenharmony_ci
89570af302Sopenharmony_ci__attribute__((always_inline))
90570af302Sopenharmony_ciinline bool __get_hook_flag()
91570af302Sopenharmony_ci{
92570af302Sopenharmony_ci#ifdef HOOK_ENABLE
93570af302Sopenharmony_ci	volatile void* impl_handle = (void *)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
94570af302Sopenharmony_ci	if (impl_handle == NULL) {
95570af302Sopenharmony_ci		return false;
96570af302Sopenharmony_ci	}
97570af302Sopenharmony_ci	else if (impl_handle == (void *)-1) {
98570af302Sopenharmony_ci		return true;
99570af302Sopenharmony_ci	}
100570af302Sopenharmony_ci	else {
101570af302Sopenharmony_ci		GetHookFlagType get_hook_func_ptr = (GetHookFlagType)(function_of_shared_lib[GET_HOOK_FLAG_FUNCTION]);
102570af302Sopenharmony_ci		bool flag = get_hook_func_ptr();
103570af302Sopenharmony_ci		return flag;
104570af302Sopenharmony_ci	}
105570af302Sopenharmony_ci#else
106570af302Sopenharmony_ci	return false;
107570af302Sopenharmony_ci#endif // HOOK_ENABLE
108570af302Sopenharmony_ci}
109570af302Sopenharmony_ci
110570af302Sopenharmony_ci__attribute__((always_inline))
111570af302Sopenharmony_ciinline bool __set_hook_flag(bool flag)
112570af302Sopenharmony_ci{
113570af302Sopenharmony_ci#ifdef HOOK_ENABLE
114570af302Sopenharmony_ci	volatile void* impl_handle = (void *)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
115570af302Sopenharmony_ci	if (impl_handle == NULL) {
116570af302Sopenharmony_ci		return false;
117570af302Sopenharmony_ci	}
118570af302Sopenharmony_ci	else if (impl_handle == (void *)-1) {
119570af302Sopenharmony_ci		return true;
120570af302Sopenharmony_ci	}
121570af302Sopenharmony_ci	else {
122570af302Sopenharmony_ci		SetHookFlagType set_hook_func_ptr = (SetHookFlagType)(function_of_shared_lib[SET_HOOK_FLAG_FUNCTION]);
123570af302Sopenharmony_ci		return set_hook_func_ptr(flag);
124570af302Sopenharmony_ci	}
125570af302Sopenharmony_ci#else
126570af302Sopenharmony_ci	return false;
127570af302Sopenharmony_ci#endif // HOOK_ENABLE
128570af302Sopenharmony_ci}
129570af302Sopenharmony_ci
130570af302Sopenharmony_ci__attribute__((always_inline))
131570af302Sopenharmony_ciinline volatile const struct MallocDispatchType* get_current_dispatch_table()
132570af302Sopenharmony_ci{
133570af302Sopenharmony_ci#ifdef HOOK_ENABLE
134570af302Sopenharmony_ci	volatile const struct MallocDispatchType* ret = (struct MallocDispatchType *)atomic_load_explicit(&__musl_libc_globals.current_dispatch_table, memory_order_acquire);
135570af302Sopenharmony_ci	if (ret != NULL) {
136570af302Sopenharmony_ci		if (__get_memleak_hook_flag()) {
137570af302Sopenharmony_ci			return ret;
138570af302Sopenharmony_ci		}
139570af302Sopenharmony_ci		if (!__get_global_hook_flag()) {
140570af302Sopenharmony_ci			ret = NULL;
141570af302Sopenharmony_ci		}
142570af302Sopenharmony_ci		else if (!__get_hook_flag()) {
143570af302Sopenharmony_ci			ret = NULL;
144570af302Sopenharmony_ci		}
145570af302Sopenharmony_ci	}
146570af302Sopenharmony_ci	return ret;
147570af302Sopenharmony_ci#else
148570af302Sopenharmony_ci	return NULL;
149570af302Sopenharmony_ci#endif // HOOK_ENABLE
150570af302Sopenharmony_ci}
151570af302Sopenharmony_ci
152570af302Sopenharmony_ci__attribute__((always_inline))
153570af302Sopenharmony_ciinline bool __send_hook_misc_data(uint64_t id, const char* stackPtr, size_t stackSize, uint32_t type)
154570af302Sopenharmony_ci{
155570af302Sopenharmony_ci#ifdef HOOK_ENABLE
156570af302Sopenharmony_ci	volatile void* impl_handle = (void*)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
157570af302Sopenharmony_ci	if (impl_handle == NULL) {
158570af302Sopenharmony_ci		return false;
159570af302Sopenharmony_ci	}
160570af302Sopenharmony_ci	else if (impl_handle == (void*)-1) {
161570af302Sopenharmony_ci		return false;
162570af302Sopenharmony_ci	}
163570af302Sopenharmony_ci	else {
164570af302Sopenharmony_ci		SendHookMiscData send_hook_func_ptr = (SendHookMiscData)(function_of_shared_lib[SEND_HOOK_MISC_DATA]);
165570af302Sopenharmony_ci		return send_hook_func_ptr(id, stackPtr, stackSize, type);
166570af302Sopenharmony_ci	}
167570af302Sopenharmony_ci#else
168570af302Sopenharmony_ci	return false;
169570af302Sopenharmony_ci#endif // HOOK_ENABLE
170570af302Sopenharmony_ci}
171570af302Sopenharmony_ci
172570af302Sopenharmony_ci__attribute__((always_inline))
173570af302Sopenharmony_ciinline void* __get_hook_config()
174570af302Sopenharmony_ci{
175570af302Sopenharmony_ci#ifdef HOOK_ENABLE
176570af302Sopenharmony_ci	volatile void* impl_handle = (void*)atomic_load_explicit(&ohos_malloc_hook_shared_library, memory_order_acquire);
177570af302Sopenharmony_ci	if (impl_handle == NULL) {
178570af302Sopenharmony_ci		return NULL;
179570af302Sopenharmony_ci	}
180570af302Sopenharmony_ci	else if (impl_handle == (void*)-1) {
181570af302Sopenharmony_ci		return NULL;
182570af302Sopenharmony_ci	}
183570af302Sopenharmony_ci	else {
184570af302Sopenharmony_ci		GetHookConfig get_hook_func_ptr = (GetHookConfig)(function_of_shared_lib[GET_HOOK_CONFIG]);
185570af302Sopenharmony_ci		return get_hook_func_ptr();
186570af302Sopenharmony_ci	}
187570af302Sopenharmony_ci#else
188570af302Sopenharmony_ci	return NULL;
189570af302Sopenharmony_ci#endif // HOOK_ENABLE
190570af302Sopenharmony_ci}
191570af302Sopenharmony_ci
192570af302Sopenharmony_ci#define MUSL_HOOK_PARAM_NAME "libc.hook_mode"
193570af302Sopenharmony_ci#define OHOS_PARAM_MAX_SIZE 96
194570af302Sopenharmony_ci#define FILE_NAME_MAX_SIZE 40
195570af302Sopenharmony_ci
196570af302Sopenharmony_ci#ifdef __cplusplus
197570af302Sopenharmony_ci}
198570af302Sopenharmony_ci#endif
199570af302Sopenharmony_ci
200570af302Sopenharmony_ci#endif
201