<div class="gmail_quote">On Fri, Feb 4, 2011 at 9:32 AM, Wesley W. Terpstra <span dir="ltr"><<a href="mailto:wesley@terpstra.ca">wesley@terpstra.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
However, the segfault persists. If you replace "printf" with "test":<br>
void test(const char* s, int x) {<br>  printf(s, x);<br>}<br>... it works.<br></blockquote><div><br>I've confirmed that MLton produces identical code except replacing 'printf' with 'test'. I tried a similar test with gcc. For some reason gcc clears eax before a call to printf but not a call to 'printm'. Perhaps this is related to varargs?<br>
<br>#include <stdio.h><br>int printm(const char* x, int k);<br><br>int beh() {<br>printm("dog %d\n", 44);<br>printf("dog %d\n", 44);<br>return 1;<br>}<br><br>beh:<br>.LFB13:<br>        subq    $8, %rsp<br>
.LCFI0:<br>        movl    $44, %esi<br>        movl    $.LC0, %edi<br>        call    printm<br>        movl    $44, %esi<br>        movl    $.LC0, %edi<br>        xorl    %eax, %eax      <<<<<<<<<<<<<<<< WTF?<br>
        call    printf<br>        movl    $1, %eax<br>        addq    $8, %rsp<br>        ret<br><br>Adding an 'xorl %eax,%eax' directly before the call to printf in the MLton generated assembler makes the problem disappear.<br>
<br>L_114:<br>        addq $0xFFFFFFFFFFFFFFD8,%rbp<br>        movq (c_stackP+0x0)(%rip),%rsp<br>        movl $0x7B,%r15d<br>        movl %r15d,%esi<br>        movq (globalObjptr+0x80)(%rip),%rdi<br>        addq $0x28,%rbp<br>
        leaq (L_115+0x0)(%rip),%r15<br>        movq %r15,0xFFFFFFFFFFFFFFF8(%rbp)<br>        movq %rbp,(gcState+0x10)(%rip)<br>        movq %r12,(gcState+0x0)(%rip)<br>xorl %eax,%eax<br>        call printf<br>        movq (gcState+0x0)(%rip),%r12<br>
        movq (gcState+0x10)(%rip),%rbp<br>        jmp L_115<br><br>I then did some digging and found this choice quote in the "System V Application Binary Interface AMD64 Architecture Processor Supplement Draft Version 0.99.5":<br>
"    When a function taking variable-arguments is called, %rax must be set to the<br>total number of floating point parameters passed to the function in vector registers"<br><br>... either we need to add another tag to imports like:<br>
_import "printf" stdarg : ... ;<br>... or we should just always set rax for every FFI call on AMD64?<br><br></div></div>