Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 5559 $
  9.  
  10. include 'export.inc'
  11.  
  12. align 4
  13.  
  14. proc load_PE stdcall, file_name:dword
  15.            locals
  16.              image  dd ?
  17.              entry  dd ?
  18.              base   dd ?
  19.            endl
  20.  
  21.         stdcall load_file, [file_name]
  22.         test    eax, eax
  23.         jz      .fail
  24.  
  25.         mov     [image], eax
  26.  
  27.         mov     edx, [eax+STRIPPED_PE_HEADER.SizeOfImage]
  28. ;        mov     cl, [eax+STRIPPED_PE_HEADER.Subsystem]
  29.         cmp     word [eax], STRIPPED_PE_SIGNATURE
  30.         jz      @f
  31.  
  32.         mov     edx, [eax+60]
  33. ;        mov     cl, [eax+5Ch+edx]
  34.         mov     edx, [eax+80+edx]
  35.  
  36. @@:
  37.         mov     [entry], 0
  38. ;        cmp     cl, 1
  39. ;        jnz     .cleanup
  40.         stdcall kernel_alloc, edx
  41.         test    eax, eax
  42.         jz      .cleanup
  43.  
  44.         mov     [base], eax
  45.         DEBUGF 1,'K : driver %s mapped to %x\n',[file_name],[base]
  46.  
  47.         push    ebx ebp
  48.         mov     ebx, [image]
  49.         mov     ebp, eax
  50.         call    map_PE
  51.         pop     ebp ebx
  52.  
  53.         mov     [entry], eax
  54.         test    eax, eax
  55.         jnz     .cleanup
  56.  
  57.         stdcall kernel_free, [base]
  58. .cleanup:
  59.         stdcall kernel_free, [image]
  60.         mov     eax, [entry]
  61.         ret
  62. .fail:
  63.         xor     eax, eax
  64.         ret
  65. endp
  66.  
  67. map_PE:                    ;ebp=base:dword, ebx=image:dword
  68.         push    edi
  69.         push    esi
  70.         sub     esp, .locals_size
  71. virtual at esp
  72. .numsections    dd      ?
  73. .import_names   dd      ?
  74. .import_targets dd      ?
  75. .peheader       dd      ?
  76. .bad_import     dd      ?
  77. .import_idx     dd      ?
  78. .import_descr   dd      ?
  79. .relocs_rva     dd      ?
  80. .relocs_size    dd      ?
  81. .section_header_size dd ?
  82. .AddressOfEntryPoint    dd ?
  83. .ImageBase      dd      ?
  84. .locals_size = $ - esp
  85. end virtual
  86.         cmp     word [ebx], STRIPPED_PE_SIGNATURE
  87.         jz      .stripped
  88.  
  89.         mov     edx, ebx
  90.         add     edx, [ebx+60]
  91.         movzx   eax, word [edx+6]
  92.         mov     [.numsections], eax
  93.         mov     eax, [edx+40]
  94.         mov     [.AddressOfEntryPoint], eax
  95.         mov     eax, [edx+52]
  96.         mov     [.ImageBase], eax
  97.         mov     ecx, [edx+84]
  98.         mov     [.section_header_size], 40
  99.         mov     eax, [edx+128]
  100.         mov     [.import_descr], eax
  101.         mov     eax, [edx+160]
  102.         mov     [.relocs_rva], eax
  103.         mov     eax, [edx+164]
  104.         mov     [.relocs_size], eax
  105.         add     edx, 256
  106.  
  107.         jmp     .common
  108. .stripped:
  109.         mov     eax, [ebx+STRIPPED_PE_HEADER.AddressOfEntryPoint]
  110.         mov     [.AddressOfEntryPoint], eax
  111.         mov     eax, [ebx+STRIPPED_PE_HEADER.ImageBase]
  112.         mov     [.ImageBase], eax
  113.         movzx   eax, [ebx+STRIPPED_PE_HEADER.NumberOfSections]
  114.         mov     [.numsections], eax
  115.         movzx   ecx, [ebx+STRIPPED_PE_HEADER.NumberOfRvaAndSizes]
  116.         xor     eax, eax
  117.         mov     [.relocs_rva], eax
  118.         mov     [.relocs_size], eax
  119.         test    ecx, ecx
  120.         jz      @f
  121.         mov     eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_IMPORT*8]
  122. @@:
  123.         mov     [.import_descr], eax
  124.         cmp     ecx, SPE_DIRECTORY_BASERELOC
  125.         jbe     @f
  126.         mov     eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8]
  127.         mov     [.relocs_rva], eax
  128.         mov     eax, [ebx+sizeof.STRIPPED_PE_HEADER+SPE_DIRECTORY_BASERELOC*8+4]
  129.         mov     [.relocs_size], eax
  130. @@:
  131.         mov     [.section_header_size], 28
  132.         lea     edx, [ebx+ecx*8+sizeof.STRIPPED_PE_HEADER+8]
  133.         mov     ecx, [ebx+STRIPPED_PE_HEADER.SizeOfHeaders]
  134.  
  135. .common:
  136.         mov     esi, ebx
  137.         mov     edi, ebp
  138.         shr     ecx, 2
  139.         rep movsd
  140.  
  141.         cmp     [.numsections], 0
  142.         jz      .nosections
  143. .copy_sections:
  144.         mov     eax, [edx+8]
  145.         test    eax, eax
  146.         je      .no_section_data
  147.         mov     esi, ebx
  148.         mov     edi, ebp
  149.         add     esi, [edx+12]
  150.         mov     ecx, eax
  151.         add     edi, [edx+4]
  152.  
  153.         add     ecx, 3
  154.         shr     ecx, 2
  155.         rep movsd
  156.  
  157. .no_section_data:
  158.         mov     ecx, [edx]
  159.         cmp     ecx, eax
  160.         jbe     .no_section_fill
  161.         sub     ecx, eax
  162.         add     eax, [edx+4]
  163.         lea     edi, [eax+ebp]
  164.  
  165.         xor     eax, eax
  166.         rep stosb
  167.  
  168. .no_section_fill:
  169.         add     edx, [.section_header_size]
  170.         dec     [.numsections]
  171.         jnz     .copy_sections
  172. .nosections:
  173.         cmp     [.relocs_size], 0
  174.         je      .no_relocations
  175.         mov     esi, ebp
  176.         mov     ecx, ebp
  177.         sub     esi, [.ImageBase]
  178.         add     ecx, [.relocs_rva]
  179. .relocs_block:
  180.         mov     edi, [ecx]
  181.         add     edi, ebp
  182.         mov     ebx, [ecx+4]
  183.         add     ecx, 8
  184.         sub     [.relocs_size], ebx
  185.         sub     ebx, 8
  186.         shr     ebx, 1
  187.         jz      .relocs_next_block
  188. .one_reloc:
  189.         movzx   eax, word [ecx]
  190.         add     ecx, 2
  191.         mov     edx, eax
  192.         shr     eax, 12
  193.         and     edx, 4095
  194.         cmp     eax, 3
  195.         jne     @f
  196.         add     [edx+edi], esi
  197. @@:
  198.         dec     ebx
  199.         jnz     .one_reloc
  200. .relocs_next_block:
  201.         cmp     [.relocs_size], 0
  202.         jg      .relocs_block
  203. .no_relocations:
  204.         cmp     [.import_descr], 0
  205.         je      .no_imports
  206.         add     [.import_descr], ebp
  207.         mov     [.bad_import], 0
  208. .import_block:
  209.         mov     ecx, [.import_descr]
  210.         cmp     dword [ecx+4], 0
  211.         jne     @f
  212.         cmp     dword [ecx+12], 0
  213.         je      .done_imports
  214. @@:
  215.         mov     edx, dword [ecx]
  216.         mov     ecx, dword [ecx+16]
  217.         test    edx, edx
  218.         jnz     @f
  219.         mov     edx, ecx
  220. @@:
  221.         mov     [.import_idx], 0
  222.         add     ecx, ebp
  223.         add     edx, ebp
  224.         mov     [.import_names], edx
  225.         mov     [.import_targets], ecx
  226. .import_func:
  227.         mov     esi, [.import_idx]
  228.         mov     edi, [.import_names]
  229.         mov     eax, [edi+esi*4]
  230.         test    eax, eax
  231.         je      .next_import_block
  232.         js      .next_import_block
  233.         lea     edi, [ebp+eax]
  234.         mov     eax, [.import_targets]
  235.         mov     dword [eax+esi*4], 0
  236.         lea     esi, [edi+2]
  237.         movzx   ebx, word [edi]
  238.         push    32
  239.         mov     ecx, [__exports+32]
  240.         mov     eax, [ecx+OS_BASE+ebx*4]
  241.         add     eax, OS_BASE
  242.         push    eax
  243.         push    esi
  244.         call    strncmp
  245.         test    eax, eax
  246.         jz      .import_func_found
  247.         xor     ebx, ebx
  248. .import_func_candidate:
  249.         push    32
  250.         mov     ecx, [__exports+32]
  251.         mov     eax, [ecx+OS_BASE+ebx*4]
  252.         add     eax, OS_BASE
  253.         push    eax
  254.         push    esi
  255.         call    strncmp
  256.         test    eax, eax
  257.         je      .import_func_found
  258.         inc     ebx
  259.         cmp     ebx, [__exports+24]
  260.         jb      .import_func_candidate
  261.  
  262.         mov     esi, msg_unresolved
  263.         call    sys_msg_board_str
  264.         lea     esi, [edi+2]
  265.         call    sys_msg_board_str
  266.         mov     esi, msg_CR
  267.         call    sys_msg_board_str
  268.  
  269.         mov     [.bad_import], 1
  270.         jmp     .next_import_func
  271. .import_func_found:
  272.         mov     esi, [__exports+28]
  273.         mov     edx, [.import_idx]
  274.         mov     ecx, [.import_targets]
  275.         mov     eax, [esi+OS_BASE+ebx*4]
  276.         add     eax, OS_BASE
  277.         mov     [ecx+edx*4], eax
  278. .next_import_func:
  279.         inc     [.import_idx]
  280.         jmp     .import_func
  281. .next_import_block:
  282.         add     [.import_descr], 20
  283.         jmp     .import_block
  284. .done_imports:
  285.         xor     eax, eax
  286.         cmp     [.bad_import], 0
  287.         jne     @f
  288. .no_imports:
  289.         mov     eax, ebp
  290.         add     eax, [.AddressOfEntryPoint]
  291. @@:
  292.         add     esp, .locals_size
  293.         pop     esi
  294.         pop     edi
  295.         ret
  296.