openmpi/opal/mca/patcher/patcher.h

122 lines
3.8 KiB
C

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2016 Los Alamos National Security, LLC. 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/mca/mca.h"
#include "opal/mca/base/base.h"
#include "opal/class/opal_list.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 (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64)
/* 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 */