2

I'm writing a small library intended to be used in place of libc in a small application. I've read the source of the major libc alternatives, but I am unable to get the parameter passing to work for the x86_64 architecture on Linux.

The library does not require any initialization step in between _start and main. Since the libc and its alternatives do use a initialization step, and my assembly knowledge being limited, I suspect the parameter reordering is causing me troubles.

This is what I've got, which contains assembly inspired from various implementations:

.text
.global _start

_start:
    /* Mark the outmost frame by clearing the frame pointer. */
    xorl %ebp, %ebp

    /* Pop the argument count of the stack and place it
     * in the first parameter-passing register. */
    popq %rdi

    /* Place the argument array in the second parameter-passing register. */
    movq %rsi, %rsp

    /* Align the stack at a 16-byte boundary. */
    andq $~15, %rsp

    /* Invoke main (defined by the host program). */
    call main

    /* Request process termination by the kernel. This
     * is x86 assembly but it works for now. */
    mov  %ebx, %eax
    mov  %eax, 1
    int  $80

And the entry point is the ordinary main signature: int main(int argc, char* argv[]). Environment variables etc. are not required for this particular project.

The AMD64 ABI says rdi should be used for the first parameter, and rsi for the second.

How do I correctly setup the stack and pass the parameters to main on Linux x86_64? Thanks!

References:
http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/libc/sysdeps/x86_64/elf/start.S?view=markup
http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/x86_64/crt1.S

haste
  • 1,441
  • 1
  • 10
  • 21

2 Answers2

1

I think you got

 /* Place the argument array in the second parameter-passing register. */
    movq %rsi, %rsp

wrong. It should be

movq %rsp, %rsi      # move argv to rsi, the second parameter in x86_64 abi
Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
  • This is AT&T syntax. Comments don't start with a semicolon. –  Dec 10 '11 at 15:16
  • Fixed. Although I like to mention that on some architectures like HP and PPC comments actually _do_ start with an semicolon – Gunther Piez Dec 10 '11 at 15:30
  • Doh. I didn't realize GAS took the operands in the opposite order (I wrote this in NASM first, then rewrote in GAS to match the sources more closely). However, the program segfaults now. Thanks for pointing this out though! – haste Dec 10 '11 at 18:24
  • Turns out there were more operands in the opposite order that I overlooked. Everything works like a dream now. Thank you. – haste Dec 10 '11 at 21:57
0

main is called by crt0.o; see also this question

The kernel is setting up the initial stack and process environment after execve as specified in the ABI document (architecture specific); the crt0 (and related) code is in charge of calling main.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547