start.S 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /* -*- mode:c; c-basic-offset:4; tab-width:4; indent-tabs-mode:t; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /* This is the canonical entry point, usually the first thing in the text
  4. segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
  5. point runs, most registers' values are unspecified, except for:
  6. %rdx Contains a function pointer to be registered with `atexit'.
  7. This is how the dynamic linker arranges to have DT_FINI
  8. functions called for shared libraries that have been loaded
  9. before this code runs.
  10. %rsp The stack contains the arguments and environment:
  11. 0(%rsp) argc
  12. 8(%rsp) argv[0]
  13. ...
  14. (8*argc)(%rsp) NULL
  15. (8*(argc+1))(%rsp) envp[0]
  16. ...
  17. NULL
  18. */
  19. .text
  20. .globl shim_start
  21. .type shim_start,@function
  22. shim_start:
  23. .cfi_startproc
  24. /* Clear the frame pointer. The ABI suggests this be done, to mark
  25. the outermost frame obviously. */
  26. xorq %rbp, %rbp
  27. movq %rsp, %rbp
  28. /* Extract the arguments as encoded on the stack and set up
  29. the arguments for shim_init (int, void *, void **),
  30. The arguments are passed via registers and on the stack:
  31. argc: %rdi
  32. argv: %rsi
  33. stack: %rdx
  34. */
  35. /* Align the stack to a 16 byte boundary to follow the ABI. */
  36. andq $~15, %rsp
  37. movq %rdi, %rcx /* Possibly the stack has to be switched */
  38. movq 0(%rbp), %rdi /* Pop the argument count. */
  39. leaq 8(%rbp), %rsi /* argv starts just at the current stack top. */
  40. /* Provide the highest stack address to the user code (for stacks
  41. which grow downwards). */
  42. pushq %rbp
  43. movq %rsp, %rdx
  44. movq shim_init@GOTPCREL(%rip), %r11
  45. call *%r11
  46. popq %rbp
  47. leaveq
  48. retq
  49. .cfi_endproc