From: Thiemo Seufer Date: Thu, 29 Sep 2005 06:45:08 +0000 (+0000) Subject: 0.9.5.11: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=3da4a7fbba3015abf8572946dc4481dc2980b943;p=sbcl.git 0.9.5.11: Linkage table support for mips. --- diff --git a/NEWS b/NEWS index c680409..63aa706 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ changes in sbcl-0.9.6 relative to sbcl-0.9.5: (thanks to Svein Ove Aas) * bug fix: Unicode symbols are correctly printed in LDB backtraces (thanks to David Lichteblau) + * enhancement: saving cores with foreign code loaded is now supported + on MIPS/Linux in addition to the previously supported platforms. changes in sbcl-0.9.5 relative to sbcl-0.9.4: * new feature: timers based on Zach Beane's excellent timer package diff --git a/make-config.sh b/make-config.sh index 87730b9..3ceb758 100644 --- a/make-config.sh +++ b/make-config.sh @@ -204,11 +204,12 @@ elif [ "$sbcl_arch" = "x86-64" ]; then printf ' :gencgc :stack-grows-downward-not-upward :c-stack-is-control-stack :linkage-table' >> $ltf printf ' :stack-allocatable-closures' >> $ltf elif [ "$sbcl_arch" = "mips" ]; then + printf ' :linkage-table' >> $ltf + printf ' :stack-allocatable-closures' >> $ltf # Use a little C program to try to guess the endianness. Ware # cross-compilers! # # FIXME: integrate to grovel-features, mayhaps - printf ' :stack-allocatable-closures' >> $ltf $GNUMAKE -C tools-for-build determine-endianness -I src/runtime tools-for-build/determine-endianness >> $ltf elif [ "$sbcl_arch" = "ppc" -a "$sbcl_os" = "linux" ]; then diff --git a/src/compiler/mips/c-call.lisp b/src/compiler/mips/c-call.lisp index 5e0cf13..0df24aa 100644 --- a/src/compiler/mips/c-call.lisp +++ b/src/compiler/mips/c-call.lisp @@ -236,6 +236,20 @@ (:generator 2 (inst li res (make-fixup foreign-symbol :foreign)))) +#!+linkage-table +(define-vop (foreign-symbol-dataref-sap) + (:translate foreign-symbol-dataref-sap) + (: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 li addr (make-fixup foreign-symbol :foreign-dataref)) + (loadw res addr))) + (define-vop (call-out) (:args (function :scs (sap-reg) :target cfunc) (args :more t)) diff --git a/src/compiler/mips/parms.lisp b/src/compiler/mips/parms.lisp index 5e0af59..4756543 100644 --- a/src/compiler/mips/parms.lisp +++ b/src/compiler/mips/parms.lisp @@ -89,6 +89,11 @@ (def!constant dynamic-0-space-end #x50000000) (def!constant dynamic-1-space-start #x50000000) (def!constant dynamic-1-space-end #x70000000) + + (def!constant linkage-table-space-start #x70000000) + (def!constant linkage-table-space-end #x71000000) + (def!constant linkage-table-entry-size 16) + ;; C stack grows downward from 0x80000000 ) diff --git a/src/runtime/mips-arch.c b/src/runtime/mips-arch.c index 0c9be42..8722021 100644 --- a/src/runtime/mips-arch.c +++ b/src/runtime/mips-arch.c @@ -244,7 +244,7 @@ next_insn_addr(os_context_t *context, unsigned int inst) void arch_skip_instruction(os_context_t *context) { - /* Skip the offending instruction. Don't use os_context_insn here, + /* Skip the offending instruction. Don't use os_context_insn here, since in case of a branch we want the branch insn, not the delay slot. */ *os_context_pc_addr(context) @@ -280,7 +280,7 @@ arch_install_breakpoint(void *pc) unsigned int *ptr = (unsigned int *)pc; unsigned int insn; - /* Don't install over a branch/jump with delay slot. */ + /* Don't install over a branch/jump with delay slot. */ if (arch_insn_with_bdelay_p(*ptr)) ptr++; @@ -321,7 +321,7 @@ arch_remove_breakpoint(void *pc, unsigned int orig_inst) os_flush_icache((os_vm_address_t)ptr, INSN_LEN); } -/* Perform the instruction that we overwrote with a breakpoint. As we +/* Perform the instruction that we overwrote with a breakpoint. As we don't have a single-step facility, this means we have to: - put the instruction back - put a second breakpoint at the following instruction, @@ -397,7 +397,7 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) break; case 0x10: - /* Clear the pseudo-atomic flag */ + /* Clear the pseudo-atomic flag. */ *os_context_register_addr(context, reg_NL4) &= ~(-1LL<<31); arch_skip_instruction(context); interrupt_handle_pending(context); @@ -522,3 +522,45 @@ funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2) return call_into_lisp(function, args, 3); } + +#ifdef LISP_FEATURE_LINKAGE_TABLE + +/* Linkage tables for MIPS + + Linkage entry size is 16, because we need 4 instructions to implement + a jump. The entry size constant is defined in parms.lisp. + + Define the register to use in the linkage jump table. For MIPS this + has to be the PIC call register $25 aka t9 aka reg_ALLOC. */ +#define LINKAGE_TEMP_REG reg_ALLOC + +/* 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: + lui $25, 0, %hi(addr) + addiu $25, $25, %lo(addr) + jr $25 + nop */ + unsigned int *insn = (unsigned int *)reloc_addr; + unsigned int addr = (unsigned int)target_addr; + unsigned int hi = ((addr + 0x8000) >> 16) & 0xffff; + unsigned int lo = addr & 0xffff; + + *insn++ = (15 << 26) | (LINKAGE_TEMP_REG << 16) | hi; + *insn++ = ((9 << 26) | (LINKAGE_TEMP_REG << 21) + | (LINKAGE_TEMP_REG << 16) | lo); + *insn++ = (LINKAGE_TEMP_REG << 21) | 8; + *insn = 0; + + os_flush_icache((os_vm_address_t)reloc_addr, LINKAGE_TABLE_ENTRY_SIZE); +} + +void +arch_write_linkage_table_ref(void *reloc_addr, void *target_addr) +{ + *(unsigned int *)reloc_addr = (unsigned int)target_addr; +} + +#endif diff --git a/version.lisp-expr b/version.lisp-expr index 02ab1e7..bdde6d6 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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.9.5.10" +"0.9.5.11"