Subversion Repositories Kolibri OS

Rev

Rev 5195 | Rev 6767 | 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_PROCESS_DATA equ dword [fs:0x30]
  14. FS_ERRNO equ dword [fs:0x34]
  15. FS_SYSCALL_PTR equ dword [fs:0xC0]
  16.  
  17. ENOMEM = 12
  18.  
  19. DLL_PROCESS_DETACH = 0
  20. DLL_PROCESS_ATTACH = 1
  21. DLL_THREAD_ATTACH = 2
  22. DLL_THREAD_DETACH = 3
  23.  
  24. SYSCALL_METHOD_I40 = 1
  25. SYSCALL_METHOD_SYSENTER = 2
  26. SYSCALL_METHOD_SYSCALL = 3
  27.  
  28. ; Pointer to this structure is passed as the third argument
  29. ; to 'start' procedure by the kernel.
  30. struct kernel_init_data
  31. version         dw      ?
  32. flags           dw      ?
  33. syscall_method  dd      ?
  34. ; either one of SYSCALL_METHOD_xxx or pointer to procedure
  35. exe_base        dd      ?
  36. stack_base      dd      ?
  37. stack_size      dd      ?
  38. exe_path        dd      ?
  39. command_line    dd      ?
  40. environment     dd      ?
  41. ends
  42.  
  43. include 'malloc.inc'
  44. include 'peloader.inc'
  45. include 'cmdline.inc'
  46.  
  47. proc syscall_int40
  48.         int     0x40
  49.         ret
  50. endp
  51.  
  52. proc syscall_sysenter
  53.         push    ebp
  54.         mov     ebp, esp
  55.         push    @f
  56.         sysenter
  57. @@:
  58.         pop     edx
  59.         pop     ecx
  60.         ret
  61. endp
  62.  
  63. proc syscall_syscall
  64.         push    ecx
  65.         syscall
  66.         pop     ecx
  67.         ret
  68. endp
  69.  
  70. proc kercall
  71.         jmp     FS_SYSCALL_PTR
  72. endp
  73.  
  74. prologue@proc equ fpo_prologue
  75. epilogue@proc equ fpo_epilogue
  76.  
  77. proc start stdcall, dll_base, reason, reserved
  78. locals
  79. exe_base dd ?
  80. exe_path_size dd ?
  81. endl
  82. ; 1. Do nothing unless called by the kernel for DLL_PROCESS_ATTACH.
  83.         cmp     [reason], DLL_PROCESS_ATTACH
  84.         jnz     .nothing
  85. ; 2. Initialize process.
  86. ; 2a. Validate version of the init struct.
  87. ; If not known, say a debug message and die.
  88.         mov     ebp, [reserved]
  89.         mov     esi, [dll_base]
  90.         cmp     [ebp+kernel_init_data.version], 1
  91.         jnz     .version_mismatch
  92. ; 2b. Get the system call code.
  93. ; Note: relocations have not been fixed yet,
  94. ; so we cannot use absolute addresses, only RVAs.
  95.         mov     eax, [ebp+kernel_init_data.syscall_method]
  96.         cmp     eax, 0x10000
  97.         jae     .syscall_absolute
  98.         dec     eax
  99.         mov     edx, rva syscall_int40
  100.         cmp     eax, num_syscall_methods
  101.         jae     @f
  102.         mov     edx, [esi+eax*4+rva syscall_methods]
  103. @@:
  104.         lea     eax, [edx+esi]
  105. .syscall_absolute:
  106.         mov     FS_SYSCALL_PTR, eax
  107. ; 2c. Fixup relocations so that we can use absolute offsets instead of RVAs
  108. ; in rest of code.
  109. ; Note: this uses syscalls, so this step should be done after
  110. ; configuring FS_SYSCALL_PTR at step 2b.
  111.         push    kolibri_dll
  112.         call    fixup_pe_relocations
  113.         pop     ecx
  114.         jc      .die
  115. ; 2d. Allocate process data.
  116.         mov     eax, 68
  117.         mov     ebx, 12
  118.         mov     ecx, 0x1000
  119.         call    FS_SYSCALL_PTR
  120.         mov     FS_PROCESS_DATA, eax
  121. ; 2e. Initialize process heap.
  122.         mov     eax, [ebp+kernel_init_data.exe_base]
  123.         mov     [exe_base], eax
  124.         mov     edx, [eax+STRIPPED_PE_HEADER.SizeOfHeapReserve]
  125.         cmp     word [eax], 'MZ'
  126.         jnz     @f
  127.         add     eax, [eax+IMAGE_DOS_HEADER.e_lfanew]
  128.         mov     edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapReserve]
  129. @@:
  130.         malloc_init
  131. ; 2f. Copy rest of init struct and free memory.
  132. ; Parse command line to argc/argv here and move arguments to the heap
  133. ; in order to save memory: init struct and heap use different pages,
  134. ; but typically data from init struct are far from the entire page,
  135. ; so moving it to heap does not increase actual physical heap size
  136. ; and allows to free init struct.
  137.         mov     eax, [ebp+kernel_init_data.stack_base]
  138.         mov     FS_STACK_MIN, eax
  139.         add     eax, [ebp+kernel_init_data.stack_size]
  140.         mov     FS_STACK_MAX, eax
  141.         mov     eax, [ebp+kernel_init_data.exe_path]
  142. @@:
  143.         inc     eax
  144.         cmp     byte [eax-1], 0
  145.         jnz     @b
  146.         sub     eax, [ebp+kernel_init_data.exe_path]
  147.         mov     [exe_path_size], eax
  148.         mov     esi, [ebp+kernel_init_data.command_line]
  149.         xor     edx, edx
  150.         xor     edi, edi
  151.         call    parse_cmdline
  152.         inc     ebx ; argv[0] = exe path
  153. .argc equ dll_base
  154. .argv equ reason
  155. .envp equ reserved
  156.         mov     [.argc], ebx
  157.         sub     esi, [ebp+kernel_init_data.command_line]
  158.         lea     esi, [esi+(ebx+1)*4]
  159.         add     esi, [exe_path_size]
  160.         stdcall malloc, esi
  161.         mov     [.argv], eax
  162.         mov     edx, eax
  163.         lea     edi, [eax+ebx*4]
  164.         mov     esi, [ebp+kernel_init_data.exe_path]
  165.         mov     [edx], edi
  166.         add     edx, 4
  167.         mov     ecx, [exe_path_size]
  168.         rep movsb
  169.         mov     esi, [ebp+kernel_init_data.command_line]
  170.         call    parse_cmdline
  171.         and     dword [edx], 0 ; argv[argc] = NULL
  172.         and     [.envp], 0
  173.         mov     eax, 68
  174.         mov     ebx, 13
  175.         mov     ecx, ebp
  176.         call    FS_SYSCALL_PTR
  177. ; 3. Configure modules: main EXE and possible statically linked DLLs.
  178.         mov     esi, [exe_base]
  179.         mov     eax, [.argv]
  180.         pushd   [eax]
  181.         call    fixup_pe_relocations
  182.         pop     ecx
  183.         jc      .die
  184. ; 4. Call exe entry point.
  185.         mov     edx, [esi+STRIPPED_PE_HEADER.AddressOfEntryPoint]
  186.         cmp     word [esi], 'MZ'
  187.         jnz     @f
  188.         mov     ecx, [esi+IMAGE_DOS_HEADER.e_lfanew]
  189.         add     ecx, esi
  190.         mov     edx, [ecx+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
  191. @@:
  192.         add     edx, esi
  193.         add     esp, fpo_localsize+4
  194.         call    edx
  195. ; If exe entry point has returned control, die.
  196.         jmp     .die
  197. .version_mismatch:
  198.         lea     eax, [esi + rva syscall_int40]
  199.         mov     FS_SYSCALL_PTR, eax
  200.         add     esi, rva msg_version_mismatch
  201.         call    sys_msg_board_str
  202. .die:
  203.         or      eax, -1
  204.         call    FS_SYSCALL_PTR
  205. .nothing:
  206.         ret
  207. endp
  208.  
  209. proc sys_msg_board_str
  210.         push    eax ebx
  211. @@:
  212.         push    ecx
  213.         mov     cl, [ecx]
  214.         test    cl, cl
  215.         jz      @f
  216.         mov     eax, 63
  217.         mov     ebx, 1
  218.         call    FS_SYSCALL_PTR
  219.         pop     ecx
  220.         inc     ecx
  221.         jmp     @b
  222. @@:
  223.         pop     ecx ebx eax
  224.         ret
  225. endp
  226.  
  227. align 4
  228. syscall_methods dd rva syscall_int40, rva syscall_sysenter, rva syscall_syscall
  229. num_syscall_methods = ($ - syscall_methods) / 4
  230.  
  231. align 4
  232. data export
  233. export 'kolibri.dll' \
  234.         , kercall, 'kercall' \
  235.         , malloc, 'malloc' \
  236.         , free, 'free' \
  237.         , calloc, 'calloc' \
  238.         , realloc, 'realloc' \
  239.         , realloc_in_place, 'realloc_in_place' \
  240.         , memalign, 'memalign' \
  241.         , create_mspace, 'create_mspace' \
  242.         , destroy_mspace, 'destroy_mspace' \
  243.         , mspace_malloc, 'mspace_malloc' \
  244.         , mspace_free, 'mspace_free' \
  245.         , mspace_calloc, 'mspace_calloc' \
  246.         , mspace_realloc, 'mspace_realloc' \
  247.         , mspace_realloc_in_place, 'mspace_realloc_in_place' \
  248.         , mspace_memalign, 'mspace_memalign' \
  249.  
  250. end data
  251.  
  252. kolibri_dll             db      'kolibri.dll',0
  253.  
  254. msg_version_mismatch    db      'S : Version mismatch between kernel and kolibri.dll',13,10,0
  255. msg_bad_relocation1     db      'S : Bad relocation type in ',0
  256. msg_newline             db      13,10,0
  257. msg_relocated1          db      'S : fixups for ',0
  258. msg_relocated2          db      ' applied',13,10,0
  259.  
  260. if FOOTERS
  261. section '.data' data readable writable
  262. malloc_magic    dd      ?
  263. end if
  264.