I'm OK with it but would like Chris to take a look if he gets around to it.
On Wed, Jul 20, 2016 at 4:55 AM, Pavel Pisa <p...@cmp.felk.cvut.cz> wrote: > From be993a950be6c382b70609bcbc38be9bd161e1d4 Mon Sep 17 00:00:00 2001 > Message-Id: > <be993a950be6c382b70609bcbc38be9bd161e1d4.1469004576.git.p...@cmp.felk.cvut.cz> > From: Pavel Pisa <p...@cmp.felk.cvut.cz> > Date: Wed, 20 Jul 2016 10:49:19 +0200 > Subject: [PATCH] libdl/rtl-obj.c: synchronize cache after code relocation. > To: rtems-de...@rtems.org > > 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 | 2 ++ > cpukit/libdl/rtl-obj.c | 65 > ++++++++++++++++++++++++++++++++++++++++++++++++-- > cpukit/libdl/rtl-obj.h | 7 ++++++ > cpukit/libdl/rtl-rap.c | 2 ++ > 4 files changed, 74 insertions(+), 2 deletions(-) > > V2: > - rtems_rtl_obj_synchronize_cache () without return value > - use rtems_cache_get_instruction_line_size () to skip > cache synchronization when given BSP build does not > provide/use instruction cache but CPUkit architecture > variant covers even systems with cache > > diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c > index 0eee540..48d81df 100644 > --- a/cpukit/libdl/rtl-elf.c > +++ b/cpukit/libdl/rtl-elf.c > @@ -941,6 +941,8 @@ 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; > > + rtems_rtl_obj_synchronize_cache (obj); > + > 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..f61d4e5 100644 > --- a/cpukit/libdl/rtl-obj.c > +++ b/cpukit/libdl/rtl-obj.c > @@ -558,6 +558,69 @@ 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; > +} > + > +void > +rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj) > +{ > + rtems_rtl_obj_sect_sync_ctx_t sync_ctx; > + > + if (rtems_cache_get_instruction_line_size() == 0) > + return; > + > + 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); > + } > +} > + > bool > rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj, > int fd, > @@ -618,8 +681,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..80fc60f 100644 > --- a/cpukit/libdl/rtl-obj.h > +++ b/cpukit/libdl/rtl-obj.h > @@ -494,6 +494,13 @@ 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. > + */ > +void 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..a7fcb9f 100644 > --- a/cpukit/libdl/rtl-rap.c > +++ b/cpukit/libdl/rtl-rap.c > @@ -970,6 +970,8 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd) > if (!rtems_rtl_rap_relocate (&rap, obj)) > return false; > > + rtems_rtl_obj_synchronize_cache (obj); > + > return true; > } > > -- > 1.9.1 > _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel