1 define(`CC', `
2 dnl')
3
4 CC Copyright (C) 2023 Free Software Foundation, Inc.
5 CC
6 CC This file is part of GNU Emacs.
7 CC
8 CC GNU Emacs is free software: you can redistribute it and/or modify
9 CC it under the terms of the GNU General Public License as published
10 CC by the Free Software Foundation, either version 3 of the License,
11 CC or (at your option) any later version.
12 CC
13 CC GNU Emacs is distributed in the hope that it will be useful, but
14 CC WITHOUT ANY WARRANTY; without even the implied warranty of
15 CC MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 CC General Public License for more details.
17 CC
18 CC You should have received a copy of the GNU General Public License
19 CC along with GNU Emacs. If not, see <https:
20
21 .section .text
22 .global _start
23 _start:
24 dnl movq $35, %rax CC SYS_nanosleep
25 dnl leaq timespec(%rip), %rdi
26 dnl xorq %rsi, %rsi
27 dnl syscall
28 popq %r13 CC original SP
29 popq %r15 CC size of load area.
30 movq $-1, %r12 CC r12 is the interpreter fd
31 .next_action:
32 movq (%rsp), %r14 CC action number
33 movq %r14, %r15 CC original action number
34 andq $-17, %r14
35 cmpq $0, %r14 CC open file?
36 je .open_file
37 cmpq $3, %r14 CC jump?
38 je .rest_of_exec
39 cmpq $4, %r14 CC anonymous mmap?
40 je .do_mmap_anon
41 .do_mmap:
42 movq $9, %rax CC SYS_mmap
43 movq 8(%rsp), %rdi CC address
44 movq 16(%rsp), %r9 CC offset
45 movq 24(%rsp), %rdx CC protection
46 movq 32(%rsp), %rsi CC length
47 movq 40(%rsp), %r10 CC flags
48 CC set r8 to the primary fd unless r15 & 16
49 testq $16, %r15
50 movq %r12, %r8
51 cmovzq %rbx, %r8
52 .do_mmap_1:
53 syscall
54 cmpq $-1, %rax CC mmap failed
55 je .perror
56 movq 48(%rsp), %r9 CC clear
57 testq %r9, %r9
58 jz .continue
59 movq 8(%rsp), %r10 CC start of mapping
60 addq 32(%rsp), %r10 CC end of mapping
61 subq %r9, %r10 CC start of clear area
62 .again:
63 testq %r9, %r9
64 jz .continue
65 subq $1, %r9
66 movb $0, (%r10, %r9, 1)
67 jmp .again
68 .continue:
69 leaq 56(%rsp), %rsp
70 jmp .next_action
71 .do_mmap_anon:
72 movq $9, %rax CC SYS_mmap
73 movq 8(%rsp), %rdi CC address
74 movq 16(%rsp), %r9 CC offset
75 movq 24(%rsp), %rdx CC protection
76 movq 32(%rsp), %rsi CC length
77 movq 40(%rsp), %r10 CC flags
78 movq $-1, %r8 CC -1
79 jmp .do_mmap_1
80 .open_file:
81 movq $2, %rax CC SYS_open
82 leaq 8(%rsp), %rdi CC rdi = %rsp + 8
83 xorq %rsi, %rsi CC flags = O_RDONLY
84 xorq %rdx, %rdx CC mode = 0
85 syscall
86 cmpq $-1, %rax CC open failed
87 jle .perror
88 movq %rdi, %rsp CC rsp = start of string
89 subq $1, %rsp
90 movq %rsp, %r14 CC r14 = start of string
91 .nextc:
92 addq $1, %rsp
93 movb (%rsp), %dil CC rdi = *rsp
94 cmpb $47, %dil CC *rsp == '/'?
95 jne .nextc1
96 movq %rsp, %r14 CC r14 = rsp
97 addq $1, %r14 CC r14 = char past separator
98 .nextc1:
99 cmpb $0, %dil CC *rsp == 0?
100 jne .nextc
101 addq $8, %rsp CC adjust past rsp prior to rounding
102 andq $-8, %rsp CC round rsp up to the next quad
103 testq $16, %r15 CC r15 & 16?
104 jz .primary
105 movq %rax, %r12 CC otherwise, move fd to r12
106 jmp .next_action
107 .primary:
108 movq %rax, %rbx CC if not, move fd to rbx
109 movq $157, %rax CC SYS_prctl
110 movq $15, %rdi CC PR_SET_NAME
111 movq %r14, %rsi CC arg1
112 xorq %rdx, %rdx CC arg2
113 xorq %r10, %r10 CC arg3
114 xorq %r8, %r8 CC arg4
115 xorq %r9, %r9 CC arg5
116 syscall
117 jmp .next_action
118 .perror:
119 movq %rax, %r12 CC error code
120 negq %r12
121 movq $1, %rax CC SYS_write
122 movq $1, %rdi CC stdout
123 leaq error(%rip), %rsi CC buffer
124 movq $23, %rdx CC count
125 syscall
126 movq $60, %rax CC SYS_exit
127 movq %r12, %rdi CC code
128 syscall
129 .rest_of_exec: CC rsp now points to six quads:
130 movq %rsp, %r8 CC now, they are r8
131 movq %r13, %rsp CC restore SP
132 popq %r10 CC argc
133 leaq 8(%rsp,%r10,8), %rsp CC now at start of environ
134 .skip_environ:
135 popq %r10 CC envp[N]
136 testq %r10, %r10 CC envp[n]?
137 jnz .skip_environ CC otherwise, rsp is now at the start of auxv
138 .one_auxv:
139 popq %rcx CC auxv type
140 addq $8, %rsp CC skip value
141 testq %rcx, %rcx CC is 0?
142 jz .cleanup
143 cmpq $3, %rcx CC is AT_PHDR?
144 je .replace_phdr
145 cmpq $4, %rcx CC is AT_PHENT?
146 je .replace_phent
147 cmpq $5, %rcx CC is AT_PHNUM?
148 je .replace_phnum
149 cmpq $9, %rcx CC is AT_ENTRY?
150 je .replace_entry
151 cmpq $7, %rcx CC is AT_BASE?
152 je .replace_base
153 jmp .one_auxv
154 .replace_phdr:
155 movq 40(%r8), %r9
156 movq %r9, -8(%rsp) CC set at_phdr
157 jmp .one_auxv
158 .replace_phent:
159 movq 24(%r8), %r9
160 movq %r9, -8(%rsp) CC set at_phent
161 jmp .one_auxv
162 .replace_phnum:
163 movq 32(%r8), %r9
164 movq %r9, -8(%rsp) CC set at_phnum
165 jmp .one_auxv
166 .replace_entry:
167 movq 16(%r8), %r9
168 movq %r9, -8(%rsp) CC set at_entry
169 jmp .one_auxv
170 .replace_base:
171 movq 48(%r8), %r9
172 movq %r9, -8(%rsp) CC set at_base
173 jmp .one_auxv
174 .cleanup:
175 movq $3, %rax CC SYS_close
176 cmpq $-1, %r12 CC see if interpreter fd is set
177 je .cleanup_1
178 movq %r12, %rdi
179 syscall
180 movq $3, %rax CC SYS_close
181 .cleanup_1:
182 movq %rbx, %rdi
183 syscall
184 .enter:
185 pushq $0
186 popfq CC clear FP state
187 movq %r13, %rsp CC restore SP
188 xorq %rdx, %rdx CC clear rtld_fini
189 jmpq *8(%r8) CC entry
190
191 error:
192 .ascii "_start: internal error."
193 timespec:
194 .quad 10
195 .quad 10