Subversion Repositories Kolibri OS

Rev

Rev 6811 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5195 clevermous 1
format PE DLL GUI 0.8 at 7FF00000h
2
entry start
3
include '../../struct.inc'
4
include '../../proc32.inc'
5
include 'fpo.inc'
6
include 'export.inc'
7
include 'pe.inc'
8
section '.text' code readable executable
9
 
10
FS_STACK_MAX equ dword [fs:4]
11
FS_STACK_MIN equ dword [fs:8]
12
FS_SELF_PTR equ dword [fs:0x18]
13
FS_ERRNO equ dword [fs:0x34]
14
FS_SYSCALL_PTR equ dword [fs:0xC0]
15
 
16
ENOMEM = 12
17
 
18
DLL_PROCESS_DETACH = 0
19
DLL_PROCESS_ATTACH = 1
20
DLL_THREAD_ATTACH = 2
21
DLL_THREAD_DETACH = 3
22
 
23
SYSCALL_METHOD_I40 = 1
24
SYSCALL_METHOD_SYSENTER = 2
25
SYSCALL_METHOD_SYSCALL = 3
26
 
27
; Pointer to this structure is passed as the third argument
28
; to 'start' procedure by the kernel.
29
struct kernel_init_data
30
version         dw      ?
31
flags           dw      ?
32
syscall_method  dd      ?
33
; either one of SYSCALL_METHOD_xxx or pointer to procedure
34
exe_base        dd      ?
35
stack_base      dd      ?
36
stack_size      dd      ?
37
exe_path        dd      ?
38
command_line    dd      ?
6614 clevermous 39
environment     dd      ?
5195 clevermous 40
ends
41
 
6767 clevermous 42
include 'sync.inc'
5195 clevermous 43
include 'malloc.inc'
6614 clevermous 44
include 'peloader.inc'
6767 clevermous 45
include 'modules.inc'
6614 clevermous 46
include 'cmdline.inc'
6811 clevermous 47
include 'thread.inc'
5195 clevermous 48
 
49
proc syscall_int40
50
        int     0x40
51
        ret
52
endp
53
 
6614 clevermous 54
proc syscall_sysenter
55
        push    ebp
56
        mov     ebp, esp
57
        push    @f
58
        sysenter
59
@@:
60
        pop     edx
61
        pop     ecx
62
        ret
63
endp
64
 
65
proc syscall_syscall
66
        push    ecx
67
        syscall
68
        pop     ecx
69
        ret
70
endp
71
 
5195 clevermous 72
proc kercall
73
        jmp     FS_SYSCALL_PTR
74
endp
75
 
76
prologue@proc equ fpo_prologue
77
epilogue@proc equ fpo_epilogue
78
 
79
proc start stdcall, dll_base, reason, reserved
80
; 1. Do nothing unless called by the kernel for DLL_PROCESS_ATTACH.
81
        cmp     [reason], DLL_PROCESS_ATTACH
82
        jnz     .nothing
6614 clevermous 83
; 2. Initialize process.
84
; 2a. Validate version of the init struct.
5195 clevermous 85
; If not known, say a debug message and die.
86
        mov     ebp, [reserved]
6614 clevermous 87
        mov     esi, [dll_base]
5195 clevermous 88
        cmp     [ebp+kernel_init_data.version], 1
89
        jnz     .version_mismatch
6614 clevermous 90
; 2b. Get the system call code.
91
; Note: relocations have not been fixed yet,
92
; so we cannot use absolute addresses, only RVAs.
5195 clevermous 93
        mov     eax, [ebp+kernel_init_data.syscall_method]
94
        cmp     eax, 0x10000
6614 clevermous 95
        jae     .syscall_absolute
96
        dec     eax
97
        mov     edx, rva syscall_int40
98
        cmp     eax, num_syscall_methods
5195 clevermous 99
        jae     @f
6614 clevermous 100
        mov     edx, [esi+eax*4+rva syscall_methods]
5195 clevermous 101
@@:
6614 clevermous 102
        lea     eax, [edx+esi]
103
.syscall_absolute:
5195 clevermous 104
        mov     FS_SYSCALL_PTR, eax
6614 clevermous 105
; 2c. Fixup relocations so that we can use absolute offsets instead of RVAs
106
; in rest of code.
107
; Note: this uses syscalls, so this step should be done after
108
; configuring FS_SYSCALL_PTR at step 2b.
109
        push    kolibri_dll
110
        call    fixup_pe_relocations
111
        pop     ecx
112
        jc      .die
6767 clevermous 113
; 2d. Initialize process heap.
5195 clevermous 114
        mov     eax, [ebp+kernel_init_data.exe_base]
115
        mov     edx, [eax+STRIPPED_PE_HEADER.SizeOfHeapReserve]
116
        cmp     word [eax], 'MZ'
117
        jnz     @f
118
        add     eax, [eax+IMAGE_DOS_HEADER.e_lfanew]
119
        mov     edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapReserve]
120
@@:
121
        malloc_init
6767 clevermous 122
; 2e. Allocate and fill MODULE structs for main exe and kolibri.dll.
123
        mov     eax, [ebp+kernel_init_data.exe_path]
124
@@:
125
        inc     eax
126
        cmp     byte [eax-1], 0
127
        jnz     @b
128
        sub     eax, [ebp+kernel_init_data.exe_path]
129
        push    eax
130
        add     eax, sizeof.MODULE
131
        stdcall malloc, eax
132
        test    eax, eax
133
        jz      .die
134
        mov     ebx, eax
135
        stdcall malloc, sizeof.MODULE + kolibri_dll.size
136
        test    eax, eax
137
        jz      .die
138
        mov     edx, modules_list
139
        mov     [edx+MODULE.next], ebx
140
        mov     [ebx+MODULE.next], eax
141
        mov     [eax+MODULE.next], edx
142
        mov     [edx+MODULE.prev], eax
143
        mov     [eax+MODULE.prev], ebx
144
        mov     [ebx+MODULE.prev], edx
145
        push    esi
146
        mov     esi, kolibri_dll
147
        mov     ecx, kolibri_dll.size
148
        lea     edi, [eax+MODULE.path]
149
        rep movsb
150
        pop     esi
151
        call    init_module_struct
152
        mov     eax, ebx
153
        mov     esi, [ebp+kernel_init_data.exe_path]
154
        pop     ecx
155
        lea     edi, [ebx+MODULE.path]
156
        rep movsb
157
        mov     esi, [ebp+kernel_init_data.exe_base]
158
        call    init_module_struct
6614 clevermous 159
; 2f. Copy rest of init struct and free memory.
160
; Parse command line to argc/argv here and move arguments to the heap
161
; in order to save memory: init struct and heap use different pages,
162
; but typically data from init struct are far from the entire page,
163
; so moving it to heap does not increase actual physical heap size
164
; and allows to free init struct.
165
        mov     eax, [ebp+kernel_init_data.stack_base]
166
        mov     FS_STACK_MIN, eax
167
        add     eax, [ebp+kernel_init_data.stack_size]
168
        mov     FS_STACK_MAX, eax
169
        mov     esi, [ebp+kernel_init_data.command_line]
170
        xor     edx, edx
171
        xor     edi, edi
172
        call    parse_cmdline
173
        inc     ebx ; argv[0] = exe path
174
.argc equ dll_base
175
.argv equ reason
176
.envp equ reserved
177
        mov     [.argc], ebx
178
        sub     esi, [ebp+kernel_init_data.command_line]
179
        lea     esi, [esi+(ebx+1)*4]
180
        stdcall malloc, esi
6767 clevermous 181
        test    eax, eax
182
        jz      .die
6614 clevermous 183
        mov     [.argv], eax
184
        mov     edx, eax
6767 clevermous 185
        lea     edi, [eax+(ebx+1)*4]
186
        mov     eax, [modules_list + MODULE.next]
187
        add     eax, MODULE.path
188
        mov     [edx], eax
6614 clevermous 189
        add     edx, 4
190
        mov     esi, [ebp+kernel_init_data.command_line]
191
        call    parse_cmdline
192
        and     dword [edx], 0 ; argv[argc] = NULL
193
        and     [.envp], 0
194
        mov     eax, 68
195
        mov     ebx, 13
196
        mov     ecx, ebp
197
        call    FS_SYSCALL_PTR
6767 clevermous 198
; 2g. Initialize mutex for list of MODULEs.
199
        mov     ecx, modules_mutex
200
        call    mutex_init
201
; 2h. For console applications, call console.dll!con_init with default parameters.
202
        mov     eax, [modules_list + MODULE.next]
203
        mov     esi, [eax+MODULE.base]
204
        mov     al, [esi+STRIPPED_PE_HEADER.Subsystem]
205
        cmp     byte [esi], 'M'
206
        jnz     @f
207
        mov     eax, [esi+3Ch]
208
        mov     al, byte [esi+eax+IMAGE_NT_HEADERS.OptionalHeader.Subsystem]
209
@@:
210
        cmp     al, IMAGE_SUBSYSTEM_WINDOWS_CUI
211
        jnz     .noconsole
212
        stdcall dlopen, console_dll, 0
213
        test    eax, eax
214
        jz      .noconsole
215
        stdcall dlsym, eax, con_init_str
216
        test    eax, eax
217
        jz      .noconsole
218
        mov     edx, [modules_list + MODULE.next]
219
        stdcall eax, -1, -1, -1, -1, [edx+MODULE.filename]
220
.noconsole:
6614 clevermous 221
; 3. Configure modules: main EXE and possible statically linked DLLs.
6767 clevermous 222
        mov     eax, [modules_list + MODULE.next]
223
        mov     esi, [eax+MODULE.base]
224
        add     eax, MODULE.path
225
        push    eax
6614 clevermous 226
        call    fixup_pe_relocations
227
        pop     ecx
228
        jc      .die
6767 clevermous 229
        mutex_lock modules_mutex
230
        mov     esi, [modules_list + MODULE.next]
231
        call    resolve_pe_imports
232
        mov     ebx, eax
233
        mutex_unlock modules_mutex
234
        test    ebx, ebx
235
        jnz     .die
6614 clevermous 236
; 4. Call exe entry point.
6767 clevermous 237
        mov     esi, [esi+MODULE.base]
6614 clevermous 238
        mov     edx, [esi+STRIPPED_PE_HEADER.AddressOfEntryPoint]
6767 clevermous 239
        cmp     byte [esi], 'M'
5195 clevermous 240
        jnz     @f
6614 clevermous 241
        mov     ecx, [esi+IMAGE_DOS_HEADER.e_lfanew]
242
        add     ecx, esi
5195 clevermous 243
        mov     edx, [ecx+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
244
@@:
6614 clevermous 245
        add     edx, esi
6767 clevermous 246
        pop     ecx
247
        mov     [process_initialized], 1
5195 clevermous 248
        call    edx
249
; If exe entry point has returned control, die.
6614 clevermous 250
        jmp     .die
251
.version_mismatch:
252
        lea     eax, [esi + rva syscall_int40]
253
        mov     FS_SYSCALL_PTR, eax
254
        add     esi, rva msg_version_mismatch
255
        call    sys_msg_board_str
256
.die:
257
        or      eax, -1
5195 clevermous 258
        call    FS_SYSCALL_PTR
6614 clevermous 259
.nothing:
260
        ret
261
endp
262
 
263
proc sys_msg_board_str
264
        push    eax ebx
5195 clevermous 265
@@:
6614 clevermous 266
        push    ecx
267
        mov     cl, [ecx]
5195 clevermous 268
        test    cl, cl
269
        jz      @f
6614 clevermous 270
        mov     eax, 63
271
        mov     ebx, 1
272
        call    FS_SYSCALL_PTR
273
        pop     ecx
274
        inc     ecx
5195 clevermous 275
        jmp     @b
276
@@:
6614 clevermous 277
        pop     ecx ebx eax
5195 clevermous 278
        ret
279
endp
280
 
281
align 4
6614 clevermous 282
syscall_methods dd rva syscall_int40, rva syscall_sysenter, rva syscall_syscall
283
num_syscall_methods = ($ - syscall_methods) / 4
284
 
285
align 4
5195 clevermous 286
data export
287
export 'kolibri.dll' \
288
        , kercall, 'kercall' \
289
        , malloc, 'malloc' \
290
        , free, 'free' \
291
        , calloc, 'calloc' \
292
        , realloc, 'realloc' \
293
        , realloc_in_place, 'realloc_in_place' \
294
        , memalign, 'memalign' \
295
        , create_mspace, 'create_mspace' \
296
        , destroy_mspace, 'destroy_mspace' \
297
        , mspace_malloc, 'mspace_malloc' \
298
        , mspace_free, 'mspace_free' \
299
        , mspace_calloc, 'mspace_calloc' \
300
        , mspace_realloc, 'mspace_realloc' \
301
        , mspace_realloc_in_place, 'mspace_realloc_in_place' \
302
        , mspace_memalign, 'mspace_memalign' \
6767 clevermous 303
        , dlopen, 'dlopen' \
304
        , dlclose, 'dlclose' \
305
        , dlsym, 'dlsym' \
6811 clevermous 306
        , create_thread, 'create_thread' \
307
        , exit_thread, 'exit_thread' \
5195 clevermous 308
 
309
end data
310
 
8088 dunkaist 311
kolibri_dll             db      '/sys/lib/kolibri.dll',0
6767 clevermous 312
.size = $ - kolibri_dll
5195 clevermous 313
 
6767 clevermous 314
console_dll             db      'console.dll',0
315
con_init_str            db      'con_init',0
316
 
6614 clevermous 317
msg_version_mismatch    db      'S : Version mismatch between kernel and kolibri.dll',13,10,0
6767 clevermous 318
msg_bad_relocation      db      'Bad relocation type in ',0
6614 clevermous 319
msg_newline             db      13,10,0
320
msg_relocated1          db      'S : fixups for ',0
321
msg_relocated2          db      ' applied',13,10,0
6767 clevermous 322
msg_noreloc1            db      'Module ',0
323
msg_noreloc2            db      ' is not at preferred base and has no fixups',0
324
loader_debugboard_prefix db     'S : ',0
8088 dunkaist 325
notify_program          db      '/sys/@notify',0
6767 clevermous 326
msg_cannot_open         db      'Cannot open ',0
327
msg_paths_begin         db      ' in any of '
6614 clevermous 328
 
8088 dunkaist 329
module_path1    db      '/sys/lib/'
6767 clevermous 330
.size = $ - module_path1
331
                        db      ', '
332
module_path2    db      '/kolibrios/lib/'
333
.size = $ - module_path2
334
                        db      ', ',0
335
msg_export_name_not_found       db      'Exported function ',0
336
msg_export_ordinal_not_found    db      'Exported ordinal #',0
337
msg_export_not_found    db      ' not found in module ',0
338
msg_unknown             db      '',0
6810 clevermous 339
msg_invalid_forwarder   db      'Invalid forwarded export in module ',0
6767 clevermous 340
 
341
section '.data' data readable writable
5195 clevermous 342
if FOOTERS
343
malloc_magic    dd      ?
344
end if
6767 clevermous 345
default_heap    dd      ?
346
modules_list    rd      2
347
modules_mutex   MUTEX
348
process_initialized     db      ?