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