1/* 2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved. 3 * 4 * UniProton is licensed under Mulan PSL v2. 5 * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 * You may obtain a copy of Mulan PSL v2 at: 7 * http://license.coscl.org.cn/MulanPSL2 8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 11 * See the Mulan PSL v2 for more details. 12 * Create: 2009-12-22 13 * Description: HOOK模块的内部头文件 14 */ 15#ifndef PRT_HOOK_EXTERNAL_H 16#define PRT_HOOK_EXTERNAL_H 17 18#include "prt_hook.h" 19#include "prt_sys.h" 20 21/* 限制:参数类型不能为U64大于uintptr_t */ 22typedef void (*OsFunPara0)(void); 23typedef void (*OsFunPara1)(uintptr_t); 24typedef void (*OsFunPara2)(uintptr_t, uintptr_t); 25typedef void (*OsFunPara3)(uintptr_t, uintptr_t, uintptr_t); 26typedef void (*OsFunPara4)(uintptr_t, uintptr_t, uintptr_t, uintptr_t); 27typedef void (*OsFunPara5)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); 28 29/* 30 * 内核钩子管理原则 31 * 1)服务于内核模块的钩子才可纳入钩子模块统一管理,例如补丁、shell模块的钩子就不适合。 32 * 内核模块指mem,kernel,ipc,服务于内核的arch。 33 * 2)没有返回值,没有输出参数的钩子才可纳入钩子模块统一管理。 34 */ 35#define OS_MHOOK_BOUNDARY ((U32)1) 36 37#define OS_MHOOK_NODE_DEAD ((OsVoidFunc)2) 38 39// 除了OS_HOOK_EMPTY和OS_MHOOK_BOUNDARY外,都是有效钩子 40#define OS_MHOOK_IS_VALID(hook) ((uintptr_t)(hook) > OS_MHOOK_BOUNDARY) 41 42#define OS_MHOOK_NOT_BOUNDARY(hook) ((uintptr_t)(hook) != OS_MHOOK_BOUNDARY) 43 44OS_SEC_ALW_INLINE INLINE bool OsMhookBoundaryCheck(OsVoidFunc hook) 45{ 46 return ((uintptr_t)hook <= OS_MHOOK_BOUNDARY); 47} 48 49OS_SEC_ALW_INLINE INLINE bool OsMhookValidCheck(OsVoidFunc hook) 50{ 51 return (hook != OS_MHOOK_NODE_DEAD); 52} 53 54#define OS_MHOOK_ACTIVATE_PROC(hook, funcType, pfn, list) \ 55 do { \ 56 OsVoidFunc *tmp_ = hook; \ 57 while (!OsMhookBoundaryCheck((OsVoidFunc)((pfn) = (funcType)(*tmp_)))) { \ 58 if (OsMhookValidCheck((OsVoidFunc)(pfn))) { \ 59 (list); \ 60 } \ 61 tmp_++; \ 62 } \ 63 } while (0) 64 65#define OS_MHOOK_ACTIVATE(hookType, funcType, list) \ 66 do { \ 67 OsVoidFunc *hook = g_hookCb[(hookType)].mulHook; \ 68 funcType pfn; \ 69 if (hook != NULL) { \ 70 OS_MHOOK_ACTIVATE_PROC(hook, funcType, pfn, (list)); \ 71 } \ 72 } while (0) 73 74#define OS_SHOOK_ACTIVATE(hookType, funcType, list) \ 75 do { \ 76 funcType pfn = (funcType)g_hookCb[(hookType)].sigHook; \ 77 if (pfn != NULL) \ 78 (list); \ 79 } while (0) 80 81#define OS_MHOOK_ACTIVATE_PARA0(hookType) OS_MHOOK_ACTIVATE((hookType), OsFunPara0, pfn()) 82#define OS_MHOOK_ACTIVATE_PARA1(hookType, arg0) OS_MHOOK_ACTIVATE((hookType), OsFunPara1, pfn((uintptr_t)(arg0))) 83#define OS_MHOOK_ACTIVATE_PARA2(hookType, arg0, arg1) OS_MHOOK_ACTIVATE((hookType), \ 84 OsFunPara2, pfn((uintptr_t)(arg0), (uintptr_t)(arg1))) 85#define OS_MHOOK_ACTIVATE_PARA3(hookType, arg0, arg1, arg2) OS_MHOOK_ACTIVATE((hookType), \ 86 OsFunPara3, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2))) 87#define OS_MHOOK_ACTIVATE_PARA4(hookType, arg0, arg1, arg2, arg3) \ 88 OS_MHOOK_ACTIVATE((hookType), \ 89 OsFunPara4, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3))) 90#define OS_MHOOK_ACTIVATE_PARA5(hookType, arg0, arg1, arg2, arg3, arg4) \ 91 OS_MHOOK_ACTIVATE((hookType), OsFunPara5, \ 92 pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3), (uintptr_t)(arg4))) 93 94#define OS_SHOOK_ACTIVATE_PARA0(hookType) OS_SHOOK_ACTIVATE((hookType), OsFunPara0, pfn()) 95#define OS_SHOOK_ACTIVATE_PARA1(hookType, arg0) OS_SHOOK_ACTIVATE((hookType), OsFunPara1, pfn((uintptr_t)(arg0))) 96#define OS_SHOOK_ACTIVATE_PARA2(hookType, arg0, arg1) OS_SHOOK_ACTIVATE((hookType), \ 97 OsFunPara2, pfn((uintptr_t)(arg0), (uintptr_t)(arg1))) 98#define OS_SHOOK_ACTIVATE_PARA3(hookType, arg0, arg1, arg2) OS_SHOOK_ACTIVATE((hookType), \ 99 OsFunPara3, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2))) 100#define OS_SHOOK_ACTIVATE_PARA4(hookType, arg0, arg1, arg2, arg3) \ 101 OS_SHOOK_ACTIVATE((hookType), OsFunPara4, \ 102 pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3))) 103#define OS_SHOOK_ACTIVATE_PARA5(hookType, arg0, arg1, arg2, arg3, arg4) \ 104 OS_SHOOK_ACTIVATE((hookType), OsFunPara5, \ 105 pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3), (uintptr_t)(arg4))) 106 107#define HOOK_ADD_IRQ_LOCK(intSave) \ 108 do { \ 109 (intSave) = PRT_HwiLock(); \ 110 } while (0) 111#define HOOK_ADD_IRQ_UNLOCK(intSave) PRT_HwiRestore((intSave)) 112 113#define HOOK_DEL_IRQ_LOCK(intSave) \ 114 do { \ 115 (intSave) = PRT_HwiLock(); \ 116 } while (0) 117#define HOOK_DEL_IRQ_UNLOCK(intSave) PRT_HwiRestore((intSave)) 118 119enum { 120 OS_HOOK_TICK_ENTRY = OS_HOOK_TYPE_NUM, 121 OS_HOOK_TICK_EXIT, 122 OS_HOOK_FIRST_TIME_SWH, 123 OS_HOOK_TSK_MON, /* TSKMON钩子 */ 124 OS_HOOK_CPUP_WARN, /* CPUP告警钩子 */ 125 OS_HOOK_ERR_REG, /* 错误处理钩子 */ 126 OS_HOOK_IDLE_PREFIX, /* IDLE前置钩子 */ 127 OS_HOOK_MEM_DAMAGE, /* 踩内存处理钩子 */ 128 129 OS_HOOK_TYPE_TOTAL 130}; 131 132#define OS_SHOOK_TYPE_START ((U32)OS_HOOK_TSK_MON) 133 134enum HookChgType { 135 HOOK_ADD_FIRST, 136 HOOK_DEL_LAST 137}; 138 139union TagMhookCb { 140 // 在初始化阶段复用为钩子注册数目 141 uintptr_t num; 142 // 单钩子 143 OsVoidFunc sigHook; 144 OsVoidFunc *mulHook; 145}; 146 147typedef U32(*OsHookChgFunc)(U32 hookType, enum HookChgType chgType); 148 149extern union TagMhookCb g_hookCb[OS_HOOK_TYPE_TOTAL]; 150 151typedef void *(*MemAllocHook)(enum MoudleId mid, U8 ptNo, U32 size); 152extern MemAllocHook g_osMemAlloc; 153 154/* 155 * 多钩子添加内部接口 156 */ 157extern U32 OsMhookAdd(U32 hookType, OsVoidFunc hook); 158 159/* 160 * 多钩子删除内部接口 161 */ 162extern U32 OsMhookDel(U32 hookType, OsVoidFunc hook); 163 164/* 165 * 钩子添加内部接口 166 */ 167extern U32 OsHookAdd(enum HookType hookType, OsVoidFunc hook); 168 169/* 170 * 钩子删除内部接口 171 */ 172extern U32 OsHookDel(enum HookType hookType, OsVoidFunc hook); 173 174/* 175 * 多钩子注册内部接口, 为了与原有规格兼容,传入NULL表示删除 176 */ 177extern U32 OsShookReg(U32 hookType, OsVoidFunc hook); 178 179/* 180 * 在注册阶段,不同模块通过osMhookReserve接口预留钩子,不影响用户注册钩子数 181 * 仅在register阶段使用 182 */ 183extern void OsMhookReserve(U32 hookType, U32 incCnt); 184 185#endif /* PRT_HOOK_EXTERNAL_H */ 186