shithub: mc

Download patch

ref: 70ab782a15f19d4ea160304bb35f7cd1defa7d5d
parent: fb85c50fc2abd8ba903f72b59567b9e7f2e31c1c
author: Ori Bernstein <[email protected]>
date: Mon Aug 11 15:34:12 EDT 2014

Spit out the runtime from libstd.

	This will allow linking code without libstd, as well
	as fixing link order on freebsd.

	Freebsd seems to be picky aobut where '_start' is
	searched from.

--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@
       6 \
       muse \
       myrbuild \
+      rt \
       libstd \
       doc
 
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -53,7 +53,6 @@
     waitstatus.myr \
 
 ASMSRC= \
-    start.s \
     syscall.s \
     util.s
 
--- a/libstd/start-freebsd.s
+++ /dev/null
@@ -1,123 +1,0 @@
-.data
-/* std._environment : byte[:][:] */
-.globl std$_environment
-std$_environment:
-.envbase:
-.quad 0 /* env size */
-.envlen:
-.quad 0 /* env ptr */
-
-.globl std$__cenvp
-std$__cenvp:
-.quad 0
-
-.text
-/*
- * counts the length of the string pointed to
- * by %r8, returning len in %r9. Does not modify
- * any registers outside of %r9
- */
-cstrlen:
-	xorq	%r9,%r9
-	jmp .lentest
-
-	.lenloop:
-	incq	%r9
-	.lentest:
-	cmpb	$0,(%r8,%r9)
-	jne	.lenloop
-	ret
-
-
-/*
- * Counts the size of the null terminated string vector
- * pointed to by %rbx. Clobbers %r10,%r11
- */
-count:
-	xorq %r9,%r9
-	movq %rbx,%r11
-.countloop:
-	movq (%r11),%r10
-	testq %r10,%r10
-	jz .countdone
-	addq $1,%r9
-	addq $8,%r11
-	jmp .countloop
-.countdone:
-	ret
-
-/*
- * iterate over the strings for argc, and put
- * them into the args array.
- * 
- * Args:
- *    %rax: holds argc
- *    %rbx: holds argv
- *    %rcx: output destination
- * Clobbers:
- *    %r8, %r9
- */
-cvt:
-        jmp .cvttest
-.cvtloop:
-	subq	$1,%rax
-	movq	(%rbx),%r8
-	call	cstrlen
-	movq	%r8, (%rcx)
-	movq	%r9, 8(%rcx)
-	addq	$8, %rbx
-	addq	$16, %rcx
-.cvttest:
-	testq	%rax,%rax
-	jnz .cvtloop
-.cvtdone:
-        ret
-
-/*
- * The entry point for the whole program.
- * This is called by the OS. In order, it:
- *  - Sets up all argc entries as slices
- *  - Sets up all envp entries as slices
- *  - Converts argc/argv to a slice
- *  - Stashes envp in std._environment
- *  - Stashes a raw envp copy in __cenvp (for syscalls to use)
- *  - Calls main()
- */
-.globl _start
-_start:
-	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
-	movq	(%rdi),%rax
-	leaq	16(%rdi,%rax,8), %rbx	/* argp = argv + 8*argc + 8 */
-        call    count
-	addq	%r9,%rax
-	imulq	$16,%rax
-	subq	%rax,%rsp
-	movq	%rsp, %rdx	/* saved args[:] */
-
-	/* convert envp to byte[:][:] for std._environment */
-	movq	(%rdi),%rax
-	leaq	16(%rdi,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
-        /* store envp for some syscalls to use without spurious conversion. */
-        movq    %rbx,std$__cenvp(%rip)
-	movq	%r9,%rax
-	movq	%rsp, %rcx
-	movq	%r9,.envlen
-	movq	%rdx,.envbase
-	call cvt
-	movq	%rcx,%rdx
-
-        /* convert argc, argv to byte[:][:] for args. */
-	movq	(%rdi), %rax	/* argc */
-	leaq	8(%rdi), %rbx	/* argv */
-	movq	(%rdi), %rsi	/* saved argc */
-        call    cvt
-	pushq   %rsi
-	pushq   %rdx
-
-	/* enter the main program */
-	call	main
-	/* exit(0) */
-        xorq	%rdi,%rdi
-	movq	$1,%rax
-	syscall
-
--- a/libstd/start-linux.s
+++ /dev/null
@@ -1,121 +1,0 @@
-.data
-/* std._environment : byte[:][:] */
-.globl std$_environment
-std$_environment:
-.envbase:
-.quad 0 /* env size */
-.envlen:
-.quad 0 /* env ptr */
-
-.globl std$__cenvp
-std$__cenvp:
-.quad 0
-
-.text
-/*
- * counts the length of the string pointed to
- * by %r8, returning len in %r9. Does not modify
- * any registers outside of %r9
- */
-cstrlen:
-	xorq	%r9,%r9
-	jmp .lentest
-
-	.lenloop:
-	incq	%r9
-	.lentest:
-	cmpb	$0,(%r8,%r9)
-	jne	.lenloop
-	ret
-
-
-/*
- * Counts the size of the null terminated string vector
- * pointed to by %rbx. Clobbers %r10,%r11
- */
-count:
-	xorq %r9,%r9
-	movq %rbx,%r11
-.countloop:
-	movq (%r11),%r10
-	testq %r10,%r10
-	jz .countdone
-	addq $1,%r9
-	addq $8,%r11
-	jmp .countloop
-.countdone:
-	ret
-
-/*
- * iterate over the strings for argc, and put
- * them into the args array.
- * 
- * argc in %rax, argv in %rbx, dest vector in %rcx
- */
-cvt:
-        jmp .cvttest
-.cvtloop:
-	subq	$1,%rax
-	movq	(%rbx),%r8
-	call	cstrlen
-	movq	%r8, (%rcx)
-	movq	%r9, 8(%rcx)
-	addq	$8, %rbx
-	addq	$16, %rcx
-.cvttest:
-	testq	%rax,%rax
-	jnz .cvtloop
-.cvtdone:
-        ret
-
-/*
- * The entry point for the whole program.
- * This is called by the OS. In order, it:
- *  - Sets up all argc entries as slices
- *  - Sets up all envp entries as slices
- *  - Converts argc/argv to a slice
- *  - Stashes envp in std._environment
- *  - Stashes a raw envp copy in __cenvp (for syscalls to use)
- *  - Calls main()
- */
-.globl _start
-_start:
-	/* turn args into a slice */
-	movq	%rsp,%rbp
-
-	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
-	movq	(%rbp),%rax
-	leaq	16(%rbp,%rax,8), %rbx	/* argp = argv + 8*argc + 8 */
-        call    count
-	addq	%r9,%rax
-	imulq	$16,%rax
-	subq	%rax,%rsp
-	movq	%rsp, %rdx	/* saved args[:] */
-
-	/* convert envp to byte[:][:] for std._environment */
-	movq	(%rbp),%rax
-	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
-        /* store envp for some syscalls to use without converting */
-        movq    %rbx,std$__cenvp(%rip)
-	movq	%r9,%rax
-	movq	%rsp, %rcx
-	movq	%r9,.envlen
-	movq	%rdx,.envbase
-	call cvt
-	movq	%rcx,%rdx
-
-        /* convert argc, argv to byte[:][:] for args. */
-	movq	(%rbp), %rax	/* argc */
-	leaq	8(%rbp), %rbx	/* argv */
-	movq	(%rbp), %rsi	/* saved argc */
-        call cvt
-	pushq %rsi
-	pushq %rdx
-
-	/* enter the main program */
-	call	main
-	/* exit(0) */
-        xorq	%rdi,%rdi
-	movq	$60,%rax
-	syscall
-
--- a/libstd/start-osx.s
+++ /dev/null
@@ -1,119 +1,0 @@
-.data
-/* std._environment : byte[:][:] */
-.globl _std$_environment
-_std$_environment:
-.envbase:
-.quad 0 /* env size */
-.envlen:
-.quad 0 /* env ptr */
-
-.globl _std$__cenvp
-_std$__cenvp:
-.quad 0
-
-.text
-/*
- * counts the length of the string pointed to
- * by %r8, returning len in %r9. Does not modify
- * any registers outside of %r9
- */
-cstrlen:
-	xorq	%r9,%r9
-	jmp .lentest
-
-	.lenloop:
-	incq	%r9
-	.lentest:
-	cmpb	$0,(%r8,%r9)
-	jne	.lenloop
-	ret
-
-
-/*
- * Counts the size of the null terminated string vector
- * pointed to by %rbx. Clobbers %r10,%r11
- */
-count:
-	xorq %r9,%r9
-	movq %rbx,%r11
-.countloop:
-	movq (%r11),%r10
-	testq %r10,%r10
-	jz .countdone
-	addq $1,%r9
-	addq $8,%r11
-	jmp .countloop
-.countdone:
-	ret
-
-/*
- * iterate over the strings for argc, and put
- * them into the args array.
- * 
- * argc in %rax, argv in %rbx, dest vector in %rcx
- */
-cvt:
-        jmp .cvttest
-.cvtloop:
-	subq	$1,%rax
-	movq	(%rbx),%r8
-	call	cstrlen
-	movq	%r8, (%rcx)
-	movq	%r9, 8(%rcx)
-	addq	$8, %rbx
-	addq	$16, %rcx
-.cvttest:
-	testq	%rax,%rax
-	jnz .cvtloop
-.cvtdone:
-        ret
-
-/*
- * The entry point for the whole program.
- * This is called by the OS. In order, it:
- *  - Sets up all argc entries as slices
- *  - Sets up all envp entries as slices
- *  - Converts argc/argv to a slice
- *  - Stashes envp in std._environment
- *  - Stashes a raw envp copy in __cenvp (for syscalls to use)
- *  - Calls main()
- */
-.globl start
-start:
-	/* turn args into a slice */
-	movq	%rsp,%rbp
-	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
-	movq	(%rbp),%rax
-	leaq	16(%rbp,%rax,8), %rbx	/* argp = argv + 8*argc + 8 */
-        call    count
-	addq	%r9,%rax
-	imulq	$16,%rax
-	subq	%rax,%rsp
-	movq	%rsp, %rdx	/* saved args[:] */
-
-	/* convert envp to byte[:][:] for std._environment */
-	movq	(%rbp),%rax
-	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
-        movq    %rbx,_std$__cenvp(%rip)
-	movq	%r9,%rax
-	movq	%rsp, %rcx
-	movq	%r9,.envlen(%rip)
-	movq	%rdx,.envbase(%rip)
-	call cvt
-	movq	%rcx,%rdx
-
-        /* convert argc, argv to byte[:][:] for args. */
-	movq	(%rbp), %rax	/* argc */
-	leaq	8(%rbp), %rbx	/* argv */
-	movq	(%rbp), %rsi	/* saved argc */
-        call cvt
-	pushq %rsi
-	pushq %rdx
-
-	/* enter the main program */
-	call	_main
-	/* exit */
-	xorq	%rdi,%rdi
-	movq	$0x2000001,%rax
-	syscall
-
--- a/myrbuild/myrbuild.c
+++ b/myrbuild/myrbuild.c
@@ -30,6 +30,8 @@
 char *ar = "ar";
 char *ld = "ld";
 char *muse = "muse";
+char *runtime = "_myrrt.o";
+char *runtimepath;
 /* the name of the output file */
 char *libname;
 char *binname;
@@ -194,7 +196,6 @@
     char buf[1024];
     size_t i;
 
-    snprintf(buf, sizeof buf, "%s/%s/%s", Instroot, "/lib/myr", lib);
     f = fopen(buf, "r");
     if (f)
         return f;
@@ -404,6 +405,10 @@
         lappend(&args, &nargs, strdup(buf));
     }
 
+    if (runtimepath) {
+        lappend(&args, &nargs, strdup(runtimepath));
+    }
+
     /* ld -T ldscript -o outfile foo.o bar.o baz.o */
     for (i = 0; i < nfiles; i++) {
         if (hassuffix(files[i], ".myr"))
@@ -420,8 +425,6 @@
         snprintf(buf, sizeof buf, "-L%s", incpaths[i]);
         lappend(&args, &nargs, strdup(buf));
     }
-    snprintf(buf, sizeof buf, "-L%s%s", Instroot, "/lib/myr");
-    lappend(&args, &nargs, strdup(buf));
 
     /* ld -T ldscript -o outfile foo.o bar.o baz.o -L/path1 -L/path2 -llib1 -llib2*/
     addlibs(&args, &nargs, libgraph);
@@ -442,6 +445,24 @@
     lfree(&args, &nargs);
 }
 
+void findruntime()
+{
+    char buf[2048];
+    size_t i;
+
+    if (!strcmp(runtime, "none"))
+        runtimepath = NULL;
+    for (i = 0; i < nincpaths; i++) {
+        snprintf(buf, sizeof buf, "%s/%s", incpaths[i], runtime);
+        if (access(buf, R_OK) == 0) {
+            printf("Got %s\n", buf);
+            runtimepath = strdup(buf);
+            return;
+        }
+    }
+    err(1, "Could not find runtime %s", runtime);
+}
+
 int main(int argc, char **argv)
 {
     int opt;
@@ -450,7 +471,8 @@
 
     if (uname(&name) == 0)
         sysname = strdup(name.sysname);
-    while ((opt = getopt(argc, argv, "hb:l:s:SI:C:A:M:L:R:")) != -1) {
+    lappend(&incpaths, &nincpaths, strdup(Instroot "/lib/myr"));
+    while ((opt = getopt(argc, argv, "hb:l:s:r:SI:C:A:M:L:R:")) != -1) {
         switch (opt) {
             case 'b': binname = optarg; break;
             case 'l': libname = optarg; break;
@@ -461,8 +483,9 @@
             case 'M': muse = optarg; break;
             case 'L': ld = optarg; break;
             case 'R': ar = optarg; break;
+            case 'r': runtime = optarg; break;
             case 'I':
-                lappend(&incpaths, &nincpaths, optarg);
+                lappend(&incpaths, &nincpaths, strdup(optarg));
                 break;
             case 'h':
                 usage(argv[0]);
@@ -481,6 +504,7 @@
     libgraph = mkht(strhash, streq);
     compiled = mkht(strhash, streq);
     loopdetect = mkht(strhash, streq);
+    findruntime();
     regcomp(&usepat, "^[[:space:]]*use[[:space:]]+([^[:space:]]+)", REG_EXTENDED);
     for (i = optind; i < argc; i++)
         compile(argv[i]);
--- /dev/null
+++ b/rt/Makefile
@@ -1,0 +1,25 @@
+OBJ = _myrrt.o
+ASMSRC = start.s common.s
+
+all: _myrrt.o
+
+include ../config.mk
+
+_myrrt.o: _myrrt.s
+	as -g -o $@ $^
+
+_myrrt.s: $(ASMSRC)
+	cat $(ASMSRC) > $@
+
+%.s: %-$(SYS).s
+	cp $< $@
+
+install: all
+	mkdir -p  $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr)
+	install _myrrt.o $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr)
+
+uninstall:
+	rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr/_myrrt.o)
+
+clean:
+	rm -f _myrrt.o _myrrt.s start.s
--- /dev/null
+++ b/rt/start-freebsd.s
@@ -1,0 +1,62 @@
+.data
+/* std._environment : byte[:][:] */
+.globl std$_environment
+std$_environment:
+.envbase:
+.quad 0 /* env size */
+.envlen:
+.quad 0 /* env ptr */
+
+.globl std$__cenvp
+std$__cenvp:
+.quad 0
+
+.text
+/*
+ * The entry point for the whole program.
+ * This is called by the OS. In order, it:
+ *  - Sets up all argc entries as slices
+ *  - Sets up all envp entries as slices
+ *  - Converts argc/argv to a slice
+ *  - Stashes envp in std._environment
+ *  - Stashes a raw envp copy in __cenvp (for syscalls to use)
+ *  - Calls main()
+ */
+.globl _start
+_start:
+	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
+	movq	(%rdi),%rax
+	leaq	16(%rdi,%rax,8), %rbx	/* argp = argv + 8*argc + 8 */
+        call    count
+	addq	%r9,%rax
+	imulq	$16,%rax
+	subq	%rax,%rsp
+	movq	%rsp, %rdx	/* saved args[:] */
+
+	/* convert envp to byte[:][:] for std._environment */
+	movq	(%rdi),%rax
+	leaq	16(%rdi,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
+        /* store envp for some syscalls to use without spurious conversion. */
+        movq    %rbx,std$__cenvp(%rip)
+	movq	%r9,%rax
+	movq	%rsp, %rcx
+	movq	%r9,.envlen
+	movq	%rdx,.envbase
+	call cvt
+	movq	%rcx,%rdx
+
+        /* convert argc, argv to byte[:][:] for args. */
+	movq	(%rdi), %rax	/* argc */
+	leaq	8(%rdi), %rbx	/* argv */
+	movq	(%rdi), %rsi	/* saved argc */
+        call    cvt
+	pushq   %rsi
+	pushq   %rdx
+
+	/* enter the main program */
+	call	main
+	/* exit(0) */
+        xorq	%rdi,%rdi
+	movq	$1,%rax
+	syscall
+
--- /dev/null
+++ b/rt/start-linux.s
@@ -1,0 +1,74 @@
+.data
+/* std._environment : byte[:][:] */
+.globl std$_environment
+std$_environment:
+.envbase:
+.quad 0 /* env size */
+.envlen:
+.quad 0 /* env ptr */
+
+.globl std$__cenvp
+std$__cenvp:
+.quad 0
+
+.text
+/*
+ * The entry point for the whole program.
+ * This is called by the OS. In order, it:
+ *  - Sets up all argc entries as slices
+ *  - Sets up all envp entries as slices
+ *  - Converts argc/argv to a slice
+ *  - Stashes envp in std._environment
+ *  - Stashes a raw envp copy in __cenvp (for syscalls to use)
+ *  - Calls main()
+ */
+.globl _start
+_start:
+	/* turn args into a slice */
+	movq	%rsp,%rbp
+
+	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
+	movq	(%rbp),%rax
+	leaq	16(%rbp,%rax,8), %rbx	/* argp = argv + 8*argc + 8 */
+        call    count
+	addq	%r9,%rax
+	imulq	$16,%rax
+	subq	%rax,%rsp
+	movq	%rsp, %rdx	/* saved args[:] */
+
+	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
+	movq	(%rbp),%rax
+	leaq	16(%rbp,%rax,8), %rbx	/* argp = argv + 8*argc + 8 */
+        call    count
+	addq	%r9,%rax
+	imulq	$16,%rax
+	subq	%rax,%rsp
+	movq	%rsp, %rdx	/* saved args[:] */
+
+	/* convert envp to byte[:][:] for std._environment */
+	movq	(%rbp),%rax
+	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
+        /* store envp for some syscalls to use without converting */
+        movq    %rbx,std$__cenvp(%rip)
+	movq	%r9,%rax
+	movq	%rsp, %rcx
+	movq	%r9,.envlen
+	movq	%rdx,.envbase
+	call cvt
+	movq	%rcx,%rdx
+
+        /* convert argc, argv to byte[:][:] for args. */
+	movq	(%rbp), %rax	/* argc */
+	leaq	8(%rbp), %rbx	/* argv */
+	movq	(%rbp), %rsi	/* saved argc */
+        call cvt
+	pushq %rsi
+	pushq %rdx
+
+	/* enter the main program */
+	call	main
+	/* exit(0) */
+        xorq	%rdi,%rdi
+	movq	$60,%rax
+	syscall
+
--- /dev/null
+++ b/rt/start-osx.s
@@ -1,0 +1,63 @@
+.data
+/* std._environment : byte[:][:] */
+.globl _std$_environment
+_std$_environment:
+.envbase:
+.quad 0 /* env size */
+.envlen:
+.quad 0 /* env ptr */
+
+.globl _std$__cenvp
+_std$__cenvp:
+.quad 0
+
+.text
+/*
+ * The entry point for the whole program.
+ * This is called by the OS. In order, it:
+ *  - Sets up all argc entries as slices
+ *  - Sets up all envp entries as slices
+ *  - Converts argc/argv to a slice
+ *  - Stashes envp in std._environment
+ *  - Stashes a raw envp copy in __cenvp (for syscalls to use)
+ *  - Calls main()
+ */
+.globl start
+start:
+	/* turn args into a slice */
+	movq	%rsp,%rbp
+	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
+	movq	(%rbp),%rax
+	leaq	16(%rbp,%rax,8), %rbx	/* argp = argv + 8*argc + 8 */
+        call    count
+	addq	%r9,%rax
+	imulq	$16,%rax
+	subq	%rax,%rsp
+	movq	%rsp, %rdx	/* saved args[:] */
+
+	/* convert envp to byte[:][:] for std._environment */
+	movq	(%rbp),%rax
+	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
+        movq    %rbx,_std$__cenvp(%rip)
+	movq	%r9,%rax
+	movq	%rsp, %rcx
+	movq	%r9,.envlen(%rip)
+	movq	%rdx,.envbase(%rip)
+	call cvt
+	movq	%rcx,%rdx
+
+        /* convert argc, argv to byte[:][:] for args. */
+	movq	(%rbp), %rax	/* argc */
+	leaq	8(%rbp), %rbx	/* argv */
+	movq	(%rbp), %rsi	/* saved argc */
+        call cvt
+	pushq %rsi
+	pushq %rdx
+
+	/* enter the main program */
+	call	_main
+	/* exit */
+	xorq	%rdi,%rdi
+	movq	$0x2000001,%rax
+	syscall
+
--- a/test/runtest.sh
+++ b/test/runtest.sh
@@ -16,7 +16,7 @@
 
 function build {
     rm -f $1 $1.o $1.s $1.use
-    ../myrbuild/myrbuild -b $1 -C../6/6m -M../muse/muse -I../libstd $1.myr
+    ../myrbuild/myrbuild -b $1 -C../6/6m -M../muse/muse -I../libstd -I../rt $1.myr
 }
 
 function pass {