-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsys.asm
More file actions
235 lines (183 loc) · 7.23 KB
/
sys.asm
File metadata and controls
235 lines (183 loc) · 7.23 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
; Процедуры (C примитивы) обеспечивающие системные вызовы.
NO_ARG := Val_int(0)
; edi = Value
; Произвольный код может быть возвращён вызовом sys_exit библиотеки Pervasives.
C_primitive caml_sys_exit
Int_val edi ; 1й
; Данная точка входа используется для завершения процесса в случаях,
; когда системные вызовы возвращают ошибку. Такие коды ошибок отрицательны.
; Ядро преобразует код по формуле (error_code & 0xff) << 8;
; см. linux/kernal/exit.c SYSCALL_DEFINE1(exit, int, error_code)
; Если в caml_sys_exit передаются небольшие положительные числа,
; пользовательские коды завершения не пересекаются и отличаются от системных.
; Пока не найдено лучшее решение (sysexits.h ?), по-видимому, оптимально
; возвращать отрицательные коды из errno.inc в качестве ошибок интерпретатора.
sys_exit:
sys.exit
ud2
end C_primitive
C_primitive caml_sys_open
end C_primitive
C_primitive caml_sys_close
end C_primitive
C_primitive caml_sys_file_exists
end C_primitive
C_primitive caml_sys_is_directory
end C_primitive
C_primitive caml_sys_remove
end C_primitive
C_primitive caml_sys_rename
end C_primitive
C_primitive caml_sys_chdir
end C_primitive
C_primitive caml_sys_getcwd
end C_primitive
; Возвращает строку со значением переменной окружения.
; RDI - адрес строки с именем переменной окружения.
C_primitive caml_sys_unsafe_getenv
caml_string_length rdi, rdx, rcx ; rdx длина строки
jz caml_raise_not_found ; флаги установлены макросом
mov r8, [environment_variables]
.check_var_name:
mov rsi, [r8]
test rsi, rsi
jz caml_raise_not_found
add r8, 8
zero ecx
.scmp: lods byte[rsi]
cmp [rdi + rcx], al
jnz .check_var_name
inc ecx
cmp ecx, edx
jnz .scmp
lods byte[rsi]
cmp al, '='
jnz .check_var_name
.found: zero edi
mov Val_header[alloc_small_ptr_backup], String_tag
.copy: lods byte[rsi]
mov [alloc_small_ptr_backup + rdi + sizeof value], al
inc edi
test al, al
jnz .copy
dec edi
jmp caml_alloc_string
end C_primitive
;!!! следует выполнить проверки аналогичные secure_getenv
C_primitive caml_sys_getenv
C_primitive_stub
jmp caml_sys_unsafe_getenv
end C_primitive
; EDI - не используется
; Возвращает пару значений:
; 0й - строка с именем исполняемого файла (байт-кода);
; 1й - массив из аргументов (начинается с имени исполняемого файла).
;
; Реализация не полная:
; Массив аргументов включает лишь первый элемент. См. так же main.1arg:
C_primitive caml_sys_get_argv
C_primitive_stub
; Вычисляем длину строки и копируем её на кучу.
zero edi
zero eax
mov rsi, [bytecode_filename]
.cnt: cmp [rsi + rdi], al
jz .len
inc edi
jmp .cnt
.len: push rdi rsi
call caml_alloc_string
pop rsi rcx
mov rdi, rax
rep movs byte[rdi], [rsi]
; Сохраняем ссылку на exe_name на случай вызова сборщика мусора.
push rax
; После данной команды память доступна и ссылки валидны.
test [alloc_small_ptr_backup + (2 + 2) * sizeof value], rax
; argv = массив из 1го элемента (с тегом 0)
mov ecx, 1 wosize
mov [alloc_small_ptr_backup + 0 * sizeof value], rcx
pop rax
mov [alloc_small_ptr_backup + 1 * sizeof value], rax
; Формируем возвращаемый объект.
; mov ecx, 2 wosize
add ecx, ecx
mov [alloc_small_ptr_backup + 2 * sizeof value], rcx
; 0й элемент пары - ссылка на строку с именем исполняемого файла.
mov [alloc_small_ptr_backup + 3 * sizeof value], rax
; 1й элемент пары - ссылка на масив.
lea rax, [alloc_small_ptr_backup + 1 * sizeof value]
mov [alloc_small_ptr_backup + 4 * sizeof value], rax
lea rax, [alloc_small_ptr_backup +(2 + 1) * sizeof value]
lea alloc_small_ptr_backup, [alloc_small_ptr_backup + 5 * sizeof value]
ret
end C_primitive
C_primitive caml_sys_system_command
end C_primitive
C_primitive caml_sys_time
end C_primitive
C_primitive caml_sys_random_seed
end C_primitive
; Возвращает Val_false на Low Endian
C_primitive caml_sys_const_big_endian
mov eax, Val_false
ret
end C_primitive
; Возвращает размер слова с битах - 64.
C_primitive caml_sys_const_word_size
mov eax, Val_int(8 * sizeof(value))
ret
end C_primitive
; Возвращает размер целого с битах - 63
; (т.к. 0й бит используется для различения целых и ссылок).
C_primitive caml_sys_const_int_size
mov eax, Val_int(8 * sizeof(value) - 1)
ret
end C_primitive
; Возвращает максимальный размер объекта (блока) на куче.
; В данной реализации размер умещается в 32 бита, что меньше чем оригинале 0x7fffffffffffff.
C_primitive caml_sys_const_max_wosize
mov rax, Val_int(Max_wosize)
ret
end C_primitive
; Возвращает тип Val_int(1) - интерпретатор байткода.
caml_sys_const_backend_type:
; Возвращает Val_true на *nix системах.
C_primitive caml_sys_const_ostype_unix
mov eax, Val_true
ret
end C_primitive
; Возвращает Val_true в случае Cygwin, Val_false в данной реализации.
caml_sys_const_ostype_cygwin:
; Возвращает Val_true в случае ОС Windows, Val_false в данной реализации.
C_primitive caml_sys_const_ostype_win32
mov eax, Val_false
ret
end C_primitive
; EDI - не используется
; Возвращает кортеж из 3-х элементов:
; 0-й - тип ОС (строка "Unix");
; 1-й - размер Value в битах (64);
; 2-й - является ли архитектура исполняющей машины Big Endian (Val_false).
C_primitive caml_sys_get_config
mov edi, 4
call caml_alloc_string
mov dword[rax], 'Unix'
; Сохраняем ссылку на тип ОС на случай вызова сборщика мусора.
push rax
mov eax, 3 wosize
mov Val_header[alloc_small_ptr_backup + 0 * sizeof value], rax
mov eax, Val_int (8 * sizeof value)
mov [alloc_small_ptr_backup + (1 + 1) * sizeof value], rax
mov eax, Val_false
mov [alloc_small_ptr_backup + (2 + 1) * sizeof value], rax
pop rax
mov [alloc_small_ptr_backup + (0 + 1) * sizeof value], rax
lea rax, [alloc_small_ptr_backup + sizeof value]
lea alloc_small_ptr_backup, [alloc_small_ptr_backup + (3 + 1) * sizeof value]
ret
end C_primitive
C_primitive caml_sys_read_directory
end C_primitive
C_primitive caml_sys_isatty
end C_primitive