shithub: mc

Download patch

ref: 5b2e3e6495320fa7ce29823d72c27de3194befd4
parent: 5341650a679df5560143a08abecb546b07448c4e
author: Ori Bernstein <[email protected]>
date: Mon Aug 26 14:20:41 EDT 2013

Initialize environment variables on Linux.

--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -4,6 +4,7 @@
     blat.myr \
     chartype.myr \
     die.myr \
+    env.myr \
     error.myr \
     extremum.myr \
     fmt.myr \
--- a/libstd/start-linux.s
+++ b/libstd/start-linux.s
@@ -1,6 +1,17 @@
+.data
+/* std._environment : byte[:][:] */
+.globl std$_environment
+std$_environment:
+.envbase:
+.quad 0 /* env size */
+.envlen:
+.quad 0 /* env ptr */
+
+.text
 /*
  * counts the length of the string pointed to
- * by %rbx, returning len in %r9
+ * by %r8, returning len in %r9. Does not modify
+ * any registers outside of %r9
  */
 cstrlen:
 	xorq	%r9,%r9
@@ -13,36 +24,74 @@
 	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
+
 .globl _start
 _start:
 	/* turn args into a slice */
 	movq	%rsp,%rbp
-	/* stack allocate sizeof(byte[:])*argc */
+	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
 	movq	(%rbp),%rax
+	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
+        call    count
+	addq	%r9,%rax
 	imulq	$16,%rax
 	subq	%rax,%rsp
 	movq	%rsp, %rdx	/* saved args[:] */
 
-	/* iterate over the strings for argc, and put
-	 * them into the args array. */
+	/* convert envp to byte[:][:] for std._environment */
+	movq	(%rbp),%rax
+	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
+	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	%rsp, %rcx
 	movq	(%rbp), %rsi	/* saved argc */
-
-	testq	%rax,%rax
-	jz .cvtdone
-	.cvtloop:
-	subq	$1,%rax
-	movq	(%rbx),%r8
-	call	cstrlen
-	movq	%r8, (%rcx)
-	movq	%r9, 8(%rcx)
-	addq	$8, %rbx
-	addq	$16, %rcx
-	testq	%rax,%rax
-	jnz .cvtloop
-	.cvtdone:
+        call cvt
 	pushq %rsi
 	pushq %rdx
 
--- a/libstd/test.myr
+++ b/libstd/test.myr
@@ -19,6 +19,10 @@
 		std.put("option %c, arg = %s\n", o, a)
         ;;
 
+	std.put("env.len = %i\n", std._environment.len)
+	for i = 0; i < std._environment.len; i++
+		std.put("env[%i] = %s\n", i, std._environment[i])
+	;;
 	std.put("args.len = %i\n", args.len)
 	for i = 0; i < args.len; i++
 		std.put("args[%i] = %s\n", i, args[i])