libs/dll: add dll_LoadLibrary for single library loading (fix #281) (#370)

Resolves #281

This PR adds a new `dll_LoadLibrary` function to `dll.obj` that loads a single library by name or full path, auto-calls `lib_init`, and returns the export table pointer.

`dll_load` is refactored on top of `dll_LoadLibrary`.

---------

Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: #370
Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com>
Reviewed-by: Burer <burer@kolibrios.org>
Co-authored-by: hrigar <h4gar02@protonmail.com>
Co-committed-by: hrigar <h4gar02@protonmail.com>
This commit was merged in pull request #370.
This commit is contained in:
2026-05-04 19:03:47 +00:00
committed by Burer
parent 27c1f44930
commit e7698cbfb6
3 changed files with 86 additions and 64 deletions
+2 -2
View File
@@ -170,8 +170,8 @@ dd APP_STARTUP_THUNK
export \
dll.Load, 'dll_load', \
dll.Link, 'dll_link', \
dll.GetProcAddress, 'dll_sym'
dll.GetProcAddress, 'dll_sym', \
dll.LoadLibrary, 'dll_loadlib'
pNotify:
dd 7, 0
+43 -36
View File
@@ -15,9 +15,9 @@ ERROR_ENTRY_NOT_FOUND = 0x101
;-----------------------------------------------------------------------------
; load one or more DLL file in COFF format and try to import functions by our list
; if first function in import list begins with 'lib_', call it as DLL initialization
; return eax = 1 as fail, if anyone of .obj file not found in /sys/lib
; return 0 if all fine or error code LIBRARY_NOT_LOAD or ENTRY_NOT_FOUND
; load each library via dll.LoadLibrary, then resolve imports via dll.Link
; return 0 if all fine, ERROR_LIBRARY_NOT_LOAD if .obj file not found,
; or ERROR_ENTRY_NOT_FOUND if import symbol not resolved
; dirties all registers! eax, ebx, ecx, edx, esi, edi
proc dll.Load, import_table:dword
mov esi, [import_table]
@@ -26,36 +26,14 @@ proc dll.Load, import_table:dword
or edx, edx
jz .exit
push esi
mov esi, [esi + 4]
mov edi, esi
cmp byte[esi], '/'
jz .load_lib
mov edi, s_libdir.fname
@@:
lodsb
stosb
or al, al
jnz @b
mov edi, s_libdir
.load_lib:
mcall 68, 19, edi ;s_libdir
or eax, eax
push edx
stdcall dll.LoadLibrary, dword[esi + 4]
pop edx
test eax, eax
jz .fail_load
push eax
stdcall dll.Link, eax, edx
test eax, eax
test eax, eax
jnz .fail_link
;push eax
mov eax, [esp]
mov eax, [eax]
cmp dword[eax], 'lib_'
pop eax
jnz @f
stdcall dll.Init, [eax + 4]
@@:
pop esi
add esi, 8
jmp .next_lib
@@ -63,13 +41,9 @@ proc dll.Load, import_table:dword
xor eax, eax
ret
.fail_load:
add esp, 4
;xor eax, eax
;inc eax
mov eax, ERROR_LIBRARY_NOT_LOAD
ret
mov eax, ERROR_LIBRARY_NOT_LOAD
.fail_link:
add esp, 4
add esp, 4
ret
endp
;-----------------------------------------------------------------------------
@@ -119,6 +93,39 @@ proc dll.Init, dllentry:dword
ret
endp
;-----------------------------------------------------------------------------
; load single library by name or full path, initialize it
; if first function in export table begins with 'lib_', call it as DLL initialization
; return eax = pointer to export table, or 0 on failure
proc dll.LoadLibrary, lib_path:dword
push ebx esi edi
mov esi, [lib_path]
mov edi, esi
cmp byte[esi], '/'
jz .do_load
mov edi, s_libdir.fname
@@:
lodsb
stosb
or al, al
jnz @b
mov edi, s_libdir
.do_load:
mcall 68, 19, edi
or eax, eax
jz .fail
mov edx, [eax]
cmp dword[edx], 'lib_'
jnz .done
stdcall dll.Init, [eax + 4]
.done:
.fail:
pop edi esi ebx
ret
endp
;-----------------------------------------------------------------------------
; scans export table for a sz_name function
; returns in eax function address or 0 if not found
proc dll.GetProcAddress, exp:dword, sz_name:dword
+41 -26
View File
@@ -1,6 +1,6 @@
;-----------------------------------------------------------------------------
; load one or more DLL file in COFF format and try to import functions by our list
; if first function in import list begins with 'lib_', call it as DLL initialization
; load each library via dll.LoadLibrary, then resolve imports via dll.Link
; return eax = 1 as fail, if anyone of .obj file not found in /sys/lib
; return 0 if all fine, but 0 not garantees in succesfull import - see dll.Link comment
; dirties all registers! eax, ebx, ecx, edx, esi, edi
@@ -11,32 +11,14 @@ proc dll.Load, import_table:dword
or edx, edx
jz .exit
push esi
mov esi, [esi + 4]
mov edi, esi
cmp byte[esi], '/'
jz .load_lib
mov edi, s_libdir.fname
@@:
lodsb
stosb
or al, al
jnz @b
mov edi, s_libdir
.load_lib:
mcall 68, 19, edi ;s_libdir
or eax, eax
push edx
stdcall dll.LoadLibrary, dword[esi + 4]
pop edx
test eax, eax
jz .fail
stdcall dll.Link, eax, edx
push eax
mov eax, [eax]
cmp dword[eax], 'lib_'
pop eax
jnz @f
stdcall dll.Init, [eax + 4]
@@:
test eax, eax
jz .fail
pop esi
add esi, 8
jmp .next_lib
@@ -87,6 +69,39 @@ proc dll.Init, dllentry:dword
ret
endp
;-----------------------------------------------------------------------------
; load single library by name or full path, initialize it
; if first function in export table begins with 'lib_', call it as DLL initialization
; return eax = pointer to export table, or 0 on failure
proc dll.LoadLibrary, lib_path:dword
push ebx esi edi
mov esi, [lib_path]
mov edi, esi
cmp byte[esi], '/'
jz .do_load
mov edi, s_libdir.fname
@@:
lodsb
stosb
or al, al
jnz @b
mov edi, s_libdir
.do_load:
mcall 68, 19, edi
or eax, eax
jz .fail
mov edx, [eax]
cmp dword[edx], 'lib_'
jnz .done
stdcall dll.Init, [eax + 4]
.done:
.fail:
pop edi esi ebx
ret
endp
;-----------------------------------------------------------------------------
; scans export table for a sz_name function
; returns in eax function address or 0 if not found
proc dll.GetProcAddress, exp:dword, sz_name:dword
@@ -133,7 +148,7 @@ proc strcmp, str1:dword, str2:dword
ret
endp
;-----------------------------------------------------------------------------
if defined dll.Load
if defined dll.Load | defined dll.LoadLibrary
s_libdir:
db '/sys/lib/'
.fname rb 32