forked from KolibriOS/kolibrios
dynamic libraries now share unmodified pages
git-svn-id: svn://kolibrios.org@1289 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
2beb55bd3a
commit
e463f78e27
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -513,6 +513,47 @@ virtual at 0
|
||||
SMAP SMAP
|
||||
end virtual
|
||||
|
||||
struc DLLDESCR
|
||||
{
|
||||
.bk dd ?
|
||||
.fd dd ? ;+4
|
||||
.data dd ? ;+8
|
||||
.size dd ? ;+12
|
||||
.timestamp dq ?
|
||||
.refcount dd ?
|
||||
.defaultbase dd ?
|
||||
.coff_hdr dd ?
|
||||
.symbols_ptr dd ?
|
||||
.symbols_num dd ?
|
||||
.symbols_lim dd ?
|
||||
.exports dd ? ;export table
|
||||
.name:
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
struc HDLL
|
||||
{
|
||||
.magic dd ? ; HDLL
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
.base dd ? ;mapped base
|
||||
.size dd ? ;mapped size
|
||||
.refcount dd ? ;reference counter for this process and this lib
|
||||
.parent dd ? ;DLLDESCR
|
||||
.sizeof:
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
DLLDESCR DLLDESCR
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
HDLL HDLL
|
||||
end virtual
|
||||
|
||||
struc display_t
|
||||
{
|
||||
.x dd ?
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -474,8 +474,8 @@ proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
|
||||
xor eax, eax
|
||||
ret
|
||||
.ok:
|
||||
mov ebx, [pSym]
|
||||
mov eax, [ebx+8]
|
||||
mov eax, [pSym]
|
||||
mov eax, [eax+8]
|
||||
ret
|
||||
endp
|
||||
|
||||
@ -681,7 +681,7 @@ proc get_proc_ex stdcall, proc_name:dword, imports:dword
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc fix_coff_symbols stdcall, sec:dword, symbols:dword,\
|
||||
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
|
||||
sym_count:dword, strings:dword, imports:dword
|
||||
locals
|
||||
retval dd ?
|
||||
@ -743,7 +743,8 @@ proc fix_coff_symbols stdcall, sec:dword, symbols:dword,\
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword
|
||||
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
|
||||
delta:dword
|
||||
locals
|
||||
n_sec dd ?
|
||||
endl
|
||||
@ -751,15 +752,15 @@ proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword
|
||||
mov eax, [coff]
|
||||
movzx ebx, [eax+CFH.nSections]
|
||||
mov [n_sec], ebx
|
||||
lea esi, [eax+20]
|
||||
.fix_sec:
|
||||
mov esi, [sec]
|
||||
mov edi, [esi+CFS.PtrReloc]
|
||||
add edi, [coff]
|
||||
|
||||
movzx ecx, [esi+CFS.NumReloc]
|
||||
test ecx, ecx
|
||||
jz .next
|
||||
.next_reloc:
|
||||
.reloc_loop:
|
||||
mov ebx, [edi+CRELOC.SymIndex]
|
||||
add ebx,ebx
|
||||
lea ebx,[ebx+ebx*8]
|
||||
@ -782,12 +783,51 @@ proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword
|
||||
mov eax, [edi+CRELOC.VirtualAddress]
|
||||
add eax, [esi+CFS.VirtualAddress]
|
||||
.fix:
|
||||
add eax, [delta]
|
||||
add [eax], edx
|
||||
.next_reloc:
|
||||
add edi, 10
|
||||
dec ecx
|
||||
jnz .next_reloc
|
||||
jnz .reloc_loop
|
||||
.next:
|
||||
add [sec], COFF_SECTION_SIZE
|
||||
add esi, COFF_SECTION_SIZE
|
||||
dec [n_sec]
|
||||
jnz .fix_sec
|
||||
.exit:
|
||||
ret
|
||||
endp
|
||||
|
||||
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
|
||||
delta:dword
|
||||
locals
|
||||
n_sec dd ?
|
||||
endl
|
||||
|
||||
mov eax, [coff]
|
||||
movzx ebx, [eax+CFH.nSections]
|
||||
mov [n_sec], ebx
|
||||
lea esi, [eax+20]
|
||||
mov edx, [delta]
|
||||
.fix_sec:
|
||||
mov edi, [esi+CFS.PtrReloc]
|
||||
add edi, [coff]
|
||||
|
||||
movzx ecx, [esi+CFS.NumReloc]
|
||||
test ecx, ecx
|
||||
jz .next
|
||||
.reloc_loop:
|
||||
cmp [edi+CRELOC.Type], 6
|
||||
jne .next_reloc
|
||||
.dir_32:
|
||||
mov eax, [edi+CRELOC.VirtualAddress]
|
||||
add eax, [esi+CFS.VirtualAddress]
|
||||
add [eax+edx], edx
|
||||
.next_reloc:
|
||||
add edi, 10
|
||||
dec ecx
|
||||
jnz .reloc_loop
|
||||
.next:
|
||||
add esi, COFF_SECTION_SIZE
|
||||
dec [n_sec]
|
||||
jnz .fix_sec
|
||||
.exit:
|
||||
@ -905,10 +945,8 @@ proc load_driver stdcall, driver_name:dword
|
||||
jz .link_fail
|
||||
|
||||
mov ebx, [coff]
|
||||
add ebx, 20
|
||||
stdcall fix_coff_relocs, [coff], ebx, [sym]
|
||||
stdcall fix_coff_relocs, ebx, [sym], 0
|
||||
|
||||
mov ebx, [coff]
|
||||
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion
|
||||
test eax, eax
|
||||
jz .link_fail
|
||||
@ -983,25 +1021,120 @@ endp
|
||||
align 4
|
||||
proc load_library stdcall, file_name:dword
|
||||
locals
|
||||
fullname rb 260
|
||||
fileinfo rb 40
|
||||
coff dd ?
|
||||
sym dd ?
|
||||
strings dd ?
|
||||
img_size dd ?
|
||||
img_base dd ?
|
||||
exports dd ?
|
||||
endl
|
||||
|
||||
cli
|
||||
|
||||
stdcall load_file, [file_name]
|
||||
test eax, eax
|
||||
; resolve file name
|
||||
mov ebx, [file_name]
|
||||
lea edi, [fullname+1]
|
||||
mov byte [edi-1], '/'
|
||||
stdcall get_full_file_name, edi, 259
|
||||
test al, al
|
||||
jz .fail
|
||||
|
||||
; scan for required DLL in list of already loaded for this process,
|
||||
; ignore timestamp
|
||||
mov esi, [CURRENT_TASK]
|
||||
shl esi, 8
|
||||
lea ebx, [esi+SLOT_BASE+APP_OBJ_OFFSET]
|
||||
mov esi, [ebx+APPOBJ.fd]
|
||||
lea edi, [fullname]
|
||||
.scan_in_process:
|
||||
cmp esi, ebx
|
||||
jz .not_in_process
|
||||
cmp dword [esi+APPOBJ.magic], 'HDLL'
|
||||
jnz .next_in_process
|
||||
mov eax, [esi+HDLL.parent]
|
||||
add eax, DLLDESCR.name
|
||||
stdcall strncmp, eax, edi, -1
|
||||
test eax, eax
|
||||
jnz .next_in_process
|
||||
; simple variant: load DLL which is already loaded in this process
|
||||
; just increment reference counters and return address of exports table
|
||||
inc [esi+HDLL.refcount]
|
||||
mov ecx, [esi+HDLL.parent]
|
||||
inc [ecx+DLLDESCR.refcount]
|
||||
mov eax, [ecx+DLLDESCR.exports]
|
||||
sub eax, [ecx+DLLDESCR.defaultbase]
|
||||
add eax, [esi+HDLL.base]
|
||||
ret
|
||||
.next_in_process:
|
||||
mov esi, [esi+APPOBJ.fd]
|
||||
jmp .scan_in_process
|
||||
.not_in_process:
|
||||
|
||||
; scan in full list, compare timestamp
|
||||
lea eax, [fileinfo]
|
||||
stdcall get_fileinfo, edi, eax
|
||||
test eax, eax
|
||||
jnz .fail
|
||||
mov esi, [dll_list.fd]
|
||||
.scan_for_dlls:
|
||||
cmp esi, dll_list
|
||||
jz .load_new
|
||||
lea eax, [esi+DLLDESCR.name]
|
||||
stdcall strncmp, eax, edi, -1
|
||||
test eax, eax
|
||||
jnz .continue_scan
|
||||
.test_prev_dll:
|
||||
mov eax, dword [fileinfo+24] ; last modified time
|
||||
mov edx, dword [fileinfo+28] ; last modified date
|
||||
cmp dword [esi+DLLDESCR.timestamp], eax
|
||||
jnz .continue_scan
|
||||
cmp dword [esi+DLLDESCR.timestamp+4], edx
|
||||
jz .dll_already_loaded
|
||||
.continue_scan:
|
||||
mov esi, [esi+DLLDESCR.fd]
|
||||
jmp .scan_for_dlls
|
||||
|
||||
; new DLL
|
||||
.load_new:
|
||||
; load file
|
||||
stdcall load_file, edi
|
||||
test eax, eax
|
||||
jz .fail
|
||||
mov [coff], eax
|
||||
movzx ecx, [eax+CFH.nSections]
|
||||
mov dword [fileinfo+32], ebx
|
||||
|
||||
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
|
||||
mov esi, edi
|
||||
mov ecx, -1
|
||||
xor eax, eax
|
||||
repnz scasb
|
||||
not ecx
|
||||
lea eax, [ecx+DLLDESCR.sizeof]
|
||||
push ecx
|
||||
call malloc
|
||||
pop ecx
|
||||
test eax, eax
|
||||
jz .fail_and_free_coff
|
||||
; save timestamp
|
||||
lea edi, [eax+DLLDESCR.name]
|
||||
rep movsb
|
||||
mov esi, eax
|
||||
mov eax, dword [fileinfo+24]
|
||||
mov dword [esi+DLLDESCR.timestamp], eax
|
||||
mov eax, dword [fileinfo+28]
|
||||
mov dword [esi+DLLDESCR.timestamp+4], eax
|
||||
; initialize DLLDESCR struct
|
||||
and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented
|
||||
mov [esi+DLLDESCR.fd], dll_list
|
||||
mov eax, [dll_list.bk]
|
||||
mov [dll_list.bk], esi
|
||||
mov [esi+DLLDESCR.bk], eax
|
||||
mov [eax+DLLDESCR.fd], esi
|
||||
|
||||
; calculate size of loaded DLL
|
||||
mov edx, [coff]
|
||||
movzx ecx, [edx+CFH.nSections]
|
||||
xor ebx, ebx
|
||||
|
||||
lea edx, [eax+20]
|
||||
add edx, 20
|
||||
@@:
|
||||
add ebx, [edx+CFS.SizeOfRawData]
|
||||
add ebx, 15
|
||||
@ -1009,85 +1142,294 @@ proc load_library stdcall, file_name:dword
|
||||
add edx, COFF_SECTION_SIZE
|
||||
dec ecx
|
||||
jnz @B
|
||||
mov [img_size], ebx
|
||||
|
||||
call init_heap
|
||||
stdcall user_alloc, [img_size]
|
||||
|
||||
; it must be nonzero and not too big
|
||||
mov [esi+DLLDESCR.size], ebx
|
||||
test ebx, ebx
|
||||
jz .fail_and_free_dll
|
||||
cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
|
||||
ja .fail_and_free_dll
|
||||
; allocate memory for kernel-side image
|
||||
stdcall kernel_alloc, ebx
|
||||
test eax, eax
|
||||
jz .fail
|
||||
mov [img_base], eax
|
||||
jz .fail_and_free_dll
|
||||
mov [esi+DLLDESCR.data], eax
|
||||
; calculate preferred base address
|
||||
add ebx, 0x1FFF
|
||||
and ebx, not 0xFFF
|
||||
mov ecx, [dll_cur_addr]
|
||||
lea edx, [ecx+ebx]
|
||||
cmp edx, MAX_DEFAULT_DLL_ADDR
|
||||
jb @f
|
||||
mov ecx, MIN_DEFAULT_DLL_ADDR
|
||||
lea edx, [ecx+ebx]
|
||||
@@:
|
||||
mov [esi+DLLDESCR.defaultbase], ecx
|
||||
mov [dll_cur_addr], edx
|
||||
|
||||
; copy sections and set correct values for VirtualAddress'es in headers
|
||||
push esi
|
||||
mov edx, [coff]
|
||||
movzx ebx, [edx+CFH.nSections]
|
||||
mov edi, [img_base]
|
||||
lea eax, [edx+20]
|
||||
mov edi, eax
|
||||
add edx, 20
|
||||
xor eax, eax
|
||||
cld
|
||||
@@:
|
||||
mov [eax+CFS.VirtualAddress], edi
|
||||
mov esi, [eax+CFS.PtrRawData]
|
||||
mov [edx+CFS.VirtualAddress], ecx
|
||||
add ecx, [edx+CFS.SizeOfRawData]
|
||||
mov esi, [edx+CFS.PtrRawData]
|
||||
push ecx
|
||||
mov ecx, [edx+CFS.SizeOfRawData]
|
||||
test esi, esi
|
||||
jnz .copy
|
||||
add edi, [eax+CFS.SizeOfRawData]
|
||||
rep stosb
|
||||
jmp .next
|
||||
.copy:
|
||||
add esi, edx
|
||||
mov ecx, [eax+CFS.SizeOfRawData]
|
||||
cld
|
||||
add esi, [coff]
|
||||
rep movsb
|
||||
.next:
|
||||
pop ecx
|
||||
add edi, 15 ;-new_app_base
|
||||
add ecx, 15
|
||||
and edi, -16
|
||||
add eax, COFF_SECTION_SIZE
|
||||
and ecx, -16
|
||||
add edx, COFF_SECTION_SIZE
|
||||
dec ebx
|
||||
jnz @B
|
||||
pop esi
|
||||
|
||||
; save some additional data from COFF file
|
||||
; later we will use COFF header, headers for sections and symbol table
|
||||
; and also relocations table for all sections
|
||||
mov edx, [coff]
|
||||
mov ebx, [edx+CFH.pSymTable]
|
||||
mov edi, dword [fileinfo+32]
|
||||
sub edi, ebx
|
||||
jc .fail_and_free_data
|
||||
mov [esi+DLLDESCR.symbols_lim], edi
|
||||
add ebx, edx
|
||||
mov [sym], ebx
|
||||
movzx ecx, [edx+CFH.nSections]
|
||||
lea ecx, [ecx*5]
|
||||
lea edi, [edi+ecx*8+20]
|
||||
add edx, 20
|
||||
@@:
|
||||
movzx eax, [edx+CFS.NumReloc]
|
||||
lea eax, [eax*5]
|
||||
lea edi, [edi+eax*2]
|
||||
add edx, COFF_SECTION_SIZE
|
||||
sub ecx, 5
|
||||
jnz @b
|
||||
stdcall kernel_alloc, edi
|
||||
test eax, eax
|
||||
jz .fail_and_free_data
|
||||
mov edx, [coff]
|
||||
movzx ecx, [edx+CFH.nSections]
|
||||
lea ecx, [ecx*5]
|
||||
lea ecx, [ecx*2+5]
|
||||
mov [esi+DLLDESCR.coff_hdr], eax
|
||||
push esi
|
||||
mov esi, edx
|
||||
mov edi, eax
|
||||
rep movsd
|
||||
pop esi
|
||||
mov [esi+DLLDESCR.symbols_ptr], edi
|
||||
push esi
|
||||
mov ecx, [edx+CFH.nSymbols]
|
||||
add ecx,ecx
|
||||
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
|
||||
add ecx, [sym]
|
||||
mov [strings], ecx
|
||||
mov [esi+DLLDESCR.symbols_num], ecx
|
||||
mov ecx, [esi+DLLDESCR.symbols_lim]
|
||||
mov esi, ebx
|
||||
rep movsb
|
||||
pop esi
|
||||
mov ebx, [esi+DLLDESCR.coff_hdr]
|
||||
push esi
|
||||
movzx eax, [edx+CFH.nSections]
|
||||
lea edx, [ebx+20]
|
||||
@@:
|
||||
movzx ecx, [edx+CFS.NumReloc]
|
||||
lea ecx, [ecx*5]
|
||||
mov esi, [edx+CFS.PtrReloc]
|
||||
mov [edx+CFS.PtrReloc], edi
|
||||
sub [edx+CFS.PtrReloc], ebx
|
||||
add esi, [coff]
|
||||
shr ecx, 1
|
||||
rep movsd
|
||||
adc ecx, ecx
|
||||
rep movsw
|
||||
add edx, COFF_SECTION_SIZE
|
||||
dec eax
|
||||
jnz @b
|
||||
pop esi
|
||||
|
||||
lea eax, [edx+20]
|
||||
; fixup symbols
|
||||
mov edx, ebx
|
||||
mov eax, [ebx+CFH.nSymbols]
|
||||
add edx, 20
|
||||
mov ecx, [esi+DLLDESCR.symbols_num]
|
||||
lea ecx, [ecx*9]
|
||||
add ecx, ecx
|
||||
add ecx, [esi+DLLDESCR.symbols_ptr]
|
||||
|
||||
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
|
||||
[strings], dword 0
|
||||
stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\
|
||||
ecx, 0
|
||||
; test eax, eax
|
||||
; jnz @F
|
||||
;
|
||||
;@@:
|
||||
|
||||
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS
|
||||
test eax, eax
|
||||
jnz @F
|
||||
|
||||
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS
|
||||
@@:
|
||||
mov edx, [coff]
|
||||
movzx ebx, [edx+CFH.nSections]
|
||||
mov edi, new_app_base
|
||||
lea eax, [edx+20]
|
||||
@@:
|
||||
add [eax+CFS.VirtualAddress], edi ;patch user space offset
|
||||
add eax, COFF_SECTION_SIZE
|
||||
dec ebx
|
||||
jnz @B
|
||||
mov [esi+DLLDESCR.exports], eax
|
||||
|
||||
add edx, 20
|
||||
stdcall fix_coff_relocs, [coff], edx, [sym]
|
||||
; fix relocs in the hidden copy in kernel memory to default address
|
||||
; it is first fix; usually this will be enough, but second fix
|
||||
; can be necessary if real load address will not equal assumption
|
||||
mov eax, [esi+DLLDESCR.data]
|
||||
sub eax, [esi+DLLDESCR.defaultbase]
|
||||
stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
|
||||
|
||||
mov ebx, [coff]
|
||||
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS
|
||||
test eax, eax
|
||||
jnz @F
|
||||
|
||||
mov ebx, [coff]
|
||||
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],sz_EXPORTS
|
||||
@@:
|
||||
mov [exports], eax
|
||||
stdcall kernel_free, [coff]
|
||||
mov eax, [exports]
|
||||
|
||||
.dll_already_loaded:
|
||||
inc [esi+DLLDESCR.refcount]
|
||||
push esi
|
||||
call init_heap
|
||||
pop esi
|
||||
|
||||
mov edi, [esi+DLLDESCR.size]
|
||||
stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
|
||||
test eax, eax
|
||||
jnz @f
|
||||
stdcall user_alloc, edi
|
||||
test eax, eax
|
||||
jz .fail_and_dereference
|
||||
@@:
|
||||
mov [img_base], eax
|
||||
mov ebx, [CURRENT_TASK]
|
||||
shl ebx, 5
|
||||
add ebx, [CURRENT_TASK+ebx+TASKDATA.pid]
|
||||
mov eax, HDLL.sizeof
|
||||
call create_kernel_object
|
||||
test eax, eax
|
||||
jz .fail_and_free_user
|
||||
mov [eax+APPOBJ.magic], 'HDLL'
|
||||
mov [eax+APPOBJ.destroy], destroy_hdll
|
||||
mov ebx, [img_base]
|
||||
mov [eax+HDLL.base], ebx
|
||||
mov [eax+HDLL.size], edi
|
||||
mov [eax+HDLL.refcount], 1
|
||||
mov [eax+HDLL.parent], esi
|
||||
mov edx, ebx
|
||||
shr edx, 12
|
||||
or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
|
||||
; copy entries of page table from kernel-side image to usermode
|
||||
; use copy-on-write for user-mode image, so map as readonly
|
||||
xor edi, edi
|
||||
mov ecx, [esi+DLLDESCR.data]
|
||||
shr ecx, 12
|
||||
.map_pages_loop:
|
||||
mov eax, [page_tabs+ecx*4]
|
||||
and eax, not 0xFFF
|
||||
or al, PG_USER
|
||||
xchg eax, [page_tabs+edx*4]
|
||||
test al, 1
|
||||
jz @f
|
||||
call free_page
|
||||
@@:
|
||||
invlpg [ebx+edi]
|
||||
inc ecx
|
||||
inc edx
|
||||
add edi, 0x1000
|
||||
cmp edi, [esi+DLLDESCR.size]
|
||||
jb .map_pages_loop
|
||||
|
||||
; if real user-mode base is not equal to preferred base, relocate image
|
||||
mov ebx, [img_base]
|
||||
sub ebx, [esi+DLLDESCR.defaultbase]
|
||||
jz @f
|
||||
stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
|
||||
@@:
|
||||
|
||||
mov eax, [esi+DLLDESCR.exports]
|
||||
sub eax, [esi+DLLDESCR.defaultbase]
|
||||
add eax, [img_base]
|
||||
ret
|
||||
.fail_and_free_data:
|
||||
stdcall kernel_free, [esi+DLLDESCR.data]
|
||||
.fail_and_free_dll:
|
||||
mov eax, esi
|
||||
call free
|
||||
.fail_and_free_coff:
|
||||
stdcall kernel_free, [coff]
|
||||
.fail:
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail_and_free_user:
|
||||
stdcall user_free, [img_base]
|
||||
.fail_and_dereference:
|
||||
mov eax, 1 ; delete 1 reference
|
||||
call dereference_dll
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
; in: eax = number of references to delete, esi -> DLLDESCR struc
|
||||
dereference_dll:
|
||||
sub [esi+DLLDESCR.refcount], eax
|
||||
jnz .ret
|
||||
mov eax, [esi+DLLDESCR.fd]
|
||||
mov edx, [esi+DLLDESCR.bk]
|
||||
mov [eax+DLLDESCR.bk], edx
|
||||
mov [edx+DLLDESCR.fd], eax
|
||||
stdcall kernel_free, [esi+DLLDESCR.symbols_ptr]
|
||||
stdcall kernel_free, [esi+DLLDESCR.data]
|
||||
mov eax, esi
|
||||
call free
|
||||
.ret:
|
||||
ret
|
||||
|
||||
destroy_hdll:
|
||||
push ebx esi edi
|
||||
push eax
|
||||
mov ebx, [eax+HDLL.base]
|
||||
push ebx ; argument for user_free
|
||||
push eax
|
||||
mov esi, [eax+HDLL.parent]
|
||||
mov edx, [esi+DLLDESCR.size]
|
||||
mov eax, ebx
|
||||
shr ebx, 12
|
||||
push ebx
|
||||
mov esi, [esi+DLLDESCR.data]
|
||||
shr esi, 12
|
||||
.unmap_loop:
|
||||
push eax
|
||||
mov eax, 2
|
||||
xchg eax, [page_tabs+ebx*4]
|
||||
cmp eax, [page_tabs+esi*4]
|
||||
jnz @f
|
||||
call free_page
|
||||
@@:
|
||||
pop eax
|
||||
invlpg [eax]
|
||||
add eax, 0x1000
|
||||
inc ebx
|
||||
inc esi
|
||||
sub edx, 0x1000
|
||||
ja .unmap_loop
|
||||
pop ebx eax
|
||||
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
|
||||
mov esi, [eax+HDLL.parent]
|
||||
mov eax, [eax+HDLL.refcount]
|
||||
call dereference_dll
|
||||
call user_free
|
||||
pop eax
|
||||
call destroy_kernel_object
|
||||
pop edi esi ebx
|
||||
ret
|
||||
|
||||
align 4
|
||||
stop_all_services:
|
||||
push ebp
|
||||
|
@ -13,7 +13,9 @@
|
||||
|
||||
$Revision$
|
||||
|
||||
|
||||
if 0
|
||||
; The code currently does not work. Kill "if 0/end if" only after correcting
|
||||
; to current kernel (dll.inc).
|
||||
macro library [name,fname]
|
||||
{
|
||||
forward
|
||||
@ -315,3 +317,4 @@ endp
|
||||
uglobal
|
||||
s_libname db 64 dup (0)
|
||||
endg
|
||||
end if
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -755,6 +755,102 @@ m_exit:
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc user_alloc_at stdcall, address:dword, alloc_size:dword
|
||||
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov ebx, [current_slot]
|
||||
mov edx, [address]
|
||||
and edx, not 0xFFF
|
||||
mov [address], edx
|
||||
sub edx, 0x1000
|
||||
jb .error
|
||||
mov esi, [ebx+APPDATA.heap_base]
|
||||
mov edi, [ebx+APPDATA.heap_top]
|
||||
cmp edx, esi
|
||||
jb .error
|
||||
.scan:
|
||||
cmp esi, edi
|
||||
jae .error
|
||||
mov ebx, esi
|
||||
shr ebx, 12
|
||||
mov eax, [page_tabs+ebx*4]
|
||||
mov ecx, eax
|
||||
and ecx, 0xFFFFF000
|
||||
add ecx, esi
|
||||
cmp edx, ecx
|
||||
jb .found
|
||||
mov esi, ecx
|
||||
jmp .scan
|
||||
.error:
|
||||
xor eax, eax
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
.found:
|
||||
test al, FREE_BLOCK
|
||||
jz .error
|
||||
mov eax, ecx
|
||||
sub eax, edx
|
||||
sub eax, 0x1000
|
||||
cmp eax, [alloc_size]
|
||||
jb .error
|
||||
|
||||
; Here we have 1 big free block which includes requested area.
|
||||
; In general, 3 other blocks must be created instead:
|
||||
; free at [esi, edx);
|
||||
; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000));
|
||||
; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx)
|
||||
; First or third block (or both) may be absent.
|
||||
mov eax, edx
|
||||
sub eax, esi
|
||||
jz .nofirst
|
||||
or al, FREE_BLOCK
|
||||
mov [page_tabs+ebx*4], eax
|
||||
.nofirst:
|
||||
mov eax, [alloc_size]
|
||||
add eax, 0x1FFF
|
||||
and eax, not 0xFFF
|
||||
mov ebx, edx
|
||||
add edx, eax
|
||||
shr ebx, 12
|
||||
or al, USED_BLOCK
|
||||
mov [page_tabs+ebx*4], eax
|
||||
shr eax, 12
|
||||
dec eax
|
||||
jz .second_nofill
|
||||
inc ebx
|
||||
.fill:
|
||||
mov dword [page_tabs+ebx*4], 2
|
||||
inc ebx
|
||||
dec eax
|
||||
jnz .fill
|
||||
.second_nofill:
|
||||
sub ecx, edx
|
||||
jz .nothird
|
||||
or cl, FREE_BLOCK
|
||||
mov [page_tabs+ebx*4], ecx
|
||||
.nothird:
|
||||
|
||||
mov edx, [current_slot]
|
||||
mov ebx, [alloc_size]
|
||||
add ebx, 0xFFF
|
||||
and ebx, not 0xFFF
|
||||
add ebx, [edx+APPDATA.mem_size]
|
||||
call update_mem_size
|
||||
|
||||
mov eax, [address]
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
proc user_free stdcall, base:dword
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -614,7 +614,7 @@ end if
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
stdcall map_page,[.err_addr],eax,dword PG_UW
|
||||
stdcall map_page,[.err_addr],eax,PG_UW
|
||||
|
||||
mov edi, [.err_addr]
|
||||
and edi, 0xFFFFF000
|
||||
@ -627,9 +627,40 @@ end if
|
||||
restore_ring3_context
|
||||
iretd
|
||||
|
||||
.err_access = .fail
|
||||
;íèêîãäà íå ïðîèñõîäèò
|
||||
;jmp .fail
|
||||
.err_access:
|
||||
; access denied? this may be a result of copy-on-write protection for DLL
|
||||
; check list of HDLLs
|
||||
and ebx, not 0xFFF
|
||||
mov eax, [CURRENT_TASK]
|
||||
shl eax, 8
|
||||
lea eax, [SLOT_BASE+eax+APP_OBJ_OFFSET]
|
||||
mov esi, [eax+APPOBJ.fd]
|
||||
.scan_hdll:
|
||||
cmp esi, eax
|
||||
jz .fail
|
||||
cmp [esi+APPOBJ.magic], 'HDLL'
|
||||
jnz .scan_hdll.next
|
||||
mov edx, ebx
|
||||
sub edx, [esi+HDLL.base]
|
||||
cmp edx, [esi+HDLL.size]
|
||||
jb .fault_in_hdll
|
||||
.scan_hdll.next:
|
||||
mov esi, [esi+APPOBJ.fd]
|
||||
jmp .scan_hdll
|
||||
.fault_in_hdll:
|
||||
; allocate new page, map it as rw and copy data
|
||||
call alloc_page
|
||||
test eax, eax
|
||||
jz .fail
|
||||
stdcall map_page,ebx,eax,PG_UW
|
||||
mov edi, ebx
|
||||
mov ecx, 1024
|
||||
sub ebx, [esi+HDLL.base]
|
||||
mov esi, [esi+HDLL.parent]
|
||||
mov esi, [esi+DLLDESCR.data]
|
||||
add esi, ebx
|
||||
rep movsd
|
||||
jmp .exit
|
||||
|
||||
.kernel_space:
|
||||
test eax, PG_MAP
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -119,6 +119,14 @@ shmem_list:
|
||||
.bk dd shmem_list
|
||||
.fd dd shmem_list
|
||||
|
||||
dll_list:
|
||||
.bk dd dll_list
|
||||
.fd dd dll_list
|
||||
|
||||
MAX_DEFAULT_DLL_ADDR = 0x20000000
|
||||
MIN_DEFAULT_DLL_ADDR = 0x10000000
|
||||
dll_cur_addr dd MIN_DEFAULT_DLL_ADDR
|
||||
|
||||
; supported videomodes
|
||||
|
||||
;mode_1280_1024_32:
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@ -1004,6 +1004,19 @@ sys_current_directory:
|
||||
.set:
|
||||
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
|
||||
; for our code: ebx->string to set
|
||||
; use generic resolver with APPDATA.cur_dir as destination
|
||||
push 0x1000
|
||||
push edx
|
||||
call get_full_file_name
|
||||
ret
|
||||
|
||||
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
|
||||
; destroys all registers except ebp,esp
|
||||
get_full_file_name:
|
||||
push ebp
|
||||
mov esi, [current_slot]
|
||||
mov esi, [esi+APPDATA.cur_dir]
|
||||
mov edx, esi
|
||||
@@:
|
||||
inc esi
|
||||
cmp byte [esi-1], 0
|
||||
@ -1012,6 +1025,7 @@ sys_current_directory:
|
||||
cmp byte [ebx], '/'
|
||||
jz .set_absolute
|
||||
; string gives relative path
|
||||
mov edi, [esp+8] ; destination
|
||||
.relative:
|
||||
cmp byte [ebx], 0
|
||||
jz .set_ok
|
||||
@ -1032,33 +1046,67 @@ sys_current_directory:
|
||||
dec esi
|
||||
cmp byte [esi], '/'
|
||||
jnz @b
|
||||
mov byte [esi], 0
|
||||
add ebx, 3
|
||||
jmp .relative
|
||||
.set_ok:
|
||||
cmp edx, edi ; is destination equal to APPDATA.cur_dir?
|
||||
jz .set_ok.cur_dir
|
||||
sub esi, edx
|
||||
cmp esi, [esp+12]
|
||||
jb .set_ok.copy
|
||||
.fail:
|
||||
mov byte [edi], 0
|
||||
xor eax, eax ; fail
|
||||
pop ebp
|
||||
ret 8
|
||||
.set_ok.copy:
|
||||
mov ecx, esi
|
||||
mov esi, edx
|
||||
rep movsb
|
||||
mov byte [edi], 0
|
||||
.ret.ok:
|
||||
mov al, 1 ; ok
|
||||
pop ebp
|
||||
ret 8
|
||||
.set_ok.cur_dir:
|
||||
mov byte [esi], 0
|
||||
jmp .ret.ok
|
||||
.doset_relative:
|
||||
add edx, 0x1000
|
||||
mov byte [esi], '/'
|
||||
inc esi
|
||||
cmp esi, edx
|
||||
jae .overflow_esi
|
||||
cmp edx, edi
|
||||
jz .doset_relative.cur_dir
|
||||
sub esi, edx
|
||||
cmp esi, [esp+12]
|
||||
jae .fail
|
||||
mov ecx, esi
|
||||
mov esi, edx
|
||||
mov edx, edi
|
||||
rep movsb
|
||||
jmp .doset_relative.copy
|
||||
.doset_relative.cur_dir:
|
||||
mov edi, esi
|
||||
.doset_relative.copy:
|
||||
add edx, [esp+12]
|
||||
mov byte [edi], '/'
|
||||
inc edi
|
||||
cmp edi, edx
|
||||
jae .overflow
|
||||
@@:
|
||||
mov al, [ebx]
|
||||
inc ebx
|
||||
mov [esi], al
|
||||
inc esi
|
||||
stosb
|
||||
test al, al
|
||||
jz .set_ok
|
||||
cmp esi, edx
|
||||
jz .ret.ok
|
||||
cmp edi, edx
|
||||
jb @b
|
||||
.overflow_esi:
|
||||
mov byte [esi-1], 0 ; force null-terminated string
|
||||
.set_ok:
|
||||
ret
|
||||
.overflow:
|
||||
dec edi
|
||||
jmp .fail
|
||||
.set_absolute:
|
||||
lea esi, [ebx+1]
|
||||
call process_replace_file_name
|
||||
mov edi, edx
|
||||
add edx, 0x1000
|
||||
mov edi, [esp+8]
|
||||
mov edx, [esp+12]
|
||||
add edx, edi
|
||||
.set_copy:
|
||||
lodsb
|
||||
stosb
|
||||
@ -1067,13 +1115,11 @@ sys_current_directory:
|
||||
.set_copy_cont:
|
||||
cmp edi, edx
|
||||
jb .set_copy
|
||||
.overflow_edi:
|
||||
mov byte [edi-1], 0
|
||||
ret
|
||||
jmp .overflow
|
||||
.set_part2:
|
||||
mov esi, ebp
|
||||
xor ebp, ebp
|
||||
test esi, esi
|
||||
jz .set_ok
|
||||
jz .ret.ok
|
||||
mov byte [edi-1], '/'
|
||||
jmp .set_copy_cont
|
||||
|
@ -613,6 +613,7 @@ include 'boot/rdload.inc'
|
||||
include 'vmodeld.inc'
|
||||
;!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
if 0
|
||||
mov ax,[OS_BASE+0x10000+bx_from_load]
|
||||
cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba}
|
||||
je no_lib_load
|
||||
@ -621,6 +622,7 @@ include 'vmodeld.inc'
|
||||
call load_file_parse_table ; prepare file parse table
|
||||
call set_kernel_conf ; configure devices and gui
|
||||
no_lib_load:
|
||||
end if
|
||||
|
||||
; LOAD FONTS I and II
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user