1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2016 Los Alamos National Security, LLC. All rights
4 * reserved.
5 * $COPYRIGHT$
6 *
7 * Additional copyrights may follow
8 *
9 * $HEADER$
10 */
11
12 #ifndef OPAL_MCA_PATCHER_PATCHER_H
13 #define OPAL_MCA_PATCHER_PATCHER_H
14
15 #include "opal_config.h"
16
17 #include "opal/mca/mca.h"
18 #include "opal/mca/base/base.h"
19 #include "opal/class/opal_list.h"
20
21 /* Any function being patched in as a hook must use SYMBOLPATCH_BEGIN at the top,
22 * and SYMBOLPATCH_END before it returns (this is just for PPC). */
23
24 #if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64)
25
26 /* special processing for ppc64 to save and restore TOC (r2)
27 * Reference: "64-bit PowerPC ELF Application Binary Interface Supplement 1.9" */
28 #define OPAL_PATCHER_BEGIN \
29 unsigned long toc_save; \
30 asm volatile ("std 2, %0" : "=m" (toc_save)); \
31 asm volatile ("nop; nop; nop; nop; nop");
32 #define OPAL_PATCHER_END \
33 asm volatile ("ld 2, %0" : : "m" (toc_save));
34
35 #else /* !__PPC64__ */
36
37 #define OPAL_PATCHER_BEGIN
38 #define OPAL_PATCHER_END
39
40 #endif
41
42 /**
43 * Make any calls to the named function redirect to a new function
44 *
45 * @param[in] func_symbol_name function to hook
46 * @param[in] func_new_addr function pointer of hook
47 * @param[out] func_old_addr address of func_symbol_name
48 *
49 * This function redirects all calls to the function func_symbol_name to
50 * the function pointer func_new_addr. If it is possible for the hook
51 * function to call the original function the patcher module will return
52 * the old function's address in func_old_addr.
53 */
54 typedef int (*mca_patcher_base_patch_symbol_fn_t)(const char *func_symbol_name, uintptr_t func_new_addr,
55 uintptr_t *func_old_addr);
56
57 /**
58 * Make any calls to a function redirect to a new function
59 *
60 * @param[in] func_symbol_name function to hook
61 * @param[in] func_new_addr function pointer of hook
62 * @param[out] func_old_addr address of func_symbol_name
63 *
64 * This function redirects all calls to the function at func_addr to
65 * the function pointer func_new_addr.
66 */
67 typedef int (*mca_patcher_base_patch_address_fn_t)(uintptr_t func_addr, uintptr_t func_new_addr);
68
69 /**
70 * Set up the patcher module
71 */
72 typedef int (*mca_patcher_base_init_fn_t) (void);
73
74 /**
75 * Finalize the patcher module
76 */
77 typedef int (*mca_patcher_base_fini_fn_t) (void);
78
79 /**
80 * Structure for patcher modules.
81 */
82 typedef struct mca_patcher_base_module_t {
83 mca_base_module_t super;
84 /** list of patches */
85 opal_list_t patch_list;
86 /** lock for patch list */
87 opal_mutex_t patch_list_mutex;
88 /** function to call if the patcher module is used. can
89 * be NULL. */
90 mca_patcher_base_init_fn_t patch_init;
91 /** function to call when patcher is unloaded. this function
92 * MUST clean up all active patches. can be NULL. */
93 mca_patcher_base_fini_fn_t patch_fini;
94 /** hook a symbol. may be NULL */
95 mca_patcher_base_patch_symbol_fn_t patch_symbol;
96 /** hook a function pointer. may be NULL */
97 mca_patcher_base_patch_address_fn_t patch_address;
98 } mca_patcher_base_module_t;
99
100
101 OPAL_DECLSPEC extern mca_patcher_base_module_t *opal_patcher;
102
103 /**
104 * Structure for patcher components.
105 */
106 typedef struct mca_patcher_base_component_1_0_0_t {
107 /** MCA base component */
108 mca_base_component_t patcherc_version;
109 /** MCA base data */
110 mca_base_component_data_t patcherc_data;
111 } mca_patcher_base_component_1_0_0_t;
112
113 typedef mca_patcher_base_component_1_0_0_t mca_patcher_base_component_t;
114
115 /*
116 * Macro for use in components that are of type patcher
117 */
118 #define OPAL_PATCHER_BASE_VERSION_1_0_0 \
119 OPAL_MCA_BASE_VERSION_2_1_0("patcher", 1, 0, 0)
120
121 #endif /* OPAL_MCA_PATCHER_PATCHER_H */