0.8.19.1: PowerPC linkage tables (darwin only for now)

* 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.
This commit is contained in:
Brian Mastenbrook 2004-12-30 13:44:26 +00:00
parent 4ae8367f88
commit b36697e233
8 changed files with 121 additions and 6 deletions

5
NEWS
View file

@ -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.

View 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

View 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

View file

@ -310,6 +310,21 @@
(: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))

View file

@ -102,7 +102,11 @@
(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))
;;;; Other random constants.

View 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

View 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

View 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"