Paste number 585: OpenBSD/x86 (elf) patch (unfinished)

Index of paste annotations: 1

Paste number 585: OpenBSD/x86 (elf) patch (unfinished)
Pasted by: uniq_
When:19 years, 1 month ago
Share:Tweet this! | http://paste.lisp.org/+G9
Channel:#lisp
Paste contents:
Raw Source | XML | Display As
This patch is a snapshot of my work on the OpenBSD/x86 (ELF) port for sbcl.

With this patch applied, the first boot stops (on my system) at an assertion
failure in gencgc.c:202, shortly after mapping the cold-sbcl.core file, during
the first GC, in generation 2, while scavenging the dynamic space - and I have
no clue what is causing this failure, as of now! :-)

The patch basically
 - changes the addresses in src/compiler/x86/parms.lisp,
 - prepares for ELF by removing the underscore symbol prefix,
 - fixes a typedef in src/runtime,
 - adds a few more debug messages, and checks.

The patch also includes modified version of the "trymap" tool, which can
now check multiple address mappings in one run, and accepts two forms of
arguments: a range (start-end), or an address and length pair (addr:length).

I'm impatient to see sbcl running on this system, again. So I'm mostly doing
quick hacks here and there, to find out what's going on. Therefore some things
have to be cleaned up later: #defines should be made backward compatible
with OpenBSD 3.3, the values in parms.lisp should be optimized, and
added/modified debug code has to be removed.

diff /home/uniq/sbcl-0.8.9/base-target-features.lisp-expr /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/base-target-features.lisp-expr
--- /home/uniq/sbcl-0.8.9/base-target-features.lisp-expr	Thu Nov 27 06:21:04 2003
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/base-target-features.lisp-expr	Mon Apr  5 00:03:53 2004
@@ -105,13 +105,13 @@
  ;; If you want to be able to use the extra debugging information,
  ;; therefore, be sure to keep the sources around, and run with the
  ;; readtable configured so that the system sources can be read.
- ; :sb-show
+ ;:sb-show
 
  ;; Build SBCL with the old CMU CL low level debugger, "ldb". If 
  ;; are aren't messing with CMU CL at a very low level (e.g. 
  ;; trying to diagnose GC problems, or trying to debug assembly
  ;; code for a port to a new CPU) you shouldn't need this.
- ; :sb-ldb
+ :sb-ldb
 
  ;; This isn't really a target Lisp feature at all, but controls
  ;; whether the build process produces an after-xc.core file. This
@@ -118,7 +118,7 @@
  ;; can be useful for shortening the edit/compile/debug cycle when
  ;; you modify SBCL's own source code, as in slam.sh. Otherwise
  ;; you don't need it.
- ; :sb-after-xc-core
+ :sb-after-xc-core
 
  ;; Enable extra debugging output in the assem.lisp assembler/scheduler
  ;; code. (This is the feature which was called :DEBUG in the
diff /home/uniq/sbcl-0.8.9/src/compiler/x86/parms.lisp /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/compiler/x86/parms.lisp
--- /home/uniq/sbcl-0.8.9/src/compiler/x86/parms.lisp	Sat Nov 29 00:35:41 2003
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/compiler/x86/parms.lisp	Mon Apr  5 02:32:53 2004
@@ -150,19 +150,27 @@
 
 #!+bsd
 (progn
+ 
+  (def!constant read-only-space-start
+    #!+freebsd #x10000000
+    #!+openbsd #x1d000000)
+  (def!constant read-only-space-end
+    #!+freebsd #x1ffff000
+    #!+openbsd #x1f000000)
 
-  (def!constant read-only-space-start #x10000000)
-  (def!constant read-only-space-end   #x1ffff000)
-
   (def!constant static-space-start
     #!+freebsd #x30000000
     #!+openbsd #x28000000)
-  (def!constant static-space-end      #x37fff000)
+  (def!constant static-space-end
+    #!+freebsd #x37fff000
+    #!+openbsd #x2a000000)
 
   (def!constant dynamic-space-start
-    #!+freebsd                             #x48000000
-    #!+openbsd                             #x50000000)
-  (def!constant dynamic-space-end          #x88000000))
+    #!+freebsd #x48000000
+    #!+openbsd #x2b000000)
+  (def!constant dynamic-space-end
+    #!+freebsd #x88000000
+    #!+openbsd #x3b000000))
 
 ;;; Given that NIL is the first thing allocated in static space, we
 ;;; know its value at compile time:
diff /home/uniq/sbcl-0.8.9/src/compiler/x86/vm.lisp /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/compiler/x86/vm.lisp
--- /home/uniq/sbcl-0.8.9/src/compiler/x86/vm.lisp	Wed Jul 16 08:26:03 2003
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/compiler/x86/vm.lisp	Tue Apr  6 00:50:07 2004
@@ -451,7 +451,7 @@
 ;;; the symbol table (for example, prepending an underscore).
 (defun extern-alien-name (name)
   (declare (type simple-base-string name))
-  ;; OpenBSD is non-ELF, and needs a _ prefix
-  #!+openbsd (concatenate 'string "_" name)
+  ;; OpenBSD before 3.4 is non-ELF, and needs a _ prefix
+  ;#!+openbsd (concatenate 'string "_" name)
   ;; The other (ELF) ports currently don't need any prefix
-  #!-openbsd name)
+  name)
diff /home/uniq/sbcl-0.8.9/src/runtime/Config.x86-openbsd /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/Config.x86-openbsd
--- /home/uniq/sbcl-0.8.9/src/runtime/Config.x86-openbsd	Mon Oct  2 17:27:11 2000
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/Config.x86-openbsd	Tue Apr  6 00:48:19 2004
@@ -8,3 +8,4 @@
 # so I've just punted and left link flags for OpenBSD in their
 # pre-dynamic-library-support state. -- WHN 2000-10-02
 OS_LINK_FLAGS = -static
+OS_LIBS = -lpthread
diff /home/uniq/sbcl-0.8.9/src/runtime/GNUmakefile /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/GNUmakefile
--- /home/uniq/sbcl-0.8.9/src/runtime/GNUmakefile	Fri Feb 20 07:51:03 2004
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/GNUmakefile	Tue Apr  6 00:50:45 2004
@@ -52,6 +52,12 @@
 sbcl: ${OBJS} 
 	$(CC) ${LINKFLAGS} ${OS_LINK_FLAGS} -o $@ ${OBJS} ${OS_LIBS} -lm
 
+trymap: trymap.o
+	$(CC) ${LINKFLAGS} ${OS_LINK_FLAGS} -o $@ trymap.o ${OS_LIBS} -lm
+
+map: ${OBJS} 
+	$(CC) -Xlinker -M ${LINKFLAGS} ${OS_LINK_FLAGS} -o $@ ${OBJS} ${OS_LIBS} -lm 2>&1 | less
+
 
 .PHONY: clean all
 clean:
diff /home/uniq/sbcl-0.8.9/src/runtime/bsd-os.c /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/bsd-os.c
--- /home/uniq/sbcl-0.8.9/src/runtime/bsd-os.c	Fri Feb 20 07:51:03 2004
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/bsd-os.c	Mon Apr  5 23:37:50 2004
@@ -37,7 +37,11 @@
 #include "validate.h"
 
 
+#if defined OpenBSD && !defined OpenBSD3_1
+vsize_t os_vm_page_size;
+#else
 vm_size_t os_vm_page_size;
+#endif
 
 void os_init(void)
 {
@@ -80,6 +84,15 @@
     if (addr)
 	flags |= MAP_FIXED;
 
+#if (OpenBSD >= 200311)
+    /* OpenBSD 3.4 has introduced the mquery() system call. */
+    if (mquery(addr, len, OS_VM_PROT_ALL, flags, -1, 0) == MAP_FAILED) {
+	warn("mquery");
+	return NULL;
+    }
+#endif
+
+    FSHOW((stderr, "/os_validate(%p, 0x%x)", addr, len));
     addr = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
 
     if (addr == MAP_FAILED) {
@@ -87,6 +100,7 @@
 	return NULL;
     }
 
+    FSHOW((stderr, " = %p\n", addr));
     return addr;
 }
 
@@ -100,6 +114,7 @@
 os_vm_address_t
 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
 {
+    FSHOW((stderr, "/os_map(%d, %d, %p, %u)", fd, offset, addr, len));
     addr = mmap(addr, len,
 		OS_VM_PROT_ALL,
 		MAP_PRIVATE | MAP_FILE | MAP_FIXED,
@@ -110,6 +125,7 @@
 	lose("unexpected mmap(..) failure");
     }
 
+    FSHOW((stderr, " = %p\n", addr));
     return addr;
 }
 
@@ -116,6 +132,7 @@
 void
 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
 {
+    FSHOW((stderr, "/os_protect(%p, %d, 0x%x)\n", address, length, prot));
     if (mprotect(address, length, prot) == -1) {
 	perror("mprotect");
     }
diff /home/uniq/sbcl-0.8.9/src/runtime/bsd-os.h /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/bsd-os.h
--- /home/uniq/sbcl-0.8.9/src/runtime/bsd-os.h	Fri Feb 20 07:51:03 2004
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/bsd-os.h	Sun Apr  4 16:48:39 2004
@@ -17,13 +17,22 @@
 #include <sys/mman.h>
 #include <sys/signal.h>
 
+#if defined __OpenBSD__
+/* defines the OpenBSDx_x macro */
+#include <sys/param.h>
+#endif
+
 typedef caddr_t os_vm_address_t;
+#if defined __OpenBSD__ && defined OpenBSD3_1
 typedef vm_size_t os_vm_size_t;
+#elif defined __OpenBSD__
+typedef vsize_t os_vm_size_t;
+#endif
 typedef off_t os_vm_offset_t;
 typedef int os_vm_prot_t;
 typedef int os_context_register_t;
 
-#if defined __OpenBSD__
+#if defined __OpenBSD__ && defined OpenBSD3_1
 /* name defined for compatibility between OpenBSD 3.1 sigaltstack(2) and
  * Linux sigaltstack(2) */
 typedef struct sigaltstack stack_t;
diff /home/uniq/sbcl-0.8.9/src/runtime/gencgc.c /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/gencgc.c
--- /home/uniq/sbcl-0.8.9/src/runtime/gencgc.c	Sat Feb  7 06:53:32 2004
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/gencgc.c	Mon Apr  5 03:44:17 2004
@@ -498,11 +498,11 @@
     int bytes_found;
     int i;
 
-    /*
+/*
     FSHOW((stderr,
 	   "/alloc_new_region for %d bytes from gen %d\n",
 	   nbytes, gc_alloc_generation));
-    */
+*/
 
     /* Check that the region is in a reset state. */
     gc_assert((alloc_region->first_page == 0)
@@ -2848,9 +2848,9 @@
     /* Grab new_areas_index. */
     current_new_areas_index = new_areas_index;
 
-    /*FSHOW((stderr,
+    FSHOW((stderr,
 	     "The first scan is finished; current_new_areas_index=%d.\n",
-	     current_new_areas_index));*/
+	     current_new_areas_index));
 
     while (current_new_areas_index > 0) {
 	/* Move the current to the previous new areas */
@@ -2880,7 +2880,7 @@
 	    if (gencgc_verbose)
 		SHOW("new_areas overflow, doing full scavenge");
 
-	    /* Don't need to record new areas that get scavenge anyway
+	    /* Don't need to record new areas that get scavenged anyway
 	     * during scavenge_newspace_generation_one_scan. */
 	    record_new_objects = 1;
 
@@ -2911,19 +2911,19 @@
 
 	current_new_areas_index = new_areas_index;
 
-	/*FSHOW((stderr,
+	FSHOW((stderr,
 	         "The re-scan has finished; current_new_areas_index=%d.\n",
-	         current_new_areas_index));*/
+	         current_new_areas_index));
     }
 
     /* Turn off recording of areas allocated by gc_alloc(). */
     record_new_objects = 0;
 
-#if SC_NS_GEN_CK
+#if 1
     /* Check that none of the write_protected pages in this generation
      * have been written to. */
     for (i = 0; i < NUM_PAGES; i++) {
-	if ((page_table[i].allocation != FREE_PAGE_FLAG)
+	if ((page_table[i].allocated != FREE_PAGE_FLAG)
 	    && (page_table[i].bytes_used != 0)
 	    && (page_table[i].gen == generation)
 	    && (page_table[i].write_protected_cleared != 0)
diff /home/uniq/sbcl-0.8.9/src/runtime/runtime.h /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/runtime.h
--- /home/uniq/sbcl-0.8.9/src/runtime/runtime.h	Wed Apr  2 11:15:23 2003
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/runtime.h	Sat Apr  3 00:20:07 2004
@@ -15,7 +15,7 @@
 #ifndef _SBCL_RUNTIME_H_
 #define _SBCL_RUNTIME_H_
 
-#define QSHOW 0 /* Enable low-level debugging output? */
+#define QSHOW 1 /* Enable low-level debugging output? */
 #if QSHOW
 #define FSHOW(args) fprintf args
 #define SHOW(string) FSHOW((stderr, "/%s\n", string))
@@ -34,7 +34,7 @@
  * necessarily reentrant. But it can still be very convenient for
  * figuring out what's going on when you have a signal handling
  * problem.. */
-#define QSHOW_SIGNALS 0
+#define QSHOW_SIGNALS 1
 
 #define N_LOWTAG_BITS 3
 #define LOWTAG_MASK ((1<<N_LOWTAG_BITS)-1)
diff /home/uniq/sbcl-0.8.9/src/runtime/trymap.c /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/trymap.c
--- /home/uniq/sbcl-0.8.9/src/runtime/trymap.c	Sun May 27 13:02:55 2001
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/trymap.c	Mon Apr  5 00:20:19 2004
@@ -19,50 +19,97 @@
 #include <sys/types.h>
 #include <sys/mman.h>
 
+#ifdef __OpenBSD__
+#include <sys/param.h>
+#include <err.h>
+#endif
+
+/* XXX addrparse and lenparse are ugly, could be simplified. */
+
+char *
+addrparse(char *s)
+{
+	long	result;
+
+	if (1 != sscanf(s, "%lx-%*x", &result) &&
+	    1 != sscanf(s, "%lx:%*x", &result) &&
+	    1 != sscanf(s, "%lx", &result)) {
+		if (1 == sscanf(s, ":%lx", &result))
+			/* no address, just a length. */
+			return (char *)0;
+		fprintf(stderr, "can't parse \"%s\" as an address\n", s);
+		exit(1);
+	}
+	return (char *)result;
+}
+
 long
-hexparse(char *s)
+lenparse(char *s)
 {
-    long result;
-    if (1 != sscanf(s, "%lx", &result)) {
-	fprintf(stderr, "can't parse \"%s\" as hexadecimal integer\n", s);
-	exit(1);
-    }
-    return result;
+	long	result;
+	long	addr;
+
+	if (1 != sscanf(s, "%*x:%lx", &result) &&
+	    1 != sscanf(s, ":%lx", &result)) {
+		if (2 == sscanf(s, "%lx-%lx", &addr, &result)) {
+			/* convert ending address to length. */
+			return result - addr;
+		}
+		if (1 == sscanf(s, "%lx", &result))
+			/* no length, just an address. */
+			return 0;
+		fprintf(stderr, "can't parse \"%s\" as a length\n", s);
+		exit(1);
+	}
+	return result;
 }
 
+void
+trymmap(char *requested_addr, long length)
+{
+	char	*addr;
+	int	 flags;
+
+	flags = MAP_PRIVATE | MAP_ANON;
+
+	if (requested_addr != (char *)0)
+		flags |= MAP_FIXED;
+
+#if (OpenBSD >= 200311)
+	/* OpenBSD 3.4 has introduced the mquery() system call. */
+	addr = mquery(requested_addr, length, 0x7, flags, -1, 0);
+	if (addr == MAP_FAILED) {
+		err(1, "mquery(%p, 0x%lx)", requested_addr, length);
+	}
+
+	if (requested_addr != addr)
+		warnx("mquery suggested %p, instead of %p", addr,
+		    requested_addr);
+#endif /* OpenBSD */
+
+	addr = mmap(requested_addr, length, 0x7, flags, -1, 0);
+	if (addr == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+
+	printf("mmap(%p, 0x%lx) = %p-%p\n", requested_addr, length, addr,
+	    &addr[length]);
+	fflush(stdout);
+}
+
 int
 main(int argc, char *argv[])
 {
-    char *addr;
-    char *requested_addr;
+	int	 i;
 
-    /* FIXME: It would be nice to make the no-command-line-arguments
-     * case of this program automatically check all the spaces that
-     * SBCL likes to map. Then we could execute this program as a
-     * sanity check in make-target-2.sh before we try to execute sbcl
-     * itself. */
-    if (argc != 3) {
-	fprintf(stderr, "usage: %s $addr $size\n", argv[0]);
-	exit(1);
-    }
+	if (argc == 1) {
+		fprintf(stderr, "usage:\t%s addr[:len] ...\n", argv[0]);
+		fprintf(stderr, "\t%s addr[-len] ...\n", argv[0]);
+		exit(2);
+	}
 
-    requested_addr = (char*)hexparse(argv[1]);
-    addr = mmap(requested_addr,
-		hexparse(argv[2]),
-		0x7,
-		MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-		-1,
-		0);
-
-    /* FIXME: It would be nice to make this a stronger test. E.g.
-     * besides just trying to mmap() the area, we could check that the
-     * area is not already mapped (perhaps by checking that attempts
-     * to reference the to-be-mapped area cause SIGSEGV or SIGBUS).
-     * (At least on OpenBSD, "A successful mmap deletes any previous
-     * mapping in the allocated address range.") */
-    if (addr != requested_addr) {
-	perror("mmap");
-    }
-	
-    exit(0);
+	for (i = 1; i < argc; i++)
+		trymmap(addrparse(argv[i]), lenparse(argv[i]));
+	exit(0);
 }
diff /home/uniq/sbcl-0.8.9/src/runtime/undefineds.h /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/undefineds.h
--- /home/uniq/sbcl-0.8.9/src/runtime/undefineds.h	Thu Sep 18 21:09:10 2003
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/undefineds.h	Fri Apr  2 18:47:11 2004
@@ -159,7 +159,7 @@
 F(socket)
 F(socketpair)
 F(stat)
-#ifndef SVR4
+#if !defined(SVR4) && !defined(__OpenBSD__)
 F(swapon)
 #endif
 F(symlink)
diff /home/uniq/sbcl-0.8.9/src/runtime/x86-assem.S /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/x86-assem.S
--- /home/uniq/sbcl-0.8.9/src/runtime/x86-assem.S	Sat Aug 16 20:38:40 2003
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/x86-assem.S	Tue Apr  6 00:53:49 2004
@@ -21,9 +21,10 @@
 #include "genesis/static-symbols.h"
 #include "genesis/symbol.h"
 #include "genesis/thread.h"
-	
+
 /* Minimize conditionalization for different OS naming schemes. */
-#if defined __linux__  || defined __FreeBSD__ /* (but *not* OpenBSD) */
+#if defined __linux__  || defined __FreeBSD__ || defined __OpenBSD__
+						/* but *not* for 3.1 */
 #define GNAME(var) var
 #else
 #define GNAME(var) _##var

Annotations for this paste:

Annotation number 1: alignment needed to be fixed in x86-assem.S
Pasted by: uniq_
When:19 years, 1 month ago
Share:Tweet this! | http://paste.lisp.org/+G9/1
Paste contents:
Raw Source | Display As
This was missing.... Now it works!  However, I've not yet done any additional
tests.


diff /home/uniq/sbcl-0.8.9/src/runtime/x86-assem.S /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/x86-assem.S
--- /home/uniq/sbcl-0.8.9/src/runtime/x86-assem.S	Sat Aug 16 20:38:40 2003
+++ /home/uniq/sbcl/w-sbcl-0.8.9/sbcl-0.8.9/src/runtime/x86-assem.S	Tue Apr  6 02:24:38 2004
@@ -21,17 +21,18 @@
 #include "genesis/static-symbols.h"
 #include "genesis/symbol.h"
 #include "genesis/thread.h"
-	
+
 /* Minimize conditionalization for different OS naming schemes. */
-#if defined __linux__  || defined __FreeBSD__ /* (but *not* OpenBSD) */
+#if defined __linux__  || defined __FreeBSD__ || defined __OpenBSD__
+						/* but *not* for 3.1 */
 #define GNAME(var) var
 #else
 #define GNAME(var) _##var
 #endif
 
-/* Get the right type of alignment. Linux and FreeBSD (but not OpenBSD)
+/* Get the right type of alignment. Linux and FreeBSD (but not OpenBSD pre-3.4)
  * want alignment in bytes. */
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
 #define align_4byte	4
 #define align_8byte	8
 #define align_16byte	16

Colorize as:
Show Line Numbers

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.