1 | ;
|
---|
2 | ; LOADER.ASM -- Load executable files
|
---|
3 | ;
|
---|
4 | ; Copyright (c) 1991-1995 by Eberhard Mattes
|
---|
5 | ;
|
---|
6 | ; This file is part of emx.
|
---|
7 | ;
|
---|
8 | ; emx is free software; you can redistribute it and/or modify it
|
---|
9 | ; under the terms of the GNU General Public License as published by
|
---|
10 | ; the Free Software Foundation; either version 2, or (at your option)
|
---|
11 | ; any later version.
|
---|
12 | ;
|
---|
13 | ; emx is distributed in the hope that it will be useful,
|
---|
14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
16 | ; GNU General Public License for more details.
|
---|
17 | ;
|
---|
18 | ; You should have received a copy of the GNU General Public License
|
---|
19 | ; along with emx; see the file COPYING. If not, write to
|
---|
20 | ; the Free Software Foundation, 59 Temple Place - Suite 330,
|
---|
21 | ; Boston, MA 02111-1307, USA.
|
---|
22 | ;
|
---|
23 | ; See emx.asm for a special exception.
|
---|
24 | ;
|
---|
25 |
|
---|
26 | INCLUDE EMX.INC
|
---|
27 | INCLUDE TABLES.INC
|
---|
28 | INCLUDE PAGING.INC
|
---|
29 | INCLUDE SEGMENTS.INC
|
---|
30 | INCLUDE MEMORY.INC
|
---|
31 | INCLUDE PMIO.INC
|
---|
32 | INCLUDE MISC.INC
|
---|
33 | INCLUDE SIGNAL.INC
|
---|
34 | INCLUDE PROCESS.INC
|
---|
35 | INCLUDE SYMBOLS.INC
|
---|
36 | INCLUDE DEBUG.INC
|
---|
37 | INCLUDE PMINT.INC
|
---|
38 | INCLUDE HEADERS.INC
|
---|
39 | INCLUDE OPTIONS.INC
|
---|
40 | INCLUDE ERRORS.INC
|
---|
41 | INCLUDE VERSION.INC
|
---|
42 |
|
---|
43 | PUBLIC LOADER
|
---|
44 |
|
---|
45 | HEADER_SIZE = SIZE A_OUT_HEADER
|
---|
46 | IF (SIZE EXE1_HEADER) GT HEADER_SIZE
|
---|
47 | HEADER_SIZE = SIZE EXE1_HEADER
|
---|
48 | ENDIF
|
---|
49 |
|
---|
50 | SV_DATA SEGMENT
|
---|
51 |
|
---|
52 | SYM_SIZE DWORD ?
|
---|
53 | STR_SIZE DWORD ?
|
---|
54 | TEXT_PAGE DWORD ?
|
---|
55 | DATA_PAGE DWORD ?
|
---|
56 |
|
---|
57 | ;
|
---|
58 | ; The file header (this buffer is used for different types of headers)
|
---|
59 | ;
|
---|
60 | HDR_E LABEL EXE1_HEADER
|
---|
61 | HDR_A LABEL A_OUT_HEADER
|
---|
62 | HDR BYTE HEADER_SIZE DUP (?)
|
---|
63 |
|
---|
64 | ;
|
---|
65 | ; The emxbind patch area
|
---|
66 | ;
|
---|
67 | HDR_B BIND_HEADER <>
|
---|
68 |
|
---|
69 | ;
|
---|
70 | ; The layout table (aka OS/2 patch area)
|
---|
71 | ;
|
---|
72 | HDR_L LAYOUT_TABLE <>
|
---|
73 |
|
---|
74 | $CANT_OPEN BYTE "Cannot open program file", CR, LF, 0
|
---|
75 | $CANT_READ BYTE "Cannot read program file", CR, LF, 0
|
---|
76 | $INVALID_PROG BYTE "Invalid program file", CR, LF, 0
|
---|
77 | $INVALID_VER BYTE "Wrong emx version", CR, LF, 0
|
---|
78 | $LOADER_MEM BYTE "Out of memory", CR, LF, 0
|
---|
79 | $INV_OPT BYTE "Invalid emx option", CR, LF, 0
|
---|
80 |
|
---|
81 | SV_DATA ENDS
|
---|
82 |
|
---|
83 |
|
---|
84 |
|
---|
85 | SV_CODE SEGMENT
|
---|
86 |
|
---|
87 | ;
|
---|
88 | ; Load executable file, called by NEW_PROCESS
|
---|
89 | ;
|
---|
90 | ; In: DI Pointer to process entry
|
---|
91 | ; AX:EDX Pointer to file name
|
---|
92 | ;
|
---|
93 | ; Out: AX Return code (0:ok)
|
---|
94 | ; EDX Error message (for AX > 0)
|
---|
95 | ;
|
---|
96 |
|
---|
97 | ASSUME CS:SV_CODE, DS:SV_DATA
|
---|
98 |
|
---|
99 | ASSUME DI:PTR PROCESS
|
---|
100 | LOADER PROC NEAR
|
---|
101 | CALL L_OPEN ; Open the file
|
---|
102 | OR AX, AX
|
---|
103 | JNZ SHORT LOADER_RET
|
---|
104 | CALL L_HEADER ; Read header
|
---|
105 | OR AX, AX
|
---|
106 | JNZ SHORT LOADER_CLOSE
|
---|
107 | CALL L_OPTIONS ; Parse emx options
|
---|
108 | OR AX, AX
|
---|
109 | JNZ SHORT LOADER_CLOSE
|
---|
110 | CALL L_LAYOUT ; Compute memory layout
|
---|
111 | OR AX, AX
|
---|
112 | JNZ SHORT LOADER_CLOSE
|
---|
113 | CALL L_VMEM ; Allocate virtual memory
|
---|
114 | OR AX, AX
|
---|
115 | JNZ SHORT LOADER_CLOSE
|
---|
116 | CALL L_SYMBOLS ; Load symbols
|
---|
117 | OR AX, AX
|
---|
118 | JNZ SHORT LOADER_CLOSE
|
---|
119 | CALL L_PRELOAD ; Preload
|
---|
120 | OR AX, AX
|
---|
121 | JZ SHORT LOADER_RET
|
---|
122 | LOADER_CLOSE: PUSH AX
|
---|
123 | PUSH EDX
|
---|
124 | MOV BX, [DI].P_EXEC_HANDLE
|
---|
125 | CALL CLOSE
|
---|
126 | POP EDX
|
---|
127 | POP AX
|
---|
128 | LOADER_RET: RET
|
---|
129 | ASSUME DI:NOTHING
|
---|
130 |
|
---|
131 | ;
|
---|
132 | ; Open the file
|
---|
133 | ;
|
---|
134 | ASSUME DI:PTR PROCESS
|
---|
135 | L_OPEN PROC NEAR
|
---|
136 | MOV CL, 20H ; Deny write; read access
|
---|
137 | CALL OPEN ; Open executable file
|
---|
138 | JC SHORT L_OPEN_ERROR ; Error -> fail
|
---|
139 | MOV [DI].P_EXEC_HANDLE, AX ; Save handle
|
---|
140 | MOV BX, AX ; Return handle in BX
|
---|
141 | XOR AX, AX ; No error
|
---|
142 | RET
|
---|
143 |
|
---|
144 | L_OPEN_ERROR: MOV AX, ENOENT ; Return error code
|
---|
145 | LEA EDX, $CANT_OPEN ; and error message
|
---|
146 | RET
|
---|
147 | ASSUME DI:NOTHING
|
---|
148 | L_OPEN ENDP
|
---|
149 |
|
---|
150 |
|
---|
151 | ;
|
---|
152 | ; Read the header
|
---|
153 | ;
|
---|
154 | ASSUME DI:PTR PROCESS
|
---|
155 | L_HEADER PROC NEAR
|
---|
156 | MOV HDR_B.BND_OPTIONS[0], 0 ; This is for plain a.out files
|
---|
157 | XOR EDX, EDX ; Read header at location 0
|
---|
158 | NEXT_HEADER: MOV [DI].P_EXEC_OFFSET, EDX ; Set offset
|
---|
159 | CALL SEEK ; Move to header
|
---|
160 | MOV ECX, SIZE HDR ; Size of biggest header
|
---|
161 | LEA EDX, HDR
|
---|
162 | MOV AX, DS
|
---|
163 | CALL READ ; Read header
|
---|
164 | JC READ_ERROR ; Error -> fail
|
---|
165 | JNZ INVALID_PROG
|
---|
166 | CMP HDR_E.EXE_MAGIC, 5A4DH ; exe?
|
---|
167 | JNE SHORT LH_10 ; No -> not bound
|
---|
168 | ;
|
---|
169 | ; It's an exe file, which works only if it's a bound executable
|
---|
170 | ;
|
---|
171 | CMP [DI].P_EXEC_OFFSET, 0 ; First header?
|
---|
172 | JNE INVALID_PROG ; No -> error
|
---|
173 | MOVZX EDX, HDR_E.EXE_HDR_SIZE ; Header size (paragraphs)
|
---|
174 | SHL EDX, 4 ; Header size (bytes)
|
---|
175 | CALL SEEK ; Start of image
|
---|
176 | MOV ECX, SIZE HDR_B
|
---|
177 | LEA EDX, HDR_B
|
---|
178 | MOV AX, DS
|
---|
179 | CALL READ ; Read patch area
|
---|
180 | JC READ_ERROR ; Error -> fail
|
---|
181 | JNZ INVALID_PROG
|
---|
182 | ASSUME DI:NOTHING
|
---|
183 | PUSH ES
|
---|
184 | PUSH SI
|
---|
185 | PUSH DI
|
---|
186 | MOV AX, G_HDR_SEL
|
---|
187 | MOV ES, AX
|
---|
188 | ASSUME ES:HDR_SEG
|
---|
189 | XOR DI, DI
|
---|
190 | LEA SI, HDR_B ; Compare signature and
|
---|
191 | MOV CX, HDR_VERSION_LEN ; version
|
---|
192 | CLD
|
---|
193 | REPE CMPS BYTE PTR DS:[SI], BYTE PTR ES:[DI]
|
---|
194 | POP DI
|
---|
195 | POP SI
|
---|
196 | POP ES
|
---|
197 | JE SHORT SIG_OK ; Match -> ok
|
---|
198 | MOV AX, HDR_VERSION_LEN
|
---|
199 | SUB AX, CX ; Length of common prefix + 1
|
---|
200 | CMP AX, HDR_EMX_LEN
|
---|
201 | JBE INVALID_PROG ; Different signature -> fail
|
---|
202 | ;
|
---|
203 | ; Version check is disabled. Leave checking the version to the C runtime
|
---|
204 | ; startup code, assuming that all DOS calls and system calls required for
|
---|
205 | ; checking the version and displaying the error message are supported by
|
---|
206 | ; all versions of emx.exe (or, vice versa: emx.exe supports the check done
|
---|
207 | ; by the startup code for all versions of the C runtime library).
|
---|
208 | ;
|
---|
209 | ;;;; JMP INVALID_VERSION ; Different version -> fail
|
---|
210 |
|
---|
211 | ASSUME ES:NOTHING
|
---|
212 | SIG_OK: CMP HDR_B.BND_BIND_FLAG, FALSE
|
---|
213 | JE INVALID_PROG ; Not bound ->
|
---|
214 | MOV EDX, HDR_B.BND_HDR_LOC
|
---|
215 | JMP NEXT_HEADER ; Redo with next header
|
---|
216 |
|
---|
217 | ;
|
---|
218 | ; Check for a.out header
|
---|
219 | ;
|
---|
220 | ASSUME DI:PTR PROCESS
|
---|
221 | LH_10: CMP HDR_A.A_MAGIC, A_OUT_MAGIC ; GNU a.out -z ?
|
---|
222 | JNE INVALID_PROG ; No -> error
|
---|
223 | ADD [DI].P_EXEC_OFFSET, A_OUT_OFFSET - 1000H
|
---|
224 | CMP HDR_A.A_TEXT_SIZE, 0
|
---|
225 | JZ INVALID_PROG
|
---|
226 | CMP HDR_A.A_ENTRY, 10000H ; Guard against old a.out files
|
---|
227 | JNE INVALID_PROG
|
---|
228 | ;
|
---|
229 | ; Read the layout table, which is required for retrieving the brk
|
---|
230 | ; pointer of a dumped heap. The layout table is located at the
|
---|
231 | ; beginning of the data segment.
|
---|
232 | ;
|
---|
233 | MOV EDX, HDR_A.A_TEXT_SIZE
|
---|
234 | ADD EDX, 0FFFH ; Round
|
---|
235 | AND EDX, NOT 0FFFH
|
---|
236 | ADD EDX, [DI].P_EXEC_OFFSET
|
---|
237 | ADD EDX, 1000H ; See P_EXEC_OFFSET above
|
---|
238 | CALL SEEK ; Move to layout table
|
---|
239 | MOV ECX, SIZE HDR_L
|
---|
240 | LEA EDX, HDR_L
|
---|
241 | MOV AX, DS
|
---|
242 | CALL READ ; Read header
|
---|
243 | JC READ_ERROR ; Error -> fail
|
---|
244 | JNZ INVALID_PROG
|
---|
245 | ;
|
---|
246 | ; Check the layout table
|
---|
247 | ;
|
---|
248 | CMP HDR_L.L_TEXT_BASE, 10000H
|
---|
249 | JNE INVALID_PROG
|
---|
250 | MOV AL, BYTE PTR HDR_L.L_FLAGS[3]
|
---|
251 | MOV [DI].P_INTERFACE, AL ; Set interface version
|
---|
252 | XOR AX, AX ; No error
|
---|
253 | RET
|
---|
254 | L_HEADER ENDP
|
---|
255 |
|
---|
256 | ;
|
---|
257 | ; Parse options.
|
---|
258 | ;
|
---|
259 | ; 1/ emxbind patch area
|
---|
260 | ; 2/ EMXOPT environment variable
|
---|
261 | ; 3/ command line (first process only)
|
---|
262 | ;
|
---|
263 | L_OPTIONS PROC NEAR
|
---|
264 | ;
|
---|
265 | ; Process the emxbind patch area
|
---|
266 | ;
|
---|
267 | MOV_ES_DS
|
---|
268 | LEA ESI, HDR_B.BND_OPTIONS
|
---|
269 | CALL PM_OPTIONS
|
---|
270 | JC SHORT LO_ERROR
|
---|
271 | ;
|
---|
272 | ;
|
---|
273 | ; Process the EMXOPT environment variable if present.
|
---|
274 | ;
|
---|
275 | MOV AX, G_ENV_SEL
|
---|
276 | MOV ES, AX
|
---|
277 | MOVZX ESI, ENV_EMXOPT
|
---|
278 | OR ESI, ESI
|
---|
279 | JZ SHORT LO_10
|
---|
280 | CALL PM_OPTIONS
|
---|
281 | JC SHORT LO_ERROR
|
---|
282 | ;
|
---|
283 | ; Process the command line options. Note that CMDL_OPTIONS[0] is
|
---|
284 | ; set to 0 after starting the first process. That is, all processes
|
---|
285 | ; but the initial one ignore the command line options.
|
---|
286 | ;
|
---|
287 | LO_10: MOV_ES_DS
|
---|
288 | LEA ESI, CMDL_OPTIONS
|
---|
289 | CALL PM_OPTIONS
|
---|
290 | JC SHORT LO_ERROR
|
---|
291 | XOR AX, AX ; No error
|
---|
292 | RET
|
---|
293 |
|
---|
294 | LO_ERROR: MOV AX, ENOEXEC ; Error:
|
---|
295 | LEA EDX, $INV_OPT ; Invalid emx option
|
---|
296 | RET
|
---|
297 | L_OPTIONS ENDP
|
---|
298 |
|
---|
299 | ;
|
---|
300 | ; Compute the memory layout of the process
|
---|
301 | ;
|
---|
302 | L_LAYOUT PROC NEAR
|
---|
303 | MOV EAX, HDR_A.A_ENTRY
|
---|
304 | MOV [DI].P_ENTRY_POINT, EAX ; Set entry point
|
---|
305 | MOV [DI].P_TEXT_OFF, EAX
|
---|
306 | MOV EAX, HDR_A.A_TEXT_SIZE
|
---|
307 | MOV [DI].P_TEXT_SIZE, EAX ; Set size of text segment
|
---|
308 | MOV EAX, HDR_A.A_DATA_SIZE
|
---|
309 | MOV [DI].P_DATA_SIZE, EAX
|
---|
310 | MOV EAX, [DI].P_TEXT_OFF
|
---|
311 | ADD EAX, HDR_A.A_TEXT_SIZE
|
---|
312 | DEC EAX
|
---|
313 | AND EAX, NOT 0FFFFH
|
---|
314 | ADD EAX, 10000H
|
---|
315 | MOV [DI].P_DATA_OFF, EAX
|
---|
316 | ;
|
---|
317 | ; Compute offset of bss segment
|
---|
318 | ;
|
---|
319 | ADD EAX, HDR_A.A_DATA_SIZE
|
---|
320 | MOV [DI].P_BSS_OFF, EAX
|
---|
321 | ;
|
---|
322 | ; Compute address of heap: If the heap is loaded from the executable,
|
---|
323 | ; use the heap base address and the brk pointer from the layout table.
|
---|
324 | ; Otherwise, put the heap after the BSS
|
---|
325 | ;
|
---|
326 | MOV EAX, HDR_L.L_HEAP_BRK
|
---|
327 | OR EAX, EAX ; Preloaded heap?
|
---|
328 | JZ SHORT LL_HEAP_1 ; No ->
|
---|
329 | MOV [DI].P_BRK, EAX
|
---|
330 | MOV EAX, HDR_L.L_HEAP_BASE
|
---|
331 | MOV [DI].P_INIT_BRK, EAX
|
---|
332 | JMP SHORT LL_HEAP_9
|
---|
333 |
|
---|
334 | LL_HEAP_1: MOV EAX, [DI].P_BSS_OFF
|
---|
335 | ADD EAX, HDR_A.A_BSS_SIZE
|
---|
336 | DEC EAX ; Align to 64K
|
---|
337 | AND EAX, NOT 0FFFFH
|
---|
338 | ADD EAX, 10000H
|
---|
339 | MOV [DI].P_BRK, EAX
|
---|
340 | MOV [DI].P_INIT_BRK, EAX
|
---|
341 | LL_HEAP_9:
|
---|
342 | ;
|
---|
343 | ; Compute address of stack
|
---|
344 | ;
|
---|
345 | MOV EAX, [DI].P_INIT_BRK ; Heap base address
|
---|
346 | AND EAX, NOT 0FFFH
|
---|
347 | ADD EAX, 1000H
|
---|
348 | ADD EAX, [DI].P_STACK_SIZE
|
---|
349 | MOV [DI].P_STACK_ADDR, EAX
|
---|
350 | MOV [DI].P_DSEG_SIZE, EAX
|
---|
351 | ;
|
---|
352 | ; Compute page numbers
|
---|
353 | ;
|
---|
354 | MOV ECX, 1
|
---|
355 | MOV TEXT_PAGE, ECX
|
---|
356 | MOV EAX, [DI].P_TEXT_SIZE
|
---|
357 | ADD EAX, 0FFFH
|
---|
358 | SHR EAX, 12
|
---|
359 | ADD ECX, EAX
|
---|
360 | MOV DATA_PAGE, ECX
|
---|
361 | MOV EAX, [DI].P_DATA_SIZE
|
---|
362 | ADD EAX, 0FFFH
|
---|
363 | SHR EAX, 12
|
---|
364 | ADD ECX, EAX
|
---|
365 | MOV [DI].P_SYM_PAGE, ECX
|
---|
366 | ;
|
---|
367 | ; Set sizes of bss and symbols areas
|
---|
368 | ;
|
---|
369 | MOV EAX, HDR_A.A_BSS_SIZE
|
---|
370 | MOV [DI].P_BSS_SIZE, EAX
|
---|
371 | MOV EAX, HDR_A.A_DRSIZE
|
---|
372 | ADD EAX, HDR_A.A_TRSIZE
|
---|
373 | MOV [DI].P_RELOC_SIZE, EAX
|
---|
374 | MOV EAX, HDR_A.A_SYM_SIZE
|
---|
375 | MOV SYM_SIZE, EAX
|
---|
376 | MOV STR_SIZE, 0
|
---|
377 | ;
|
---|
378 | ; ...
|
---|
379 | ;
|
---|
380 | MOV [DI].P_LAST_PAGE, 0
|
---|
381 | OR EAX, EAX
|
---|
382 | JZ SHORT LL_29
|
---|
383 | CMP STEP_FLAG, FALSE
|
---|
384 | JE SHORT LL_29
|
---|
385 | MOV EDX, [DI].P_SYM_PAGE
|
---|
386 | SHL EDX, 12
|
---|
387 | ADD EDX, [DI].P_EXEC_OFFSET
|
---|
388 | ADD EDX, [DI].P_RELOC_SIZE
|
---|
389 | ADD EDX, EAX ; EAX=SYM_SIZE
|
---|
390 | CALL SEEK
|
---|
391 | JC INVALID_PROG
|
---|
392 | PUSH ECX
|
---|
393 | LEA EDX, STR_SIZE
|
---|
394 | MOV AX, DS
|
---|
395 | MOV ECX, 4
|
---|
396 | CALL READ
|
---|
397 | POP ECX
|
---|
398 | JC READ_ERROR
|
---|
399 | JNZ INVALID_PROG
|
---|
400 | MOV EAX, SYM_SIZE
|
---|
401 | ADD EAX, STR_SIZE
|
---|
402 | MOV EDX, EAX
|
---|
403 | ADD EAX, 0FFFH
|
---|
404 | SHR EAX, 12
|
---|
405 | ADD EAX, [DI].P_SYM_PAGE
|
---|
406 | DEC EAX ; Number of last page
|
---|
407 | AND EDX, 0FFFH ; Complete page?
|
---|
408 | JZ SHORT LL_29 ; Yes -> skip
|
---|
409 | MOV [DI].P_LAST_PAGE, EAX ; Special handling of
|
---|
410 | MOV [DI].P_LAST_BYTES, DX ; last page
|
---|
411 | LL_29: XOR AX, AX ; No error
|
---|
412 | RET
|
---|
413 | ASSUME DI:NOTHING
|
---|
414 | L_LAYOUT ENDP
|
---|
415 |
|
---|
416 |
|
---|
417 | ;
|
---|
418 | ; Prepare page tables for virtual memory
|
---|
419 | ;
|
---|
420 | ASSUME DI:PTR PROCESS
|
---|
421 | L_VMEM PROC NEAR
|
---|
422 | ;
|
---|
423 | ; Check parameters
|
---|
424 | ;
|
---|
425 | TEST [DI].P_STACK_SIZE, 0FFFH
|
---|
426 | JNZ INVALID_PROG
|
---|
427 | TEST [DI].P_STACK_ADDR, 0FFFH
|
---|
428 | JNZ INVALID_PROG
|
---|
429 | TEST [DI].P_TEXT_OFF, 0FFFH
|
---|
430 | JNZ INVALID_PROG
|
---|
431 | TEST [DI].P_DATA_OFF, 0FFFH
|
---|
432 | JNZ INVALID_PROG
|
---|
433 | MOV EAX, [DI].P_TEXT_OFF
|
---|
434 | MOV ECX, [DI].P_TEXT_SIZE
|
---|
435 | ADD EAX, ECX
|
---|
436 | ADD EAX, 0FFFH
|
---|
437 | AND EAX, NOT 0FFFH
|
---|
438 | CMP EAX, [DI].P_DATA_OFF
|
---|
439 | JA INVALID_PROG
|
---|
440 | ;
|
---|
441 | ; Allocate linear address space and initialize page tables
|
---|
442 | ;
|
---|
443 | MOV EAX, [DI].P_DSEG_SIZE ; Add 1.5 MB for __memaccess
|
---|
444 | ADD EAX, 180000H ; and ADD_PAGES
|
---|
445 | MOV [DI].P_LIN_SIZE, EAX
|
---|
446 | ADD EAX, [DI].P_DATA_OFF
|
---|
447 | MOV ECX, EAX ; Combined size
|
---|
448 | MOV AL, [DI].P_PIDX ; Get process index
|
---|
449 | CALL ALLOC_PAGES
|
---|
450 | MOV [DI].P_LINEAR, EAX
|
---|
451 | CALL INIT_PAGES
|
---|
452 | JC OUT_OF_MEM
|
---|
453 | ;
|
---|
454 | ; SRC_EXEC pages (code)
|
---|
455 | ;
|
---|
456 | MOV EAX, [DI].P_TEXT_OFF
|
---|
457 | ADD EAX, [DI].P_LINEAR
|
---|
458 | MOV ECX, [DI].P_TEXT_SIZE
|
---|
459 | ADD ECX, 0FFFH
|
---|
460 | SHR ECX, 12
|
---|
461 | MOV EBX, PAGE_USER ; Page table entry
|
---|
462 | MOV EDX, TEXT_PAGE
|
---|
463 | SHL EDX, 12
|
---|
464 | OR EDX, SRC_EXEC ; Swap table entry
|
---|
465 | MOV DL, [DI].P_PIDX ; PIDX
|
---|
466 | CALL SET_PAGES
|
---|
467 | MOV EBX, [DI].P_LINEAR
|
---|
468 | MOV ECX, [DI].P_TEXT_OFF
|
---|
469 | ADD ECX, [DI].P_TEXT_SIZE
|
---|
470 | TEST [DI].P_HW_ACCESS, HW_ACCESS_CODE ; Data executable?
|
---|
471 | JZ SHORT TEXT_EXEC ; No -> restrict CS to .text
|
---|
472 | MOV ECX, [DI].P_DSEG_SIZE ; Big code segment, with stack
|
---|
473 | TEXT_EXEC: MOV SI, [DI].P_LDT_PTR
|
---|
474 | ADD SI, L_CODE_SEL AND NOT 07H
|
---|
475 | MOV AX, A_CODE32 OR DPL_3
|
---|
476 | CALL CREATE_SEG
|
---|
477 |
|
---|
478 | MOV ECX, [DI].P_DSEG_SIZE
|
---|
479 | MOV EAX, [DI].P_LINEAR
|
---|
480 | ADD EAX, [DI].P_DATA_OFF
|
---|
481 | SUB ECX, [DI].P_DATA_OFF
|
---|
482 | ADD ECX, 0FFFH
|
---|
483 | SHR ECX, 12
|
---|
484 | MOV EBX, 000H ; Page table entry
|
---|
485 | MOV EDX, 000H ; Swap table entry
|
---|
486 | CALL SET_PAGES ; Inaccessible
|
---|
487 |
|
---|
488 | ;
|
---|
489 | ; SRC_NONE pages (stack)
|
---|
490 | ;
|
---|
491 | MOV EAX, [DI].P_STACK_ADDR
|
---|
492 | ADD EAX, [DI].P_LINEAR
|
---|
493 | MOV ECX, [DI].P_STACK_SIZE
|
---|
494 | SUB EAX, ECX
|
---|
495 | SHR ECX, 12
|
---|
496 | MOV EBX, PAGE_WRITE OR PAGE_USER
|
---|
497 | MOV EDX, SRC_NONE ; SRC
|
---|
498 | TEST [DI].P_FLAGS, PF_DONT_ZERO
|
---|
499 | JNZ SHORT LV_04
|
---|
500 | MOV EDX, SRC_ZERO ; Swap table entry
|
---|
501 | LV_04: MOV DL, [DI].P_PIDX ; PIDX
|
---|
502 | CALL SET_PAGES ; Stack
|
---|
503 | ;
|
---|
504 | ; Commit stack pages
|
---|
505 | ;
|
---|
506 | TEST [DI].P_FLAGS, PF_COMMIT
|
---|
507 | JZ SHORT LV_09
|
---|
508 | MOV ECX, [DI].P_COMMIT_SIZE
|
---|
509 | ADD ECX, 4*4096
|
---|
510 | CMP ECX, [DI].P_STACK_SIZE
|
---|
511 | JB SHORT LV_05
|
---|
512 | MOV ECX, [DI].P_STACK_SIZE
|
---|
513 | LV_05: MOV EAX, [DI].P_STACK_ADDR
|
---|
514 | ADD EAX, [DI].P_LINEAR
|
---|
515 | SUB EAX, ECX
|
---|
516 | SHR ECX, 12
|
---|
517 | CALL SET_COMMIT ; Set PAGE_ALLOC bit
|
---|
518 | CALL SET_PAGES
|
---|
519 | JC OUT_OF_MEM
|
---|
520 | LV_09:
|
---|
521 | ;
|
---|
522 | ; SRC_ZERO pages (bss)
|
---|
523 | ;
|
---|
524 | MOV EAX, [DI].P_BSS_OFF
|
---|
525 | ADD EAX, [DI].P_LINEAR
|
---|
526 | MOV ECX, [DI].P_BSS_SIZE
|
---|
527 | JECXZ LV_11
|
---|
528 | ADD ECX, EAX
|
---|
529 | DEC ECX
|
---|
530 | SHR ECX, 12 ; Last bss page
|
---|
531 | MOV EDX, EAX
|
---|
532 | SHR EDX, 12 ; First bss page
|
---|
533 | SUB ECX, EDX
|
---|
534 | INC ECX
|
---|
535 | MOV EBX, PAGE_WRITE OR PAGE_USER ; Page table entry
|
---|
536 | MOV EDX, SRC_ZERO ; Swap table entry
|
---|
537 | MOV DL, [DI].P_PIDX ; PIDX
|
---|
538 | CALL SET_COMMIT ; Set PAGE_ALLOC bit
|
---|
539 | CALL SET_PAGES ; Stack
|
---|
540 | JC OUT_OF_MEM ; ...deallocate memory
|
---|
541 | LV_11:
|
---|
542 |
|
---|
543 | ;
|
---|
544 | ; SRC_EXEC pages (data)
|
---|
545 | ;
|
---|
546 | MOV EAX, [DI].P_DATA_OFF
|
---|
547 | ADD EAX, [DI].P_LINEAR
|
---|
548 | MOV ECX, [DI].P_DATA_SIZE
|
---|
549 | ADD ECX, 0FFFH
|
---|
550 | SHR ECX, 12
|
---|
551 | MOV EBX, PAGE_WRITE OR PAGE_USER
|
---|
552 | MOV EDX, DATA_PAGE
|
---|
553 | SHL EDX, 12
|
---|
554 | OR EDX, SRC_EXEC
|
---|
555 | MOV DL, [DI].P_PIDX ; PIDX
|
---|
556 | CALL SET_COMMIT ; Set PAGE_ALLOC bit
|
---|
557 | CALL SET_PAGES
|
---|
558 | JC OUT_OF_MEM ; ...deallocate memory
|
---|
559 |
|
---|
560 | MOV EBX, [DI].P_LINEAR
|
---|
561 | MOV ECX, [DI].P_DSEG_SIZE
|
---|
562 | MOV SI, [DI].P_LDT_PTR
|
---|
563 | ADD SI, L_DATA_SEL AND NOT 07H
|
---|
564 | MOV AX, A_DATA32 OR DPL_3
|
---|
565 | CALL CREATE_SEG
|
---|
566 | CALL CLEAR_TLB
|
---|
567 | XOR AX, AX
|
---|
568 | RET
|
---|
569 | ASSUME DI:NOTHING
|
---|
570 | L_VMEM ENDP
|
---|
571 |
|
---|
572 | ;
|
---|
573 | ; Load symbols
|
---|
574 | ;
|
---|
575 | ASSUME DI:PTR PROCESS
|
---|
576 | L_SYMBOLS PROC NEAR
|
---|
577 | CMP STEP_FLAG, FALSE ; Debugging?
|
---|
578 | JE SHORT L_SYMBOLS_RET ; No -> done
|
---|
579 | MOV EAX, SYM_SIZE
|
---|
580 | OR EAX, EAX
|
---|
581 | JZ SHORT L_SYMBOLS_RET
|
---|
582 | MOV [DI].P_STR_OFF, EAX
|
---|
583 | XOR EDX, EDX
|
---|
584 | MOV EBX, SIZE NLIST
|
---|
585 | DIV EBX
|
---|
586 | MOV [DI].P_SYMBOLS, EAX
|
---|
587 | MOV ECX, SYM_SIZE
|
---|
588 | ADD ECX, STR_SIZE
|
---|
589 | MOV AL, [DI].P_PIDX ; Get process index
|
---|
590 | CALL ALLOC_PAGES
|
---|
591 | CALL INIT_PAGES
|
---|
592 | JC OUT_OF_MEM
|
---|
593 | MOV EBX, PAGE_USER ; Read only
|
---|
594 | MOV EDX, [DI].P_SYM_PAGE
|
---|
595 | SHL EDX, 12
|
---|
596 | OR EDX, SRC_EXEC ; SRC
|
---|
597 | MOV DL, [DI].P_PIDX ; PIDX
|
---|
598 | CALL SET_PAGES
|
---|
599 | MOV ECX, SYM_SIZE
|
---|
600 | ADD ECX, STR_SIZE
|
---|
601 | MOV EBX, EAX
|
---|
602 | MOV SI, [DI].P_LDT_PTR
|
---|
603 | ADD SI, L_SYM_SEL AND NOT 07H
|
---|
604 | MOV AX, A_READ32 OR DPL_3
|
---|
605 | CALL CREATE_SEG
|
---|
606 | CALL CLEAR_TLB
|
---|
607 | L_SYMBOLS_RET: XOR AX, AX
|
---|
608 | RET
|
---|
609 | ASSUME DI:NOTHING
|
---|
610 | L_SYMBOLS ENDP
|
---|
611 |
|
---|
612 |
|
---|
613 | ;
|
---|
614 | ; Preload code and initialized data
|
---|
615 | ;
|
---|
616 | ASSUME DI:PTR PROCESS
|
---|
617 | L_PRELOAD PROC NEAR
|
---|
618 | TEST [DI].P_FLAGS, PF_PRELOAD; Preloading disabled?
|
---|
619 | JNZ L_PRELOAD_RET ; Yes -> return
|
---|
620 | CALL PM_AVAIL ; Number of available pages
|
---|
621 | MOV EDX, EAX ; of memory
|
---|
622 | MOV EAX, [DI].P_DATA_OFF
|
---|
623 | ADD EAX, [DI].P_DATA_SIZE
|
---|
624 | ADD EAX, 0FFFH ; Number of pages required
|
---|
625 | SHR EAX, 12
|
---|
626 | CMP EAX, EDX ; Enough memory?
|
---|
627 | JA L_PRELOAD_RET ; No -> don't preload
|
---|
628 | OR [DI].P_FLAGS, PF_PRELOADING ; Preloading...
|
---|
629 | MOV BX, [DI].P_EXEC_HANDLE ; Get file handle
|
---|
630 | .386P
|
---|
631 | SLDT AX
|
---|
632 | PUSH AX ; Save LDTR
|
---|
633 | LLDT [DI].P_LDT ; Switch to new process
|
---|
634 | .386
|
---|
635 | ;
|
---|
636 | ; Preload code
|
---|
637 | ;
|
---|
638 | MOV EDX, TEXT_PAGE
|
---|
639 | SHL EDX, 12
|
---|
640 | ADD EDX, [DI].P_EXEC_OFFSET ; Get location of image
|
---|
641 | CALL SEEK ; Seek to code segment
|
---|
642 | JC SHORT L_PRELOAD_ERR
|
---|
643 | MOV ECX, [DI].P_TEXT_SIZE ; Size of code
|
---|
644 | MOV EDX, [DI].P_TEXT_OFF ; Destination address
|
---|
645 | MOV AX, L_DATA_SEL
|
---|
646 | CALL READ ; Read image
|
---|
647 | JC SHORT L_PRELOAD_ERR
|
---|
648 | JNZ SHORT L_PRELOAD_ERR
|
---|
649 | MOV EAX, [DI].P_TEXT_OFF
|
---|
650 | ADD EAX, [DI].P_LINEAR
|
---|
651 | MOV ECX, [DI].P_TEXT_SIZE
|
---|
652 | ADD ECX, 0FFFH
|
---|
653 | SHR ECX, 12
|
---|
654 | CALL CLEAR_DIRTY
|
---|
655 | ;
|
---|
656 | ; Preload data
|
---|
657 | ;
|
---|
658 | MOV EDX, DATA_PAGE
|
---|
659 | SHL EDX, 12
|
---|
660 | ADD EDX, [DI].P_EXEC_OFFSET ; Get location of image
|
---|
661 | CALL SEEK ; Seek to data segment
|
---|
662 | JC SHORT L_PRELOAD_ERR
|
---|
663 | MOV ECX, [DI].P_DATA_SIZE ; Size of data
|
---|
664 | MOV EDX, [DI].P_DATA_OFF ; Destination address
|
---|
665 | MOV AX, L_DATA_SEL
|
---|
666 | CALL READ ; Read image
|
---|
667 | JC SHORT L_PRELOAD_ERR
|
---|
668 | JNZ SHORT L_PRELOAD_ERR
|
---|
669 | MOV EAX, [DI].P_DATA_OFF
|
---|
670 | ADD EAX, [DI].P_LINEAR
|
---|
671 | MOV ECX, [DI].P_DATA_SIZE
|
---|
672 | ADD ECX, 0FFFH
|
---|
673 | SHR ECX, 12
|
---|
674 | CALL CLEAR_DIRTY
|
---|
675 | XOR AX, AX ; NC, ZR
|
---|
676 | L_PRELOAD_ERR: POP AX
|
---|
677 | .386P
|
---|
678 | LLDT AX ; Restore LDT
|
---|
679 | .386
|
---|
680 | JC SHORT READ_ERROR
|
---|
681 | JNZ SHORT INVALID_PROG
|
---|
682 | AND [DI].P_FLAGS, NOT PF_PRELOADING ; End of preloading
|
---|
683 | L_PRELOAD_RET: XOR AX, AX ; No error
|
---|
684 | RET
|
---|
685 | ASSUME DI:NOTHING
|
---|
686 | L_PRELOAD ENDP
|
---|
687 |
|
---|
688 |
|
---|
689 | READ_ERROR:: MOV AX, ENOEXEC
|
---|
690 | LEA EDX, $CANT_READ
|
---|
691 | RET
|
---|
692 |
|
---|
693 | INVALID_PROG:: MOV AX, ENOEXEC
|
---|
694 | LEA EDX, $INVALID_PROG
|
---|
695 | RET
|
---|
696 |
|
---|
697 | INVALID_VERSION::
|
---|
698 | MOV AX, ENOEXEC
|
---|
699 | LEA EDX, $INVALID_VER
|
---|
700 | RET
|
---|
701 |
|
---|
702 | OUT_OF_MEM:: MOV AX, ENOMEM
|
---|
703 | LEA EDX, $LOADER_MEM
|
---|
704 | RET
|
---|
705 |
|
---|
706 | LOADER ENDP
|
---|
707 |
|
---|
708 |
|
---|
709 | SV_CODE ENDS
|
---|
710 |
|
---|
711 | END
|
---|