diff options
author | Ben Gamari <bgamari.foss@gmail.com> | 2016-11-02 14:58:59 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-11-02 15:42:00 -0400 |
commit | f4fb3bc15f49997962e223c4f8c489566d7f5d91 (patch) | |
tree | 82dbbaa3320cd4c80c15400754e57411e3a18f8c /rts | |
parent | cc4710af723ca4bbcf77172ff715af22f9ce8419 (diff) | |
download | haskell-f4fb3bc15f49997962e223c4f8c489566d7f5d91.tar.gz |
linker: Split out CacheFlush logic
Test Plan: Validate
Reviewers: erikd, austin, simonmar
Reviewed By: erikd
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2643
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Linker.c | 69 | ||||
-rw-r--r-- | rts/linker/CacheFlush.c | 71 | ||||
-rw-r--r-- | rts/linker/CacheFlush.h | 12 |
3 files changed, 84 insertions, 68 deletions
diff --git a/rts/Linker.c b/rts/Linker.c index 7600ba824e..3e94069dbe 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -28,6 +28,7 @@ #include "Profiling.h" #include "sm/OSMem.h" #include "linker/M32Alloc.h" +#include "linker/CacheFlush.h" #include "PathUtils.h" #if !defined(mingw32_HOST_OS) @@ -2775,29 +2776,6 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first ) #endif #endif // NEED_SYMBOL_EXTRAS -#if defined(arm_HOST_ARCH) - -static void -ocFlushInstructionCache( ObjectCode *oc ) -{ - int i; - // Object code - for (i=0; i < oc->n_sections; i++) { - Section *s = &oc->sections[i]; - // This is a bit too broad but we don't have any way to determine what - // is certainly code - if (s->kind == SECTIONKIND_CODE_OR_RODATA) - __clear_cache(s->start, (void*) ((uintptr_t) s->start + s->size)); - } - - // Jump islands - // Note the (+1) to ensure that the last symbol extra is covered by the - // flush. - __clear_cache(oc->symbol_extras, &oc->symbol_extras[oc->n_symbol_extras+1]); -} - -#endif - #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) #if !defined(x86_64_HOST_ARCH) || !defined(mingw32_HOST_OS) @@ -2905,51 +2883,6 @@ static SymbolExtra* makeArmSymbolExtra( ObjectCode* oc, } #endif // arm_HOST_ARCH -/* -------------------------------------------------------------------------- - * PowerPC specifics (instruction cache flushing) - * ------------------------------------------------------------------------*/ - -#ifdef powerpc_HOST_ARCH -/* - ocFlushInstructionCache - - Flush the data & instruction caches. - Because the PPC has split data/instruction caches, we have to - do that whenever we modify code at runtime. - */ - -static void -ocFlushInstructionCacheFrom(void* begin, size_t length) -{ - size_t n = (length + 3) / 4; - unsigned long* p = begin; - - while (n--) - { - __asm__ volatile ( "dcbf 0,%0\n\t" - "sync\n\t" - "icbi 0,%0" - : - : "r" (p) - ); - p++; - } - __asm__ volatile ( "sync\n\t" - "isync" - ); -} - -static void -ocFlushInstructionCache( ObjectCode *oc ) -{ - /* The main object code */ - ocFlushInstructionCacheFrom(oc->image + oc->misalignment, oc->fileSize); - - /* Jump Islands */ - ocFlushInstructionCacheFrom(oc->symbol_extras, sizeof(SymbolExtra) * oc->n_symbol_extras); -} -#endif /* powerpc_HOST_ARCH */ - /* -------------------------------------------------------------------------- * PEi386(+) specifics (Win32 targets) diff --git a/rts/linker/CacheFlush.c b/rts/linker/CacheFlush.c new file mode 100644 index 0000000000..206b2ef7ef --- /dev/null +++ b/rts/linker/CacheFlush.c @@ -0,0 +1,71 @@ +/* Platform-dependent cache flushing logic */ + +#include "Rts.h" +#include "linker/CacheFlush.h" + +#if defined(arm_HOST_ARCH) + +void +ocFlushInstructionCache( ObjectCode *oc ) +{ + int i; + // Object code + for (i=0; i < oc->n_sections; i++) { + Section *s = &oc->sections[i]; + // This is a bit too broad but we don't have any way to determine what + // is certainly code + if (s->kind == SECTIONKIND_CODE_OR_RODATA) + __clear_cache(s->start, (void*) ((uintptr_t) s->start + s->size)); + } + + // Jump islands + // Note the (+1) to ensure that the last symbol extra is covered by the + // flush. + __clear_cache(oc->symbol_extras, &oc->symbol_extras[oc->n_symbol_extras+1]); +} + +#elif defined(powerpc_HOST_ARCH) +/* + ocFlushInstructionCache + + Flush the data & instruction caches. + Because the PPC has split data/instruction caches, we have to + do that whenever we modify code at runtime. + */ + +static void +ocFlushInstructionCacheFrom(void* begin, size_t length) +{ + size_t n = (length + 3) / 4; + unsigned long* p = begin; + + while (n--) + { + __asm__ volatile ( "dcbf 0,%0\n\t" + "sync\n\t" + "icbi 0,%0" + : + : "r" (p) + ); + p++; + } + __asm__ volatile ( "sync\n\t" + "isync" + ); +} + +void +ocFlushInstructionCache( ObjectCode *oc ) +{ + /* The main object code */ + ocFlushInstructionCacheFrom(oc->image + oc->misalignment, oc->fileSize); + + /* Jump Islands */ + ocFlushInstructionCacheFrom(oc->symbol_extras, sizeof(SymbolExtra) * oc->n_symbol_extras); +} + +#else + +void ocFlushInstructionCache( ObjectCode *oc STG_UNUSED ) {} + +#endif /* powerpc_HOST_ARCH */ diff --git a/rts/linker/CacheFlush.h b/rts/linker/CacheFlush.h new file mode 100644 index 0000000000..f4d939d21e --- /dev/null +++ b/rts/linker/CacheFlush.h @@ -0,0 +1,12 @@ +#ifndef CACHE_FLUSH_H +#define CACHE_FLUSH_H + +#include "LinkerInternals.h" + +#include "BeginPrivate.h" + +void ocFlushInstructionCache( ObjectCode *oc ); + +#include "EndPrivate.h" + +#endif /* CACHE_FLUSH_H */ |