summaryrefslogtreecommitdiffstats
path: root/cpukit/libdl/rtl-unwind-dw2.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libdl/rtl-unwind-dw2.c')
-rw-r--r--cpukit/libdl/rtl-unwind-dw2.c71
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;
+}