385:
(format nil "~4,1F" 0.001) => "0.00" (should be " 0.0");
(format nil "~4,1@F" 0.001) => "+.00" (should be "+0.0").
+
+386: SunOS/x86 stack exhaustion handling broken
+ According to <http://alfa.s145.xrea.com/sbcl/solaris-x86.html>, the
+ stack exhaustion checking (implemented with a write-protected guard
+ page) does not work on SunOS/x86.
Matthias Hoelzl:
He reported and fixed COMPILE's misbehavior on macros.
+Daisuke Homma:
+ He added support for SunOS on x86 processors.
+
Espen S Johnsen:
He provided an ANSI-compliant version of CHANGE-CLASS for PCL.
;;;; -*- coding: utf-8; -*-
changes in sbcl-0.9.4 relative to sbcl-0.9.3:
+ * new port: the Solaris operating system on x86 processors is now
+ mostly supported, though some rough edges in the environment
+ remain. (thanks to Daisuke Homma)
* enhancement: SBCL on MIPS platforms now has a much larger dynamic
space for its heap. (thanks to Thiemo Seufer)
* minor incompatible change: eof selects abort in the debugger.
echo //guessing default target CPU architecture from host architecture
case `uname -m` in
*86) guessed_sbcl_arch=x86 ;;
+ i86pc) guessed_sbcl_arch=x86 ;;
*x86_64) guessed_sbcl_arch=x86-64 ;;
[Aa]lpha) guessed_sbcl_arch=alpha ;;
sparc*) guessed_sbcl_arch=sparc ;;
(inst rep)
(inst movs :dword)
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)
+
;; Restore the count.
(inst mov ecx edx)
(inst rep)
(inst movs :dword)
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)
+
;; Load the register arguments carefully.
(loadw edx ebp-tn -1)
;; FIXME: Or we could just get rid of this, since the uses of it look
;; disposable.
;; FIXME II: this could well be wrong
- 8192)
+ #!+sparc 8192
+ #!+x86 4096)
(inst mov eax-tn nil-value)
(inst std)
(inst mov ecx-tn (- nvals register-arg-count))
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)
;; Jump into the default loop.
(inst jmp default-stack-vals)
(inst std)
(inst rep)
(inst movs :dword)
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)
;; Restore ESI.
(loadw esi-tn ebx-tn (- (1+ 2)))
;; Now we have to default the remaining args. Find out how many.
(emit-label default-stack-vals)
(inst rep)
(inst stos eax-tn)
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)
;; Restore EDI, and reset the stack.
(emit-label restore-edi)
(loadw edi-tn ebx-tn (- (1+ 1)))
(inst loop loop)
;; NIL out the last cons.
(storew nil-value dst 1 list-pointer-lowtag))
- (emit-label done))))
+ (emit-label done)
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld))))
;;; Return the location and size of the &MORE arg glob created by
;;; COPY-MORE-ARG. SUPPLIED is the total number of arguments supplied
(inst movs :dword)
DONE
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)
;; Reset the CSP at last moved arg.
(inst lea esp-tn (make-ea :dword :base edi :disp n-word-bytes))))
(def!constant linkage-table-space-start #x70000000)
(def!constant linkage-table-space-end #x7ffff000))
+#!+sunos
+(progn
+ (def!constant read-only-space-start #x20000000)
+ (def!constant read-only-space-end #x2ffff000)
+
+ (def!constant static-space-start #x40000000)
+ (def!constant static-space-end #x42fff000)
+
+ (def!constant dynamic-space-start #x48000000)
+ (def!constant dynamic-space-end #xA0000000)
+
+ (def!constant linkage-table-space-start #xA2000000)
+ (def!constant linkage-table-space-end #xA3000000))
+
#!+freebsd
(progn
(def!constant read-only-space-start #x10000000)
(inst cmp esp-tn esi)
(inst jmp :be loop)
DONE
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)
(inst lea esp-tn (make-ea :dword :base edi :disp n-word-bytes))
(inst sub edi esi)
(loop for moved = moved-ptrs then (tn-ref-across moved)
(inst push temp)
(inst loop loop)
- DONE))
+ DONE
+ ;; solaris requires DF being zero.
+ #!+sunos (inst cld)))
--- /dev/null
+CC=gcc
+CFLAGS = -O2 -Wall -DSVR4
+ASFLAGS = -Wall -DSVR4
+LD = ld
+NM = nm -xgp
+GREP = ggrep
+
+ASSEM_SRC = x86-assem.S ldso-stubs.S
+ARCH_SRC = x86-arch.c
+
+OS_SRC = sunos-os.c x86-sunos-os.c os-common.c
+OS_LIBS= -ldl -lsocket -lnsl -lrt
+
+GC_SRC= gencgc.c
+
LINKFLAGS = -g
NM = nm -gp
DEPEND_FLAGS = -MM
+GREP = grep
CFLAGS = -g -Wall -O3
ASFLAGS = $(CFLAGS)
$(CC) ${LINKFLAGS} -o $@ $^ $(LIBS)
sbcl.nm: sbcl
- $(NM) sbcl | grep -v " F \| U " > ,$@
+ $(NM) sbcl | $(GREP) -v " F \| U " > ,$@
mv -f ,$@ $@
sbcl.h: $(wildcard genesis/*.h)
boolean enable_page_protection = 1;
/* Should we unmap a page and re-mmap it to have it zero filled? */
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun)
/* comment from cmucl-2.4.8: This can waste a lot of swap on FreeBSD
* so don't unmap there.
*
* old version of FreeBSD (pre-4.0), so this might no longer be true.
* OTOH, if it is true, this behavior might exist on OpenBSD too, so
* for now we don't unmap there either. -- WHN 2001-04-07 */
+/* Apparently this flag is required to be 0 for SunOS/x86, as there
+ * are reports of heap corruption otherwise. */
boolean gencgc_unmap_zero = 0;
#else
boolean gencgc_unmap_zero = 1;
#include "validate.h"
#include "target-arch-os.h"
+#ifdef LISP_FEATURE_X86
+#include "genesis/static-symbols.h"
+#include "genesis/fdefn.h"
+#endif
+
+#ifdef LISP_FEATURE_GENCGC
+#include "gencgc-internal.h"
+#endif
+
+#if defined LISP_FEATURE_SPARC
#define OS_VM_DEFAULT_PAGESIZE 8192
+#elif defined LISP_FEATURE_X86
+#define OS_VM_DEFAULT_PAGESIZE 4096
+#else
+#error "Don't know OS_VM_DEFAULT_PAGESIZE"
+#endif
long os_vm_page_size=(-1);
static long os_real_page_size=(-1);
struct thread *th;
if(in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE) ||
in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE) ||
+#ifdef LISP_FEATURE_GENCGC
+ in_range_p(addr, DYNAMIC_SPACE_START, DYNAMIC_SPACE_SIZE)
+#else
in_range_p(addr, DYNAMIC_0_SPACE_START, DYNAMIC_SPACE_SIZE) ||
- in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE))
+ in_range_p(addr, DYNAMIC_1_SPACE_START, DYNAMIC_SPACE_SIZE)
+#endif
+ )
return 1;
for_each_thread(th) {
if((th->control_stack_start <= addr) && (addr < th->control_stack_end))
}
\f
+#if defined LISP_FEATURE_GENCGC
+
+void
+sigsegv_handler(int signal, siginfo_t *info, void* void_context)
+{
+ os_context_t *context = arch_os_get_context(&void_context);
+ void* fault_addr = (void*)info->si_addr;
+ if(info->si_code == 1)
+ {
+ perror("error: SEGV_MAPERR\n");
+ exit(1);
+ }
+
+ if (!gencgc_handle_wp_violation(fault_addr))
+ if(!handle_guard_page_triggered(context, fault_addr))
+#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
+ arrange_return_to_lisp_function(context,
+ SymbolFunction(MEMORY_FAULT_ERROR));
+#else
+ interrupt_handle_now(signal, info, context);
+#endif
+}
+
+#else
static void
sigsegv_handler(int signal, siginfo_t *info, void* void_context)
}
}
+#endif
+
void
os_install_interrupt_handlers()
{
int *
context_eflags_addr(os_context_t *context)
{
-#if defined __linux__
+#if defined __linux__ || defined __sun
/* KLUDGE: As of kernel 2.2.14 on Red Hat 6.2, there's code in the
* <sys/ucontext.h> file to define symbolic names for offsets into
* gregs[], but it's conditional on __USE_GNU and not defined, so
* turns out not to matter, perhaps it's just clutter we could get
* rid of? -- WHN 2004-04-18)
*/
-#if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
+#if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __sun
#define GNAME(var) var
#else
#define GNAME(var) _##var
* matter any more, perhaps it's just clutter we could get
* rid of? -- WHN 2004-04-18)
*/
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun)
#define align_4byte 4
#define align_8byte 8
#define align_16byte 16
--- /dev/null
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include "sbcl.h"
+#include "./signal.h"
+#include "os.h"
+#include "arch.h"
+#include "globals.h"
+#include "interrupt.h"
+#include "interr.h"
+#include "lispregs.h"
+#include <sys/socket.h>
+#include <sys/utsname.h>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "validate.h"
+#ifdef LISP_FEATURE_SB_THREAD
+#error "Define threading support functions"
+#else
+int arch_os_thread_init(struct thread *thread) {
+ stack_t sigstack;
+#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
+ /* Signal handlers are run on the control stack, so if it is exhausted
+ * we had better use an alternate stack for whatever signal tells us
+ * we've exhausted it */
+ sigstack.ss_sp=((void *) thread)+dynamic_values_bytes;
+ sigstack.ss_flags=0;
+ sigstack.ss_size = 32*SIGSTKSZ;
+ sigaltstack(&sigstack,0);
+#endif
+ return 1; /* success */
+}
+int arch_os_thread_cleanup(struct thread *thread) {
+ return 1; /* success */
+}
+#endif
+
+os_context_register_t *
+os_context_register_addr(os_context_t *context, int offset)
+{
+ switch(offset) {
+ case reg_EAX: return &context->uc_mcontext.gregs[11];
+ case reg_ECX: return &context->uc_mcontext.gregs[10];
+ case reg_EDX: return &context->uc_mcontext.gregs[9];
+ case reg_EBX: return &context->uc_mcontext.gregs[8];
+ case reg_ESP: return &context->uc_mcontext.gregs[7];
+ case reg_EBP: return &context->uc_mcontext.gregs[6];
+ case reg_ESI: return &context->uc_mcontext.gregs[5];
+ case reg_EDI: return &context->uc_mcontext.gregs[4];
+ default: return 0;
+ }
+ return &context->uc_mcontext.gregs[offset];
+}
+
+os_context_register_t *
+os_context_pc_addr(os_context_t *context)
+{
+ return &(context->uc_mcontext.gregs[14]); /* REG_EIP */
+}
+
+os_context_register_t *
+os_context_sp_addr(os_context_t *context)
+{
+ return &(context->uc_mcontext.gregs[17]); /* REG_UESP */
+}
+
+sigset_t *
+os_context_sigmask_addr(os_context_t *context)
+{
+ return &(context->uc_sigmask);
+}
+
+void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
+{
+}
--- /dev/null
+#ifndef _X86_SOLARIS_OS_H
+#define _X86_SOLARIS_OS_H
+
+typedef ucontext_t os_context_t;
+
+static inline os_context_t *arch_os_get_context(void **void_context) {
+ return (os_context_t *) *void_context;
+}
+
+#endif /* _X86_SOLARIS_OS_H */
"dlsym")
#!+os-provides-dladdr
'("dladdr")
- #!-(and sparc sunos) ;; !defined(SVR4)
+ #!-sunos ;; !defined(SVR4)
'("sigsetmask")))
(with-open-file (f "src/runtime/ldso-stubs.S" :direction :output :if-exists :supersede)
;;; 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.3.62"
+"0.9.3.63"