
This commit adds a framework to abstract runtime code patching. Components in the new framework can provide functions for either patching a named function or a function pointer. The later functionality is not being used but may provide a way to allow memory hooks when dlopen functionality is disabled. This commit adds two different flavors of code patching. The first is provided by the overwrite component. This component overwrites the first several instructions of the target function with code to jump to the provided hook function. The hook is expected to provide the full functionality of the hooked function. The linux patcher component is based on the memory hooks in ucx. It only works on linux and operates by overwriting function pointers in the symbol table. In this case the hook is free to call the original function using the function pointer returned by dlsym. Both components restore the original functions when the patcher framework closes. Changes had to be made to support Power/PowerPC with the Linux dynamic loader patcher. Some of the changes: - Move code necessary for powerpc/power support to the patcher base. The code is needed by both the overwrite and linux components. - Move patch structure down to base and move the patch list to mca_patcher_base_module_t. The structure has been modified to include a function pointer to the function that will unapply the patch. This allows the mixing of multiple different types of patches in the patch_list. - Update linux patching code to keep track of the matching between got entry and original (unpatched) address. This allows us to completely clean up the patch on finalize. All patchers keep track of the changes they made so that they can be reversed when the patcher framework is closed. At this time there are bugs in the Linux dynamic loader patcher so its priority is lower than the overwrite patcher. Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
213 строки
6.0 KiB
C
213 строки
6.0 KiB
C
/*
|
|
* Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
|
|
* University Research and Technology
|
|
* Corporation. All rights reserved.
|
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
|
* of Tennessee Research Foundation. All rights
|
|
* reserved.
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
* University of Stuttgart. All rights reserved.
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
* All rights reserved.
|
|
* Copyright (c) 2008-2015 Cisco Systems, Inc. All rights reserved.
|
|
* Copyright (c) 2010-2015 Los Alamos National Security, LLC.
|
|
* All rights reserved.
|
|
* Copyright (c) 2013-2015 Intel, Inc. All rights reserved
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
/** @file **/
|
|
|
|
#include "opal_config.h"
|
|
|
|
#include "opal/class/opal_object.h"
|
|
#include "opal/dss/dss.h"
|
|
#include "opal/util/output.h"
|
|
#include "opal/util/malloc.h"
|
|
#include "opal/util/net.h"
|
|
#include "opal/util/keyval_parse.h"
|
|
#include "opal/util/show_help.h"
|
|
#include "opal/memoryhooks/memory.h"
|
|
#include "opal/mca/base/base.h"
|
|
#include "opal/runtime/opal.h"
|
|
#include "opal/constants.h"
|
|
#include "opal/datatype/opal_datatype.h"
|
|
#include "opal/mca/if/base/base.h"
|
|
#include "opal/mca/installdirs/base/base.h"
|
|
#include "opal/mca/memchecker/base/base.h"
|
|
#include "opal/mca/memcpy/base/base.h"
|
|
#include "opal/mca/memory/base/base.h"
|
|
#include "opal/mca/patcher/base/base.h"
|
|
#include "opal/mca/backtrace/base/base.h"
|
|
#include "opal/mca/sec/base/base.h"
|
|
#include "opal/mca/timer/base/base.h"
|
|
#include "opal/mca/hwloc/base/base.h"
|
|
#include "opal/mca/event/base/base.h"
|
|
#include "opal/runtime/opal_progress.h"
|
|
#include "opal/mca/shmem/base/base.h"
|
|
#if OPAL_ENABLE_FT_CR == 1
|
|
#include "opal/mca/compress/base/base.h"
|
|
#endif
|
|
|
|
#include "opal/runtime/opal_cr.h"
|
|
#include "opal/mca/crs/base/base.h"
|
|
|
|
extern int opal_initialized;
|
|
extern int opal_util_initialized;
|
|
extern bool opal_init_called;
|
|
|
|
static void __opal_attribute_destructor__ opal_cleanup (void)
|
|
{
|
|
if (!opal_initialized) {
|
|
/* nothing to do */
|
|
return;
|
|
}
|
|
|
|
/* finalize the class/object system */
|
|
opal_class_finalize();
|
|
}
|
|
|
|
int
|
|
opal_finalize_util(void)
|
|
{
|
|
if( --opal_util_initialized != 0 ) {
|
|
if( opal_util_initialized < 0 ) {
|
|
return OPAL_ERROR;
|
|
}
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
/* close interfaces code. */
|
|
(void) mca_base_framework_close(&opal_if_base_framework);
|
|
|
|
(void) mca_base_framework_close(&opal_event_base_framework);
|
|
|
|
/* Clear out all the registered MCA params */
|
|
opal_deregister_params();
|
|
mca_base_var_finalize();
|
|
|
|
opal_net_finalize();
|
|
|
|
/* keyval lex-based parser */
|
|
opal_util_keyval_parse_finalize();
|
|
|
|
(void) mca_base_framework_close(&opal_installdirs_base_framework);
|
|
|
|
/* finalize the memory allocator */
|
|
opal_malloc_finalize();
|
|
|
|
/* finalize the show_help system */
|
|
opal_show_help_finalize();
|
|
|
|
/* finalize the output system. This has to come *after* the
|
|
malloc code, as the malloc code needs to call into this, but
|
|
the malloc code turning off doesn't affect opal_output that
|
|
much */
|
|
opal_output_finalize();
|
|
|
|
/* close the dss */
|
|
opal_dss_close();
|
|
|
|
opal_datatype_finalize();
|
|
|
|
#if OPAL_NO_LIB_DESTRUCTOR
|
|
opal_cleanup ();
|
|
#endif
|
|
|
|
free (opal_process_info.nodename);
|
|
opal_process_info.nodename = NULL;
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
|
|
int
|
|
opal_finalize(void)
|
|
{
|
|
if( --opal_initialized != 0 ) {
|
|
if( opal_initialized < 0 ) {
|
|
return OPAL_ERROR;
|
|
}
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
opal_progress_finalize();
|
|
|
|
/* close the checkpoint and restart service */
|
|
opal_cr_finalize();
|
|
|
|
/* close the security framework */
|
|
(void) mca_base_framework_close(&opal_sec_base_framework);
|
|
|
|
#if OPAL_ENABLE_FT_CR == 1
|
|
(void) mca_base_framework_close(&opal_compress_base_framework);
|
|
#endif
|
|
|
|
(void) mca_base_framework_close(&opal_event_base_framework);
|
|
|
|
/* close high resolution timers */
|
|
(void) mca_base_framework_close(&opal_timer_base_framework);
|
|
|
|
(void) mca_base_framework_close(&opal_backtrace_base_framework);
|
|
(void) mca_base_framework_close(&opal_memchecker_base_framework);
|
|
|
|
/* close the memory manager components. Registered hooks can
|
|
still be fired any time between now and the call to
|
|
opal_mem_free_finalize(), and callbacks from the memory manager
|
|
hooks to the bowels of the mem_free code can still occur any
|
|
time between now and end of application (even post main()!) */
|
|
(void) mca_base_framework_close(&opal_memory_base_framework);
|
|
(void) mca_base_framework_close(&opal_patcher_base_framework);
|
|
|
|
/* close the memcpy framework */
|
|
(void) mca_base_framework_close(&opal_memcpy_base_framework);
|
|
|
|
/* finalize the memory manager / tracker */
|
|
opal_mem_hooks_finalize();
|
|
|
|
/* close the hwloc framework */
|
|
(void) mca_base_framework_close(&opal_hwloc_base_framework);
|
|
|
|
/* close the shmem framework */
|
|
(void) mca_base_framework_close(&opal_shmem_base_framework);
|
|
|
|
/* close the sec framework */
|
|
(void) mca_base_framework_close(&opal_sec_base_framework);
|
|
|
|
/* finalize util code */
|
|
opal_finalize_util();
|
|
|
|
return OPAL_SUCCESS;
|
|
}
|
|
|
|
|
|
void opal_finalize_test(void)
|
|
{
|
|
/* Clear out all the registered MCA params */
|
|
mca_base_var_finalize();
|
|
|
|
(void) mca_base_framework_close(&opal_installdirs_base_framework);
|
|
|
|
/* finalize the mca */
|
|
mca_base_close();
|
|
|
|
/* finalize the show_help system */
|
|
opal_show_help_finalize();
|
|
|
|
/* finalize the output system. This has to come *after* the
|
|
malloc code, as the malloc code needs to call into this, but
|
|
the malloc code turning off doesn't affect opal_output that
|
|
much */
|
|
opal_output_finalize();
|
|
|
|
/* close the dss */
|
|
opal_dss_close();
|
|
|
|
/* finalize the class/object system */
|
|
opal_class_finalize();
|
|
}
|