1 /* Macros for using symbol sets for running lists of functions. 2 Copyright (C) 1994-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #ifndef _SET_HOOKS_H 20 #define _SET_HOOKS_H 1 21 22 #define __need_size_t 23 #include <stddef.h> 24 #include <sys/cdefs.h> 25 #include <libc-symbols.h> 26 27 #include "set-hooks-arch.h" 28 29 #ifdef symbol_set_define 30 /* Define a hook variable called NAME. Functions put on this hook take 31 arguments described by PROTO. Use `text_set_element (NAME, FUNCTION)' 32 from include/libc-symbols.h to add a function to the hook. */ 33 34 # define DEFINE_HOOK(NAME, PROTO) \ 35 typedef void __##NAME##_hook_function_t PROTO; \ 36 symbol_set_define (NAME) 37 38 # define DECLARE_HOOK(NAME, PROTO) \ 39 typedef void __##NAME##_hook_function_t PROTO;\ 40 symbol_set_declare (NAME) 41 42 /* Run all the functions hooked on the set called NAME. 43 Each function is called like this: `function ARGS'. */ 44 45 # define RUN_HOOK(NAME, ARGS) \ 46 do { \ 47 void *const *ptr; \ 48 for (ptr = (void *const *) symbol_set_first_element (NAME); \ 49 ! symbol_set_end_p (NAME, ptr); ++ptr) \ 50 (*(__##NAME##_hook_function_t *) *ptr) ARGS; \ 51 } while (0) 52 53 /* Define a hook variable with NAME and PROTO, and a function called RUNNER 54 which calls each function on the hook in turn, with ARGS. */ 55 56 # define DEFINE_HOOK_RUNNER(name, runner, proto, args) \ 57 DEFINE_HOOK (name, proto); \ 58 extern void runner proto; void runner proto { RUN_HOOK (name, args); } 59 60 # ifdef SET_RELHOOK 61 /* This is similar to RUN_RELHOOK, but the hooks were registered with 62 * SET_RELHOOK so that a relative offset was computed by the linker 63 * rather than an absolute address by the dynamic linker. */ 64 # define RUN_RELHOOK(NAME, ARGS) \ 65 do { \ 66 void *const *ptr; \ 67 for (ptr = (void *const *) symbol_set_first_element (NAME); \ 68 ! symbol_set_end_p (NAME, ptr); ++ptr) { \ 69 __##NAME##_hook_function_t *f = \ 70 (void*) ((uintptr_t) ptr + (ptrdiff_t) *ptr); \ 71 (*f) ARGS; \ 72 } \ 73 } while (0) 74 # else 75 # define SET_RELHOOK(NAME, HOOK) text_set_element (NAME, HOOK) 76 # define RUN_RELHOOK(NAME, ARGS) RUN_HOOK(NAME, ARGS) 77 # endif 78 79 #else 80 81 /* The system does not provide necessary support for this. */ 82 # define DEFINE_HOOK(NAME, PROTO) 83 84 # define DECLARE_HOOK(NAME, PROTO) 85 86 # define RUN_HOOK(NAME, ARGS) 87 88 # define DEFINE_HOOK_RUNNER(name, runner, proto, args) 89 90 # define SET_RELHOOK(NAME, HOOK) 91 92 # define RUN_RELHOOK(NAME, ARGS) 93 94 #endif 95 96 #endif /* set-hooks.h */ 97