diff options
author | Chris Johns <chrisj@rtems.org> | 2016-12-07 17:20:38 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2016-12-14 09:07:16 +1100 |
commit | c6eead1353e03542e5bad9efda3b6553125520d8 (patch) | |
tree | f2495a17c8d001a8249b0e6f785c3428df721a1d /cpukit/libdl/rtl-unwind-dw2.c | |
parent | score: Prevent thread_dispatch_disable_level < 0. (diff) | |
download | rtems-c6eead1353e03542e5bad9efda3b6553125520d8.tar.bz2 |
libdl: Add C++ exception support to loaded modules.
This has been tested on SPARC, i386, PowerPC and ARM.
Closes #2767.
Diffstat (limited to 'cpukit/libdl/rtl-unwind-dw2.c')
-rw-r--r-- | cpukit/libdl/rtl-unwind-dw2.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/cpukit/libdl/rtl-unwind-dw2.c b/cpukit/libdl/rtl-unwind-dw2.c new file mode 100644 index 0000000000..d9237c5b7e --- /dev/null +++ b/cpukit/libdl/rtl-unwind-dw2.c @@ -0,0 +1,71 @@ +/* + * COPYRIGHT (c) 2012-2016 Chris Johns <chrisj@rtems.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ +/** + * @file + * + * @ingroup rtems_rtld + * + * @brief RTEMS Run-Time Link Editor + * + * This is the RTL implementation. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> +#include <stdio.h> + +#include <rtems/rtl/rtl.h> +#include "rtl-elf.h" +#include "rtl-error.h" +#include "rtl-unwind.h" +#include "rtl-unwind-dw2.h" + +/* + * These interfaces are not exported outside the GCC source. + */ +void __register_frame (void *begin); +void __deregister_frame (void *begin); + +bool +rtems_rtl_elf_unwind_dw2_parse (const rtems_rtl_obj_t* obj, + const char* name, + uint32_t flags) +{ + return + ((flags & RTEMS_RTL_OBJ_SECT_CONST) != 0) && + ((strcmp(name, ".eh_frame") == 0) || + (strncmp(name, ".gcc_except_table.", sizeof (".gcc_except_table.") - 1) == 0)); +} + +bool +rtems_rtl_elf_unwind_dw2_register (const rtems_rtl_obj_t* obj) +{ + rtems_rtl_obj_sect_t* sect = rtems_rtl_obj_find_section (obj, ".eh_frame"); + + if (sect != NULL && sect->size > 0 && sect->base != NULL) + { + __register_frame (sect->base); + } + + return true; +} + +bool rtems_rtl_elf_unwind_dw2_deregister (const rtems_rtl_obj_t* obj) +{ + rtems_rtl_obj_sect_t* sect = rtems_rtl_obj_find_section (obj, ".eh_frame"); + + if (sect != NULL && sect->size > 0 && sect->base != NULL) + { + __deregister_frame (sect->base); + } + + return true; +} |