From 49fdb02506c8cf8e8dda4cc3ebe0ad4240e458e2 Mon Sep 17 00:00:00 2001 From: toy <toy> Date: Thu, 24 Oct 2002 20:39:00 +0000 Subject: [PATCH] o Port over Tim Moore's cool foreign linkage table stuff to sparc. o Make new-genesis save target-foreign-linkage-table-size to internals.h. --- code/sparc-svr4-vm.lisp | 18 +++- compiler/generic/new-genesis.lisp | 13 ++- compiler/sparc/c-call.lisp | 30 ++++++- compiler/sparc/cell.lisp | 18 +++- compiler/sparc/parms.lisp | 12 ++- lisp/Config.sun4_solaris_gcc | 6 +- lisp/os-common.c | 30 ++++++- lisp/solaris-os.c | 46 +++++++++- lisp/sparc-arch.c | 138 +++++++++++++++++++++++++++++- lisp/sparc-assem.S | 71 ++++++++++++++- lisp/sparc-validate.h | 21 ++++- 11 files changed, 381 insertions(+), 22 deletions(-) diff --git a/code/sparc-svr4-vm.lisp b/code/sparc-svr4-vm.lisp index 896f395c7..1740cab39 100644 --- a/code/sparc-svr4-vm.lisp +++ b/code/sparc-svr4-vm.lisp @@ -5,7 +5,7 @@ ;;; Carnegie Mellon University, and has been placed in the public domain. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/code/sparc-svr4-vm.lisp,v 1.4 1997/02/19 01:41:40 dtc Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/code/sparc-svr4-vm.lisp,v 1.5 2002/10/24 20:38:57 toy Exp $") ;;; ;;; ********************************************************************** ;;; @@ -310,3 +310,19 @@ (* (code-header-ref component code-code-size-slot) word-bytes))) nil) + +#+linkage-table +(progn +(defun lisp::foreign-symbol-address-aux (name flavor) + (let ((entry-num (lisp::register-foreign-linkage name flavor))) + (+ #.vm:target-foreign-linkage-space-start + (* entry-num vm:target-foreign-linkage-entry-size)))) + +(defun lisp::find-foreign-symbol (addr) + (declare (type (unsigned-byte 32) addr)) + (when (>= addr vm:target-foreign-linkage-space-start) + (let ((entry (/ (- addr vm:target-foreign-linkage-space-start) + vm:target-foreign-linkage-entry-size))) + (when (< entry (lisp::foreign-linkage-symbols)) + (lisp::foreign-linkage-entry entry))))) +) diff --git a/compiler/generic/new-genesis.lisp b/compiler/generic/new-genesis.lisp index b3dc359a2..b3b77cb13 100644 --- a/compiler/generic/new-genesis.lisp +++ b/compiler/generic/new-genesis.lisp @@ -4,7 +4,7 @@ ;;; Carnegie Mellon University, and has been placed in the public domain. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/generic/new-genesis.lisp,v 1.48 2002/08/27 22:18:27 moore Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/generic/new-genesis.lisp,v 1.49 2002/10/24 20:38:58 toy Exp $") ;;; ;;; ********************************************************************** ;;; @@ -1954,8 +1954,12 @@ (defun init-foreign-linkage () (setf (fill-pointer *cold-linkage-table*) 0) (clrhash *cold-foreign-hash*) - ;; This has gotta be the first entry. - (cold-register-foreign-linkage "resolve_linkage_tramp" :code)) + ;; This has gotta be the first entry. This has to match what + ;; os_foreign_linkage_init does! + #+x86 + (cold-register-foreign-linkage "resolve_linkage_tramp" :code) + #+sparc + (cold-register-foreign-linkage "call_into_c" :code)) (defvar *cold-assembler-routines* nil) @@ -2252,7 +2256,8 @@ (test-tail "-TRAP" "trap_" 2) (test-tail "-SUBTYPE" "subtype_" 3) (test-head "TRACE-TABLE-" "tracetab_" 4) - (test-tail "-SC-NUMBER" "sc_" 5))))) + (test-tail "-SC-NUMBER" "sc_" 5) + (test-head "TARGET-FOREIGN-" "" 6))))) (setf constants (sort constants #'(lambda (const1 const2) diff --git a/compiler/sparc/c-call.lisp b/compiler/sparc/c-call.lisp index f49924980..90c30d685 100644 --- a/compiler/sparc/c-call.lisp +++ b/compiler/sparc/c-call.lisp @@ -5,7 +5,7 @@ ;;; Carnegie Mellon University, and has been placed in the public domain. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/c-call.lisp,v 1.15 2001/01/23 04:40:15 dtc Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/c-call.lisp,v 1.16 2002/10/24 20:38:58 toy Exp $") ;;; ;;; ********************************************************************** ;;; @@ -190,6 +190,7 @@ (c::give-up)))) +#-linkage-table (define-vop (foreign-symbol-address) (:translate foreign-symbol-address) (:policy :fast-safe) @@ -202,6 +203,33 @@ (inst li res (make-fixup (extern-alien-name foreign-symbol) :foreign)))) +(define-vop (foreign-symbol-code-address) + (:translate #+linkage-table foreign-symbol-code-address + #-linkage-table foreign-symbol-address) + (:policy :fast-safe) + (:args) + (:arg-types (:constant simple-string)) + (:info foreign-symbol) + (:results (res :scs (sap-reg))) + (:result-types system-area-pointer) + (:generator 2 + (inst li res (make-fixup (extern-alien-name foreign-symbol) + :foreign)))) + +(define-vop (foreign-symbol-data-address) + (:translate foreign-symbol-data-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 li addr (make-fixup (extern-alien-name foreign-symbol) + :foreign-data)) + (loadw res addr))) + (define-vop (call-out) (:args (function :scs (sap-reg) :target cfunc) (args :more t)) diff --git a/compiler/sparc/cell.lisp b/compiler/sparc/cell.lisp index 1d68f73a7..550849627 100644 --- a/compiler/sparc/cell.lisp +++ b/compiler/sparc/cell.lisp @@ -5,7 +5,7 @@ ;;; Carnegie Mellon University, and has been placed in the public domain. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/cell.lisp,v 1.20 1994/10/31 04:46:41 ram Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/cell.lisp,v 1.21 2002/10/24 20:38:58 toy Exp $") ;;; ;;; ********************************************************************** ;;; @@ -126,7 +126,13 @@ (inst cmp type function-header-type) (inst b :eq normal-fn) (inst move lip function) - (inst li lip (make-fixup (extern-alien-name "closure_tramp") :foreign)) + ;; For the linkage-table stuff, we need to look up the address + ;; from the linkage table instead of using the address directly. + (inst li lip (make-fixup (extern-alien-name "closure_tramp") + #-linkage-table :foreign + #+linkage-table :foreign-data)) + #+linkage-table + (loadw lip lip) (emit-label normal-fn) (storew function fdefn fdefn-function-slot other-pointer-type) (storew lip fdefn fdefn-raw-addr-slot other-pointer-type) @@ -140,7 +146,13 @@ (:results (result :scs (descriptor-reg))) (:generator 38 (storew null-tn fdefn fdefn-function-slot other-pointer-type) - (inst li temp (make-fixup (extern-alien-name "undefined_tramp") :foreign)) + ;; For the linkage-table stuff, we need to look up the address + ;; from the linkage table instead of using the address directly. + (inst li temp (make-fixup (extern-alien-name "undefined_tramp") + #-linkage-table :foreign + #+linkage-table :foreign-data)) + #+linkage-table + (loadw temp temp) (storew temp fdefn fdefn-raw-addr-slot other-pointer-type) (move result fdefn))) diff --git a/compiler/sparc/parms.lisp b/compiler/sparc/parms.lisp index da9e1ad0b..077338656 100644 --- a/compiler/sparc/parms.lisp +++ b/compiler/sparc/parms.lisp @@ -5,7 +5,7 @@ ;;; Carnegie Mellon University, and has been placed in the public domain. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/parms.lisp,v 1.35 2002/09/03 16:29:46 toy Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/parms.lisp,v 1.36 2002/10/24 20:38:59 toy Exp $") ;;; ;;; ********************************************************************** ;;; @@ -196,9 +196,12 @@ (defparameter target-read-only-space-start #x10000000) (defparameter target-static-space-start #x28000000) (defparameter target-dynamic-space-start #x40000000) -(defparameter target-foreign-linkage-space-start #x0fc00000) -(defconstant target-foreign-linkage-entry-size 8) ;In bytes. Duh. +;; This better match the value in sparc-validate.h! +(defparameter target-foreign-linkage-space-start #x0f800000) +;; This better agree with what sparc-arch.c thinks it is! Right now, +;; it's 4 instructions, so 16 bytes. +(defconstant target-foreign-linkage-entry-size 16) ;;;; Other random constants. @@ -273,6 +276,9 @@ lisp::*free-interrupt-context-index* unix::*interrupts-enabled* unix::*interrupt-pending* + + ;; Foreign linkage stuff + lisp::*linkage-table-data* )) (defparameter static-functions diff --git a/lisp/Config.sun4_solaris_gcc b/lisp/Config.sun4_solaris_gcc index aca79ed9e..78f7f5d6b 100644 --- a/lisp/Config.sun4_solaris_gcc +++ b/lisp/Config.sun4_solaris_gcc @@ -19,16 +19,16 @@ vpath %.S .:$(PATH1) #CC_V8PLUS = -xarch=v8plus #AS_V8PLUS = -Wa -CPPFLAGS = -I. -I$(PATH1) -I/usr/openwin/include -I/usr/include/X11 -DSOLARIS -DSOLARIS25 -DSVR4 $(CC_V8PLUS) +CPPFLAGS = -I. -I$(PATH1) -I/usr/openwin/include -I/usr/include/X11 -DSOLARIS -DSOLARIS25 -DSVR4 $(CC_V8PLUS) -DLINKAGE_TABLE CC = gcc CPP = gcc -E -CFLAGS = -g -O3 $(AS_V8PLUS) +CFLAGS = -g $(AS_V8PLUS) # Needed for sys/asm_linkage.h and sparc-assem.S (at least in 2.3) # Note that the sys/asm_linkage.h braindamage breaks make depend ASFLAGS = -g -traditional-cpp DEPEND_FLAGS = -traditional-cpp -NM = ./solaris-nm +NM = $(PATH1)/solaris-nm ASSEM_SRC = sparc-assem.S ARCH_SRC = sparc-arch.c diff --git a/lisp/os-common.c b/lisp/os-common.c index 26815657d..16fbee750 100644 --- a/lisp/os-common.c +++ b/lisp/os-common.c @@ -1,6 +1,6 @@ /* - $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/os-common.c,v 1.6 2002/08/28 13:29:25 pmai Exp $ + $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/os-common.c,v 1.7 2002/10/24 20:38:59 toy Exp $ This code was written as part of the CMU Common Lisp project at Carnegie Mellon University, and has been placed in the public domain. @@ -104,7 +104,11 @@ os_vm_address_t os_reallocate(os_vm_address_t addr, os_vm_size_t old_len, } #ifdef LINKAGE_TABLE + +/* These declarations are lies. They actually take args, but are + never called by C. Only by Lisp */ extern void resolve_linkage_tramp(void); +extern void call_into_c(void); /* In words */ #define LINKAGE_DATA_ENTRY_SIZE 3 @@ -127,13 +131,29 @@ void os_foreign_linkage_init (void) = (struct vector *)PTR(data_vector->data[i]); long type = fixnum_value(data_vector->data[i + 1]); lispobj lib_list = data_vector->data[i + 2]; - + + /* + * Verify the "known" entries. This had better match what + * init-foreign-linkage in new-genesis does! + */ if (i == 0) { +#ifdef sparc + if (type != 1 || strcmp((char *)symbol_name->data, + "call_into_c")) { + fprintf(stderr, "linkage_data is %s but expected call_into_c\n", + (char*)symbol_name->data); + lose("First element of linkage_data is bogus.\n"); + } + arch_make_linkage_entry(i, &call_into_c, 1); +#else if (type != 1 || strcmp((char *)symbol_name->data, "resolve_linkage_tramp")) { + fprintf(stderr, "linkage_data is %s but expected resolve_linkage_tramp\n", + (char*)symbol_name->data); lose("First element of linkage_data is bogus.\n"); } - arch_make_linkage_entry(0, &resolve_linkage_tramp, 1); + arch_make_linkage_entry(i, &resolve_linkage_tramp, 1); +#endif continue; } if (type == 2 && lib_list == NIL) { @@ -147,6 +167,7 @@ void os_foreign_linkage_init (void) } else { arch_make_lazy_linkage(i / LINKAGE_DATA_ENTRY_SIZE); } + } #endif /* LINKAGE_TABLE */ } @@ -215,6 +236,9 @@ unsigned long os_link_one_symbol(long entry) type = fixnum_value(data_vector->data[table_index + 1]); target_addr = os_dlsym((char *)symbol_name->data, data_vector->data[table_index + 2]); + fprintf(stderr, "Looked up %s symbol %s at %lx\n", + type == 1 ? "code" : "data", + (char*) symbol_name->data, (unsigned long) target_addr); if (!target_addr) { undefined_foreign_symbol_trap((lispobj)data_vector->data[table_index]); } diff --git a/lisp/solaris-os.c b/lisp/solaris-os.c index 0c2e78e9d..67a317f07 100644 --- a/lisp/solaris-os.c +++ b/lisp/solaris-os.c @@ -1,5 +1,5 @@ /* - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/solaris-os.c,v 1.4 2000/12/05 03:03:48 dtc Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/solaris-os.c,v 1.5 2002/10/24 20:38:59 toy Exp $ * * OS-dependent routines. This file (along with os.h) exports an * OS-independent interface to the operating system VM facilities. @@ -23,6 +23,9 @@ #include <unistd.h> #include <errno.h> #include <sys/param.h> + +#include <dlfcn.h> + #define OS_PROTERR SEGV_ACCERR #define OS_MAPERR SEGV_MAPERR #define OS_HASERRNO(code) ((code)->si_errno != 0) @@ -35,6 +38,9 @@ /* To get memory map */ #include "sparc-validate.h" +/* For type_ListPointer and NIL */ +#include "internals.h" + /* block size must be larger than the system page size */ #define SPARSE_BLOCK_SIZE (1<<15) #define SPARSE_SIZE_MASK (SPARSE_BLOCK_SIZE-1) @@ -447,3 +453,41 @@ void make_holes(void) os_protect(hole, HOLE_SIZE, 0); } +/* Some symbols, most notably stat and lstat, don't appear at all in + the glibc .so files as a result of preprocessor and linker magic / + braindamage. So, try falling back to a stub in linux-stubs.S that + will call the proper function if it's one of those. */ + +static void *dlsym_fallback(void *handle, const char *name) +{ + fprintf(stderr, "dlsym_fallback name = %s\n", name); +} + +void *os_dlsym(const char *sym_name, lispobj lib_list) +{ + static void *program_handle; + void *sym_addr = 0; + + if (!program_handle) + program_handle = dlopen((void *)0, RTLD_LAZY | RTLD_GLOBAL); + if (lib_list != NIL) { + lispobj lib_list_head; + + for (lib_list_head = lib_list; + lib_list_head != NIL; + lib_list_head = (CONS(lib_list_head))->cdr) { + struct cons *lib_cons = CONS(CONS(lib_list_head)->car); + struct sap *dlhandle = (struct sap *)PTR(lib_cons->car); + + sym_addr = dlsym((void *)dlhandle->pointer, sym_name); + if (sym_addr) + return sym_addr; + } + } + sym_addr = dlsym(program_handle, sym_name); + if (!sym_addr && dlerror()) { + return dlsym_fallback(program_handle,sym_name); + } else { + return sym_addr; + } +} diff --git a/lisp/sparc-arch.c b/lisp/sparc-arch.c index 68e610f79..35f7ef462 100644 --- a/lisp/sparc-arch.c +++ b/lisp/sparc-arch.c @@ -1,6 +1,6 @@ /* - $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sparc-arch.c,v 1.11 2002/05/02 21:09:33 toy Exp $ + $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sparc-arch.c,v 1.12 2002/10/24 20:39:00 toy Exp $ This code was written as part of the CMU Common Lisp project at Carnegie Mellon University, and has been placed in the public domain. @@ -416,3 +416,139 @@ lispobj funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2) return call_into_lisp(function, args, 3); } + +#ifdef LINKAGE_TABLE + +/* This is mostly stolen from the x86 version, with adjustments for sparc */ + +/* + * Linkage entry size is 16, because we need at least 3 instruction to + * implement a jump: + * + * sethi %hi(addr), %g4 + * jmpl [%g4 + %lo(addr)], %g5 + * nop + * + * The Sparc V9 ABI seems to use 8 words for its jump tables. Maybe + * we should do the same? + */ + +/* + * This had better match lisp::target-foreign-linkage-entry-size in + * sparc/parms.lisp! Each entry is 4 instructions long, so 16 bytes. + */ +#ifndef LinkageEntrySize +#define LinkageEntrySize (4*4) +#endif + + +/* + * Define the registers to use in the linkage jump table. Can be the + * same. This MUST be coordinated with resolve_linkage_tramp which + * needs to know the register used for LINKAGE_ADDR_REG. + * + * Some care must be exercised when choosing these. It has to be a + * register that is not otherwise being used. reg_L0 is a good + * choice. call_into_c trashes reg_L0 without preserving it, so we + * can trash it in the linkage jump table. For the linkage entries + * that call resolve_linkage_tramp, we can use reg_L0 too because + * resolve_linkage_tramp is always called from call_into_c. (This is + * enforced by having new-genesis create an entry for call_into_c, so + * we never have to do a lookup for call_into_c.) + */ +#define LINKAGE_TEMP_REG reg_L0 +#define LINKAGE_ADDR_REG reg_L0 + +/* + * Insert the necessary jump instructions at the given address. + * Return the address of the next word + */ +void* arch_make_jump_entry(void* reloc_addr, void *target_addr) +{ + + /* + * Make JMP to function entry. + * + * The instruction sequence is: + * + * sethi %hi(addr), temp_reg + * jmp %temp_reg + %lo(addr), %addr_reg + * nop + * nop + * + */ + int* inst_ptr; + unsigned long hi; /* Top 22 bits of address */ + unsigned long lo; /* Low 10 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 & 0x3ff; + hi >>= 10; + + /* + * sethi %hi(addr), temp_reg + */ + + inst = (0 << 30) | (LINKAGE_TEMP_REG << 25) | (4 << 22) | hi; + *inst_ptr++ = inst; + + /* + * jmpl [temp_reg + %lo(addr)], addr_reg + */ + + inst = (2 << 30) | (LINKAGE_ADDR_REG << 25) | (0x38 << 19) + | (LINKAGE_TEMP_REG << 14) | (1 << 13) | lo; + *inst_ptr++ = inst; + + /* nop (really sethi 0, %g0) */ + + inst = (0 << 30) | (0 << 25) | (4 << 22) | 0; + + *inst_ptr++ = inst; + *inst_ptr++ = inst; + + os_flush_icache(reloc_addr, (char*) inst_ptr - (char*) reloc_addr); + return reloc_addr; +} + +void arch_make_linkage_entry(long linkage_entry, void *target_addr, long type) +{ + int *reloc_addr = (int *)(FOREIGN_LINKAGE_SPACE_START + + linkage_entry * LinkageEntrySize); + + if (type == 1) + { /* code reference */ + arch_make_jump_entry(reloc_addr, target_addr); + } + else if (type == 2) + { + *(unsigned long *)reloc_addr = (unsigned long)target_addr; + } +} + +/* Make a the entry a jump to resolve_linkage_tramp. */ + +extern void resolve_linkage_tramp(void); + +void arch_make_lazy_linkage(long linkage_entry) +{ + arch_make_linkage_entry(linkage_entry, (void*) resolve_linkage_tramp, 1); +} + +/* Get linkage entry. We're given the return address which should be + the address of the jmpl instruction (2nd word) of the linkage + entry. Figure out which entry this address belong to. */ + +long arch_linkage_entry(unsigned long retaddr) +{ + return (retaddr - (FOREIGN_LINKAGE_SPACE_START)) + / LinkageEntrySize; +} +#endif /* LINKAGE_TABLE */ diff --git a/lisp/sparc-assem.S b/lisp/sparc-assem.S index 37a5653e8..d5d1cd802 100644 --- a/lisp/sparc-assem.S +++ b/lisp/sparc-assem.S @@ -17,6 +17,11 @@ #define _function_end_breakpoint_guts function_end_breakpoint_guts #define _call_into_c call_into_c #define _flush_icache flush_icache +#ifdef LINKAGE_TABLE +#define _resolve_linkage_tramp resolve_linkage_tramp +#define _lazy_resolve_linkage lazy_resolve_linkage +#define _undefined_foreign_symbol_trap undefined_foreign_symbol_trap +#endif #ifdef __STDC__ #define FUNCDEF(x) .type x, \#function #else @@ -53,7 +58,7 @@ #ifdef v8plus #define FRAMESIZE (SA(WINDOWSIZE+4 + 6*8)) #else -#define FRAMESIZE (SA(WINDOWSIZE+4)) +#define FRAMESIZE (SA(MINFRAME)) #endif .seg "text" .global _call_into_lisp @@ -186,6 +191,7 @@ _call_into_c: store(reg_BSP,_current_binding_stack_pointer) store(reg_CSP,_current_control_stack_pointer) store(reg_CFP,_current_control_frame_pointer) + /* Use reg_CFP as a work register, and restore it */ andn reg_ALLOC, 7, reg_CFP store(reg_CFP,_current_dynamic_space_free_pointer) @@ -349,6 +355,69 @@ _flush_icache: nop SET_SIZE(_flush_icache) +#ifdef LINKAGE_TABLE +/* + * Call into C code to resolve a linkage entry. + * + * We get here by Lisp calling call_into_c with an address of the + * desired function which is contained in the register reg_CFUNC (aka + * %i4, aka %r28). This is the address of the entry in the linkage + * table, which is what we need to figure out what function we really + * wanted. + * + * Note that because we get here from call_into_c, all necessary live + * registers have been saved, including FP registers. Hence, no need + * to save them. + */ + .global _lazy_resolve_linkage + .global _resolve_linkage_tramp + FUNCDEF(_resolve_linkage_tramp) +_resolve_linkage_tramp: + /* + * At this point, all of the global %g registers have been + * saved by call_into_c, so we can use them as temps. %g2, + * aka reg_NIL, aka null-tn is a good choice. reg_L0 contains + * the address of the jmpl instruction in the linkage jump + * table. (See sparc-arch.c.) + */ + + mov reg_L0, reg_NIL + + /* + * New stack frame so the %o regs become %i. We can't touch + * the original %o because they contain the parameters to the + * function! + */ + save %sp, -FRAMESIZE, %sp + + /* %g2 tells where we came from in the linkage table */ + call _lazy_resolve_linkage + mov reg_NIL, %o0 ! in the delay slot + + mov %o0, reg_NIL + restore %sp, FRAMESIZE, %sp + + /* And away we go! */ + jmp reg_NIL + nop + + SET_SIZE(_resolve_linkage_tramp) + + .global _undefined_foreign_symbol_trap + FUNCDEF(_undefined_foreign_symbol_trap) +_undefined_foreign_symbol_trap: + unimp trap_Error + .byte 2 /* Number of argument bytes */ + .byte UNDEFINED_FOREIGN_SYMBOL_ERROR + /* Escape to create 16bit BE number from following two values */ + .byte 254 + /* SC_OFFSET(sc_DescriptorReg,NL0) NL0 = %o0 */ + .byte sc_NonDescriptorReg + .byte 0 + .align 4 + +#endif + #ifndef SOLARIS /****************************************************************\ diff --git a/lisp/sparc-validate.h b/lisp/sparc-validate.h index 29d268271..53898faf5 100644 --- a/lisp/sparc-validate.h +++ b/lisp/sparc-validate.h @@ -1,6 +1,6 @@ /* - $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sparc-validate.h,v 1.10 2000/10/27 19:32:03 dtc Exp $ + $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/sparc-validate.h,v 1.11 2002/10/24 20:39:00 toy Exp $ This code was written as part of the CMU Common Lisp project at Carnegie Mellon University, and has been placed in the public domain. @@ -41,6 +41,25 @@ * initialization.) * */ + +#ifdef LINKAGE_TABLE +/* + * This space start better match the value of + * target-foreign-linkage-space-start defined in sparc/parms.lisp! + * + * See the notes there! + */ +#define FOREIGN_LINKAGE_SPACE_START (0x0f800000) + +/* + * This allows for about 510K symbols (assuming each entry is 16 bytes + * long). Hope that's enough! Make sure this doesn't overlap the + * READ_ONLY_SPACE_START! + */ +#define FOREIGN_LINKAGE_SPACE_SIZE (0x007f8000) /* 8 MB - 32 KB */ +#endif + + #define READ_ONLY_SPACE_START (0x10000000) #define READ_ONLY_SPACE_SIZE (0x07ff8000) /* 128 MB - 32 KB, 256 MB max */ -- GitLab