mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
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:
parent
4ae8367f88
commit
b36697e233
5
NEWS
5
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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in a new issue