summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2016-11-02 14:58:59 -0400
committerBen Gamari <ben@smart-cactus.org>2016-11-02 15:42:00 -0400
commitf4fb3bc15f49997962e223c4f8c489566d7f5d91 (patch)
tree82dbbaa3320cd4c80c15400754e57411e3a18f8c /rts
parentcc4710af723ca4bbcf77172ff715af22f9ce8419 (diff)
downloadhaskell-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.c69
-rw-r--r--rts/linker/CacheFlush.c71
-rw-r--r--rts/linker/CacheFlush.h12
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 */