Subversion Repositories Kolibri OS

Rev

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