1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
point runs, most registers' values are unspecified, except for:
%rdx Contains a function pointer to be registered with `atexit'.
This is how the dynamic linker arranges to have DT_FINI
functions called for shared libraries that have been loaded
before this code runs.
%rsp The stack contains the arguments and environment:
0(%rsp) argc
8(%rsp) argv[0]
...
(8*argc)(%rsp) NULL
(8*(argc+1))(%rsp) envp[0]
...
NULL
*/
.text
.globl _start
.type _start,@function
_start:
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorq %rbp, %rbp
/* Extract the arguments as encoded on the stack and set up
the arguments for __libc_start_main (int (*main) (int, char **, char **),
int argc, char *argv,
void (*init) (void), void (*fini) (void),
void (*rtld_fini) (void), void *stack_end).
The arguments are passed via registers and on the stack:
main: %rdi
argc: %rsi
argv: %rdx
init: %rcx
fini: %r8
rtld_fini: %r9
stack_end: stack. */
movq %rdx, %r9 /* Address of the shared library termination
function. */
popq %rsi /* Pop the argument count. */
movq %rsp, %rdx /* argv starts just at the current stack top. */
movq operatingsystem_parameter_argc@GOTPCREL(%rip),%rax
movq %rsi,(%rax)
movq operatingsystem_parameter_argv@GOTPCREL(%rip),%rax
movq %rsp,(%rax) /* argv starts just at the current stack top. */
leaq 8(,%rsi,8),%rax
addq %rsp,%rax
movq operatingsystem_parameter_envp@GOTPCREL(%rip),%rcx
movq %rax,(%rcx)
/* Align the stack to a 16 byte boundary to follow the ABI. */
andq $~15, %rsp
pushq %rax /* Push garbage because we push 8 more bytes. */
/* Provide the highest stack address to the user code (for stacks
which grow downwards). */
pushq %rsp
/* Pass address of our own entry points to .fini and .init. */
movq __libc_csu_init@GOTPCREL(%rip), %rcx
movq __libc_csu_fini@GOTPCREL(%rip), %r8
movq main_stub@GOTPCREL(%rip), %rdi
/* Call the user's main function, and exit with its value.
But let the libc call main. */
call __libc_start_main@PLT
hlt /* Crash if somehow `exit' does return. */
/* fake main routine which will be run from libc */
.globl main_stub
.type main_stub,@function
main_stub:
/* save return address */
popq %rax
// stack alignment
pushq %rax
movq ___fpc_ret_rbp@GOTPCREL(%rip),%rcx
movq %rbp,(%rcx)
movq ___fpc_ret@GOTPCREL(%rip),%rcx
movq %rax,(%rcx)
pushq %rax
/* Save initial stackpointer */
movq __stkptr@GOTPCREL(%rip),%rax
movq %rsp,(%rax)
/* start the program */
xorq %rbp,%rbp
call PASCALMAIN@PLT
hlt
.size main_stub,.-main_stub
.globl _haltproc
.type _haltproc,@function
_haltproc:
movq operatingsystem_result@GOTPCREL(%rip),%rax
movzwl (%rax),%eax
/* return to libc */
movq ___fpc_ret_rbp@GOTPCREL(%rip),%rcx
movq (%rcx),%rbp
movq ___fpc_ret@GOTPCREL(%rip),%rcx
popq %rdx
movq (%rcx),%rdx
pushq %rdx
ret
.size _haltproc,.-_haltproc
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
__data_start:
.long 0
.weak data_start
data_start = __data_start
.globl ___fpc_brk_addr /* heap management */
.type ___fpc_brk_addr,@object
.size ___fpc_brk_addr,8
___fpc_brk_addr:
.quad 0
___fpc_ret: /* return address to libc */
.quad 0
___fpc_ret_rbp:
.quad 0
.bss
.comm __stkptr,8
.comm operatingsystem_parameter_envp,8
.comm operatingsystem_parameter_argc,8
.comm operatingsystem_parameter_argv,8
/* We need this stuff to make gdb behave itself, otherwise
gdb will chokes with SIGILL when trying to debug apps.
*/
.section ".note.ABI-tag", "a"
.align 4
.long 1f - 0f
.long 3f - 2f
.long 1
0: .asciz "GNU"
1: .align 4
2: .long 0
.long 2,4,0
3: .align 4
.section .note.GNU-stack,"",@progbits
|