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
|
.data
/* sys.__cenvp : byte## */
.globl environ
.globl sys$__cenvp
environ:
sys$__cenvp:
.quad 0
.globl __progname
__progname:
.quad 0
.globl thread$__tls
thread$__tls:
.fill 88 /* sizeof(tlshdr) + (8 * sizeof(void#)) = 24 + 64 */
.text
/*
* The entry point for the whole program.
* This is called by the OS. In order, it:
* - Sets up all argc entries as slices
* - Converts argc/argv to a slice
* - Stashes a raw envp copy in __cenvp (for syscalls to use)
* - Sets up thread local storage for the main thread
* - Calls main()
*/
.globl _start
_start:
andq $-16,%rsp /* align the stack pointer */
/* load argc, argv, envp from stack */
movq (%rdi),%rax /* argc */
leaq 8(%rdi),%rbx /* argv */
movq (%rbx),%rcx /* save progname */
movq %rcx,__progname
leaq 16(%rdi,%rax,8),%rcx /* envp = argv + 8*argc + 8 */
/* store envp for some syscalls to use without converting */
movq %rcx,sys$__cenvp(%rip)
/* stack allocate sizeof(byte[:])*argc */
imulq $16,%rax,%rdx
subq %rdx,%rsp
movq %rsp,%rcx /* args[:] */
/* convert argc, argv to byte[:][:] for args. */
pushq %rax
pushq %rcx
call cvt
/* set up the intial tls region for the main thread */
subq $0x10,%rsp
movq $165,%rax /* sysarch */
movq $129,%rdi /* Archamd64setfs */
leaq thread$__tls(%rip),%rsi
movq %rsi,(%rsp)
movq %rsp,%rsi
syscall
addq $0x10,%rsp
xorq %rbp,%rbp
call __init__
call main
call __fini__
/* exit(0) */
xorq %rdi,%rdi
movq $1,%rax
syscall
|