shithub: mc

Download patch

ref: 9ce53dbcee324f705af4011390b771c318f12b6b
parent: 6ce96d38dbca03afdb6700c87ecd62d3dd0dfb51
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