diff options
author | Chris Johns <chrisj@rtems.org> | 2019-01-15 17:47:41 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2019-02-09 10:06:34 +1100 |
commit | d8c70ba65b13cd023b50b8aed5d91e455017cdd5 (patch) | |
tree | f78c3441ef74a7315ef4f7850bd27631bf0d2502 /cpukit/libdl/rtl-obj.c | |
parent | 4408603e27d028c5c735cf5d9d8160807ce1d591 (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.c | 33 |
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); } } |