* fix in library unloading of bug introduced in rev. 1289

* fix in malloc(): release mutex in rare control path


git-svn-id: svn://kolibrios.org@1292 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Evgeny Grechnikov (Diamond) 2009-11-28 11:46:46 +00:00
parent c81e27d3e4
commit 24e13906b7
2 changed files with 39 additions and 9 deletions

View File

@ -1310,7 +1310,7 @@ proc load_library stdcall, file_name:dword
mov [img_base], eax mov [img_base], eax
mov ebx, [CURRENT_TASK] mov ebx, [CURRENT_TASK]
shl ebx, 5 shl ebx, 5
add ebx, [CURRENT_TASK+ebx+TASKDATA.pid] mov ebx, [CURRENT_TASK+ebx+TASKDATA.pid]
mov eax, HDLL.sizeof mov eax, HDLL.sizeof
call create_kernel_object call create_kernel_object
test eax, eax test eax, eax
@ -1384,7 +1384,7 @@ dereference_dll:
mov edx, [esi+DLLDESCR.bk] mov edx, [esi+DLLDESCR.bk]
mov [eax+DLLDESCR.bk], edx mov [eax+DLLDESCR.bk], edx
mov [edx+DLLDESCR.fd], eax mov [edx+DLLDESCR.fd], eax
stdcall kernel_free, [esi+DLLDESCR.symbols_ptr] stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
stdcall kernel_free, [esi+DLLDESCR.data] stdcall kernel_free, [esi+DLLDESCR.data]
mov eax, esi mov eax, esi
call free call free
@ -1395,10 +1395,28 @@ destroy_hdll:
push ebx esi edi push ebx esi edi
push eax push eax
mov ebx, [eax+HDLL.base] mov ebx, [eax+HDLL.base]
push ebx ; argument for user_free
push eax
mov esi, [eax+HDLL.parent] mov esi, [eax+HDLL.parent]
mov edx, [esi+DLLDESCR.size] mov edx, [esi+DLLDESCR.size]
; The following actions require the context of application where HDLL is mapped.
; However, destroy_hdll can be called in the context of OS thread when
; cleaning up objects created by the application which is destroyed.
; So remember current cr3 and set it to page table of target.
mov eax, [eax+HDLL.pid]
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
; page table from APPDATA of current thread.
; Also set [current_slot] because it is used by user_free.
pushf
cli
push [current_slot]
mov [current_slot], eax
mov eax, cr3
push eax
mov cr3, ecx
push ebx ; argument for user_free
mov eax, ebx mov eax, ebx
shr ebx, 12 shr ebx, 12
push ebx push ebx
@ -1408,8 +1426,11 @@ destroy_hdll:
push eax push eax
mov eax, 2 mov eax, 2
xchg eax, [page_tabs+ebx*4] xchg eax, [page_tabs+ebx*4]
cmp eax, [page_tabs+esi*4] mov ecx, [page_tabs+esi*4]
jnz @f and eax, not 0xFFF
and ecx, not 0xFFF
cmp eax, ecx
jz @f
call free_page call free_page
@@: @@:
pop eax pop eax
@ -1419,12 +1440,20 @@ destroy_hdll:
inc esi inc esi
sub edx, 0x1000 sub edx, 0x1000
ja .unmap_loop ja .unmap_loop
pop ebx eax pop ebx
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
call user_free
; Restore context.
pop eax
mov cr3, eax
pop [current_slot]
popf
; Ok, cheating is done.
pop eax
push eax
mov esi, [eax+HDLL.parent] mov esi, [eax+HDLL.parent]
mov eax, [eax+HDLL.refcount] mov eax, [eax+HDLL.refcount]
call dereference_dll call dereference_dll
call user_free
pop eax pop eax
call destroy_kernel_object call destroy_kernel_object
pop edi esi ebx pop edi esi ebx

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -135,6 +135,7 @@ malloc:
mov [eax+12], ecx ; r->bk = B; mov [eax+12], ecx ; r->bk = B;
mov eax, ebx mov eax, ebx
pop esi pop esi
mov [mst.mutex], 0
ret ret
.small: .small: