Subversion Repositories Kolibri OS

Rev

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