source: vendor/emx/current/src/dos/loader.asm

Last change on this file was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 25.4 KB
Line 
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
45HEADER_SIZE = SIZE A_OUT_HEADER
46 IF (SIZE EXE1_HEADER) GT HEADER_SIZE
47HEADER_SIZE = SIZE EXE1_HEADER
48 ENDIF
49
50SV_DATA SEGMENT
51
52SYM_SIZE DWORD ?
53STR_SIZE DWORD ?
54TEXT_PAGE DWORD ?
55DATA_PAGE DWORD ?
56
57;
58; The file header (this buffer is used for different types of headers)
59;
60HDR_E LABEL EXE1_HEADER
61HDR_A LABEL A_OUT_HEADER
62HDR BYTE HEADER_SIZE DUP (?)
63
64;
65; The emxbind patch area
66;
67HDR_B BIND_HEADER <>
68
69;
70; The layout table (aka OS/2 patch area)
71;
72HDR_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
81SV_DATA ENDS
82
83
84
85SV_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
100LOADER 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
122LOADER_CLOSE: PUSH AX
123 PUSH EDX
124 MOV BX, [DI].P_EXEC_HANDLE
125 CALL CLOSE
126 POP EDX
127 POP AX
128LOADER_RET: RET
129 ASSUME DI:NOTHING
130
131;
132; Open the file
133;
134 ASSUME DI:PTR PROCESS
135L_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
144L_OPEN_ERROR: MOV AX, ENOENT ; Return error code
145 LEA EDX, $CANT_OPEN ; and error message
146 RET
147 ASSUME DI:NOTHING
148L_OPEN ENDP
149
150
151;
152; Read the header
153;
154 ASSUME DI:PTR PROCESS
155L_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
158NEXT_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
212SIG_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
221LH_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
254L_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;
263L_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;
287LO_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
294LO_ERROR: MOV AX, ENOEXEC ; Error:
295 LEA EDX, $INV_OPT ; Invalid emx option
296 RET
297L_OPTIONS ENDP
298
299;
300; Compute the memory layout of the process
301;
302L_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
334LL_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
341LL_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
411LL_29: XOR AX, AX ; No error
412 RET
413 ASSUME DI:NOTHING
414L_LAYOUT ENDP
415
416
417;
418; Prepare page tables for virtual memory
419;
420 ASSUME DI:PTR PROCESS
421L_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
473TEXT_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
501LV_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
513LV_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
520LV_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
541LV_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
570L_VMEM ENDP
571
572;
573; Load symbols
574;
575 ASSUME DI:PTR PROCESS
576L_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
607L_SYMBOLS_RET: XOR AX, AX
608 RET
609 ASSUME DI:NOTHING
610L_SYMBOLS ENDP
611
612
613;
614; Preload code and initialized data
615;
616 ASSUME DI:PTR PROCESS
617L_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
676L_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
683L_PRELOAD_RET: XOR AX, AX ; No error
684 RET
685 ASSUME DI:NOTHING
686L_PRELOAD ENDP
687
688
689READ_ERROR:: MOV AX, ENOEXEC
690 LEA EDX, $CANT_READ
691 RET
692
693INVALID_PROG:: MOV AX, ENOEXEC
694 LEA EDX, $INVALID_PROG
695 RET
696
697INVALID_VERSION::
698 MOV AX, ENOEXEC
699 LEA EDX, $INVALID_VER
700 RET
701
702OUT_OF_MEM:: MOV AX, ENOMEM
703 LEA EDX, $LOADER_MEM
704 RET
705
706LOADER ENDP
707
708
709SV_CODE ENDS
710
711 END
Note: See TracBrowser for help on using the repository browser.