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