0.8.19.1: PowerPC linkage tables (darwin only for now)
authorBrian Mastenbrook <bmastenb@cs.indiana.edu>
Thu, 30 Dec 2004 13:44:26 +0000 (13:44 +0000)
committerBrian Mastenbrook <bmastenb@cs.indiana.edu>
Thu, 30 Dec 2004 13:44:26 +0000 (13:44 +0000)
   * Linkage tables are now implemented on PowerPC.
     Right now I've only enabled it on Darwin; to enable it on Linux,
 the addresses used for linkage table spaces would need to be tested.
   * Lazy foreign functions do not work correctly - the code expects the signal
     that occurs when jumping to a write-protected page to be the same as the
 signal that occurs when reading from one. On Darwin the former is SIGBUS
 and the latter is SIGSEGV; this means that the fault address testing does
 not work on Darwin.

NEWS
make-config.sh
src/code/save.lisp
src/compiler/ppc/c-call.lisp
src/compiler/ppc/parms.lisp
src/runtime/Config.ppc-darwin
src/runtime/ppc-arch.c
version.lisp-expr

diff --git a/NEWS b/NEWS
index d956277..601d7bd 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+changes in sbcl-0.8.19 relative to sbcl-0.8.18:
+  * enhancement: saving cores with foreign code loaded is now
+    supported on ppc/Darwin in addition to the previously supported
+    platforms.
+
 changes in sbcl-0.8.18 relative to sbcl-0.8.17:
   * new feature: reloading changed shared object files with
     LOAD-SHARED-OBJECT now causes the new definitions to take effect.
index e725cfe..0ba561e 100644 (file)
@@ -206,7 +206,7 @@ elif [ "$sbcl_arch" = "ppc" -a "$sbcl_os" = "linux" ]; then
     tools-for-build/where-is-mcontext > src/runtime/ppc-linux-mcontext.h
 elif [ "$sbcl_arch" = "ppc" -a "$sbcl_os" = "darwin" ]; then
     # We provide a dlopen shim, so a little lie won't hurt
-    printf " :os-provides-dlopen" >> $ltf
+    printf " :os-provides-dlopen :linkage-table" >> $ltf
     # The default stack ulimit under darwin is too small to run PURIFY.
     # Best we can do is complain and exit at this stage
     if [ "`ulimit -s`" = "512" ]; then
index 5351515..8cefec9 100644 (file)
@@ -78,7 +78,7 @@ do not survive intact on all platforms: in this case a WARNING is
 signalled when saving the core. If no warning is signalled, then the
 foreign symbol references will remain intact. Platforms where this is
 currently the case are x86/FreeBSD, x86/Linux, x86/NetBSD,
-sparc/Linux, and sparc/SunOS.
+sparc/Linux, sparc/SunOS, and ppc/Darwin.
 
 This implementation is not as polished and painless as you might like:
   * It corrupts the current Lisp image enough that the current process
index d14fe07..1942ef5 100644 (file)
   (:generator 2
     (inst lr res  (make-fixup (extern-alien-name foreign-symbol) :foreign))))
 
+#!+linkage-table
+(define-vop (foreign-symbol-dataref-address)
+  (:translate foreign-symbol-dataref-address)
+  (:policy :fast-safe)
+  (:args)
+  (:arg-types (:constant simple-string))
+  (:info foreign-symbol)
+  (:results (res :scs (sap-reg)))
+  (:result-types system-area-pointer)
+  (:temporary (:scs (non-descriptor-reg)) addr)
+  (:generator 2
+    (inst lr addr (make-fixup (extern-alien-name foreign-symbol)
+                              :foreign-dataref))
+    (loadw res addr)))
+
 (define-vop (call-out)
   (:args (function :scs (sap-reg) :target cfunc)
         (args :more t))
index 2b7db4f..aaebb53 100644 (file)
 (def!constant dynamic-1-space-start #x48000000)
 (def!constant dynamic-1-space-end   #x4ffff000)
 
-
+#+darwin
+(progn
+  (def!constant linkage-table-space-start #x50000000)
+  (def!constant linkage-table-space-end   #x51000000)
+  (def!constant linkage-table-entry-size 16))
 
 \f
 ;;;; Other random constants.
index 0b136ab..01ec5f6 100644 (file)
@@ -3,8 +3,7 @@ CFLAGS = -Dppc -g -Wall -O2 -no-cpp-precomp
 OS_SRC = bsd-os.c os-common.c ppc-darwin-os.c ppc-darwin-dlshim.c ppc-darwin-langinfo.c
 OS_LIBS = -lSystem -lc -lm
 
-# Avoid the gcc 3.3 prerelease tarpit of death!
-CC = gcc3
+CC = gcc
 
 ASSEM_SRC = ppc-assem.S ldso-stubs.S
 ARCH_SRC = ppc-arch.c
index a8df962..7aa24ef 100644 (file)
@@ -266,3 +266,95 @@ ppc_flush_icache(os_vm_address_t address, os_vm_size_t length)
     address += 32;
   }
 }
+
+#ifdef LISP_FEATURE_LINKAGE_TABLE
+
+/* Linkage tables for PowerPC
+ *
+ * Linkage entry size is 16, because we need at least 4 instructions to
+ * implement a jump.
+ */
+
+/*
+ * Define the registers to use in the linkage jump table. Can be the
+ * same. Some care must be exercised when choosing these. It has to be
+ * a register that is not otherwise being used. reg_NFP is a good
+ * choice. call_into_c trashes reg_NFP without preserving it, so we can
+ * trash it in the linkage jump table.
+ */
+#define LINKAGE_TEMP_REG        reg_NFP
+#define LINKAGE_ADDR_REG        reg_NFP
+
+/*
+ * Insert the necessary jump instructions at the given address.
+ */
+void
+arch_write_linkage_table_jmp(void* reloc_addr, void *target_addr)
+{
+  /*
+   * Make JMP to function entry.
+   *
+   * The instruction sequence is:
+   *
+   *        addis 13, 0, (hi part of addr)
+   *        ori   13, 13, (low part of addr)
+   *        mtctr 13
+   *        bctr
+   *        
+   */
+  int* inst_ptr;
+  unsigned long hi;                   /* Top 16 bits of address */
+  unsigned long lo;                   /* Low 16 bits of address */
+  unsigned int inst;
+
+  inst_ptr = (int*) reloc_addr;
+
+  /*
+   * Split the target address into hi and lo parts for the sethi
+   * instruction.  hi is the top 22 bits.  lo is the low 10 bits.
+   */
+  hi = (unsigned long) target_addr;
+  lo = hi & 0xffff;
+  hi >>= 16;
+
+  /*
+   * addis 13, 0, (hi part)
+   */
+      
+  inst = (15 << 26) | (LINKAGE_TEMP_REG << 21) | (0 << 16) | hi;
+  *inst_ptr++ = inst;
+
+  /*
+   * ori 13, 13, (lo part)
+   */
+
+  inst = (24 << 26) | (LINKAGE_TEMP_REG << 21) | (LINKAGE_TEMP_REG << 16) | lo;
+  *inst_ptr++ = inst;
+  
+  /*
+   * mtctr 13
+   */
+
+  inst = (31 << 26) | (LINKAGE_TEMP_REG << 21) | (9 << 16) | (467 << 1);
+  *inst_ptr++ = inst;
+
+  /*
+   * bctr
+   */
+
+  inst = (19 << 26) | (20 << 21) | (528 << 1);
+  *inst_ptr++ = inst;
+
+
+  *inst_ptr++ = inst;
+  
+  os_flush_icache((os_vm_address_t) reloc_addr, (char*) inst_ptr - (char*) reloc_addr);
+}
+
+void 
+arch_write_linkage_table_ref(void * reloc_addr, void *target_addr)
+{
+    *(unsigned long *)reloc_addr = (unsigned long)target_addr;
+}
+
+#endif
index 0371295..eff2dce 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.18"
+"0.8.19.1"