From: Pavel Pisa <p...@cmp.felk.cvut.cz> Memory content changes caused by relocation has to be propagated to memory/cache level which is used/snooped during instruction cache fill. --- cpukit/libdl/rtl-elf.c | 3 +++ cpukit/libdl/rtl-obj.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++-- cpukit/libdl/rtl-obj.h | 9 +++++++ cpukit/libdl/rtl-rap.c | 3 +++ 4 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c index 0eee540..85853be 100644 --- a/cpukit/libdl/rtl-elf.c +++ b/cpukit/libdl/rtl-elf.c @@ -941,6 +941,9 @@ rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd) if (!rtems_rtl_obj_relocate (obj, fd, rtems_rtl_elf_relocator, &ehdr)) return false; + if (!rtems_rtl_obj_synchronize_cache (obj)) + return false; + rtems_rtl_symbol_obj_erase_local (obj); if (!rtems_rtl_elf_load_details (obj)) diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c index 00a1c6e..dba661d 100644 --- a/cpukit/libdl/rtl-obj.c +++ b/cpukit/libdl/rtl-obj.c @@ -558,6 +558,71 @@ rtems_rtl_obj_relocate (rtems_rtl_obj_t* obj, return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data); } +/** + * Cache synchronization after runtime object load (dlopen) + */ +typedef struct +{ + uint32_t mask; + void *start_va; + void *end_va; +} rtems_rtl_obj_sect_sync_ctx_t; + +static bool +rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data) +{ + rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node; + rtems_rtl_obj_sect_sync_ctx_t* sync_ctx = data; + uintptr_t old_end; + uintptr_t new_start; + + if ( !(sect->flags & sync_ctx->mask) || !sect->size) + return true; + + if (sync_ctx->end_va == sync_ctx->start_va) { + sync_ctx->start_va = sect->base; + } else { + old_end = (uintptr_t)sync_ctx->end_va & ~(CPU_CACHE_LINE_BYTES - 1); + new_start = (uintptr_t)sect->base & ~(CPU_CACHE_LINE_BYTES - 1); + if ( (sect->base < sync_ctx->start_va) || + (new_start - old_end > CPU_CACHE_LINE_BYTES) ) { + rtems_cache_instruction_sync_after_code_change(sync_ctx->start_va, + sync_ctx->end_va - sync_ctx->start_va + 1); + sync_ctx->start_va = sect->base; + } + } + + sync_ctx->end_va = sect->base + sect->size; + + return true; +} + +bool +rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj) +{ + rtems_rtl_obj_sect_sync_ctx_t sync_ctx; + + if (CPU_CACHE_LINE_BYTES == 0) + return true; + + sync_ctx.mask = RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST | + RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_BSS | + RTEMS_RTL_OBJ_SECT_EXEC; + + sync_ctx.start_va = 0; + sync_ctx.end_va = sync_ctx.start_va; + rtems_rtl_chain_iterate (&obj->sections, + rtems_rtl_obj_sect_sync_handler, + &sync_ctx); + + if (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); + } + + return true; +} + bool rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj, int fd, @@ -618,8 +683,6 @@ rtems_rtl_obj_sections_loader (uint32_t mask, first = false; } - rtems_cache_instruction_sync_after_code_change(base, base_offset); - node = rtems_chain_next (node); } diff --git a/cpukit/libdl/rtl-obj.h b/cpukit/libdl/rtl-obj.h index 1202fd5..b1cb1d5 100644 --- a/cpukit/libdl/rtl-obj.h +++ b/cpukit/libdl/rtl-obj.h @@ -494,6 +494,15 @@ bool rtems_rtl_obj_relocate (rtems_rtl_obj_t* obj, void* data); /** + * Synchronize caches to make code visible to CPU(s) + * + * @param obj The object file's descriptor. + * @retval true Cache synchronization succeed. + * @retval false Cache synchronization failed. + */ +bool rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj); + +/** * Relocate an object file's unresolved reference. * * @param rec The unresolved relocation record. diff --git a/cpukit/libdl/rtl-rap.c b/cpukit/libdl/rtl-rap.c index 439eb20..0cb169e 100644 --- a/cpukit/libdl/rtl-rap.c +++ b/cpukit/libdl/rtl-rap.c @@ -970,6 +970,9 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd) if (!rtems_rtl_rap_relocate (&rap, obj)) return false; + if (!rtems_rtl_obj_synchronize_cache (obj)) + return false; + return true; } -- 1.9.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel