📄 sloader.asm
字号:
;
; Copyright (C) 1996-2002 Supernar Systems, Ltd. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are
; met:
;
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
;
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; 3. The end-user documentation included with the redistribution, if any,
; must include the following acknowledgment:
;
; "This product uses DOS/32 Advanced DOS Extender technology."
;
; Alternately, this acknowledgment may appear in the software itself, if
; and wherever such third-party acknowledgments normally appear.
;
; 4. Products derived from this software may not be called "DOS/32A" or
; "DOS/32 Advanced".
;
; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED
; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
;
APP_MAXOBJECTS = 64
if SVR ne 0
include sloadlc.asm
endif
.CODE
load_le_app:
mov _app_type,0
jmp load_application
load_lx_app:
mov _app_type,1
jmp load_application
if SVR eq 0
load_lc_app:
mov _app_type,2
jmp @lerr8
endif
load_application:
mov __saved_esp,esp
call load_header ; load 'LE' exec header
mov ecx,1 ; start with Object #1
@@1: call load_object ; load object
call create_selector ; allocate selector for loaded object
push edx ; save Object Selector/Object Flags
push edi ; save Address of loaded Object
push esi ; save Page Table Index
push ebx ; save # Page Table Entries
inc ecx ; increment Current_Object#
cmp ecx,_app_num_objects
jbe @@1 ; loop until all objects are loaded
call preload_fixups ; preload fixup tables and records
mov ebp,esp ; base pointer to last loaded Object
mov ebx,_app_num_objects ; number of Objects
dec ebx
shl ebx,4
mov _app_tmp_addr1,ebx
@@2: call relocate_object
sub ebx,10h
jnc @@2
call unload_fixups ; free allocated memory for fixups
mov esp,__saved_esp
ret
;=============================================================================
load_header:
mov ecx,0C4h ; load 'LE' header
mov edx,0
call load_fs_block
mov ax,fs:[0010h] ; get Module Flags
and ax,2000h ; check if not-loadable/no-fixups
jnz @lerr7
mov eax,fs:[0044h] ; get # Objects
cmp eax,APP_MAXOBJECTS
mov _app_num_objects,eax
ja @lerr1 ; "too many objects"
mov edx,__exec_start
mov eax,fs:[0040h] ; get Object Table Offset
add eax,edx
mov _app_off_objects,eax
mov eax,fs:[0048h] ; get Object PageTable Offset
add eax,edx
mov _app_off_objpagetab,eax
mov eax,fs:[0068h] ; get Fixup PageTable Offset
add eax,edx
mov _app_off_fixpagetab,eax
mov eax,fs:[006Ch] ; get Fixup Record Table Offset
add eax,edx
mov _app_off_fixrectab,eax
mov eax,fs:[0080h] ; get Data Pages Offset
add _app_off_datapages,eax
mov eax,fs:[0018h] ; get EIP Object #
mov _app_eip_object,eax
mov eax,fs:[0020h] ; get ESP Object #
mov _app_esp_object,eax
mov eax,fs:[001Ch] ; get EIP
mov _app_eip,eax
mov eax,fs:[0024h] ; get ESP
mov _app_esp,eax
mov eax,fs:[0030h] ; get Fixup Records Size
mov _app_siz_fixrecstab,eax
mov eax,fs:[002Ch] ; get bytes on last page
mov _app_siz_lastpage,eax
mov eax,0FFFh
cmp _app_type,0
jz @@done
mov ax,1
mov cx,fs:[002Ch] ; get Page Offset Shift for LX-type
shl ax,cl ; max shift is 15 (8000h-1)
dec ax
@@done: mov _app_off_pageshift,eax
ret
;-----------------------------------------------------------------------------
load_object:
push ecx
mov edx,_app_off_objects
call seek_from_start ; move to object header
mov ecx,18h
xor edx,edx
call load_fs_block ; load object header
add _app_off_objects,ecx
mov edx,_app_off_datapages ; get Data_Pages_Offset
call seek_from_start ; move to object data
mov eax,fs:[0000h] ; get Virtual_Size[Object]
mov ebx,fs:[0010h] ; get # Page Table Entries
mov ecx,fs:[0008h] ; get Flags[Object]
mov esi,fs:[000Ch] ; get Page Table Index
push ecx ; save Object Flags
call alloc_block ; allocate EAX memory block to EDI
mov ecx,eax ; ECX = bytes to read
mov ebp,eax ; EBP = preserve Virtual Size
mov edx,edi ; EDX = addres to read to
call fill_zero_pages ; fill allocated memory with zeroes
mov eax,ebx
test eax,eax ; check if # Page Table Entries = 0
jz @@5 ; if yes, skip loading
shl eax,12 ; convert # Page Table Entries to bytes
cmp eax,ecx ; check if # bytes >= bytes to load
jae @@1 ; if yes, jump
mov ecx,eax ; else adjust number of bytes to read
@@1: mov ax,[esp+4] ; get Object #
cmp ax,word ptr _app_num_objects
jnz @@3
cmp _app_type,0
jnz @@2
lea ecx,[ebx-1] ; load LE-style Last Object (BSS)
shl ecx,12
add ecx,_app_siz_lastpage
jmp @@3
@@2: mov ecx,ebx ; load LX-style Last Object (BSS)
shl ecx,12
@@3: call load_gs_block ; load object data
mov eax,ecx
mov edx,_app_off_pageshift
test eax,edx
jz @@4
mov ecx,edx
not edx
and eax,edx
lea eax,[eax+ecx+1]
@@4: add _app_off_datapages,eax
@@5: pop edx ; restore Object Flags
@@done: pop ecx
ret
;=============================================================================
relocate_object:
cmp _app_type,0
jnz relocate_lx_object
relocate_le_object:
xor eax,eax
cmp eax,[ebp+ebx+0] ; get # Page Table Entries[Object]
jz @@done ; if zero, done
mov ecx,[ebp+ebx+4] ; get Page Table Index
mov edx,_app_off_objpagetab ; get Object Page Table Offset in exec
lea edx,[ecx*4+edx-4]
call seek_from_start ; move file ptr
@@1: push eax ; EAX = counter
mov ecx,4
xor edx,edx
call load_fs_block ; load block
xor ecx,ecx ; get index into FixupPageTab
mov ch,fs:[0001h]
mov cl,fs:[0002h]
jecxz @@3
mov eax,_app_off_fixpagetab ; get Fixup Page Table Offset
lea eax,[ecx*4+eax-4]
mov esi,[eax+00h] ; get offset of 1st fixup table
mov ecx,[eax+04h] ; get offset of 2nd fixup table
sub ecx,esi ; calculate size of 1st tab
jz @@3 ; if 1st == 2nd, no fixups
add esi,_app_off_fixrectab ; get Fixup Record Table Offset
mov edi,[esp] ; get current page number
shl edi,12
add edi,[ebp+ebx+8] ; address of page target to fix in mem
add ecx,esi
call apply_le_fixups ; patch target with fixup data
@@3: pop eax
inc eax
cmp eax,[ebp+ebx+0]
jb @@1
@@done: ret
relocate_lx_object:
xor eax,eax
cmp eax,[ebp+ebx+0] ; get # Page Table Entries[Object]
jz @@done ; if zero, done
mov ecx,[ebp+ebx+4] ; get Page Table Index
mov edx,_app_off_fixpagetab ; get Fixup Page Table Offset
lea edx,[ecx*4+edx-4]
@@1: push eax edx ; EAX = counter
mov esi,[edx+00h] ; get offset of 1st fixup table
mov ecx,[edx+04h] ; get offset of 2nd fixup table
sub ecx,esi ; calculate size of 1st tab
jz @@3 ; if 1st == 2nd, no fixups
add esi,_app_off_fixrectab ; get Fixup Record Table Offset
mov edi,[esp+4] ; get current page number
shl edi,12
add edi,[ebp+ebx+8] ; address of page target to fix in mem
add ecx,esi
call apply_le_fixups ; patch target with fixup data
@@3: pop edx eax
add edx,4
inc eax
cmp eax,[ebp+ebx+0]
jb @@1
@@done: ret
;=============================================================================
apply_le_fixups:
@@0: push ecx edi
mov cx,[esi+0] ; get SRC/FLAGS
movsx edx,word ptr [esi+2] ; get SRCOFF
movzx eax,word ptr [esi+4] ; get OBJNUM
add edi,edx ; calculate dest addr to be fixed
test cx,0F20h ; SrcLists/Imports not supported
jnz @lerr4 ; jump if one of these
test cx,4000h ; test if 16bit object number
jnz @@1 ; if yes, jump
mov ah,0
dec esi
@@1: add esi,6
dec eax ; Object Number - 1
shl eax,4
mov edx,_app_tmp_addr1
sub edx,eax
jc @lerr4
mov _app_tmp_addr2,edx
mov edx,[ebp+edx+8] ; EDX = Destination Object Address
mov al,cl
and al,0Fh
cmp al,02h ; check if 16bit Selector
jz @@3 ; if yes, jump
cmp al,08h
ja @lerr4
mov eax,[esi]
test cx,1000h ; check for Alias flag
jnz @@2 ; if not, jump
movzx eax,ax
sub esi,2
@@2: add esi,4
@@3: push esi
mov esi,ecx
and esi,0Fh
call cs:fix_tab[esi*4]
pop esi
pop edi ecx
cmp esi,ecx
jb @@0
ret
;
; EAX = Data
; EDX = Address of Object
; EDI = Address to Fixup
;
; EBP:EBX = Ptr to Current Object Table
;
fix_byte:
mov gs:[edi+0],al
ret
fix_16off:
mov gs:[edi+0],ax
ret
fix_32off:
add eax,edx
mov gs:[edi+0],eax
ret
fix_32selfrel:
add eax,edx
lea ecx,[edi+4]
sub eax,ecx
test word ptr [ebp+ebx+12],2000h
jnz @@1
lea ecx,[eax+8002h]
shr ecx,16
jnz @lerr5
mov gs:[edi+0],ax
ret
@@1: mov gs:[edi+0],eax
ret
fix_16sel:
call check_range
mov gs:[edi+0],dx
ret
fix_1616ptr:
call check_range
mov gs:[edi+0],ax
mov gs:[edi+2],dx
ret
fix_1632ptr:
add eax,edx
mov gs:[edi+0],eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -