summaryrefslogtreecommitdiff
path: root/cpukit/libdl/rtl-obj.c
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2019-01-15 17:47:41 +1100
committerChris Johns <chrisj@rtems.org>2019-02-09 10:06:34 +1100
commitd8c70ba65b13cd023b50b8aed5d91e455017cdd5 (patch)
treef78c3441ef74a7315ef4f7850bd27631bf0d2502 /cpukit/libdl/rtl-obj.c
parent4408603e27d028c5c735cf5d9d8160807ce1d591 (diff)
libdl: Add support for trampolines
- Trampolines or fixups for veneers provide long jump support for instruciton sets that implement short relative address branches. The linker provides trampolines when creating a static image. This patch adds trampoline support to libdl and the ARM architecture. - The dl09 test requires enough memory so modules are outside the relative branch instruction ranges for the architecture. Updates #3685
Diffstat (limited to 'cpukit/libdl/rtl-obj.c')
-rw-r--r--cpukit/libdl/rtl-obj.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c
index 858713dee1..6f1f2e4916 100644
--- a/cpukit/libdl/rtl-obj.c
+++ b/cpukit/libdl/rtl-obj.c
@@ -118,6 +118,7 @@ rtems_rtl_obj_free (rtems_rtl_obj* obj)
rtems_rtl_obj_erase_sections (obj);
rtems_rtl_obj_erase_dependents (obj);
rtems_rtl_symbol_obj_erase (obj);
+ rtems_rtl_obj_erase_trampoline (obj);
rtems_rtl_obj_free_names (obj);
if (obj->sec_num != NULL)
free (obj->sec_num);
@@ -557,6 +558,26 @@ rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
}
bool
+rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj)
+{
+ if (obj->tramp_size == 0)
+ return true;
+ obj->trampoline = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+ obj->tramp_size,
+ true);
+ if (obj->trampoline == NULL)
+ rtems_rtl_set_error (ENOMEM, "no memory for the trampoline");
+ obj->tramp_brk = obj->trampoline;
+ return obj->trampoline != NULL;
+}
+
+void
+rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj)
+{
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj->trampoline);
+}
+
+bool
rtems_rtl_obj_alloc_dependents (rtems_rtl_obj* obj, size_t dependents)
{
rtems_rtl_obj_depends* depends;
@@ -837,9 +858,17 @@ rtems_rtl_obj_synchronize_cache (rtems_rtl_obj* obj)
rtems_rtl_obj_sect_sync_handler,
&sync_ctx);
- if (sync_ctx.end_va != sync_ctx.start_va) {
+ if (sync_ctx.end_va != sync_ctx.start_va)
+ {
+ size_t size = sync_ctx.end_va - sync_ctx.start_va;
rtems_cache_instruction_sync_after_code_change(sync_ctx.start_va,
- sync_ctx.end_va - sync_ctx.start_va);
+ size);
+ }
+
+ if (obj->trampoline != NULL)
+ {
+ rtems_cache_instruction_sync_after_code_change(obj->trampoline,
+ obj->tramp_size);
}
}