forked from KolibriOS/kolibrios
make dll a per-process object
git-svn-id: svn://kolibrios.org@1311 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
6b29296f2c
commit
af8dc3b80a
@ -531,8 +531,6 @@ struc DLLDESCR
|
|||||||
|
|
||||||
struc HDLL
|
struc HDLL
|
||||||
{
|
{
|
||||||
.magic dd ? ; HDLL
|
|
||||||
.destroy dd ? ;internal destructor
|
|
||||||
.fd dd ? ;next object in list
|
.fd dd ? ;next object in list
|
||||||
.bk dd ? ;prev object in list
|
.bk dd ? ;prev object in list
|
||||||
.pid dd ? ;owner id
|
.pid dd ? ;owner id
|
||||||
|
@ -1064,14 +1064,14 @@ proc load_library stdcall, file_name:dword
|
|||||||
; ignore timestamp
|
; ignore timestamp
|
||||||
mov esi, [CURRENT_TASK]
|
mov esi, [CURRENT_TASK]
|
||||||
shl esi, 8
|
shl esi, 8
|
||||||
lea ebx, [esi+SLOT_BASE+APP_OBJ_OFFSET]
|
|
||||||
mov esi, [ebx+APPOBJ.fd]
|
|
||||||
lea edi, [fullname]
|
lea edi, [fullname]
|
||||||
|
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
|
||||||
|
test ebx, ebx
|
||||||
|
jz .not_in_process
|
||||||
|
mov esi, [ebx+HDLL.fd]
|
||||||
.scan_in_process:
|
.scan_in_process:
|
||||||
cmp esi, ebx
|
cmp esi, ebx
|
||||||
jz .not_in_process
|
jz .not_in_process
|
||||||
cmp dword [esi+APPOBJ.magic], 'HDLL'
|
|
||||||
jnz .next_in_process
|
|
||||||
mov eax, [esi+HDLL.parent]
|
mov eax, [esi+HDLL.parent]
|
||||||
add eax, DLLDESCR.name
|
add eax, DLLDESCR.name
|
||||||
stdcall strncmp, eax, edi, -1
|
stdcall strncmp, eax, edi, -1
|
||||||
@ -1087,7 +1087,7 @@ proc load_library stdcall, file_name:dword
|
|||||||
add eax, [esi+HDLL.base]
|
add eax, [esi+HDLL.base]
|
||||||
ret
|
ret
|
||||||
.next_in_process:
|
.next_in_process:
|
||||||
mov esi, [esi+APPOBJ.fd]
|
mov esi, [esi+HDLL.fd]
|
||||||
jmp .scan_in_process
|
jmp .scan_in_process
|
||||||
.not_in_process:
|
.not_in_process:
|
||||||
|
|
||||||
@ -1335,15 +1335,25 @@ proc load_library stdcall, file_name:dword
|
|||||||
jz .fail_and_dereference
|
jz .fail_and_dereference
|
||||||
@@:
|
@@:
|
||||||
mov [img_base], eax
|
mov [img_base], eax
|
||||||
mov ebx, [CURRENT_TASK]
|
|
||||||
shl ebx, 5
|
|
||||||
mov ebx, [CURRENT_TASK+ebx+TASKDATA.pid]
|
|
||||||
mov eax, HDLL.sizeof
|
mov eax, HDLL.sizeof
|
||||||
call create_kernel_object
|
call malloc
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .fail_and_free_user
|
jz .fail_and_free_user
|
||||||
mov [eax+APPOBJ.magic], 'HDLL'
|
mov ebx, [CURRENT_TASK]
|
||||||
mov [eax+APPOBJ.destroy], destroy_hdll
|
shl ebx, 5
|
||||||
|
mov edx, [CURRENT_TASK+ebx+TASKDATA.pid]
|
||||||
|
mov [eax+HDLL.pid], edx
|
||||||
|
push eax
|
||||||
|
call init_dlls_in_thread
|
||||||
|
pop ebx
|
||||||
|
test eax, eax
|
||||||
|
jz .fail_and_free_user
|
||||||
|
mov edx, [eax+HDLL.fd]
|
||||||
|
mov [ebx+HDLL.fd], edx
|
||||||
|
mov [ebx+HDLL.bk], eax
|
||||||
|
mov [eax+HDLL.fd], ebx
|
||||||
|
mov [edx+HDLL.bk], ebx
|
||||||
|
mov eax, ebx
|
||||||
mov ebx, [img_base]
|
mov ebx, [img_base]
|
||||||
mov [eax+HDLL.base], ebx
|
mov [eax+HDLL.base], ebx
|
||||||
mov [eax+HDLL.size], edi
|
mov [eax+HDLL.size], edi
|
||||||
@ -1374,7 +1384,6 @@ proc load_library stdcall, file_name:dword
|
|||||||
jb .map_pages_loop
|
jb .map_pages_loop
|
||||||
|
|
||||||
; if real user-mode base is not equal to preferred base, relocate image
|
; if real user-mode base is not equal to preferred base, relocate image
|
||||||
mov ebx, [img_base]
|
|
||||||
sub ebx, [esi+DLLDESCR.defaultbase]
|
sub ebx, [esi+DLLDESCR.defaultbase]
|
||||||
jz @f
|
jz @f
|
||||||
stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
|
stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
|
||||||
@ -1403,6 +1412,37 @@ proc load_library stdcall, file_name:dword
|
|||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
; initialize [APPDATA.dlls_list_ptr] for given thread
|
||||||
|
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
|
||||||
|
; kept in sync for all threads of one process.
|
||||||
|
; out: eax = APPDATA.dlls_list_ptr if all is OK,
|
||||||
|
; NULL if memory allocation failed
|
||||||
|
init_dlls_in_thread:
|
||||||
|
mov ebx, [current_slot]
|
||||||
|
mov eax, [ebx+APPDATA.dlls_list_ptr]
|
||||||
|
test eax, eax
|
||||||
|
jnz .ret
|
||||||
|
push [ebx+APPDATA.dir_table]
|
||||||
|
mov eax, 8
|
||||||
|
call malloc
|
||||||
|
pop edx
|
||||||
|
test eax, eax
|
||||||
|
jz .ret
|
||||||
|
mov [eax], eax
|
||||||
|
mov [eax+4], eax
|
||||||
|
mov ecx, [TASK_COUNT]
|
||||||
|
mov ebx, SLOT_BASE+256
|
||||||
|
.set:
|
||||||
|
cmp [ebx+APPDATA.dir_table], edx
|
||||||
|
jnz @f
|
||||||
|
mov [ebx+APPDATA.dlls_list_ptr], eax
|
||||||
|
@@:
|
||||||
|
add ebx, 256
|
||||||
|
dec ecx
|
||||||
|
jnz .set
|
||||||
|
.ret:
|
||||||
|
ret
|
||||||
|
|
||||||
; in: eax = number of references to delete, esi -> DLLDESCR struc
|
; in: eax = number of references to delete, esi -> DLLDESCR struc
|
||||||
dereference_dll:
|
dereference_dll:
|
||||||
sub [esi+DLLDESCR.refcount], eax
|
sub [esi+DLLDESCR.refcount], eax
|
||||||
@ -1419,7 +1459,7 @@ dereference_dll:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
destroy_hdll:
|
destroy_hdll:
|
||||||
push ebx esi edi
|
push ebx ecx esi edi
|
||||||
push eax
|
push eax
|
||||||
mov ebx, [eax+HDLL.base]
|
mov ebx, [eax+HDLL.base]
|
||||||
mov esi, [eax+HDLL.parent]
|
mov esi, [eax+HDLL.parent]
|
||||||
@ -1428,21 +1468,17 @@ destroy_hdll:
|
|||||||
; However, destroy_hdll can be called in the context of OS thread when
|
; However, destroy_hdll can be called in the context of OS thread when
|
||||||
; cleaning up objects created by the application which is destroyed.
|
; cleaning up objects created by the application which is destroyed.
|
||||||
; So remember current cr3 and set it to page table of target.
|
; So remember current cr3 and set it to page table of target.
|
||||||
mov eax, [eax+HDLL.pid]
|
mov eax, [ecx+APPDATA.dir_table]
|
||||||
call pid_to_slot
|
|
||||||
shl eax, 8
|
|
||||||
add eax, SLOT_BASE
|
|
||||||
mov ecx, [eax+APPDATA.dir_table]
|
|
||||||
; Because we cheat with cr3, disable interrupts: task switch would restore
|
; Because we cheat with cr3, disable interrupts: task switch would restore
|
||||||
; page table from APPDATA of current thread.
|
; page table from APPDATA of current thread.
|
||||||
; Also set [current_slot] because it is used by user_free.
|
; Also set [current_slot] because it is used by user_free.
|
||||||
pushf
|
pushf
|
||||||
cli
|
cli
|
||||||
push [current_slot]
|
push [current_slot]
|
||||||
mov [current_slot], eax
|
mov [current_slot], ecx
|
||||||
mov eax, cr3
|
mov ecx, cr3
|
||||||
push eax
|
push ecx
|
||||||
mov cr3, ecx
|
mov cr3, eax
|
||||||
push ebx ; argument for user_free
|
push ebx ; argument for user_free
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
shr ebx, 12
|
shr ebx, 12
|
||||||
@ -1482,8 +1518,25 @@ destroy_hdll:
|
|||||||
mov eax, [eax+HDLL.refcount]
|
mov eax, [eax+HDLL.refcount]
|
||||||
call dereference_dll
|
call dereference_dll
|
||||||
pop eax
|
pop eax
|
||||||
call destroy_kernel_object
|
mov edx, [eax+HDLL.bk]
|
||||||
pop edi esi ebx
|
mov ebx, [eax+HDLL.fd]
|
||||||
|
mov [ebx+HDLL.bk], edx
|
||||||
|
mov [edx+HDLL.fd], ebx
|
||||||
|
call free
|
||||||
|
pop edi esi ecx ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ecx -> APPDATA for slot, esi = dlls_list_ptr
|
||||||
|
destroy_all_hdlls:
|
||||||
|
test esi, esi
|
||||||
|
jz .ret
|
||||||
|
.loop:
|
||||||
|
mov eax, [esi+HDLL.fd]
|
||||||
|
cmp eax, esi
|
||||||
|
jz free
|
||||||
|
call destroy_hdll
|
||||||
|
jmp .loop
|
||||||
|
.ret:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
|
@ -639,19 +639,19 @@ end if
|
|||||||
and ebx, not 0xFFF
|
and ebx, not 0xFFF
|
||||||
mov eax, [CURRENT_TASK]
|
mov eax, [CURRENT_TASK]
|
||||||
shl eax, 8
|
shl eax, 8
|
||||||
lea eax, [SLOT_BASE+eax+APP_OBJ_OFFSET]
|
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
|
||||||
mov esi, [eax+APPOBJ.fd]
|
test eax, eax
|
||||||
|
jz .fail
|
||||||
|
mov esi, [eax+HDLL.fd]
|
||||||
.scan_hdll:
|
.scan_hdll:
|
||||||
cmp esi, eax
|
cmp esi, eax
|
||||||
jz .fail
|
jz .fail
|
||||||
cmp [esi+APPOBJ.magic], 'HDLL'
|
|
||||||
jnz .scan_hdll.next
|
|
||||||
mov edx, ebx
|
mov edx, ebx
|
||||||
sub edx, [esi+HDLL.base]
|
sub edx, [esi+HDLL.base]
|
||||||
cmp edx, [esi+HDLL.size]
|
cmp edx, [esi+HDLL.size]
|
||||||
jb .fault_in_hdll
|
jb .fault_in_hdll
|
||||||
.scan_hdll.next:
|
.scan_hdll.next:
|
||||||
mov esi, [esi+APPOBJ.fd]
|
mov esi, [esi+HDLL.fd]
|
||||||
jmp .scan_hdll
|
jmp .scan_hdll
|
||||||
.fault_in_hdll:
|
.fault_in_hdll:
|
||||||
; allocate new page, map it as rw and copy data
|
; allocate new page, map it as rw and copy data
|
||||||
|
@ -508,10 +508,10 @@ term9:
|
|||||||
pop esi
|
pop esi
|
||||||
jmp @B
|
jmp @B
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
mov eax, [.slot]
|
mov eax, [.slot]
|
||||||
shl eax, 8
|
shl eax, 8
|
||||||
mov eax,[SLOT_BASE+eax+APPDATA.dir_table]
|
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
|
||||||
stdcall destroy_app_space, eax
|
|
||||||
|
|
||||||
mov esi, [.slot]
|
mov esi, [.slot]
|
||||||
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
|
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
|
||||||
|
@ -486,7 +486,7 @@ end if
|
|||||||
dec [pg_data.pg_mutex]
|
dec [pg_data.pg_mutex]
|
||||||
cmp [dir_addr], 0
|
cmp [dir_addr], 0
|
||||||
je @f
|
je @f
|
||||||
stdcall destroy_app_space, [dir_addr]
|
stdcall destroy_app_space, [dir_addr], 0
|
||||||
@@:
|
@@:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
@ -523,12 +523,10 @@ proc destroy_page_table stdcall, pg_tab:dword
|
|||||||
endp
|
endp
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
proc destroy_app_space stdcall, pg_dir:dword
|
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
|
||||||
|
|
||||||
mov ebx, pg_data.pg_mutex
|
|
||||||
call wait_mutex ;ebx
|
|
||||||
|
|
||||||
xor edx,edx
|
xor edx,edx
|
||||||
|
push edx
|
||||||
mov eax,0x2
|
mov eax,0x2
|
||||||
mov ebx, [pg_dir]
|
mov ebx, [pg_dir]
|
||||||
.loop:
|
.loop:
|
||||||
@ -538,8 +536,10 @@ proc destroy_app_space stdcall, pg_dir:dword
|
|||||||
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
|
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
|
||||||
jz @f ;skip empty slots
|
jz @f ;skip empty slots
|
||||||
shl ecx,3
|
shl ecx,3
|
||||||
cmp [SLOT_BASE+ecx+0xB8],ebx ;compare page directory addresses
|
add ecx,SLOT_BASE
|
||||||
|
cmp [ecx+APPDATA.dir_table],ebx ;compare page directory addresses
|
||||||
jnz @f
|
jnz @f
|
||||||
|
mov [ebp-4],ecx
|
||||||
inc edx ;thread found
|
inc edx ;thread found
|
||||||
@@:
|
@@:
|
||||||
inc eax
|
inc eax
|
||||||
@ -548,13 +548,19 @@ proc destroy_app_space stdcall, pg_dir:dword
|
|||||||
|
|
||||||
;edx = number of threads
|
;edx = number of threads
|
||||||
;our process is zombi so it isn't counted
|
;our process is zombi so it isn't counted
|
||||||
|
pop ecx
|
||||||
cmp edx,1
|
cmp edx,1
|
||||||
jg .exit
|
jg .ret
|
||||||
;if there isn't threads then clear memory.
|
;if there isn't threads then clear memory.
|
||||||
|
mov esi, [dlls_list]
|
||||||
|
call destroy_all_hdlls
|
||||||
|
|
||||||
|
mov ebx, pg_data.pg_mutex
|
||||||
|
call wait_mutex ;ebx
|
||||||
|
|
||||||
mov eax, [pg_dir]
|
mov eax, [pg_dir]
|
||||||
and eax, not 0xFFF
|
and eax, not 0xFFF
|
||||||
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
|
stdcall map_page,[tmp_task_pdir],eax,PG_SW
|
||||||
mov esi, [tmp_task_pdir]
|
mov esi, [tmp_task_pdir]
|
||||||
mov edi, (OS_BASE shr 20)/4
|
mov edi, (OS_BASE shr 20)/4
|
||||||
.destroy:
|
.destroy:
|
||||||
@ -562,7 +568,7 @@ proc destroy_app_space stdcall, pg_dir:dword
|
|||||||
test eax, 1
|
test eax, 1
|
||||||
jz .next
|
jz .next
|
||||||
and eax, not 0xFFF
|
and eax, not 0xFFF
|
||||||
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW
|
stdcall map_page,[tmp_task_ptab],eax,PG_SW
|
||||||
stdcall destroy_page_table, [tmp_task_ptab]
|
stdcall destroy_page_table, [tmp_task_ptab]
|
||||||
mov eax, [esi]
|
mov eax, [esi]
|
||||||
call free_page
|
call free_page
|
||||||
@ -574,9 +580,10 @@ proc destroy_app_space stdcall, pg_dir:dword
|
|||||||
mov eax, [pg_dir]
|
mov eax, [pg_dir]
|
||||||
call free_page
|
call free_page
|
||||||
.exit:
|
.exit:
|
||||||
stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP
|
stdcall map_page,[tmp_task_ptab],0,PG_UNMAP
|
||||||
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
|
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP
|
||||||
dec [pg_data.pg_mutex]
|
dec [pg_data.pg_mutex]
|
||||||
|
.ret:
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
@ -908,6 +915,9 @@ proc new_sys_threads
|
|||||||
mov ecx,[ebx+APPDATA.dir_table]
|
mov ecx,[ebx+APPDATA.dir_table]
|
||||||
mov [edx+APPDATA.dir_table],ecx ;copy page directory
|
mov [edx+APPDATA.dir_table],ecx ;copy page directory
|
||||||
|
|
||||||
|
mov eax,[ebx+APPDATA.dlls_list_ptr]
|
||||||
|
mov [edx+APPDATA.dlls_list_ptr],eax
|
||||||
|
|
||||||
mov eax, [ebx+APPDATA.tls_base]
|
mov eax, [ebx+APPDATA.tls_base]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz @F
|
jz @F
|
||||||
|
@ -142,7 +142,8 @@ struc APPDATA
|
|||||||
.wait_test dd ? ;+96 +++
|
.wait_test dd ? ;+96 +++
|
||||||
.wait_param dd ? ;+100 +++
|
.wait_param dd ? ;+100 +++
|
||||||
.tls_base dd ? ;+104
|
.tls_base dd ? ;+104
|
||||||
db 20 dup(?) ;+108
|
.dlls_list_ptr dd ? ;+108
|
||||||
|
db 16 dup(?) ;+112
|
||||||
|
|
||||||
.wnd_shape dd ? ;+128
|
.wnd_shape dd ? ;+128
|
||||||
.wnd_shape_scale dd ? ;+132
|
.wnd_shape_scale dd ? ;+132
|
||||||
|
Loading…
Reference in New Issue
Block a user