Subversion Repositories Kolibri OS

Rev

Rev 6614 | Rev 6810 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. format PE DLL GUI 0.8 at 7FF00000h
  2. entry start
  3. include '../../struct.inc'
  4. include '../../proc32.inc'
  5. include 'fpo.inc'
  6. include 'export.inc'
  7. include 'pe.inc'
  8. section '.text' code readable executable
  9.  
  10. FS_STACK_MAX equ dword [fs:4]
  11. FS_STACK_MIN equ dword [fs:8]
  12. FS_SELF_PTR equ dword [fs:0x18]
  13. FS_ERRNO equ dword [fs:0x34]
  14. FS_SYSCALL_PTR equ dword [fs:0xC0]
  15.  
  16. ENOMEM = 12
  17.  
  18. DLL_PROCESS_DETACH = 0
  19. DLL_PROCESS_ATTACH = 1
  20. DLL_THREAD_ATTACH = 2
  21. DLL_THREAD_DETACH = 3
  22.  
  23. SYSCALL_METHOD_I40 = 1
  24. SYSCALL_METHOD_SYSENTER = 2
  25. SYSCALL_METHOD_SYSCALL = 3
  26.  
  27. ; Pointer to this structure is passed as the third argument
  28. ; to 'start' procedure by the kernel.
  29. struct kernel_init_data
  30. version         dw      ?
  31. flags           dw      ?
  32. syscall_method  dd      ?
  33. ; either one of SYSCALL_METHOD_xxx or pointer to procedure
  34. exe_base        dd      ?
  35. stack_base      dd      ?
  36. stack_size      dd      ?
  37. exe_path        dd      ?
  38. command_line    dd      ?
  39. environment     dd      ?
  40. ends
  41.  
  42. include 'sync.inc'
  43. include 'malloc.inc'
  44. include 'peloader.inc'
  45. include 'modules.inc'
  46. include 'cmdline.inc'
  47.  
  48. proc syscall_int40
  49.         int     0x40
  50.         ret
  51. endp
  52.  
  53. proc syscall_sysenter
  54.         push    ebp
  55.         mov     ebp, esp
  56.         push    @f
  57.         sysenter
  58. @@:
  59.         pop     edx
  60.         pop     ecx
  61.         ret
  62. endp
  63.  
  64. proc syscall_syscall
  65.         push    ecx
  66.         syscall
  67.         pop     ecx
  68.         ret
  69. endp
  70.  
  71. proc kercall
  72.         jmp     FS_SYSCALL_PTR
  73. endp
  74.  
  75. prologue@proc equ fpo_prologue
  76. epilogue@proc equ fpo_epilogue
  77.  
  78. proc start stdcall, dll_base, reason, reserved
  79. ; 1. Do nothing unless called by the kernel for DLL_PROCESS_ATTACH.
  80.         cmp     [reason], DLL_PROCESS_ATTACH
  81.         jnz     .nothing
  82. ; 2. Initialize process.
  83. ; 2a. Validate version of the init struct.
  84. ; If not known, say a debug message and die.
  85.         mov     ebp, [reserved]
  86.         mov     esi, [dll_base]
  87.         cmp     [ebp+kernel_init_data.version], 1
  88.         jnz     .version_mismatch
  89. ; 2b. Get the system call code.
  90. ; Note: relocations have not been fixed yet,
  91. ; so we cannot use absolute addresses, only RVAs.
  92.         mov     eax, [ebp+kernel_init_data.syscall_method]
  93.         cmp     eax, 0x10000
  94.         jae     .syscall_absolute
  95.         dec     eax
  96.         mov     edx, rva syscall_int40
  97.         cmp     eax, num_syscall_methods
  98.         jae     @f
  99.         mov     edx, [esi+eax*4+rva syscall_methods]
  100. @@:
  101.         lea     eax, [edx+esi]
  102. .syscall_absolute:
  103.         mov     FS_SYSCALL_PTR, eax
  104. ; 2c. Fixup relocations so that we can use absolute offsets instead of RVAs
  105. ; in rest of code.
  106. ; Note: this uses syscalls, so this step should be done after
  107. ; configuring FS_SYSCALL_PTR at step 2b.
  108.         push    kolibri_dll
  109.         call    fixup_pe_relocations
  110.         pop     ecx
  111.         jc      .die
  112. ; 2d. Initialize process heap.
  113.         mov     eax, [ebp+kernel_init_data.exe_base]
  114.         mov     edx, [eax+STRIPPED_PE_HEADER.SizeOfHeapReserve]
  115.         cmp     word [eax], 'MZ'
  116.         jnz     @f
  117.         add     eax, [eax+IMAGE_DOS_HEADER.e_lfanew]
  118.         mov     edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapReserve]
  119. @@:
  120.         malloc_init
  121. ; 2e. Allocate and fill MODULE structs for main exe and kolibri.dll.
  122.         mov     eax, [ebp+kernel_init_data.exe_path]
  123. @@:
  124.         inc     eax
  125.         cmp     byte [eax-1], 0
  126.         jnz     @b
  127.         sub     eax, [ebp+kernel_init_data.exe_path]
  128.         push    eax
  129.         add     eax, sizeof.MODULE
  130.         stdcall malloc, eax
  131.         test    eax, eax
  132.         jz      .die
  133.         mov     ebx, eax
  134.         stdcall malloc, sizeof.MODULE + kolibri_dll.size
  135.         test    eax, eax
  136.         jz      .die
  137.         mov     edx, modules_list
  138.         mov     [edx+MODULE.next], ebx
  139.         mov     [ebx+MODULE.next], eax
  140.         mov     [eax+MODULE.next], edx
  141.         mov     [edx+MODULE.prev], eax
  142.         mov     [eax+MODULE.prev], ebx
  143.         mov     [ebx+MODULE.prev], edx
  144.         push    esi
  145.         mov     esi, kolibri_dll
  146.         mov     ecx, kolibri_dll.size
  147.         lea     edi, [eax+MODULE.path]
  148.         rep movsb
  149.         pop     esi
  150.         call    init_module_struct
  151.         mov     eax, ebx
  152.         mov     esi, [ebp+kernel_init_data.exe_path]
  153.         pop     ecx
  154.         lea     edi, [ebx+MODULE.path]
  155.         rep movsb
  156.         mov     esi, [ebp+kernel_init_data.exe_base]
  157.         call    init_module_struct
  158. ; 2f. Copy rest of init struct and free memory.
  159. ; Parse command line to argc/argv here and move arguments to the heap
  160. ; in order to save memory: init struct and heap use different pages,
  161. ; but typically data from init struct are far from the entire page,
  162. ; so moving it to heap does not increase actual physical heap size
  163. ; and allows to free init struct.
  164.         mov     eax, [ebp+kernel_init_data.stack_base]
  165.         mov     FS_STACK_MIN, eax
  166.         add     eax, [ebp+kernel_init_data.stack_size]
  167.         mov     FS_STACK_MAX, eax
  168.         mov     esi, [ebp+kernel_init_data.command_line]
  169.         xor     edx, edx
  170.         xor     edi, edi
  171.         call    parse_cmdline
  172.         inc     ebx ; argv[0] = exe path
  173. .argc equ dll_base
  174. .argv equ reason
  175. .envp equ reserved
  176.         mov     [.argc], ebx
  177.         sub     esi, [ebp+kernel_init_data.command_line]
  178.         lea     esi, [esi+(ebx+1)*4]
  179.         stdcall malloc, esi
  180.         test    eax, eax
  181.         jz      .die
  182.         mov     [.argv], eax
  183.         mov     edx, eax
  184.         lea     edi, [eax+(ebx+1)*4]
  185.         mov     eax, [modules_list + MODULE.next]
  186.         add     eax, MODULE.path
  187.         mov     [edx], eax
  188.         add     edx, 4
  189.         mov     esi, [ebp+kernel_init_data.command_line]
  190.         call    parse_cmdline
  191.         and     dword [edx], 0 ; argv[argc] = NULL
  192.         and     [.envp], 0
  193.         mov     eax, 68
  194.         mov     ebx, 13
  195.         mov     ecx, ebp
  196.         call    FS_SYSCALL_PTR
  197. ; 2g. Initialize mutex for list of MODULEs.
  198.         mov     ecx, modules_mutex
  199.         call    mutex_init
  200. ; 2h. For console applications, call console.dll!con_init with default parameters.
  201.         mov     eax, [modules_list + MODULE.next]
  202.         mov     esi, [eax+MODULE.base]
  203.         mov     al, [esi+STRIPPED_PE_HEADER.Subsystem]
  204.         cmp     byte [esi], 'M'
  205.         jnz     @f
  206.         mov     eax, [esi+3Ch]
  207.         mov     al, byte [esi+eax+IMAGE_NT_HEADERS.OptionalHeader.Subsystem]
  208. @@:
  209.         cmp     al, IMAGE_SUBSYSTEM_WINDOWS_CUI
  210.         jnz     .noconsole
  211.         stdcall dlopen, console_dll, 0
  212.         test    eax, eax
  213.         jz      .noconsole
  214.         stdcall dlsym, eax, con_init_str
  215.         test    eax, eax
  216.         jz      .noconsole
  217.         mov     edx, [modules_list + MODULE.next]
  218.         stdcall eax, -1, -1, -1, -1, [edx+MODULE.filename]
  219. .noconsole:
  220. ; 3. Configure modules: main EXE and possible statically linked DLLs.
  221.         mov     eax, [modules_list + MODULE.next]
  222.         mov     esi, [eax+MODULE.base]
  223.         add     eax, MODULE.path
  224.         push    eax
  225.         call    fixup_pe_relocations
  226.         pop     ecx
  227.         jc      .die
  228.         mutex_lock modules_mutex
  229.         mov     esi, [modules_list + MODULE.next]
  230.         call    resolve_pe_imports
  231.         mov     ebx, eax
  232.         mutex_unlock modules_mutex
  233.         test    ebx, ebx
  234.         jnz     .die
  235. ; 4. Call exe entry point.
  236.         mov     esi, [esi+MODULE.base]
  237.         mov     edx, [esi+STRIPPED_PE_HEADER.AddressOfEntryPoint]
  238.         cmp     byte [esi], 'M'
  239.         jnz     @f
  240.         mov     ecx, [esi+IMAGE_DOS_HEADER.e_lfanew]
  241.         add     ecx, esi
  242.         mov     edx, [ecx+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
  243. @@:
  244.         add     edx, esi
  245.         pop     ecx
  246.         mov     [process_initialized], 1
  247.         call    edx
  248. ; If exe entry point has returned control, die.
  249.         jmp     .die
  250. .version_mismatch:
  251.         lea     eax, [esi + rva syscall_int40]
  252.         mov     FS_SYSCALL_PTR, eax
  253.         add     esi, rva msg_version_mismatch
  254.         call    sys_msg_board_str
  255. .die:
  256.         or      eax, -1
  257.         call    FS_SYSCALL_PTR
  258. .nothing:
  259.         ret
  260. endp
  261.  
  262. proc sys_msg_board_str
  263.         push    eax ebx
  264. @@:
  265.         push    ecx
  266.         mov     cl, [ecx]
  267.         test    cl, cl
  268.         jz      @f
  269.         mov     eax, 63
  270.         mov     ebx, 1
  271.         call    FS_SYSCALL_PTR
  272.         pop     ecx
  273.         inc     ecx
  274.         jmp     @b
  275. @@:
  276.         pop     ecx ebx eax
  277.         ret
  278. endp
  279.  
  280. align 4
  281. syscall_methods dd rva syscall_int40, rva syscall_sysenter, rva syscall_syscall
  282. num_syscall_methods = ($ - syscall_methods) / 4
  283.  
  284. align 4
  285. data export
  286. export 'kolibri.dll' \
  287.         , kercall, 'kercall' \
  288.         , malloc, 'malloc' \
  289.         , free, 'free' \
  290.         , calloc, 'calloc' \
  291.         , realloc, 'realloc' \
  292.         , realloc_in_place, 'realloc_in_place' \
  293.         , memalign, 'memalign' \
  294.         , create_mspace, 'create_mspace' \
  295.         , destroy_mspace, 'destroy_mspace' \
  296.         , mspace_malloc, 'mspace_malloc' \
  297.         , mspace_free, 'mspace_free' \
  298.         , mspace_calloc, 'mspace_calloc' \
  299.         , mspace_realloc, 'mspace_realloc' \
  300.         , mspace_realloc_in_place, 'mspace_realloc_in_place' \
  301.         , mspace_memalign, 'mspace_memalign' \
  302.         , dlopen, 'dlopen' \
  303.         , dlclose, 'dlclose' \
  304.         , dlsym, 'dlsym' \
  305.  
  306. end data
  307.  
  308. kolibri_dll             db      '/rd/1/lib/kolibri.dll',0
  309. .size = $ - kolibri_dll
  310.  
  311. console_dll             db      'console.dll',0
  312. con_init_str            db      'con_init',0
  313.  
  314. msg_version_mismatch    db      'S : Version mismatch between kernel and kolibri.dll',13,10,0
  315. msg_bad_relocation      db      'Bad relocation type in ',0
  316. msg_newline             db      13,10,0
  317. msg_relocated1          db      'S : fixups for ',0
  318. msg_relocated2          db      ' applied',13,10,0
  319. msg_noreloc1            db      'Module ',0
  320. msg_noreloc2            db      ' is not at preferred base and has no fixups',0
  321. loader_debugboard_prefix db     'S : ',0
  322. notify_program          db      '/rd/1/@notify',0
  323. msg_cannot_open         db      'Cannot open ',0
  324. msg_paths_begin         db      ' in any of '
  325.  
  326. module_path1    db      '/rd/1/lib/'
  327. .size = $ - module_path1
  328.                         db      ', '
  329. module_path2    db      '/kolibrios/lib/'
  330. .size = $ - module_path2
  331.                         db      ', ',0
  332. msg_export_name_not_found       db      'Exported function ',0
  333. msg_export_ordinal_not_found    db      'Exported ordinal #',0
  334. msg_export_not_found    db      ' not found in module ',0
  335. msg_unknown             db      '<unknown>',0
  336.  
  337. section '.data' data readable writable
  338. if FOOTERS
  339. malloc_magic    dd      ?
  340. end if
  341. default_heap    dd      ?
  342. modules_list    rd      2
  343. modules_mutex   MUTEX
  344. process_initialized     db      ?
  345.