forked from KolibriOS/kolibrios
f19e882566
Added code for packing the kernel.mnt git-svn-id: svn://kolibrios.org@1713 a494cfbc-eb01-0410-851d-a64ba20cac60
484 lines
8.2 KiB
PHP
484 lines
8.2 KiB
PHP
;*********************************************************************
|
|
pack:
|
|
call displogo_and_readfile
|
|
jz inopened
|
|
;---------------------------------------------------------------------
|
|
infileerr:
|
|
call return_memory
|
|
mov esi,errload_str
|
|
push errload_len
|
|
pop ecx
|
|
jmp write_string
|
|
;---------------------------------------------------------------------
|
|
inopened:
|
|
mov ebx,[insize]
|
|
test ebx,ebx
|
|
jz infileerr
|
|
; maximum memory requests: 2*insize + 2*(maxoutsize+400h) + worksize
|
|
xor esi,esi
|
|
add esi,ebx
|
|
mov [inbuftmp],esi
|
|
add esi,ebx
|
|
mov [outfile],esi
|
|
mov [outfile1],esi
|
|
mov [outfilebest],esi
|
|
|
|
mov ecx,ebx
|
|
shr ecx,3
|
|
add ecx,ebx
|
|
add ecx,400h
|
|
add esi,ecx
|
|
mov [outfile2],esi
|
|
add esi,ecx
|
|
mov [workmem],esi
|
|
add ecx,ebx
|
|
add ecx,ecx
|
|
; LZMA requires 0x448000 + dictsize*9.5 bytes for workmem,
|
|
and [lzma_dictsize],0
|
|
push ecx
|
|
mov eax,ebx
|
|
dec eax
|
|
bsr ecx,eax
|
|
inc ecx
|
|
cmp ecx,28
|
|
jb @f
|
|
|
|
mov cl,28
|
|
;--------------------------------------
|
|
@@:
|
|
mov edx,ecx
|
|
xor eax,eax
|
|
inc eax
|
|
shl eax,cl
|
|
imul eax,19
|
|
shr eax,1
|
|
add eax,448000h
|
|
pop ecx
|
|
add ecx,eax
|
|
|
|
mcall 68,12
|
|
|
|
mov [infile],eax
|
|
add [inbuftmp],eax
|
|
add [outfile],eax
|
|
add [outfile1],eax
|
|
add [outfilebest],eax
|
|
add [outfile2],eax
|
|
add [workmem],eax
|
|
;--------------------------------------
|
|
; try to use smaller dictionary
|
|
;meml0:
|
|
; cmp edx,4
|
|
; jbe memf1
|
|
;
|
|
; dec edx
|
|
; xor eax,eax
|
|
; inc eax
|
|
; mov ecx,edx
|
|
; shl eax,cl
|
|
; imul eax,19
|
|
; shr eax,1
|
|
; add eax,509000h
|
|
; pop ecx
|
|
; push ecx
|
|
; add ecx,eax
|
|
; mcall 64
|
|
; test eax,eax
|
|
; jnz meml0
|
|
;--------------------------------------
|
|
; ok, say warning and continue
|
|
; mov [lzma_dictsize],edx
|
|
; mov esi,lzma_memsmall_str
|
|
; push lzma_memsmall_len
|
|
; pop ecx
|
|
; call write_string
|
|
; jmp mem_ok
|
|
;---------------------------------------------------------------------
|
|
;memf1:
|
|
; mov esi,nomem_str
|
|
; push nomem_len
|
|
; pop ecx
|
|
; jmp write_string
|
|
;---------------------------------------------------------------------
|
|
mem_ok:
|
|
mov eax,[insize]
|
|
mov ebx,fn70block
|
|
mov [ebx],byte 0
|
|
mov [ebx+12],eax
|
|
mov esi,[infile]
|
|
mov [ebx+16],esi
|
|
mcall 70
|
|
test eax,eax
|
|
jnz infileerr
|
|
|
|
mov eax,[outfile]
|
|
mov [eax],dword 'KPCK'
|
|
mov ecx,[insize]
|
|
mov [eax+4],dword ecx
|
|
mov edi,eax
|
|
; set LZMA dictionary size
|
|
mov eax,[lzma_dictsize]
|
|
test eax,eax
|
|
js no_lzma_setds
|
|
jnz lzma_setds
|
|
|
|
mov ecx,[insize]
|
|
dec ecx
|
|
bsr eax,ecx
|
|
inc eax
|
|
cmp eax,28
|
|
jb lzma_setds
|
|
|
|
mov eax,28
|
|
;--------------------------------------
|
|
lzma_setds:
|
|
push eax
|
|
call lzma_set_dict_size
|
|
;--------------------------------------
|
|
no_lzma_setds:
|
|
call tell_compress_mess
|
|
|
|
mov esi,[outfile1]
|
|
mov edi,[outfile2]
|
|
movsd
|
|
movsd
|
|
movsd
|
|
call pack_lzma
|
|
mov [outsize],eax
|
|
mov eax,[outfile]
|
|
mov [outfilebest],eax
|
|
mov [method],use_lzma
|
|
;--------------------------------------
|
|
@@:
|
|
call preprocess_calltrick
|
|
test eax,eax
|
|
jz noct1
|
|
|
|
call set_outfile
|
|
call pack_lzma
|
|
add eax,5
|
|
cmp eax,[outsize]
|
|
jae @f
|
|
|
|
mov [outsize],eax
|
|
mov eax,[outfile]
|
|
mov [outfilebest],eax
|
|
mov [method],use_lzma or use_calltrick1
|
|
;--------------------------------------
|
|
@@:
|
|
noct1:
|
|
call set_outfile
|
|
push [ctn]
|
|
mov al,[cti]
|
|
push eax
|
|
call preprocess_calltrick2
|
|
test eax,eax
|
|
jz noct2
|
|
|
|
call set_outfile
|
|
call pack_lzma
|
|
add eax,5
|
|
cmp eax,[outsize]
|
|
jae @f
|
|
|
|
mov [outsize],eax
|
|
mov eax,[outfile]
|
|
mov [outfilebest],eax
|
|
mov [method],use_lzma or use_calltrick2
|
|
pop ecx
|
|
pop ecx
|
|
push [ctn]
|
|
mov al,[cti]
|
|
push eax
|
|
;--------------------------------------
|
|
@@:
|
|
noct2:
|
|
pop eax
|
|
mov [cti],al
|
|
pop [ctn]
|
|
add [outsize],12
|
|
mov eax,[outsize]
|
|
cmp eax,[insize]
|
|
jb packed_ok
|
|
|
|
mov esi,too_big_str
|
|
push too_big_len
|
|
pop ecx
|
|
jmp write_string
|
|
;---------------------------------------------------------------------
|
|
packed_ok:
|
|
; set header
|
|
movzx eax,[method]
|
|
mov edi,[outfilebest]
|
|
mov [edi+8],eax
|
|
test al,use_calltrick1 or use_calltrick2
|
|
jz @f
|
|
|
|
mov ecx,[outsize]
|
|
add ecx,edi
|
|
mov eax,[ctn]
|
|
mov [ecx-5],eax
|
|
mov al,[cti]
|
|
mov [ecx-1],al
|
|
;--------------------------------------
|
|
@@:
|
|
mov eax,[outsize]
|
|
mov ecx,100
|
|
mul ecx
|
|
div [insize]
|
|
aam
|
|
xchg al,ah
|
|
add ax,'00'
|
|
mov [ratio],ax
|
|
mov esi,done_str
|
|
push done_len
|
|
pop ecx
|
|
call write_string
|
|
;--------------------------------------
|
|
; save output file
|
|
saveout:
|
|
mov esi,outname
|
|
call get_full_name
|
|
mov ebx,fn70block
|
|
mov [ebx],byte 2
|
|
mov eax,[outfilebest]
|
|
mov ecx,[outsize]
|
|
mov [ebx+12],ecx
|
|
mov [ebx+16],eax
|
|
mcall 70
|
|
test eax,eax
|
|
jz @f
|
|
;--------------------------------------
|
|
outerr:
|
|
mov esi,outfileerr_str
|
|
push outfileerr_len
|
|
pop ecx
|
|
jmp write_string
|
|
;---------------------------------------------------------------------
|
|
@@:
|
|
xor eax,eax
|
|
mov ebx,fn70block
|
|
mov [ebx],byte 6
|
|
mov [ebx+4],eax
|
|
mov [ebx+8],eax
|
|
mov [ebx+12],eax
|
|
mov [ebx+16],dword file_attr
|
|
mcall 70
|
|
|
|
call return_memory
|
|
ret
|
|
;---------------------------------------------------------------------
|
|
set_outfile:
|
|
mov eax,[outfilebest]
|
|
xor eax,[outfile1]
|
|
xor eax,[outfile2]
|
|
mov [outfile],eax
|
|
ret
|
|
;---------------------------------------------------------------------
|
|
pack_calltrick_fail:
|
|
xor eax,eax
|
|
mov [ctn],0
|
|
ret
|
|
;---------------------------------------------------------------------
|
|
preprocess_calltrick:
|
|
; input preprocessing
|
|
xor eax,eax
|
|
mov edi,ct1
|
|
mov ecx,256/4
|
|
push edi
|
|
rep stosd
|
|
pop edi
|
|
mov ecx,[insize]
|
|
mov esi,[infile]
|
|
xchg eax,edx
|
|
mov ebx,[inbuftmp]
|
|
;--------------------------------------
|
|
input_pre:
|
|
lodsb
|
|
sub al,0E8h
|
|
cmp al,1
|
|
ja input_pre_cont
|
|
|
|
cmp ecx,5
|
|
jb input_pre_done
|
|
|
|
lodsd
|
|
add eax,esi
|
|
sub eax,[infile]
|
|
cmp eax,[insize]
|
|
jae xxx
|
|
|
|
cmp eax,1000000h
|
|
jae xxx
|
|
|
|
sub ecx,4
|
|
; bswap is not supported on i386
|
|
xchg al,ah
|
|
ror eax,16
|
|
xchg al,ah
|
|
mov [esi-4],eax
|
|
inc edx
|
|
mov [ebx],esi
|
|
add ebx,4
|
|
jmp input_pre_cont
|
|
;---------------------------------------------------------------------
|
|
xxx:
|
|
sub esi,4
|
|
movzx eax,byte [esi]
|
|
mov [eax+edi],byte 1
|
|
;--------------------------------------
|
|
input_pre_cont:
|
|
loop input_pre
|
|
;--------------------------------------
|
|
input_pre_done:
|
|
mov [ctn],edx
|
|
xor eax,eax
|
|
mov ecx,256
|
|
repnz scasb
|
|
jnz pack_calltrick_fail
|
|
|
|
not cl
|
|
mov [cti],cl
|
|
@@:
|
|
cmp ebx,[inbuftmp]
|
|
jz @f
|
|
|
|
sub ebx,4
|
|
mov eax,[ebx]
|
|
mov [eax-4],cl
|
|
jmp @b
|
|
;---------------------------------------------------------------------
|
|
@@:
|
|
mov al,1
|
|
ret
|
|
;---------------------------------------------------------------------
|
|
pack_lzma:
|
|
mov eax,[outfile]
|
|
add eax,11
|
|
push [workmem] ;workmem
|
|
push [insize] ;length
|
|
push eax ;destination
|
|
push [infile] ;source
|
|
call lzma_compress
|
|
mov ecx,[outfile]
|
|
mov edx,[ecx+12]
|
|
xchg dl,dh
|
|
ror edx,16
|
|
xchg dl,dh
|
|
mov [ecx+12],edx
|
|
dec eax
|
|
ret
|
|
;---------------------------------------------------------------------
|
|
preprocess_calltrick2:
|
|
; restore input
|
|
mov esi,[infile]
|
|
mov ecx,[ctn]
|
|
jecxz pc2l2
|
|
;--------------------------------------
|
|
pc2l1:
|
|
lodsb
|
|
sub al,0E8h
|
|
cmp al,1
|
|
ja pc2l1
|
|
|
|
mov al,[cti]
|
|
cmp [esi],al
|
|
jnz pc2l1
|
|
|
|
lodsd
|
|
shr ax,8
|
|
ror eax,16
|
|
xchg al,ah
|
|
sub eax,esi
|
|
add eax,[infile]
|
|
mov [esi-4],eax
|
|
loop pc2l1
|
|
;--------------------------------------
|
|
pc2l2:
|
|
; input preprocessing
|
|
mov edi,ct1
|
|
xor eax,eax
|
|
push edi
|
|
mov ecx,256/4
|
|
rep stosd
|
|
pop edi
|
|
mov ecx,[insize]
|
|
mov esi,[infile]
|
|
mov ebx,[inbuftmp]
|
|
xchg eax,edx
|
|
;--------------------------------------
|
|
input_pre2:
|
|
lodsb
|
|
;--------------------------------------
|
|
@@:
|
|
cmp al,0Fh
|
|
jnz ip1
|
|
|
|
dec ecx
|
|
jz input_pre_done2
|
|
|
|
lodsb
|
|
cmp al,80h
|
|
jb @b
|
|
|
|
cmp al,90h
|
|
jb @f
|
|
;--------------------------------------
|
|
ip1:
|
|
sub al,0E8h
|
|
cmp al,1
|
|
ja input_pre_cont2
|
|
;--------------------------------------
|
|
@@:
|
|
cmp ecx,5
|
|
jb input_pre_done2
|
|
|
|
lodsd
|
|
add eax,esi
|
|
sub eax,[infile]
|
|
cmp eax,[insize]
|
|
jae xxx2
|
|
|
|
cmp eax,1000000h
|
|
jae xxx2
|
|
|
|
sub ecx,4
|
|
xchg al,ah
|
|
rol eax,16
|
|
xchg al,ah
|
|
mov [esi-4],eax
|
|
inc edx
|
|
mov [ebx],esi
|
|
add ebx,4
|
|
jmp input_pre_cont2
|
|
;---------------------------------------------------------------------
|
|
xxx2: sub esi,4
|
|
movzx eax,byte [esi]
|
|
mov [eax+edi],byte 1
|
|
;--------------------------------------
|
|
input_pre_cont2:
|
|
loop input_pre2
|
|
;--------------------------------------
|
|
input_pre_done2:
|
|
mov [ctn],edx
|
|
xor eax,eax
|
|
mov ecx,256
|
|
repnz scasb
|
|
jnz pack_calltrick_fail
|
|
|
|
not cl
|
|
mov [cti],cl
|
|
;--------------------------------------
|
|
@@:
|
|
cmp ebx,[inbuftmp]
|
|
jz @f
|
|
|
|
sub ebx,4
|
|
mov eax,[ebx]
|
|
mov [eax-4],cl
|
|
jmp @b
|
|
;---------------------------------------------------------------------
|
|
@@:
|
|
mov al,1
|
|
ret
|
|
;********************************************************************* |