shithub: mc

Download patch

ref: 0173ca92374d915bd5c9b40c307f368e1cadbaf4
parent: 37e8b94b73dde2743b74e642b8d7cba7e2775622
author: Ori Bernstein <[email protected]>
date: Thu Sep 18 08:31:51 EDT 2014

Fix ABI bugs in cstring() and alloca() calls.

    These calls were clobbering registers. There was also an
    off by one error in cstring() where it overwrote the top
    byte of the stack. (This didn't matter before the ABI fixes,
    since the top byte of the stack was a return address that never
    got used.)

--- a/libstd/util.s
+++ b/libstd/util.s
@@ -12,22 +12,37 @@
 .globl _std$cstring
 _std$cstring:
 std$cstring:
-	movq (%rsp),%r15	/* ret addr */
-	movq 8(%rsp),%rsi	/* src */
-	movq 16(%rsp),%rcx	/* len */
+	/* save registers */
+	pushq %rbp
+	movq %rsp,%rbp
+	pushq %r15
+	pushq %rsi
+	pushq %rdi
+	pushq %rcx
+
+	movq 8(%rbp),%r15	/* ret addr */
+	movq 16(%rbp),%rsi	/* src */
+	movq 24(%rbp),%rcx	/* len */
 	
-	subq %rcx,%rsp          /* get stack */
-	movq %rsp,%rdi          /* dest */
-	movq %rsp,%rax          /* ret val */
+	subq %rcx,%rsp		/* get stack */
+	subq $1,%rsp		/* +1 for nul */
+	movq %rsp,%rdi		/* dest */
+	movq %rsp,%rax		/* ret val */
 	subq $16,%rsp		/* "unpop" the args */
-	subq $1,%rsp            /* nul */
-	andq $(~15),%rsp        /* align */
+	andq $(~15),%rsp	/* align */
 	
 	cld
 	rep movsb
-	movb $0,(%rdi)          /* terminate */
+	movb $0,(%rdi)		/* terminate */
 	
-	pushq %r15              /* ret addr */
+	pushq %r15		/* ret addr */
+
+	/* restore registers */
+	movq -32(%rbp),%rcx
+	movq -24(%rbp),%rdi
+	movq -16(%rbp),%rsi
+	movq -8(%rbp),%r15
+	movq (%rbp),%rbp
 	ret
 
 .globl std$alloca
@@ -34,14 +49,25 @@
 .globl _std$alloca
 _std$alloca:
 std$alloca:
-	movq (%rsp),%r15	/* ret addr */
-	movq 8(%rsp),%rbx	/* len */
+	/* save registers */
+	pushq %rbp
+	movq %rsp,%rbp
+	pushq %r15
+	pushq %rbx
+
+	movq 8(%rbp),%r15	/* ret addr */
+	movq 16(%rbp),%rbx	/* len */
 	
 	/* get stack space */
-	subq %rbx,%rsp          /* get stack space */
-	movq %rsp,%rax          /* top of stack (return value) */
+	subq %rbx,%rsp		/* get stack space */
+	movq %rsp,%rax		/* top of stack (return value) */
 	subq $16,%rsp		/* "unpop" the args for return */
-	andq $(~15),%rsp        /* align */
+	andq $(~15),%rsp	/* align */
 
-	pushq %r15              /* ret addr */
+	pushq %r15		/* ret addr */
+
+	/* restore registers */
+	movq -16(%rbp),%rbx
+	movq -8(%rbp),%r15
+	movq (%rbp),%rbp
 	ret