Subversion Repositories Kolibri OS

Rev

Rev 5195 | Rev 6767 | 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_PROCESS_DATA equ dword [fs:0x30]
14
FS_ERRNO equ dword [fs:0x34]
15
FS_SYSCALL_PTR equ dword [fs:0xC0]
16
 
17
ENOMEM = 12
18
 
19
DLL_PROCESS_DETACH = 0
20
DLL_PROCESS_ATTACH = 1
21
DLL_THREAD_ATTACH = 2
22
DLL_THREAD_DETACH = 3
23
 
24
SYSCALL_METHOD_I40 = 1
25
SYSCALL_METHOD_SYSENTER = 2
26
SYSCALL_METHOD_SYSCALL = 3
27
 
28
; Pointer to this structure is passed as the third argument
29
; to 'start' procedure by the kernel.
30
struct kernel_init_data
31
version         dw      ?
32
flags           dw      ?
33
syscall_method  dd      ?
34
; either one of SYSCALL_METHOD_xxx or pointer to procedure
35
exe_base        dd      ?
36
stack_base      dd      ?
37
stack_size      dd      ?
38
exe_path        dd      ?
39
command_line    dd      ?
6614 clevermous 40
environment     dd      ?
5195 clevermous 41
ends
42
 
43
include 'malloc.inc'
6614 clevermous 44
include 'peloader.inc'
45
include 'cmdline.inc'
5195 clevermous 46
 
47
proc syscall_int40
48
        int     0x40
49
        ret
50
endp
51
 
6614 clevermous 52
proc syscall_sysenter
53
        push    ebp
54
        mov     ebp, esp
55
        push    @f
56
        sysenter
57
@@:
58
        pop     edx
59
        pop     ecx
60
        ret
61
endp
62
 
63
proc syscall_syscall
64
        push    ecx
65
        syscall
66
        pop     ecx
67
        ret
68
endp
69
 
5195 clevermous 70
proc kercall
71
        jmp     FS_SYSCALL_PTR
72
endp
73
 
74
prologue@proc equ fpo_prologue
75
epilogue@proc equ fpo_epilogue
76
 
77
proc start stdcall, dll_base, reason, reserved
6614 clevermous 78
locals
79
exe_base dd ?
80
exe_path_size dd ?
81
endl
5195 clevermous 82
; 1. Do nothing unless called by the kernel for DLL_PROCESS_ATTACH.
83
        cmp     [reason], DLL_PROCESS_ATTACH
84
        jnz     .nothing
6614 clevermous 85
; 2. Initialize process.
86
; 2a. Validate version of the init struct.
5195 clevermous 87
; If not known, say a debug message and die.
88
        mov     ebp, [reserved]
6614 clevermous 89
        mov     esi, [dll_base]
5195 clevermous 90
        cmp     [ebp+kernel_init_data.version], 1
91
        jnz     .version_mismatch
6614 clevermous 92
; 2b. Get the system call code.
93
; Note: relocations have not been fixed yet,
94
; so we cannot use absolute addresses, only RVAs.
5195 clevermous 95
        mov     eax, [ebp+kernel_init_data.syscall_method]
96
        cmp     eax, 0x10000
6614 clevermous 97
        jae     .syscall_absolute
98
        dec     eax
99
        mov     edx, rva syscall_int40
100
        cmp     eax, num_syscall_methods
5195 clevermous 101
        jae     @f
6614 clevermous 102
        mov     edx, [esi+eax*4+rva syscall_methods]
5195 clevermous 103
@@:
6614 clevermous 104
        lea     eax, [edx+esi]
105
.syscall_absolute:
5195 clevermous 106
        mov     FS_SYSCALL_PTR, eax
6614 clevermous 107
; 2c. Fixup relocations so that we can use absolute offsets instead of RVAs
108
; in rest of code.
109
; Note: this uses syscalls, so this step should be done after
110
; configuring FS_SYSCALL_PTR at step 2b.
111
        push    kolibri_dll
112
        call    fixup_pe_relocations
113
        pop     ecx
114
        jc      .die
115
; 2d. Allocate process data.
116
        mov     eax, 68
117
        mov     ebx, 12
118
        mov     ecx, 0x1000
119
        call    FS_SYSCALL_PTR
120
        mov     FS_PROCESS_DATA, eax
121
; 2e. Initialize process heap.
5195 clevermous 122
        mov     eax, [ebp+kernel_init_data.exe_base]
6614 clevermous 123
        mov     [exe_base], eax
5195 clevermous 124
        mov     edx, [eax+STRIPPED_PE_HEADER.SizeOfHeapReserve]
125
        cmp     word [eax], 'MZ'
126
        jnz     @f
127
        add     eax, [eax+IMAGE_DOS_HEADER.e_lfanew]
128
        mov     edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapReserve]
129
@@:
130
        malloc_init
6614 clevermous 131
; 2f. Copy rest of init struct and free memory.
132
; Parse command line to argc/argv here and move arguments to the heap
133
; in order to save memory: init struct and heap use different pages,
134
; but typically data from init struct are far from the entire page,
135
; so moving it to heap does not increase actual physical heap size
136
; and allows to free init struct.
137
        mov     eax, [ebp+kernel_init_data.stack_base]
138
        mov     FS_STACK_MIN, eax
139
        add     eax, [ebp+kernel_init_data.stack_size]
140
        mov     FS_STACK_MAX, eax
141
        mov     eax, [ebp+kernel_init_data.exe_path]
142
@@:
143
        inc     eax
144
        cmp     byte [eax-1], 0
145
        jnz     @b
146
        sub     eax, [ebp+kernel_init_data.exe_path]
147
        mov     [exe_path_size], eax
148
        mov     esi, [ebp+kernel_init_data.command_line]
149
        xor     edx, edx
150
        xor     edi, edi
151
        call    parse_cmdline
152
        inc     ebx ; argv[0] = exe path
153
.argc equ dll_base
154
.argv equ reason
155
.envp equ reserved
156
        mov     [.argc], ebx
157
        sub     esi, [ebp+kernel_init_data.command_line]
158
        lea     esi, [esi+(ebx+1)*4]
159
        add     esi, [exe_path_size]
160
        stdcall malloc, esi
161
        mov     [.argv], eax
162
        mov     edx, eax
163
        lea     edi, [eax+ebx*4]
164
        mov     esi, [ebp+kernel_init_data.exe_path]
165
        mov     [edx], edi
166
        add     edx, 4
167
        mov     ecx, [exe_path_size]
168
        rep movsb
169
        mov     esi, [ebp+kernel_init_data.command_line]
170
        call    parse_cmdline
171
        and     dword [edx], 0 ; argv[argc] = NULL
172
        and     [.envp], 0
173
        mov     eax, 68
174
        mov     ebx, 13
175
        mov     ecx, ebp
176
        call    FS_SYSCALL_PTR
177
; 3. Configure modules: main EXE and possible statically linked DLLs.
178
        mov     esi, [exe_base]
179
        mov     eax, [.argv]
180
        pushd   [eax]
181
        call    fixup_pe_relocations
182
        pop     ecx
183
        jc      .die
184
; 4. Call exe entry point.
185
        mov     edx, [esi+STRIPPED_PE_HEADER.AddressOfEntryPoint]
186
        cmp     word [esi], 'MZ'
5195 clevermous 187
        jnz     @f
6614 clevermous 188
        mov     ecx, [esi+IMAGE_DOS_HEADER.e_lfanew]
189
        add     ecx, esi
5195 clevermous 190
        mov     edx, [ecx+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
191
@@:
6614 clevermous 192
        add     edx, esi
193
        add     esp, fpo_localsize+4
5195 clevermous 194
        call    edx
195
; If exe entry point has returned control, die.
6614 clevermous 196
        jmp     .die
197
.version_mismatch:
198
        lea     eax, [esi + rva syscall_int40]
199
        mov     FS_SYSCALL_PTR, eax
200
        add     esi, rva msg_version_mismatch
201
        call    sys_msg_board_str
202
.die:
203
        or      eax, -1
5195 clevermous 204
        call    FS_SYSCALL_PTR
6614 clevermous 205
.nothing:
206
        ret
207
endp
208
 
209
proc sys_msg_board_str
210
        push    eax ebx
5195 clevermous 211
@@:
6614 clevermous 212
        push    ecx
213
        mov     cl, [ecx]
5195 clevermous 214
        test    cl, cl
215
        jz      @f
6614 clevermous 216
        mov     eax, 63
217
        mov     ebx, 1
218
        call    FS_SYSCALL_PTR
219
        pop     ecx
220
        inc     ecx
5195 clevermous 221
        jmp     @b
222
@@:
6614 clevermous 223
        pop     ecx ebx eax
5195 clevermous 224
        ret
225
endp
226
 
227
align 4
6614 clevermous 228
syscall_methods dd rva syscall_int40, rva syscall_sysenter, rva syscall_syscall
229
num_syscall_methods = ($ - syscall_methods) / 4
230
 
231
align 4
5195 clevermous 232
data export
233
export 'kolibri.dll' \
234
        , kercall, 'kercall' \
235
        , malloc, 'malloc' \
236
        , free, 'free' \
237
        , calloc, 'calloc' \
238
        , realloc, 'realloc' \
239
        , realloc_in_place, 'realloc_in_place' \
240
        , memalign, 'memalign' \
241
        , create_mspace, 'create_mspace' \
242
        , destroy_mspace, 'destroy_mspace' \
243
        , mspace_malloc, 'mspace_malloc' \
244
        , mspace_free, 'mspace_free' \
245
        , mspace_calloc, 'mspace_calloc' \
246
        , mspace_realloc, 'mspace_realloc' \
247
        , mspace_realloc_in_place, 'mspace_realloc_in_place' \
248
        , mspace_memalign, 'mspace_memalign' \
249
 
250
end data
251
 
6614 clevermous 252
kolibri_dll             db      'kolibri.dll',0
5195 clevermous 253
 
6614 clevermous 254
msg_version_mismatch    db      'S : Version mismatch between kernel and kolibri.dll',13,10,0
255
msg_bad_relocation1     db      'S : Bad relocation type in ',0
256
msg_newline             db      13,10,0
257
msg_relocated1          db      'S : fixups for ',0
258
msg_relocated2          db      ' applied',13,10,0
259
 
5195 clevermous 260
if FOOTERS
261
section '.data' data readable writable
262
malloc_magic    dd      ?
263
end if