Page 1 of 1

Запрос подготовки ядра к нововведениям

Posted: Sun Nov 22, 2020 2:54 pm
by ProMiNick
изменяемый хедер - (root)/kernel/trunk/core/taskman.inc

затрагиваемая процедура - fs_execute
Что процедура должна научиться делать - чистить за собой сущности созданные между lock_application_table и unlock_application_table (не трогать esi во время этой очистки)
примерный набросок

Code: Select all

proc fs_execute
; edx = flags
; ecx -> cmdline
; ebx -> absolute file path
; eax = string length
    locals
        cmdline         rd  1
        flags           rd  1
        slot            rd  1
        slot_base       rd  1
; app header data
        hdr_cmdline     rd  1
        hdr_path        rd  1
        hdr_eip         rd  1
        hdr_esp         rd  1
        hdr_edata       rd  1
        hdr_emem        rd  1
        file_base       rd  1
        file_size       rd  1
        filename_size   rd  1
        cmdline_size    rd  1
        path_string     rd  1
    endl

        mov     [flags], edx
        mov     [cmdline], ecx
        mov     [path_string], ebx
        mov     [filename_size], eax
        mov     esi, -ERROR_FILE_NOT_FOUND
        test    eax, eax
        jz      .err_file
        stdcall load_file, ebx
        test    eax, eax
        jz      .err_file

        mov     [file_base], eax
        mov     [file_size], ebx
        lea     ebx, [hdr_cmdline]
        call    test_app_header
        mov     esi, -0x1F
        test    eax, eax
        jz      .err_hdr

        call    lock_application_table
        call    alloc_thread_slot
        mov     esi, -0x20  ; too many processes
        test    eax, eax
        jz      .err_0

        mov     [slot], eax
        shl     eax, 8
        lea     edi, [SLOT_BASE+eax]
        mov     [slot_base], edi
; clean extended information about process
        mov     ecx, sizeof.APPDATA/4
        xor     eax, eax
        cld
        rep stosd
; write application name
        stdcall strrchr, [path_string], '/'
        lea     esi, [eax+1]    ; -> name without path
        mov     ecx, 11
        mov     edi, [slot_base]
@@:
        call    utf8to16
        call    uni2ansi_char
        cmp     al, '.'
        jz      @f
        test    al, al
        jz      @f
        stosb
        loop    @b
@@:
        mov     edi, [cmdline]
        xor     eax, eax
        test    edi, edi
        jz      @f
        mov     ecx, 65535
        call    _strnlen
        cmp     eax, 256
        jb      @f
        lea     ebx, [eax+1]
        add     [hdr_emem], ebx
@@:
        mov     [cmdline_size], eax
        stdcall create_process, [hdr_emem]
        mov     esi, -30    ; no memory
        test    eax, eax
        jz      .err_hdr

        mov     ebx, [sys_proc+LHEAD.prev]
        __list_add eax, ebx, sys_proc
        mov     ebx, [hdr_emem]
        mov     [eax+PROC.mem_used], ebx
        mov     ebx, [slot_base]
        mov     [ebx+APPDATA.process], eax
        lea     edx, [ebx+APPDATA.list]
        lea     ecx, [eax+PROC.thr_list]
        list_add_tail edx, ecx
        mov     eax, [cmdline_size]
        add     eax, sizeof.APP_HDR
        stdcall kernel_alloc, eax
        mov     [ebx+APPDATA.exec_params], eax
        mov     edi, eax
        lea     esi, [hdr_cmdline]
        mov     ecx, sizeof.APP_HDR/4
        rep movsd
        mov     ecx, [cmdline_size]
        mov     esi, [cmdline]
        rep movsb
        lea     eax, [hdr_cmdline]
        stdcall set_app_params , [slot], eax, [flags]
        call    try_to_load_imports_if_any
        test    esi,esi
        js      .err_with_cleanup_needance
        mov     eax, [process_number]   ;set result
        call    unlock_application_table
        ret
.err_with_cleanup_needance:
        ; we must free all entities that created since lock_application_table
        ; and make slot back freed
.err_0:
        call    unlock_application_table
.err_hdr:
        stdcall kernel_free, [file_base]
.err_file:
        stdcall kernel_free, [path_string]
        mov     eax, esi
        ret
endp
собственно ядерщики нужен код по метке .err_with_cleanup_needance

try_to_load_imports_if_any пока можно реализовать в виде заглушки

Code: Select all

align 4
try_to_load_imports_if_any:
        xor     esi,esi
        ret 

Re: Запрос подготовки ядра к нововведениям

Posted: Sun Nov 22, 2020 4:34 pm
by ProMiNick
а может зря я заморачиваюсь.
Во время неудачной попытки импорта приложение просто тихо не стартанет, не забъет же это слот процессов (наверно сам освободится как то - когда приложение грохнется), да и систему это не грохнет (не должно).
так что будет готово ядро или нет. функционал импорта допилим в него.

Re: Запрос подготовки ядра к нововведениям

Posted: Mon Nov 23, 2020 1:37 am
by ProMiNick
заготовка пока вот такая

Code: Select all

MAX_SUPPORTED_MENUET_FILE_VERSION = 2

proc fs_execute
; edx = flags
; ecx -> cmdline
; ebx -> absolute file path
; eax = string length
    locals
        cmdline         rd  1
        flags           rd  1
        slot            rd  1
        slot_base       rd  1
; app header data
        hdr_cmdline     rd  1
        hdr_path        rd  1
        hdr_eip         rd  1
        hdr_esp         rd  1
        hdr_edata       rd  1
        hdr_emem        rd  1
        file_base       rd  1
        file_size       rd  1
        filename_size   rd  1
        cmdline_size    rd  1
        path_string     rd  1
    endl

        mov     [flags], edx
        mov     [cmdline], ecx
        mov     [path_string], ebx
        mov     [filename_size], eax
        mov     esi, -ERROR_FILE_NOT_FOUND
        test    eax, eax
        jz      .err_file
        stdcall load_file, ebx
        test    eax, eax
        jz      .err_file

        mov     [file_base], eax
        mov     [file_size], ebx
        lea     ebx, [hdr_cmdline]
        call    test_app_header
        mov     esi, -0x1F
        test    eax, eax
        jz      .err_hdr

        call    lock_application_table
        call    alloc_thread_slot
        mov     esi, -0x20  ; too many processes
        test    eax, eax
        jz      .err_0

        mov     [slot], eax
        shl     eax, 8
        lea     edi, [SLOT_BASE+eax]
        mov     [slot_base], edi
; clean extended information about process
        mov     ecx, sizeof.APPDATA/4
        xor     eax, eax
        cld
        rep stosd
; write application name
        stdcall strrchr, [path_string], '/'
        lea     esi, [eax+1]    ; -> name without path
        mov     ecx, 11
        mov     edi, [slot_base]
@@:
        call    utf8to16
        call    uni2ansi_char
        cmp     al, '.'
        jz      @f
        test    al, al
        jz      @f
        stosb
        loop    @b
@@:
        mov     edi, [cmdline]
        xor     eax, eax
        test    edi, edi
        jz      @f
        mov     ecx, 65535
        call    _strnlen
        cmp     eax, 256
        jb      @f
        lea     ebx, [eax+1]
        add     [hdr_emem], ebx
@@:
        mov     [cmdline_size], eax
        stdcall create_process, [hdr_emem]
        mov     esi, -30    ; no memory
        test    eax, eax
        jz      .err_hdr

        mov     ebx, [sys_proc+LHEAD.prev]
        __list_add eax, ebx, sys_proc
        mov     ebx, [hdr_emem]
        mov     [eax+PROC.mem_used], ebx
        mov     ebx, [slot_base]
        mov     [ebx+APPDATA.process], eax
        lea     edx, [ebx+APPDATA.list]
        lea     ecx, [eax+PROC.thr_list]
        list_add_tail edx, ecx
        mov     eax, [cmdline_size]
        add     eax, sizeof.APP_HDR
        stdcall kernel_alloc, eax
        mov     [ebx+APPDATA.exec_params], eax
        mov     edi, eax
        lea     esi, [hdr_cmdline]
        mov     ecx, sizeof.APP_HDR/4
        rep movsd
        mov     ecx, [cmdline_size]
        mov     esi, [cmdline]
        rep movsb
        lea     eax, [hdr_cmdline]
        stdcall set_app_params , [slot], eax, [flags]
        call    try_to_load_imports_if_any
        test    eax,eax
        js      .err_with_cleanup_needance
        mov     eax, [process_number]   ;set result
        call    unlock_application_table
        ret
.err_with_cleanup_needance:
        ; we must free all entities that created since lock_application_table
        ; and make slot back freed
.err_0:
        call    unlock_application_table
.err_hdr:
        stdcall kernel_free, [file_base]
.err_file:
        stdcall kernel_free, [path_string]
        mov     eax, esi
        ret
endp

align 4
try_to_load_imports_if_any:
        pushad
        mov     ebp, eax
        mov     eax, [ebp+36] ; +36 - imports field
        test    eax, eax
        jz      .locret       ; no imports section
        cmp     eax, [ebp+16] ; check that content fit in init range
        jae     .locret       ; more likely app dont know about placing imports there
        cmp     dword[eax], 'ProM' ; check import signature
        jne     .locret       ; more likely app dont know about placing imports there
        cmp     dword[eax+4], 'iNic' ; check import signature
        jne     .locret       ; more likely app dont know about placing imports there
        cmp     byte[eax+8], 'k' ; I stolen 12 bytes for signature
        jne     .locret       ; more likely app dont know about placing imports there
        add     eax,12
        push    eax
        jmp     LoadLibraries
 .locret:
        popad
        xor     esi, esi
        ret

virtual at 0
        LIBRARY_ENTRY:
        .lookup_table   dd ?
        .lpname         dd ?
        sizeof.LIBRARY_ENTRY = $
end virtual

virtual at 0
        EXPORT_ENTRY:
        .lpname dd ?
        .lpproc dd ?
        sizeof.EXPORT_ENTRY = $
end virtual

virtual at 0
        IMPORT_ENTRY:
        .lpproc dd ?
        sizeof.IMPORT_ENTRY = $
end virtual

GetStrLength:
; string:                   [in]        edi
; string length:            [out]       ecx
;                           [unchanged] ebx, edx, esi, edi, ebp, esp
        or      ecx, -1
        xor     eax, eax
        cld
        repne scasb
        not     ecx
        sub     edi,ecx
        retn

GetProcOrdinalAddress:
; hInstance (export table): [in]        esi
; proc ordinal:             [in]        edi
; proc address:             [out]       eax
;                           [unchanged] ebx, ecx, edx, ebp, esp
        xor     edi, $80000000
      .check_entry:
        mov     eax, [esi+EXPORT_ENTRY.lpname]
        test    eax, eax
        jz      .not_found
        sub     edi, 1
        je      .matched
        add     esi, sizeof.EXPORT_ENTRY
        jmp     .check_entry
      .matched:
        mov     eax, [esi+EXPORT_ENTRY.lpproc]
      .not_found:
        retn

GetProcAddress:
; hInstance (export table): [in]        esi
; proc name:                [in]        edi
; proc address:             [out]       eax
;                           [unchanged] ebp, esp
        call    GetStrLength
        mov     edx, ecx
        mov     ebx, edi
        mov     eax, esi
      .check_entry:
        mov     esi, ebx
        mov     edi, [eax+EXPORT_ENTRY.lpname]
        test    edi, edi
        jz      .not_found
        repe cmpsb
        je      .matched
        mov     ecx, edx
        add     eax, sizeof.EXPORT_ENTRY
        jmp     .check_entry
      .not_found:
        sub     eax, EXPORT_ENTRY.lpproc
      .matched:
        mov     eax, [eax+EXPORT_ENTRY.lpproc]
        retn

ResolveImports:
; hInstance (export table): [in]        esi
; lib.lookup table:         [in]        ebp
; ?isResolved:              [out]       eax
;                           [unchanged] esi, esp
        load_libraries_error equ esp+16

     .import_loop:
        mov     edi, [ebp+IMPORT_ENTRY.lpproc]
        test    edi, edi
        jz      .done
        push    esi
        js      .search_by_ordinal
        call    GetProcAddress
        jmp     .get_proc_addr_done
      .search_by_ordinal:
        call    GetProcOrdinalAddress
      .get_proc_addr_done:
        pop     esi
        test    eax, eax
        jz      .import_not_found
        mov     [ebp+IMPORT_ENTRY.lpproc], eax
        add     ebp, sizeof.IMPORT_ENTRY
        jmp     .import_loop
      .import_not_found:
        or      [ebp+IMPORT_ENTRY.lpproc], -1
        or      dword[load_libraries_error], -$1001
       if defined unresolved_proc_termination
        jmp     ShowImportErrorWindow
       else
        add     ebp, sizeof.IMPORT_ENTRY
        jmp     .import_loop
       end if
      .done:
        retn
        restore load_libraries_error


@copy_path_wo_pdname:
; library name:             [in]        edx
; result path:              [in]        esi
; library path:             [in]        edi
;                           [out]       no
;                           [unchanged] ebx, edx, ebp, esp
        call    GetStrLength
        add     edi, ecx
        mov     al, '/'
        std
        repne scasb
        cld
        sub     edi, ecx
        add     ecx, 2
        xchg    esi, edi
        mov     eax, ecx
        shr     ecx, 2
        rep movsd
        mov     ecx, eax
        and     ecx, 3
        rep movsb

        mov     esi, edx
        xchg    esi, edi
        call    GetStrLength
        xchg    esi, edi
        mov     eax, ecx
        shr     ecx, 2
        rep movsd
        mov     ecx, eax
        and     ecx, 3
        rep movsb
        retn

LoadLibrary:
; library name:             [in]        edx
; hInstance (export table): [out]       eax
;                           [unchanged] edx, ebp, esp
        mov     edi, cur_dir_path
        mov     esi, library_path
        call    @copy_path_wo_pdname
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,library_path
        test    eax, eax
        jnz     .done
        mov     edi, LoadLibrary.sys_lib_path
        mov     esi, library_path
        call    @copy_path_wo_pdname
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,library_path
      .done:
        retn
.sys_lib_path db '/sys/lib/',0

TryEnterLibEntryPoint:
; hInstance (export table): [in]        esi
;                           [out]       no
;                           [unchanged] esp
        mov     edi, TryEnterLibEntryPoint.name
        call    GetProcAddress
        test    eax, eax
        jz      .processed
        push    eax
        mov     eax, mem.Alloc
        mov     ebx, mem.Free
        mov     ecx, mem.ReAlloc
        mov     edx, LoadLibraries
      .processed:
        retn
.name db 'lib_init',0

align 4
proc LoadLibraries stdcall, current_lib_entry,pushad_edi,load_libraries_error,pushad_ebp,pushad_esp,pushad_ebx,pushad_edx,pushad_ecx,file_base
; eax -> import.root aka 1st_lib_entry
 .LoopLibraries:
        mov     eax, [current_lib_entry]
        mov     ebp, [eax+LIBRARY_ENTRY.lookup_table]
        test    ebp, ebp
        jz      .done
        mov     edx, [eax+LIBRARY_ENTRY.lpname]
        call    LoadLibrary;edx=name
        test    eax, eax
        jz      .loadlibError
        mov     esi, eax
        mov     eax, dword[current_lib_entry]
        call    ResolveImports
        call    TryEnterLibEntryPoint
        add     dword[current_lib_entry], sizeof.LIBRARY_ENTRY
        jmp     .LoopLibraries
 .loadlibError:
        call    DisplayErrorSomeway
        mov     [load_libraries_error],-$1000
        ret
endp

mem.Alloc:
        size equ esp+4

        push    ebx
        push    ecx
        mcall   SF_SYS_MISC, SSF_MEM_ALLOC, dword[size]
        pop     ecx
        pop     ebx
        retn 4
        restore size

mem.ReAlloc:
        mptr equ esp+4
        size equ esp+8

        push    ebx
        push    ecx
        push    edx
        mcall   SF_SYS_MISC, SSF_MEM_REALLOC, dword[size], dword[mptr]
        pop     edx
        pop     ecx
        pop     ebx
        retn 8
        restore size,mptr

mem.Free:
        mptr equ esp+4

        push    ebx
        push    ecx
        mcall   SF_SYS_MISC, SSF_MEM_FREE, dword[mptr]
        pop     ecx
        pop     ebx
        retn 4
        restore mptr

align 4
DisplayErrorSomeway: ret ; òîëüêî çàãëóøêà

align 4
LoadLibrary:
; library name:             [in]        edx
; hInstance (export table): [out]       eax
;                           [unchanged] edx, ebp, esp
        mov     edi, cur_dir_path
        mov     esi, library_path
        call    @copy_path_wo_pdname
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,library_path
        test    eax, eax
        jnz     .done
        mov     edi, LoadLibrary.sys_lib_path
        mov     esi, library_path
        call    @copy_path_wo_pdname
        mcall   SF_SYS_MISC,SSF_LOAD_DLL,library_path
      .done:
        retn
.sys_lib_path db '/sys/lib/',0

align 4
test_app_header:
       virtual at eax
         APP_HEADER_00 APP_HEADER_00_
       end virtual
       virtual at eax
         APP_HEADER_01 APP_HEADER_01_
       end virtual

        cmp     dword [eax], 'MENU'
        je      .menuet_may_be
        cmp     dword [eax], 'KOLI'
        jne     .fail
        cmp     dword [eax+4], 'BRI1'
        jne     .fail
        jmp     .banner_OK
  .menuet_may_be:
        cmp     word [eax+4], 'ET'
        jne     .fail
  .banner_OK:
        mov     ecx, [APP_HEADER_00.start]
        mov     [ebx+APP_HDR.eip], ecx
        mov     ecx, [APP_HEADER_00.mem_size]
        mov     edx, [APP_HEADER_00.i_end]
        cmp     ecx, edx ; {diamond}[20.08.2006] test that inited mem fit in allocated mem to prevent kernel faults
        jb      .fail
        mov     [ebx+APP_HDR._emem], ecx
        mov     [ebx+APP_HDR._edata], edx

        mov     dx, word [eax+6]
        cmp     dx, 'I1'
        jz      .skip_menuet_checks
        sub     dx, '00'
        jne     .check_01_header
        mov     [ebx+APP_HDR.path], 0

        shr     ecx, 1
        sub     ecx, 0x10
        mov     edx, [APP_HEADER_00.i_param]
        jmp     @F
 .check_01_header:
        cmp     dx, MAX_SUPPORTED_MENUET_FILE_VERSION
        ja      .fail
 .skip_menuet_checks:
        mov     ecx, [APP_HEADER_01.i_icon]
        mov     [ebx+APP_HDR.path], ecx

        mov     ecx, [APP_HEADER_01.stack_top]
        mov     edx, [APP_HEADER_01.i_param]
      @@:
        mov     [ebx+APP_HDR.esp], ecx
        mov     [ebx+APP_HDR.cmdline], edx
        ret
.fail:
        xor     eax, eax
        ret 
надо только перейти от юзермодных вызовов к внутриядерным функциям
одно но проброс лоадлибрари в библиотеки был юзермодной лоадлибрари, а если система теперь сразу это уметь будет, то при загрузке библиотеки уже должны грузится ее импорты.
Походу реализацию импорта надо где то на загрузке либ - туда реализовывать, а тут (в менуэт формате) лишь использовать.
будем изучать начинку ядра за реализацию mcall SF_SYS_MISC,SSF_LOAD_DLL - она и должна разрешать импорты для коффов.