Subversion Repositories Kolibri OS

Rev

Rev 2665 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. ; flat assembler core
  3. ; Copyright (c) 1999-2013, Tomasz Grysztar.
  4. ; All rights reserved.
  5.  
  6. formatter:
  7.         mov     [current_offset],edi
  8.         cmp     [output_file],0
  9.         jne     output_path_ok
  10.         mov     esi,[input_file]
  11.         mov     edi,[free_additional_memory]
  12.       copy_output_path:
  13.         lods    byte [esi]
  14.         cmp     edi,[structures_buffer]
  15.         jae     out_of_memory
  16.         stos    byte [edi]
  17.         or      al,al
  18.         jnz     copy_output_path
  19.         dec     edi
  20.         mov     eax,edi
  21.       find_extension:
  22.         dec     eax
  23.         cmp     eax,[free_additional_memory]
  24.         jb      extension_found
  25.         cmp     byte [eax],'\'
  26.         je      extension_found
  27.         cmp     byte [eax],'/'
  28.         je      extension_found
  29.         cmp     byte [eax],'.'
  30.         jne     find_extension
  31.         mov     edi,eax
  32.       extension_found:
  33.         lea     eax,[edi+9]
  34.         cmp     eax,[structures_buffer]
  35.         jae     out_of_memory
  36.         cmp     [file_extension],0
  37.         jne     extension_specified
  38.         mov     al,[output_format]
  39.         cmp     al,2
  40.         je      exe_extension
  41.         jb      bin_extension
  42.         cmp     al,4
  43.         je      obj_extension
  44.         cmp     al,5
  45.         je      o_extension
  46.         cmp     al,3
  47.         jne     no_extension
  48.         cmp     [subsystem],1
  49.         je      sys_extension
  50.         cmp     [subsystem],10
  51.         jae     efi_extension
  52.         bt      [format_flags],8
  53.         jnc     exe_extension
  54.         mov     eax,'.dll'
  55.         jmp     make_extension
  56.       sys_extension:
  57.         mov     eax,'.sys'
  58.         jmp     make_extension
  59.       efi_extension:
  60.         mov     eax,'.efi'
  61.         jmp     make_extension
  62.       bin_extension:
  63.         mov     eax,'.bin'
  64.         bt      [format_flags],0
  65.         jnc     make_extension
  66.         mov     eax,'.com'
  67.         jmp     make_extension
  68.       obj_extension:
  69.         mov     eax,'.obj'
  70.         jmp     make_extension
  71.       o_extension:
  72.         mov     eax,'.o'
  73.         bt      [format_flags],0
  74.         jnc     make_extension
  75.       no_extension:
  76.         xor     eax,eax
  77.         jmp     make_extension
  78.       exe_extension:
  79.         mov     eax,'.exe'
  80.       make_extension:
  81.         xchg    eax,[edi]
  82.         scas    dword [edi]
  83.         mov     byte [edi],0
  84.         scas    byte [edi]
  85.         mov     esi,edi
  86.         stos    dword [edi]
  87.         sub     edi,9
  88.         xor     eax,eax
  89.         mov     ebx,characters
  90.       adapt_case:
  91.         mov     al,[esi]
  92.         or      al,al
  93.         jz      adapt_next
  94.         xlat    byte [ebx]
  95.         cmp     al,[esi]
  96.         je      adapt_ok
  97.         sub     byte [edi],20h
  98.       adapt_ok:
  99.         inc     esi
  100.       adapt_next:
  101.         inc     edi
  102.         cmp     byte [edi],0
  103.         jne     adapt_case
  104.         jmp     extension_ok
  105.       extension_specified:
  106.         mov     al,'.'
  107.         stos    byte [edi]
  108.         mov     esi,[file_extension]
  109.       copy_extension:
  110.         lods    byte [esi]
  111.         stos    byte [edi]
  112.         test    al,al
  113.         jnz     copy_extension
  114.         dec     edi
  115.       extension_ok:
  116.         mov     esi,edi
  117.         lea     ecx,[esi+1]
  118.         sub     ecx,[free_additional_memory]
  119.         mov     edi,[structures_buffer]
  120.         dec     edi
  121.         std
  122.         rep     movs byte [edi],[esi]
  123.         cld
  124.         inc     edi
  125.         mov     [structures_buffer],edi
  126.         mov     [output_file],edi
  127.       output_path_ok:
  128.         cmp     [symbols_file],0
  129.         je      labels_table_ok
  130.         mov     ecx,[memory_end]
  131.         sub     ecx,[labels_list]
  132.         mov     edi,[tagged_blocks]
  133.         sub     edi,8
  134.         mov     [edi],ecx
  135.         or      dword [edi+4],-1
  136.         sub     edi,ecx
  137.         cmp     edi,[current_offset]
  138.         jbe     out_of_memory
  139.         mov     [tagged_blocks],edi
  140.         mov     esi,[memory_end]
  141.       copy_labels:
  142.         sub     esi,32
  143.         cmp     esi,[labels_list]
  144.         jb      labels_table_ok
  145.         mov     ecx,32 shr 2
  146.         rep     movs dword [edi],[esi]
  147.         sub     esi,32
  148.         jmp     copy_labels
  149.       labels_table_ok:
  150.         mov     edi,[current_offset]
  151.         cmp     [output_format],4
  152.         je      coff_formatter
  153.         cmp     [output_format],5
  154.         jne     common_formatter
  155.         bt      [format_flags],0
  156.         jnc     elf_formatter
  157.       common_formatter:
  158.         mov     eax,edi
  159.         sub     eax,[code_start]
  160.         mov     [real_code_size],eax
  161.         cmp     edi,[undefined_data_end]
  162.         jne     calculate_code_size
  163.         mov     edi,[undefined_data_start]
  164.       calculate_code_size:
  165.         mov     [current_offset],edi
  166.         sub     edi,[code_start]
  167.         mov     [code_size],edi
  168.         and     [written_size],0
  169.         mov     edx,[output_file]
  170.         call    create
  171.         jc      write_failed
  172.         cmp     [output_format],3
  173.         jne     stub_written
  174.         mov     edx,[code_start]
  175.         mov     ecx,[stub_size]
  176.         sub     edx,ecx
  177.         add     [written_size],ecx
  178.         call    write
  179.       stub_written:
  180.         cmp     [output_format],2
  181.         jne     write_output
  182.         call    write_mz_header
  183.       write_output:
  184.         call    write_code
  185.       output_written:
  186.         call    close
  187.         cmp     [symbols_file],0
  188.         jne     dump_symbols
  189.         ret
  190.       write_code:
  191.         mov     eax,[written_size]
  192.         mov     [headers_size],eax
  193.         mov     edx,[code_start]
  194.         mov     ecx,[code_size]
  195.         add     [written_size],ecx
  196.         lea     eax,[edx+ecx]
  197.         call    write
  198.         jc      write_failed
  199.         ret
  200. format_directive:
  201.         cmp     edi,[code_start]
  202.         jne     unexpected_instruction
  203.         mov     ebp,[addressing_space]
  204.         test    byte [ds:ebp+0Ah],1
  205.         jnz     unexpected_instruction
  206.         cmp     [output_format],0
  207.         jne     unexpected_instruction
  208.         lods    byte [esi]
  209.         cmp     al,1Ch
  210.         je      format_prefix
  211.         cmp     al,18h
  212.         jne     invalid_argument
  213.         lods    byte [esi]
  214.       select_format:
  215.         mov     dl,al
  216.         shr     al,4
  217.         mov     [output_format],al
  218.         and     edx,0Fh
  219.         or      [format_flags],edx
  220.         cmp     al,2
  221.         je      format_mz
  222.         cmp     al,3
  223.         je      format_pe
  224.         cmp     al,4
  225.         je      format_coff
  226.         cmp     al,5
  227.         je      format_elf
  228.       format_defined:
  229.         cmp     byte [esi],86h
  230.         jne     instruction_assembled
  231.         cmp     word [esi+1],'('
  232.         jne     invalid_argument
  233.         mov     eax,[esi+3]
  234.         add     esi,3+4
  235.         mov     [file_extension],esi
  236.         lea     esi,[esi+eax+1]
  237.         jmp     instruction_assembled
  238.       format_prefix:
  239.         lods    byte [esi]
  240.         mov     ah,al
  241.         lods    byte [esi]
  242.         cmp     al,18h
  243.         jne     invalid_argument
  244.         lods    byte [esi]
  245.         mov     edx,eax
  246.         shr     dl,4
  247.         shr     dh,4
  248.         cmp     dl,dh
  249.         jne     invalid_argument
  250.         or      al,ah
  251.         jmp     select_format
  252. entry_directive:
  253.         bts     [format_flags],10h
  254.         jc      setting_already_specified
  255.         mov     al,[output_format]
  256.         cmp     al,2
  257.         je      mz_entry
  258.         cmp     al,3
  259.         je      pe_entry
  260.         cmp     al,5
  261.         jne     illegal_instruction
  262.         bt      [format_flags],0
  263.         jc      elf_entry
  264.         jmp     illegal_instruction
  265. stack_directive:
  266.         bts     [format_flags],11h
  267.         jc      setting_already_specified
  268.         mov     al,[output_format]
  269.         cmp     al,2
  270.         je      mz_stack
  271.         cmp     al,3
  272.         je      pe_stack
  273.         jmp     illegal_instruction
  274. heap_directive:
  275.         bts     [format_flags],12h
  276.         jc      setting_already_specified
  277.         mov     al,[output_format]
  278.         cmp     al,2
  279.         je      mz_heap
  280.         cmp     al,3
  281.         je      pe_heap
  282.         jmp     illegal_instruction
  283. segment_directive:
  284.         mov     al,[output_format]
  285.         cmp     al,2
  286.         je      mz_segment
  287.         cmp     al,5
  288.         je      elf_segment
  289.         jmp     illegal_instruction
  290. section_directive:
  291.         mov     al,[output_format]
  292.         cmp     al,3
  293.         je      pe_section
  294.         cmp     al,4
  295.         je      coff_section
  296.         cmp     al,5
  297.         je      elf_section
  298.         jmp     illegal_instruction
  299. public_directive:
  300.         mov     al,[output_format]
  301.         cmp     al,4
  302.         je      public_allowed
  303.         cmp     al,5
  304.         jne     illegal_instruction
  305.         bt      [format_flags],0
  306.         jc      illegal_instruction
  307.       public_allowed:
  308.         mov     [base_code],0C0h
  309.         lods    byte [esi]
  310.         cmp     al,2
  311.         je      public_label
  312.         cmp     al,1Dh
  313.         jne     invalid_argument
  314.         lods    byte [esi]
  315.         and     al,7
  316.         add     [base_code],al
  317.         lods    byte [esi]
  318.         cmp     al,2
  319.         jne     invalid_argument
  320.       public_label:
  321.         lods    dword [esi]
  322.         cmp     eax,0Fh
  323.         jb      invalid_use_of_symbol
  324.         je      reserved_word_used_as_symbol
  325.         inc     esi
  326.         mov     dx,[current_pass]
  327.         mov     [eax+18],dx
  328.         or      byte [eax+8],8
  329.         cmp     [symbols_file],0
  330.         je      public_reference_ok
  331.         cmp     [next_pass_needed],0
  332.         jne     public_reference_ok
  333.         mov     ebx,eax
  334.         call    store_label_reference
  335.         mov     eax,ebx
  336.       public_reference_ok:
  337.         mov     ebx,[free_additional_memory]
  338.         lea     edx,[ebx+10h]
  339.         cmp     edx,[structures_buffer]
  340.         jae     out_of_memory
  341.         mov     [free_additional_memory],edx
  342.         mov     [ebx+8],eax
  343.         mov     eax,[current_line]
  344.         mov     [ebx+0Ch],eax
  345.         lods    byte [esi]
  346.         cmp     al,86h
  347.         jne     invalid_argument
  348.         lods    word [esi]
  349.         cmp     ax,'('
  350.         jne     invalid_argument
  351.         mov     [ebx+4],esi
  352.         lods    dword [esi]
  353.         lea     esi,[esi+eax+1]
  354.         mov     al,[base_code]
  355.         mov     [ebx],al
  356.         jmp     instruction_assembled
  357. extrn_directive:
  358.         mov     al,[output_format]
  359.         cmp     al,4
  360.         je      extrn_allowed
  361.         cmp     al,5
  362.         jne     illegal_instruction
  363.         bt      [format_flags],0
  364.         jc      illegal_instruction
  365.       extrn_allowed:
  366.         lods    word [esi]
  367.         cmp     ax,'('
  368.         jne     invalid_argument
  369.         mov     ebx,esi
  370.         lods    dword [esi]
  371.         lea     esi,[esi+eax+1]
  372.         mov     edx,[free_additional_memory]
  373.         lea     eax,[edx+0Ch]
  374.         cmp     eax,[structures_buffer]
  375.         jae     out_of_memory
  376.         mov     [free_additional_memory],eax
  377.         mov     byte [edx],80h
  378.         mov     [edx+4],ebx
  379.         lods    byte [esi]
  380.         cmp     al,86h
  381.         jne     invalid_argument
  382.         lods    byte [esi]
  383.         cmp     al,2
  384.         jne     invalid_argument
  385.         lods    dword [esi]
  386.         cmp     eax,0Fh
  387.         jb      invalid_use_of_symbol
  388.         je      reserved_word_used_as_symbol
  389.         inc     esi
  390.         mov     ebx,eax
  391.         xor     ah,ah
  392.         lods    byte [esi]
  393.         cmp     al,':'
  394.         je      get_extrn_size
  395.         dec     esi
  396.         cmp     al,11h
  397.         jne     extrn_size_ok
  398.       get_extrn_size:
  399.         lods    word [esi]
  400.         cmp     al,11h
  401.         jne     invalid_argument
  402.       extrn_size_ok:
  403.         mov     [address_symbol],edx
  404.         mov     [label_size],ah
  405.         movzx   ecx,ah
  406.         mov     [edx+8],ecx
  407.         xor     eax,eax
  408.         xor     edx,edx
  409.         xor     ebp,ebp
  410.         mov     [address_sign],0
  411.         mov     ch,2
  412.         test    [format_flags],8
  413.         jz      make_free_label
  414.         mov     ch,4
  415.         jmp     make_free_label
  416. mark_relocation:
  417.         cmp     [value_type],0
  418.         je      relocation_ok
  419.         mov     ebp,[addressing_space]
  420.         test    byte [ds:ebp+0Ah],1
  421.         jnz     relocation_ok
  422.         cmp     [output_format],2
  423.         je      mark_mz_relocation
  424.         cmp     [output_format],3
  425.         je      mark_pe_relocation
  426.         cmp     [output_format],4
  427.         je      mark_coff_relocation
  428.         cmp     [output_format],5
  429.         je      mark_elf_relocation
  430.       relocation_ok:
  431.         ret
  432. close_pass:
  433.         mov     al,[output_format]
  434.         cmp     al,3
  435.         je      close_pe
  436.         cmp     al,4
  437.         je      close_coff
  438.         cmp     al,5
  439.         je      close_elf
  440.         ret
  441.  
  442. format_mz:
  443.         mov     edx,[additional_memory]
  444.         push    edi
  445.         mov     edi,edx
  446.         mov     ecx,1Ch shr 2
  447.         xor     eax,eax
  448.         rep     stos dword [edi]
  449.         mov     [free_additional_memory],edi
  450.         pop     edi
  451.         mov     word [edx+0Ch],0FFFFh
  452.         mov     word [edx+10h],1000h
  453.         mov     [code_type],16
  454.         jmp     format_defined
  455. mark_mz_relocation:
  456.         push    eax ebx
  457.         inc     [number_of_relocations]
  458.         mov     ebx,[free_additional_memory]
  459.         mov     eax,edi
  460.         sub     eax,[code_start]
  461.         mov     [ebx],ax
  462.         shr     eax,16
  463.         shl     ax,12
  464.         mov     [ebx+2],ax
  465.         cmp     word [ebx],0FFFFh
  466.         jne     mz_relocation_ok
  467.         inc     word [ebx+2]
  468.         sub     word [ebx],10h
  469.       mz_relocation_ok:
  470.         add     ebx,4
  471.         cmp     ebx,[structures_buffer]
  472.         jae     out_of_memory
  473.         mov     [free_additional_memory],ebx
  474.         pop     ebx eax
  475.         ret
  476. mz_segment:
  477.         lods    byte [esi]
  478.         cmp     al,2
  479.         jne     invalid_argument
  480.         lods    dword [esi]
  481.         cmp     eax,0Fh
  482.         jb      invalid_use_of_symbol
  483.         je      reserved_word_used_as_symbol
  484.         inc     esi
  485.         mov     ebx,eax
  486.         mov     eax,edi
  487.         sub     eax,[code_start]
  488.         mov     ecx,0Fh
  489.         add     eax,0Fh
  490.         and     eax,1111b
  491.         sub     ecx,eax
  492.         mov     edx,edi
  493.         xor     eax,eax
  494.         rep     stos byte [edi]
  495.         mov     eax,edx
  496.         call    undefined_data
  497.         push    ebx
  498.         call    create_addressing_space
  499.         pop     ebx
  500.         mov     eax,edi
  501.         sub     eax,[code_start]
  502.         shr     eax,4
  503.         cmp     eax,10000h
  504.         jae     value_out_of_range
  505.         mov     edx,eax
  506.         mov     al,16
  507.         cmp     byte [esi],13h
  508.         jne     segment_type_ok
  509.         inc     esi
  510.         lods    byte [esi]
  511.       segment_type_ok:
  512.         mov     [code_type],al
  513.         mov     eax,edx
  514.         mov     ch,1
  515.         mov     [address_sign],0
  516.         xor     edx,edx
  517.         xor     ebp,ebp
  518.         mov     [label_size],0
  519.         mov     [address_symbol],edx
  520.         jmp     make_free_label
  521. mz_entry:
  522.         lods    byte [esi]
  523.         cmp     al,'('
  524.         jne     invalid_argument
  525.         call    get_word_value
  526.         cmp     [value_type],1
  527.         je      initial_cs_ok
  528.         call    recoverable_invalid_address
  529.       initial_cs_ok:
  530.         mov     edx,[additional_memory]
  531.         mov     [edx+16h],ax
  532.         lods    byte [esi]
  533.         cmp     al,':'
  534.         jne     invalid_argument
  535.         lods    byte [esi]
  536.         cmp     al,'('
  537.         jne     invalid_argument
  538.         ja      invalid_address
  539.         call    get_word_value
  540.         cmp     [value_type],0
  541.         jne     invalid_use_of_symbol
  542.         mov     edx,[additional_memory]
  543.         mov     [edx+14h],ax
  544.         jmp     instruction_assembled
  545.       recoverable_invalid_address:
  546.         cmp     [error_line],0
  547.         jne     ignore_invalid_address
  548.         push    [current_line]
  549.         pop     [error_line]
  550.         mov     [error],invalid_address
  551.       ignore_invalid_address:
  552.         ret
  553. mz_stack:
  554.         lods    byte [esi]
  555.         cmp     al,'('
  556.         jne     invalid_argument
  557.         call    get_word_value
  558.         cmp     byte [esi],':'
  559.         je      stack_pointer
  560.         cmp     ax,10h
  561.         jb      invalid_value
  562.         cmp     [value_type],0
  563.         jne     invalid_use_of_symbol
  564.         mov     edx,[additional_memory]
  565.         mov     [edx+10h],ax
  566.         jmp     instruction_assembled
  567.       stack_pointer:
  568.         cmp     [value_type],1
  569.         je      initial_ss_ok
  570.         call    recoverable_invalid_address
  571.       initial_ss_ok:
  572.         mov     edx,[additional_memory]
  573.         mov     [edx+0Eh],ax
  574.         lods    byte [esi]
  575.         cmp     al,':'
  576.         jne     invalid_argument
  577.         lods    byte [esi]
  578.         cmp     al,'('
  579.         jne     invalid_argument
  580.         call    get_word_value
  581.         cmp     [value_type],0
  582.         jne     invalid_use_of_symbol
  583.         mov     edx,[additional_memory]
  584.         mov     [edx+10h],ax
  585.         bts     [format_flags],4
  586.         jmp     instruction_assembled
  587. mz_heap:
  588.         cmp     [output_format],2
  589.         jne     illegal_instruction
  590.         lods    byte [esi]
  591.         call    get_size_operator
  592.         cmp     ah,1
  593.         je      invalid_value
  594.         cmp     ah,2
  595.         ja      invalid_value
  596.         cmp     al,'('
  597.         jne     invalid_argument
  598.         call    get_word_value
  599.         cmp     [value_type],0
  600.         jne     invalid_use_of_symbol
  601.         mov     edx,[additional_memory]
  602.         mov     [edx+0Ch],ax
  603.         jmp     instruction_assembled
  604. write_mz_header:
  605.         mov     edx,[additional_memory]
  606.         bt      [format_flags],4
  607.         jc      mz_stack_ok
  608.         mov     eax,[real_code_size]
  609.         dec     eax
  610.         shr     eax,4
  611.         inc     eax
  612.         mov     [edx+0Eh],ax
  613.         shl     eax,4
  614.         movzx   ecx,word [edx+10h]
  615.         add     eax,ecx
  616.         mov     [real_code_size],eax
  617.       mz_stack_ok:
  618.         mov     edi,[free_additional_memory]
  619.         mov     eax,[number_of_relocations]
  620.         shl     eax,2
  621.         add     eax,1Ch
  622.         sub     edi,eax
  623.         xchg    edi,[free_additional_memory]
  624.         mov     ecx,0Fh
  625.         add     eax,0Fh
  626.         and     eax,1111b
  627.         sub     ecx,eax
  628.         xor     al,al
  629.         rep     stos byte [edi]
  630.         sub     edi,[free_additional_memory]
  631.         mov     ecx,edi
  632.         shr     edi,4
  633.         mov     word [edx],'MZ'         ; signature
  634.         mov     [edx+8],di              ; header size in paragraphs
  635.         mov     eax,[number_of_relocations]
  636.         mov     [edx+6],ax              ; number of relocation entries
  637.         mov     eax,[code_size]
  638.         add     eax,ecx
  639.         mov     esi,eax
  640.         shr     esi,9
  641.         and     eax,1FFh
  642.         inc     si
  643.         or      ax,ax
  644.         jnz     mz_size_ok
  645.         dec     si
  646.       mz_size_ok:
  647.         mov     [edx+2],ax              ; number of bytes in last page
  648.         mov     [edx+4],si              ; number of pages
  649.         mov     eax,[real_code_size]
  650.         dec     eax
  651.         shr     eax,4
  652.         inc     eax
  653.         mov     esi,[code_size]
  654.         dec     esi
  655.         shr     esi,4
  656.         inc     esi
  657.         sub     eax,esi
  658.         mov     [edx+0Ah],ax            ; minimum memory in addition to code
  659.         add     [edx+0Ch],ax            ; maximum memory in addition to code
  660.         salc
  661.         mov     ah,al
  662.         or      [edx+0Ch],ax
  663.         mov     word [edx+18h],1Ch      ; offset of relocation table
  664.         add     [written_size],ecx
  665.         call    write
  666.         jc      write_failed
  667.         ret
  668.  
  669. make_stub:
  670.         mov     [stub_file],edx
  671.         or      edx,edx
  672.         jnz     stub_from_file
  673.         push    esi
  674.         mov     edx,edi
  675.         xor     eax,eax
  676.         mov     ecx,20h
  677.         rep     stos dword [edi]
  678.         mov     eax,40h+default_stub_end-default_stub
  679.         mov     cx,100h+default_stub_end-default_stub
  680.         mov     word [edx],'MZ'
  681.         mov     byte [edx+4],1
  682.         mov     word [edx+2],ax
  683.         mov     byte [edx+8],4
  684.         mov     byte [edx+0Ah],10h
  685.         mov     word [edx+0Ch],0FFFFh
  686.         mov     word [edx+10h],cx
  687.         mov     word [edx+3Ch],ax
  688.         mov     byte [edx+18h],40h
  689.         lea     edi,[edx+40h]
  690.         mov     esi,default_stub
  691.         mov     ecx,default_stub_end-default_stub
  692.         rep     movs byte [edi],[esi]
  693.         pop     esi
  694.         jmp     stub_ok
  695.       default_stub:
  696.         use16
  697.         push    cs
  698.         pop     ds
  699.         mov     dx,stub_message-default_stub
  700.         mov     ah,9
  701.         int     21h
  702.         mov     ax,4C01h
  703.         int     21h
  704.       stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
  705.         rq      1
  706.       default_stub_end:
  707.         use32
  708.       stub_from_file:
  709.         push    esi
  710.         mov     esi,edx
  711.         call    open_binary_file
  712.         mov     edx,edi
  713.         mov     ecx,1Ch
  714.         mov     esi,edx
  715.         call    read
  716.         jc      binary_stub
  717.         cmp     word [esi],'MZ'
  718.         jne     binary_stub
  719.         add     edi,1Ch
  720.         movzx   ecx,word [esi+6]
  721.         add     ecx,11b
  722.         and     ecx,not 11b
  723.         add     ecx,(40h-1Ch) shr 2
  724.         lea     eax,[edi+ecx*4]
  725.         cmp     edi,[tagged_blocks]
  726.         jae     out_of_memory
  727.         xor     eax,eax
  728.         rep     stos dword [edi]
  729.         mov     edx,40h
  730.         xchg    dx,[esi+18h]
  731.         xor     al,al
  732.         call    lseek
  733.         movzx   ecx,word [esi+6]
  734.         shl     ecx,2
  735.         lea     edx,[esi+40h]
  736.         call    read
  737.         mov     edx,edi
  738.         sub     edx,esi
  739.         shr     edx,4
  740.         xchg    dx,[esi+8]
  741.         shl     edx,4
  742.         xor     al,al
  743.         call    lseek
  744.         movzx   ecx,word [esi+4]
  745.         dec     ecx
  746.         shl     ecx,9
  747.         movzx   edx,word [esi+2]
  748.         test    edx,edx
  749.         jnz     stub_header_size_ok
  750.         mov     dx,200h
  751.      stub_header_size_ok:
  752.         add     ecx,edx
  753.         mov     edx,edi
  754.         sub     ecx,eax
  755.         je      read_stub_code
  756.         jb      stub_code_ok
  757.         push    ecx
  758.         dec     ecx
  759.         shr     ecx,3
  760.         inc     ecx
  761.         shl     ecx,1
  762.         lea     eax,[edi+ecx*4]
  763.         cmp     eax,[tagged_blocks]
  764.         jae     out_of_memory
  765.         xor     eax,eax
  766.         rep     stos dword [edi]
  767.         pop     ecx
  768.      read_stub_code:
  769.         call    read
  770.      stub_code_ok:
  771.         call    close
  772.         mov     edx,edi
  773.         sub     edx,esi
  774.         mov     ax,dx
  775.         and     ax,1FFh
  776.         mov     [esi+2],ax
  777.         dec     edx
  778.         shr     edx,9
  779.         inc     edx
  780.         mov     [esi+4],dx
  781.         mov     eax,edi
  782.         sub     eax,esi
  783.         mov     [esi+3Ch],eax
  784.         pop     esi
  785.       stub_ok:
  786.         ret
  787.       binary_stub:
  788.         mov     esi,edi
  789.         mov     ecx,40h shr 2
  790.         xor     eax,eax
  791.         rep     stos dword [edi]
  792.         mov     al,2
  793.         xor     edx,edx
  794.         call    lseek
  795.         push    eax
  796.         xor     al,al
  797.         xor     edx,edx
  798.         call    lseek
  799.         mov     ecx,[esp]
  800.         add     ecx,40h+111b
  801.         and     ecx,not 111b
  802.         mov     ax,cx
  803.         and     ax,1FFh
  804.         mov     [esi+2],ax
  805.         lea     eax,[ecx+1FFh]
  806.         shr     eax,9
  807.         mov     [esi+4],ax
  808.         mov     [esi+3Ch],ecx
  809.         sub     ecx,40h
  810.         mov     eax,10000h
  811.         sub     eax,ecx
  812.         jbe     binary_heap_ok
  813.         shr     eax,4
  814.         mov     [esi+0Ah],ax
  815.       binary_heap_ok:
  816.         mov     word [esi],'MZ'
  817.         mov     byte [esi+8],4
  818.         mov     ax,0FFFFh
  819.         mov     [esi+0Ch],ax
  820.         dec     ax
  821.         mov     [esi+10h],ax
  822.         sub     ax,0Eh
  823.         mov     [esi+0Eh],ax
  824.         mov     [esi+16h],ax
  825.         mov     word [esi+14h],100h
  826.         mov     byte [esi+18h],40h
  827.         mov     eax,[tagged_blocks]
  828.         sub     eax,ecx
  829.         cmp     edi,eax
  830.         jae     out_of_memory
  831.         mov     edx,edi
  832.         shr     ecx,2
  833.         xor     eax,eax
  834.         rep     stos dword [edi]
  835.         pop     ecx
  836.         call    read
  837.         call    close
  838.         pop     esi
  839.         ret
  840.  
  841. format_pe:
  842.         xor     edx,edx
  843.         mov     [machine],14Ch
  844.         mov     [subsystem],3
  845.         mov     [subsystem_version],3 + 10 shl 16
  846.         mov     [image_base],400000h
  847.         and     [image_base_high],0
  848.         test    [format_flags],8
  849.         jz      pe_settings
  850.         mov     [machine],8664h
  851.         mov     [subsystem_version],5 + 0 shl 16
  852.       pe_settings:
  853.         cmp     byte [esi],84h
  854.         je      get_stub_name
  855.         cmp     byte [esi],80h
  856.         je      get_pe_base
  857.         cmp     byte [esi],1Bh
  858.         jne     pe_settings_ok
  859.         lods    byte [esi]
  860.         lods    byte [esi]
  861.         test    al,80h+40h
  862.         jz      subsystem_setting
  863.         cmp     al,80h
  864.         je      dll_flag
  865.         cmp     al,81h
  866.         je      wdm_flag
  867.         cmp     al,82h
  868.         je      large_flag
  869.         cmp     al,83h
  870.         je      nx_flag
  871.         jmp     pe_settings
  872.       dll_flag:
  873.         bts     [format_flags],8
  874.         jc      setting_already_specified
  875.         jmp     pe_settings
  876.       wdm_flag:
  877.         bts     [format_flags],9
  878.         jc      setting_already_specified
  879.         jmp     pe_settings
  880.       large_flag:
  881.         bts     [format_flags],11
  882.         jc      setting_already_specified
  883.         test    [format_flags],8
  884.         jnz     invalid_argument
  885.         jmp     pe_settings
  886.       nx_flag:
  887.         bts     [format_flags],12
  888.         jc      setting_already_specified
  889.         jmp     pe_settings
  890.       subsystem_setting:
  891.         bts     [format_flags],7
  892.         jc      setting_already_specified
  893.         and     ax,3Fh
  894.         mov     [subsystem],ax
  895.         cmp     ax,10
  896.         jb      subsystem_type_ok
  897.         or      [format_flags],4
  898.       subsystem_type_ok:
  899.         cmp     byte [esi],'('
  900.         jne     pe_settings
  901.         inc     esi
  902.         cmp     byte [esi],'.'
  903.         jne     invalid_value
  904.         inc     esi
  905.         push    edx
  906.         cmp     byte [esi+11],0
  907.         jne     invalid_value
  908.         cmp     byte [esi+10],2
  909.         ja      invalid_value
  910.         mov     dx,[esi+8]
  911.         cmp     dx,8000h
  912.         je      zero_version
  913.         mov     eax,[esi+4]
  914.         cmp     dx,7
  915.         jg      invalid_value
  916.         mov     cx,7
  917.         sub     cx,dx
  918.         mov     eax,[esi+4]
  919.         shr     eax,cl
  920.         mov     ebx,eax
  921.         shr     ebx,24
  922.         cmp     bl,100
  923.         jae     invalid_value
  924.         and     eax,0FFFFFFh
  925.         mov     ecx,100
  926.         mul     ecx
  927.         shrd    eax,edx,24
  928.         jnc     version_value_ok
  929.         inc     eax
  930.       version_value_ok:
  931.         shl     eax,16
  932.         mov     ax,bx
  933.         jmp     subsystem_version_ok
  934.       zero_version:
  935.         xor     eax,eax
  936.       subsystem_version_ok:
  937.         pop     edx
  938.         add     esi,13
  939.         mov     [subsystem_version],eax
  940.         jmp     pe_settings
  941.       get_pe_base:
  942.         bts     [format_flags],10
  943.         jc      setting_already_specified
  944.         lods    word [esi]
  945.         cmp     ah,'('
  946.         jne     invalid_argument
  947.         cmp     byte [esi],'.'
  948.         je      invalid_value
  949.         push    edx edi
  950.         add     edi,[stub_size]
  951.         test    [format_flags],4
  952.         jnz     get_peplus_base
  953.         call    get_dword_value
  954.         mov     [image_base],eax
  955.         jmp     pe_base_ok
  956.       get_peplus_base:
  957.         call    get_qword_value
  958.         mov     [image_base],eax
  959.         mov     [image_base_high],edx
  960.       pe_base_ok:
  961.         pop     edi edx
  962.         cmp     [value_type],0
  963.         jne     invalid_use_of_symbol
  964.         cmp     byte [esi],84h
  965.         jne     pe_settings_ok
  966.       get_stub_name:
  967.         lods    byte [esi]
  968.         lods    word [esi]
  969.         cmp     ax,'('
  970.         jne     invalid_argument
  971.         lods    dword [esi]
  972.         mov     edx,esi
  973.         add     esi,eax
  974.         inc     esi
  975.       pe_settings_ok:
  976.         mov     ebp,[stub_size]
  977.         or      ebp,ebp
  978.         jz      make_pe_stub
  979.         cmp     edx,[stub_file]
  980.         je      pe_stub_ok
  981.         sub     edi,[stub_size]
  982.         mov     [code_start],edi
  983.       make_pe_stub:
  984.         call    make_stub
  985.         mov     eax,edi
  986.         sub     eax,[code_start]
  987.         mov     [stub_size],eax
  988.         mov     [code_start],edi
  989.         mov     ebp,eax
  990.       pe_stub_ok:
  991.         mov     edx,edi
  992.         mov     ecx,18h+0E0h
  993.         test    [format_flags],4
  994.         jz      zero_pe_header
  995.         add     ecx,10h
  996.       zero_pe_header:
  997.         add     ebp,ecx
  998.         shr     ecx,2
  999.         xor     eax,eax
  1000.         rep     stos dword [edi]
  1001.         mov     word [edx],'PE'         ; signature
  1002.         mov     ax,[machine]
  1003.         mov     word [edx+4],ax
  1004.         mov     byte [edx+38h+1],10h    ; section alignment
  1005.         mov     byte [edx+3Ch+1],2      ; file alignment
  1006.         mov     byte [edx+40h],1        ; OS version
  1007.         mov     eax,[subsystem_version]
  1008.         mov     [edx+48h],eax
  1009.         mov     ax,[subsystem]
  1010.         mov     [edx+5Ch],ax
  1011.         cmp     ax,1
  1012.         jne     pe_alignment_ok
  1013.         mov     eax,20h
  1014.         mov     dword [edx+38h],eax
  1015.         mov     dword [edx+3Ch],eax
  1016.       pe_alignment_ok:
  1017.         mov     word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8
  1018.         test    [format_flags],4
  1019.         jnz     init_peplus_specific
  1020.         mov     byte [edx+14h],0E0h     ; size of optional header
  1021.         mov     dword [edx+16h],10B010Fh; flags and magic value
  1022.         mov     eax,[image_base]
  1023.         mov     [edx+34h],eax
  1024.         mov     byte [edx+60h+1],10h    ; stack reserve
  1025.         mov     byte [edx+64h+1],10h    ; stack commit
  1026.         mov     byte [edx+68h+2],1      ; heap reserve
  1027.         mov     byte [edx+74h],16       ; number of directories
  1028.         jmp     pe_header_ok
  1029.       init_peplus_specific:
  1030.         mov     byte [edx+14h],0F0h     ; size of optional header
  1031.         mov     dword [edx+16h],20B002Fh; flags and magic value
  1032.         mov     eax,[image_base]
  1033.         mov     [edx+30h],eax
  1034.         mov     eax,[image_base_high]
  1035.         mov     [edx+34h],eax
  1036.         mov     byte [edx+60h+1],10h    ; stack reserve
  1037.         mov     byte [edx+68h+1],10h    ; stack commit
  1038.         mov     byte [edx+70h+2],1      ; heap reserve
  1039.         mov     byte [edx+84h],16       ; number of directories
  1040.       pe_header_ok:
  1041.         bsf     ecx,[edx+3Ch]
  1042.         imul    ebx,[number_of_sections],28h
  1043.         or      ebx,ebx
  1044.         jnz     reserve_space_for_section_headers
  1045.         mov     ebx,28h
  1046.       reserve_space_for_section_headers:
  1047.         add     ebx,ebp
  1048.         dec     ebx
  1049.         shr     ebx,cl
  1050.         inc     ebx
  1051.         shl     ebx,cl
  1052.         sub     ebx,ebp
  1053.         mov     ecx,ebx
  1054.         mov     eax,[tagged_blocks]
  1055.         sub     eax,ecx
  1056.         cmp     edi,eax
  1057.         jae     out_of_memory
  1058.         shr     ecx,2
  1059.         xor     eax,eax
  1060.         rep     stos dword [edi]
  1061.         mov     eax,edi
  1062.         sub     eax,[code_start]
  1063.         add     eax,[stub_size]
  1064.         mov     [edx+54h],eax           ; size of headers
  1065.         mov     ecx,[edx+38h]
  1066.         dec     ecx
  1067.         add     eax,ecx
  1068.         not     ecx
  1069.         and     eax,ecx
  1070.         bt      [format_flags],8
  1071.         jc      pe_entry_init_ok
  1072.         mov     [edx+28h],eax           ; entry point rva
  1073.       pe_entry_init_ok:
  1074.         and     [number_of_sections],0
  1075.         movzx   ebx,word [edx+14h]
  1076.         lea     ebx,[edx+18h+ebx]
  1077.         mov     [current_section],ebx
  1078.         mov     dword [ebx],'.fla'
  1079.         mov     dword [ebx+4],'t'
  1080.         mov     [ebx+14h],edi
  1081.         mov     [ebx+0Ch],eax
  1082.         mov     dword [ebx+24h],0E0000060h
  1083.         xor     ecx,ecx
  1084.         xor     bl,bl
  1085.         not     eax
  1086.         not     ecx
  1087.         not     bl
  1088.         add     eax,1
  1089.         adc     ecx,0
  1090.         adc     bl,0
  1091.         add     eax,edi
  1092.         adc     ecx,0
  1093.         adc     bl,0
  1094.         test    [format_flags],4
  1095.         jnz     peplus_org
  1096.         sub     eax,[edx+34h]
  1097.         sbb     ecx,0
  1098.         sbb     bl,0
  1099.         jmp     pe_org_ok
  1100.       peplus_org:
  1101.         sub     eax,[edx+30h]
  1102.         sbb     ecx,[edx+34h]
  1103.         sbb     bl,0
  1104.       pe_org_ok:
  1105.         test    [format_flags],8
  1106.         jnz     pe64_code
  1107.         mov     bh,2
  1108.         mov     [code_type],32
  1109.         jmp     pe_code_type_ok
  1110.       pe64_code:
  1111.         mov     bh,4
  1112.         mov     [code_type],64
  1113.       pe_code_type_ok:
  1114.         bt      [resolver_flags],0
  1115.         jc      pe_labels_type_ok
  1116.         xor     bh,bh
  1117.       pe_labels_type_ok:
  1118.         push    eax ebx
  1119.         call    init_addressing_space
  1120.         mov     ebp,ebx
  1121.         pop     ebx eax
  1122.         mov     [ds:ebp],eax
  1123.         mov     [ds:ebp+4],ecx
  1124.         mov     [ds:ebp+8],bx
  1125.         mov     [ds:ebp+18h],edi
  1126.         bt      [format_flags],8
  1127.         jnc     dll_flag_ok
  1128.         or      byte [edx+16h+1],20h
  1129.       dll_flag_ok:
  1130.         bt      [format_flags],9
  1131.         jnc     wdm_flag_ok
  1132.         or      byte [edx+5Eh+1],20h
  1133.       wdm_flag_ok:
  1134.         bt      [format_flags],11
  1135.         jnc     large_flag_ok
  1136.         or      byte [edx+16h],20h
  1137.       large_flag_ok:
  1138.         bt      [format_flags],12
  1139.         jnc     nx_ok
  1140.         or      byte [edx+5Eh+1],1
  1141.       nx_ok:
  1142.         jmp     format_defined
  1143. pe_section:
  1144.         call    close_pe_section
  1145.         push    eax ebx
  1146.         call    create_addressing_space
  1147.         mov     ebp,ebx
  1148.         pop     ebx eax
  1149.         bts     [format_flags],5
  1150.         lea     ecx,[ebx+28h]
  1151.         add     edx,[edx+54h]
  1152.         sub     edx,[stub_size]
  1153.         cmp     ecx,edx
  1154.         jbe     new_section
  1155.         lea     ebx,[edx-28h]
  1156.         or      [next_pass_needed],-1
  1157.         push    edi
  1158.         mov     edi,ebx
  1159.         mov     ecx,28h shr 4
  1160.         xor     eax,eax
  1161.         rep     stos dword [edi]
  1162.         pop     edi
  1163.       new_section:
  1164.         mov     [ebx+0Ch],eax
  1165.         lods    word [esi]
  1166.         cmp     ax,'('
  1167.         jne     invalid_argument
  1168.         lea     edx,[esi+4]
  1169.         mov     ecx,[esi]
  1170.         lea     esi,[esi+4+ecx+1]
  1171.         cmp     ecx,8
  1172.         ja      name_too_long
  1173.         xor     eax,eax
  1174.         mov     [ebx],eax
  1175.         mov     [ebx+4],eax
  1176.         push    esi edi
  1177.         mov     edi,ebx
  1178.         mov     esi,edx
  1179.         rep     movs byte [edi],[esi]
  1180.         pop     edi esi
  1181.         and     dword [ebx+24h],0
  1182.         mov     [ebx+14h],edi
  1183.         mov     edx,[code_start]
  1184.         mov     eax,edi
  1185.         xor     ecx,ecx
  1186.         sub     eax,[ebx+0Ch]
  1187.         sbb     ecx,0
  1188.         sbb     byte [ds:ebp+8],0
  1189.         mov     byte [ds:ebp+9],2
  1190.         mov     [code_type],32
  1191.         test    [format_flags],8
  1192.         jz      pe_section_code_type_ok
  1193.         mov     byte [ds:ebp+9],4
  1194.         mov     [code_type],64
  1195.       pe_section_code_type_ok:
  1196.         test    [format_flags],4
  1197.         jnz     peplus_section_org
  1198.         sub     eax,[edx+34h]
  1199.         sbb     ecx,0
  1200.         sbb     byte [ds:ebp+8],0
  1201.         bt      [resolver_flags],0
  1202.         jc      pe_section_org_ok
  1203.         mov     byte [ds:ebp+9],0
  1204.         jmp     pe_section_org_ok
  1205.       peplus_section_org:
  1206.         sub     eax,[edx+30h]
  1207.         sbb     ecx,[edx+34h]
  1208.         sbb     byte [ds:ebp+8],0
  1209.         bt      [resolver_flags],0
  1210.         jc      pe_section_org_ok
  1211.         mov     byte [ds:ebp+9],0
  1212.       pe_section_org_ok:
  1213.         mov     [ds:ebp],eax
  1214.         mov     [ds:ebp+4],ecx
  1215.         mov     [ds:ebp+18h],edi
  1216.       get_section_flags:
  1217.         lods    byte [esi]
  1218.         cmp     al,1Ah
  1219.         je      set_directory
  1220.         cmp     al,19h
  1221.         je      section_flag
  1222.         dec     esi
  1223.         jmp     instruction_assembled
  1224.       set_directory:
  1225.         movzx   eax,byte [esi]
  1226.         inc     esi
  1227.         mov     ecx,ebx
  1228.         test    [format_flags],4
  1229.         jnz     peplus_directory
  1230.         xchg    ecx,[edx+78h+eax*8]
  1231.         mov     dword [edx+78h+eax*8+4],-1
  1232.         jmp     pe_directory_set
  1233.       peplus_directory:
  1234.         xchg    ecx,[edx+88h+eax*8]
  1235.         mov     dword [edx+88h+eax*8+4],-1
  1236.       pe_directory_set:
  1237.         or      ecx,ecx
  1238.         jnz     data_already_defined
  1239.         push    ebx edx
  1240.         call    generate_pe_data
  1241.         pop     edx ebx
  1242.         jmp     get_section_flags
  1243.       section_flag:
  1244.         lods    byte [esi]
  1245.         cmp     al,9
  1246.         je      invalid_argument
  1247.         cmp     al,11
  1248.         je      invalid_argument
  1249.         mov     cl,al
  1250.         mov     eax,1
  1251.         shl     eax,cl
  1252.         test    dword [ebx+24h],eax
  1253.         jnz     setting_already_specified
  1254.         or      dword [ebx+24h],eax
  1255.         jmp     get_section_flags
  1256.       close_pe_section:
  1257.         mov     ebx,[current_section]
  1258.         mov     edx,[code_start]
  1259.         mov     eax,edi
  1260.         sub     eax,[ebx+14h]
  1261.         jnz     finish_section
  1262.         bt      [format_flags],5
  1263.         jc      finish_section
  1264.         mov     eax,[ebx+0Ch]
  1265.         ret
  1266.       finish_section:
  1267.         mov     [ebx+8],eax
  1268.         cmp     edi,[undefined_data_end]
  1269.         jne     align_section
  1270.         cmp     dword [edx+38h],1000h
  1271.         jb      align_section
  1272.         mov     edi,[undefined_data_start]
  1273.       align_section:
  1274.         and     [undefined_data_end],0
  1275.         mov     ebp,edi
  1276.         sub     ebp,[ebx+14h]
  1277.         mov     ecx,[edx+3Ch]
  1278.         dec     ecx
  1279.         lea     eax,[ebp+ecx]
  1280.         not     ecx
  1281.         and     eax,ecx
  1282.         mov     [ebx+10h],eax
  1283.         sub     eax,ebp
  1284.         mov     ecx,eax
  1285.         xor     al,al
  1286.         rep     stos byte [edi]
  1287.         mov     eax,[code_start]
  1288.         sub     eax,[stub_size]
  1289.         sub     [ebx+14h],eax
  1290.         mov     ecx,[ebx+10h]
  1291.         test    byte [ebx+24h],20h
  1292.         jz      pe_code_sum_ok
  1293.         add     [edx+1Ch],ecx
  1294.         cmp     dword [edx+2Ch],0
  1295.         jne     pe_code_sum_ok
  1296.         mov     eax,[ebx+0Ch]
  1297.         mov     [edx+2Ch],eax
  1298.       pe_code_sum_ok:
  1299.         test    byte [ebx+24h],40h
  1300.         jz      pe_data_sum_ok
  1301.         add     [edx+20h],ecx
  1302.         test    [format_flags],4
  1303.         jnz     pe_data_sum_ok
  1304.         cmp     dword [edx+30h],0
  1305.         jne     pe_data_sum_ok
  1306.         mov     eax,[ebx+0Ch]
  1307.         mov     [edx+30h],eax
  1308.       pe_data_sum_ok:
  1309.         mov     eax,[ebx+8]
  1310.         or      eax,eax
  1311.         jz      udata_ok
  1312.         cmp     dword [ebx+10h],0
  1313.         jne     udata_ok
  1314.         or      byte [ebx+24h],80h
  1315.         add     [edx+24h],ecx
  1316.       udata_ok:
  1317.         mov     ecx,[edx+38h]
  1318.         dec     ecx
  1319.         add     eax,ecx
  1320.         not     ecx
  1321.         and     eax,ecx
  1322.         add     eax,[ebx+0Ch]
  1323.         add     ebx,28h
  1324.         mov     [current_section],ebx
  1325.         inc     word [number_of_sections]
  1326.         jz      format_limitations_exceeded
  1327.         ret
  1328. data_directive:
  1329.         cmp     [output_format],3
  1330.         jne     illegal_instruction
  1331.         lods    byte [esi]
  1332.         cmp     al,1Ah
  1333.         je      predefined_data_type
  1334.         cmp     al,'('
  1335.         jne     invalid_argument
  1336.         call    get_byte_value
  1337.         cmp     al,16
  1338.         jb      data_type_ok
  1339.         jmp     invalid_value
  1340.       predefined_data_type:
  1341.         movzx   eax,byte [esi]
  1342.         inc     esi
  1343.       data_type_ok:
  1344.         mov     ebx,[current_section]
  1345.         mov     ecx,edi
  1346.         sub     ecx,[ebx+14h]
  1347.         add     ecx,[ebx+0Ch]
  1348.         mov     edx,[code_start]
  1349.         test    [format_flags],4
  1350.         jnz     peplus_data
  1351.         xchg    ecx,[edx+78h+eax*8]
  1352.         jmp     init_pe_data
  1353.       peplus_data:
  1354.         xchg    ecx,[edx+88h+eax*8]
  1355.       init_pe_data:
  1356.         or      ecx,ecx
  1357.         jnz     data_already_defined
  1358.         call    allocate_structure_data
  1359.         mov     word [ebx],data_directive-instruction_handler
  1360.         mov     [ebx+2],al
  1361.         mov     edx,[current_line]
  1362.         mov     [ebx+4],edx
  1363.         call    generate_pe_data
  1364.         jmp     instruction_assembled
  1365.       end_data:
  1366.         cmp     [output_format],3
  1367.         jne     illegal_instruction
  1368.         call    find_structure_data
  1369.         jc      unexpected_instruction
  1370.         movzx   eax,byte [ebx+2]
  1371.         mov     edx,[current_section]
  1372.         mov     ecx,edi
  1373.         sub     ecx,[edx+14h]
  1374.         add     ecx,[edx+0Ch]
  1375.         mov     edx,[code_start]
  1376.         test    [format_flags],4
  1377.         jnz     end_peplus_data
  1378.         sub     ecx,[edx+78h+eax*8]
  1379.         mov     [edx+78h+eax*8+4],ecx
  1380.         jmp     remove_structure_data
  1381.       end_peplus_data:
  1382.         sub     ecx,[edx+88h+eax*8]
  1383.         mov     [edx+88h+eax*8+4],ecx
  1384.         jmp     remove_structure_data
  1385. pe_entry:
  1386.         lods    byte [esi]
  1387.         cmp     al,'('
  1388.         jne     invalid_argument
  1389.         cmp     byte [esi],'.'
  1390.         je      invalid_value
  1391.         test    [format_flags],8
  1392.         jnz     pe64_entry
  1393.         call    get_dword_value
  1394.         mov     bl,2
  1395.         bt      [resolver_flags],0
  1396.         jc      check_pe_entry_label_type
  1397.         xor     bl,bl
  1398.       check_pe_entry_label_type:
  1399.         cmp     [value_type],bl
  1400.         je      pe_entry_ok
  1401.         call    recoverable_invalid_address
  1402.       pe_entry_ok:
  1403.       cdq
  1404.         test    [format_flags],4
  1405.         jnz     pe64_entry_type_ok
  1406.         mov     edx,[code_start]
  1407.         sub     eax,[edx+34h]
  1408.         mov     [edx+28h],eax
  1409.         jmp     instruction_assembled
  1410.       pe64_entry:
  1411.         call    get_qword_value
  1412.         mov     bl,4
  1413.         bt      [resolver_flags],0
  1414.         jc      check_pe64_entry_label_type
  1415.         xor     bl,bl
  1416.       check_pe64_entry_label_type:
  1417.         cmp     [value_type],bl
  1418.         je      pe64_entry_type_ok
  1419.         call    recoverable_invalid_address
  1420.       pe64_entry_type_ok:
  1421.         mov     ecx,[code_start]
  1422.         sub     eax,[ecx+30h]
  1423.         sbb     edx,[ecx+34h]
  1424.         jz      pe64_entry_range_ok
  1425.         call    recoverable_overflow
  1426.       pe64_entry_range_ok:
  1427.         mov     [ecx+28h],eax
  1428.         jmp     instruction_assembled
  1429. pe_stack:
  1430.         lods    byte [esi]
  1431.         cmp     al,'('
  1432.         jne     invalid_argument
  1433.         cmp     byte [esi],'.'
  1434.         je      invalid_value
  1435.         test    [format_flags],4
  1436.         jnz     peplus_stack
  1437.         call    get_count_value
  1438.         mov     edx,[code_start]
  1439.         mov     [edx+60h],eax
  1440.         cmp     byte [esi],','
  1441.         jne     default_stack_commit
  1442.         lods    byte [esi]
  1443.         lods    byte [esi]
  1444.         cmp     al,'('
  1445.         jne     invalid_argument
  1446.         cmp     byte [esi],'.'
  1447.         je      invalid_value
  1448.         call    get_count_value
  1449.         mov     edx,[code_start]
  1450.         mov     [edx+64h],eax
  1451.         cmp     eax,[edx+60h]
  1452.         ja      value_out_of_range
  1453.         jmp     instruction_assembled
  1454.       default_stack_commit:
  1455.         mov     dword [edx+64h],1000h
  1456.         mov     eax,[edx+60h]
  1457.         cmp     eax,1000h
  1458.         ja      instruction_assembled
  1459.         mov     dword [edx+64h],eax
  1460.         jmp     instruction_assembled
  1461.       peplus_stack:
  1462.         call    get_qword_value
  1463.         cmp     [value_type],0
  1464.         jne     invalid_use_of_symbol
  1465.         mov     ecx,[code_start]
  1466.         mov     [ecx+60h],eax
  1467.         mov     [ecx+64h],edx
  1468.         cmp     byte [esi],','
  1469.         jne     default_peplus_stack_commit
  1470.         lods    byte [esi]
  1471.         lods    byte [esi]
  1472.         cmp     al,'('
  1473.         jne     invalid_argument
  1474.         cmp     byte [esi],'.'
  1475.         je      invalid_value
  1476.         call    get_qword_value
  1477.         cmp     [value_type],0
  1478.         jne     invalid_use_of_symbol
  1479.         mov     ecx,[code_start]
  1480.         mov     [ecx+68h],eax
  1481.         mov     [ecx+6Ch],edx
  1482.         cmp     edx,[ecx+64h]
  1483.         ja      value_out_of_range
  1484.         jb      instruction_assembled
  1485.         cmp     eax,[ecx+60h]
  1486.         ja      value_out_of_range
  1487.         jmp     instruction_assembled
  1488.       default_peplus_stack_commit:
  1489.         mov     dword [ecx+68h],1000h
  1490.         cmp     dword [ecx+64h],0
  1491.         jne     instruction_assembled
  1492.         mov     eax,[ecx+60h]
  1493.         cmp     eax,1000h
  1494.         ja      instruction_assembled
  1495.         mov     dword [ecx+68h],eax
  1496.         jmp     instruction_assembled
  1497. pe_heap:
  1498.         lods    byte [esi]
  1499.         cmp     al,'('
  1500.         jne     invalid_argument
  1501.         cmp     byte [esi],'.'
  1502.         je      invalid_value
  1503.         test    [format_flags],4
  1504.         jnz     peplus_heap
  1505.         call    get_count_value
  1506.         mov     edx,[code_start]
  1507.         mov     [edx+68h],eax
  1508.         cmp     byte [esi],','
  1509.         jne     instruction_assembled
  1510.         lods    byte [esi]
  1511.         lods    byte [esi]
  1512.         cmp     al,'('
  1513.         jne     invalid_argument
  1514.         cmp     byte [esi],'.'
  1515.         je      invalid_value
  1516.         call    get_count_value
  1517.         mov     edx,[code_start]
  1518.         mov     [edx+6Ch],eax
  1519.         cmp     eax,[edx+68h]
  1520.         ja      value_out_of_range
  1521.         jmp     instruction_assembled
  1522.       peplus_heap:
  1523.         call    get_qword_value
  1524.         cmp     [value_type],0
  1525.         jne     invalid_use_of_symbol
  1526.         mov     ecx,[code_start]
  1527.         mov     [ecx+70h],eax
  1528.         mov     [ecx+74h],edx
  1529.         cmp     byte [esi],','
  1530.         jne     instruction_assembled
  1531.         lods    byte [esi]
  1532.         lods    byte [esi]
  1533.         cmp     al,'('
  1534.         jne     invalid_argument
  1535.         cmp     byte [esi],'.'
  1536.         je      invalid_value
  1537.         call    get_qword_value
  1538.         cmp     [value_type],0
  1539.         jne     invalid_use_of_symbol
  1540.         mov     ecx,[code_start]
  1541.         mov     [ecx+78h],eax
  1542.         mov     [ecx+7Ch],edx
  1543.         cmp     edx,[ecx+74h]
  1544.         ja      value_out_of_range
  1545.         jb      instruction_assembled
  1546.         cmp     eax,[ecx+70h]
  1547.         ja      value_out_of_range
  1548.         jmp     instruction_assembled
  1549. mark_pe_relocation:
  1550.         push    eax ebx
  1551.         test    [format_flags],4
  1552.         jz      check_standard_pe_relocation_type
  1553.         cmp     [value_type],4
  1554.         je      pe_relocation_type_ok
  1555.       check_standard_pe_relocation_type:
  1556.         cmp     [value_type],2
  1557.         je      pe_relocation_type_ok
  1558.         call    recoverable_misuse
  1559.       pe_relocation_type_ok:
  1560.         mov     ebx,[current_section]
  1561.         mov     eax,edi
  1562.         sub     eax,[ebx+14h]
  1563.         add     eax,[ebx+0Ch]
  1564.         mov     ebx,[free_additional_memory]
  1565.         inc     [number_of_relocations]
  1566.         add     ebx,5
  1567.         cmp     ebx,[structures_buffer]
  1568.         jae     out_of_memory
  1569.         mov     [free_additional_memory],ebx
  1570.         mov     [ebx-5],eax
  1571.         cmp     [value_type],2
  1572.         je      fixup_32bit
  1573.         mov     byte [ebx-1],0Ah
  1574.         jmp     fixup_ok
  1575.       fixup_32bit:
  1576.         mov     byte [ebx-1],3
  1577.       fixup_ok:
  1578.         pop     ebx eax
  1579.         ret
  1580. generate_pe_data:
  1581.         cmp     al,2
  1582.         je      make_pe_resource
  1583.         cmp     al,5
  1584.         je      make_pe_fixups
  1585.         ret
  1586. make_pe_fixups:
  1587.         mov     edx,[code_start]
  1588.         and     byte [edx+16h],not 1
  1589.         or      byte [edx+5Eh],40h
  1590.         bts     [resolver_flags],0
  1591.         jc      fixups_ready
  1592.         or      [next_pass_needed],-1
  1593.       fixups_ready:
  1594.         and     [last_fixup_base],0
  1595.         call    make_fixups
  1596.         xchg    eax,[actual_fixups_size]
  1597.         sub     eax,[actual_fixups_size]
  1598.         ja      reserve_forward_fixups
  1599.         xor     eax,eax
  1600.       reserve_forward_fixups:
  1601.         mov     [reserved_fixups],edi
  1602.         add     edi,eax
  1603.         mov     [reserved_fixups_size],eax
  1604.         ret
  1605.       make_fixups:
  1606.         push    esi
  1607.         xor     ecx,ecx
  1608.         xchg    ecx,[number_of_relocations]
  1609.         mov     esi,[free_additional_memory]
  1610.         lea     eax,[ecx*5]
  1611.         sub     esi,eax
  1612.         mov     [free_additional_memory],esi
  1613.         mov     edx,[last_fixup_base]
  1614.         mov     ebp,edi
  1615.         jecxz   fixups_done
  1616.       make_fixup:
  1617.         cmp     [esi],edx
  1618.         jb      store_fixup
  1619.         mov     eax,edi
  1620.         sub     eax,ebp
  1621.         test    eax,11b
  1622.         jz      fixups_block
  1623.         xor     ax,ax
  1624.         stos    word [edi]
  1625.         add     dword [ebx],2
  1626.       fixups_block:
  1627.         mov     eax,edx
  1628.         add     edx,1000h
  1629.         cmp     [esi],edx
  1630.         jae     fixups_block
  1631.         stos    dword [edi]
  1632.         mov     ebx,edi
  1633.         mov     eax,8
  1634.         stos    dword [edi]
  1635.       store_fixup:
  1636.         add     dword [ebx],2
  1637.         mov     ah,[esi+1]
  1638.         and     ah,0Fh
  1639.         mov     al,[esi+4]
  1640.         shl     al,4
  1641.         or      ah,al
  1642.         mov     al,[esi]
  1643.         stos    word [edi]
  1644.         add     esi,5
  1645.         loop    make_fixup
  1646.       fixups_done:
  1647.         mov     [last_fixup_base],edx
  1648.         pop     esi
  1649.         mov     eax,edi
  1650.         sub     eax,ebp
  1651.         ret
  1652. make_pe_resource:
  1653.         cmp     byte [esi],82h
  1654.         jne     resource_done
  1655.         inc     esi
  1656.         lods    word [esi]
  1657.         cmp     ax,'('
  1658.         jne     invalid_argument
  1659.         lods    dword [esi]
  1660.         mov     edx,esi
  1661.         lea     esi,[esi+eax+1]
  1662.         cmp     [next_pass_needed],0
  1663.         je      resource_from_file
  1664.         cmp     [current_pass],0
  1665.         jne     reserve_space_for_resource
  1666.         and     [resource_size],0
  1667.       reserve_space_for_resource:
  1668.         add     edi,[resource_size]
  1669.         cmp     edi,[tagged_blocks]
  1670.         ja      out_of_memory
  1671.         jmp     resource_done
  1672.       resource_from_file:
  1673.         push    esi
  1674.         mov     esi,edx
  1675.         call    open_binary_file
  1676.         push    ebx
  1677.         mov     esi,[free_additional_memory]
  1678.         lea     eax,[esi+20h]
  1679.         cmp     eax,[structures_buffer]
  1680.         ja      out_of_memory
  1681.         mov     edx,esi
  1682.         mov     ecx,20h
  1683.         call    read
  1684.         jc      invalid_file_format
  1685.         xor     eax,eax
  1686.         cmp     [esi],eax
  1687.         jne     invalid_file_format
  1688.         mov     ax,0FFFFh
  1689.         cmp     [esi+8],eax
  1690.         jne     invalid_file_format
  1691.         cmp     [esi+12],eax
  1692.         jne     invalid_file_format
  1693.         mov     eax,20h
  1694.         cmp     [esi+4],eax
  1695.         jne     invalid_file_format
  1696.       read_resource_headers:
  1697.         test    eax,11b
  1698.         jz      resource_file_alignment_ok
  1699.         mov     edx,4
  1700.         and     eax,11b
  1701.         sub     edx,eax
  1702.         mov     al,1
  1703.         call    lseek
  1704.       resource_file_alignment_ok:
  1705.         mov     [esi],eax
  1706.         lea     edx,[esi+12]
  1707.         mov     ecx,8
  1708.         call    read
  1709.         jc      resource_headers_ok
  1710.         mov     ecx,[esi+16]
  1711.         add     [esi],ecx
  1712.         lea     edx,[esi+20]
  1713.         sub     ecx,8
  1714.         mov     [esi+16],ecx
  1715.         lea     eax,[edx+ecx]
  1716.         cmp     eax,[structures_buffer]
  1717.         ja      out_of_memory
  1718.         call    read
  1719.         jc      invalid_file_format
  1720.         mov     edx,[esi]
  1721.         add     edx,[esi+12]
  1722.         mov     eax,[esi+16]
  1723.         lea     ecx,[esi+20]
  1724.         lea     esi,[ecx+eax]
  1725.         add     ecx,2
  1726.         cmp     word [ecx-2],0FFFFh
  1727.         je      resource_header_type_ok
  1728.       check_resource_header_type:
  1729.         cmp     ecx,esi
  1730.         jae     invalid_file_format
  1731.         cmp     word [ecx],0
  1732.         je      resource_header_type_ok
  1733.         add     ecx,2
  1734.         jmp     check_resource_header_type
  1735.       resource_header_type_ok:
  1736.         add     ecx,2
  1737.         cmp     word [ecx],0FFFFh
  1738.         je      resource_header_name_ok
  1739.       check_resource_header_name:
  1740.         cmp     ecx,esi
  1741.         jae     invalid_file_format
  1742.         cmp     word [ecx],0
  1743.         je      resource_header_name_ok
  1744.         add     ecx,2
  1745.         jmp     check_resource_header_name
  1746.       resource_header_name_ok:
  1747.         xor     al,al
  1748.         call    lseek
  1749.         jmp     read_resource_headers
  1750.       resource_headers_ok:
  1751.         xor     eax,eax
  1752.         mov     [esi],eax
  1753.         mov     [resource_data],edi
  1754.         lea     eax,[edi+16]
  1755.         cmp     eax,[tagged_blocks]
  1756.         jae     out_of_memory
  1757.         xor     eax,eax
  1758.         stos    dword [edi]
  1759.         call    make_timestamp
  1760.         stos    dword [edi]
  1761.         xor     eax,eax
  1762.         stos    dword [edi]
  1763.         stos    dword [edi]
  1764.         xor     ebx,ebx
  1765.       make_type_name_directory:
  1766.         mov     esi,[free_additional_memory]
  1767.         xor     edx,edx
  1768.       find_type_name:
  1769.         cmp     dword [esi],0
  1770.         je      type_name_ok
  1771.         add     esi,20
  1772.         cmp     word [esi],0FFFFh
  1773.         je      check_next_type_name
  1774.         or      ebx,ebx
  1775.         jz      check_this_type_name
  1776.         xor     ecx,ecx
  1777.       compare_with_previous_type_name:
  1778.         mov     ax,[esi+ecx]
  1779.         cmp     ax,[ebx+ecx]
  1780.         ja      check_this_type_name
  1781.         jb      check_next_type_name
  1782.         add     ecx,2
  1783.         mov     ax,[esi+ecx]
  1784.         or      ax,[ebx+ecx]
  1785.         jnz     compare_with_previous_type_name
  1786.         jmp     check_next_type_name
  1787.       check_this_type_name:
  1788.         or      edx,edx
  1789.         jz      type_name_found
  1790.         xor     ecx,ecx
  1791.       compare_with_current_type_name:
  1792.         mov     ax,[esi+ecx]
  1793.         cmp     ax,[edx+ecx]
  1794.         ja      check_next_type_name
  1795.         jb      type_name_found
  1796.         add     ecx,2
  1797.         mov     ax,[esi+ecx]
  1798.         or      ax,[edx+ecx]
  1799.         jnz     compare_with_current_type_name
  1800.         jmp     same_type_name
  1801.       type_name_found:
  1802.         mov     edx,esi
  1803.       same_type_name:
  1804.         mov     [esi-16],edi
  1805.       check_next_type_name:
  1806.         mov     eax,[esi-4]
  1807.         add     esi,eax
  1808.         jmp     find_type_name
  1809.       type_name_ok:
  1810.         or      edx,edx
  1811.         jz      type_name_directory_done
  1812.         mov     ebx,edx
  1813.       make_type_name_entry:
  1814.         mov     eax,[resource_data]
  1815.         inc     word [eax+12]
  1816.         lea     eax,[edi+8]
  1817.         cmp     eax,[tagged_blocks]
  1818.         jae     out_of_memory
  1819.         mov     eax,ebx
  1820.         stos    dword [edi]
  1821.         xor     eax,eax
  1822.         stos    dword [edi]
  1823.         jmp     make_type_name_directory
  1824.       type_name_directory_done:
  1825.         mov     ebx,-1
  1826.       make_type_id_directory:
  1827.         mov     esi,[free_additional_memory]
  1828.         mov     edx,10000h
  1829.       find_type_id:
  1830.         cmp     dword [esi],0
  1831.         je      type_id_ok
  1832.         add     esi,20
  1833.         cmp     word [esi],0FFFFh
  1834.         jne     check_next_type_id
  1835.         movzx   eax,word [esi+2]
  1836.         cmp     eax,ebx
  1837.         jle     check_next_type_id
  1838.         cmp     eax,edx
  1839.         jg      check_next_type_id
  1840.         mov     edx,eax
  1841.         mov     [esi-16],edi
  1842.       check_next_type_id:
  1843.         mov     eax,[esi-4]
  1844.         add     esi,eax
  1845.         jmp     find_type_id
  1846.       type_id_ok:
  1847.         cmp     edx,10000h
  1848.         je      type_id_directory_done
  1849.         mov     ebx,edx
  1850.       make_type_id_entry:
  1851.         mov     eax,[resource_data]
  1852.         inc     word [eax+14]
  1853.         lea     eax,[edi+8]
  1854.         cmp     eax,[tagged_blocks]
  1855.         jae     out_of_memory
  1856.         mov     eax,ebx
  1857.         stos    dword [edi]
  1858.         xor     eax,eax
  1859.         stos    dword [edi]
  1860.         jmp     make_type_id_directory
  1861.       type_id_directory_done:
  1862.         mov     esi,[resource_data]
  1863.         add     esi,10h
  1864.         mov     ecx,[esi-4]
  1865.         or      cx,cx
  1866.         jz      resource_directories_ok
  1867.       make_resource_directories:
  1868.         push    ecx
  1869.         push    edi
  1870.         mov     edx,edi
  1871.         sub     edx,[resource_data]
  1872.         bts     edx,31
  1873.         mov     [esi+4],edx
  1874.         lea     eax,[edi+16]
  1875.         cmp     eax,[tagged_blocks]
  1876.         jae     out_of_memory
  1877.         xor     eax,eax
  1878.         stos    dword [edi]
  1879.         call    make_timestamp
  1880.         stos    dword [edi]
  1881.         xor     eax,eax
  1882.         stos    dword [edi]
  1883.         stos    dword [edi]
  1884.         mov     ebp,esi
  1885.         xor     ebx,ebx
  1886.       make_resource_name_directory:
  1887.         mov     esi,[free_additional_memory]
  1888.         xor     edx,edx
  1889.       find_resource_name:
  1890.         cmp     dword [esi],0
  1891.         je      resource_name_ok
  1892.         push    esi
  1893.         cmp     [esi+4],ebp
  1894.         jne     check_next_resource_name
  1895.         add     esi,20
  1896.         call    skip_resource_name
  1897.         cmp     word [esi],0FFFFh
  1898.         je      check_next_resource_name
  1899.         or      ebx,ebx
  1900.         jz      check_this_resource_name
  1901.         xor     ecx,ecx
  1902.       compare_with_previous_resource_name:
  1903.         mov     ax,[esi+ecx]
  1904.         cmp     ax,[ebx+ecx]
  1905.         ja      check_this_resource_name
  1906.         jb      check_next_resource_name
  1907.         add     ecx,2
  1908.         mov     ax,[esi+ecx]
  1909.         or      ax,[ebx+ecx]
  1910.         jnz     compare_with_previous_resource_name
  1911.         jmp     check_next_resource_name
  1912.       skip_resource_name:
  1913.         cmp     word [esi],0FFFFh
  1914.         jne     skip_unicode_string
  1915.         add     esi,4
  1916.         ret
  1917.       skip_unicode_string:
  1918.         add     esi,2
  1919.         cmp     word [esi-2],0
  1920.         jne     skip_unicode_string
  1921.         ret
  1922.       check_this_resource_name:
  1923.         or      edx,edx
  1924.         jz      resource_name_found
  1925.         xor     ecx,ecx
  1926.       compare_with_current_resource_name:
  1927.         mov     ax,[esi+ecx]
  1928.         cmp     ax,[edx+ecx]
  1929.         ja      check_next_resource_name
  1930.         jb      resource_name_found
  1931.         add     ecx,2
  1932.         mov     ax,[esi+ecx]
  1933.         or      ax,[edx+ecx]
  1934.         jnz     compare_with_current_resource_name
  1935.         jmp     same_resource_name
  1936.       resource_name_found:
  1937.         mov     edx,esi
  1938.       same_resource_name:
  1939.         mov     eax,[esp]
  1940.         mov     [eax+8],edi
  1941.       check_next_resource_name:
  1942.         pop     esi
  1943.         mov     eax,[esi+16]
  1944.         lea     esi,[esi+20+eax]
  1945.         jmp     find_resource_name
  1946.       resource_name_ok:
  1947.         or      edx,edx
  1948.         jz      resource_name_directory_done
  1949.         mov     ebx,edx
  1950.       make_resource_name_entry:
  1951.         mov     eax,[esp]
  1952.         inc     word [eax+12]
  1953.         lea     eax,[edi+8]
  1954.         cmp     eax,[tagged_blocks]
  1955.         jae     out_of_memory
  1956.         mov     eax,ebx
  1957.         stos    dword [edi]
  1958.         xor     eax,eax
  1959.         stos    dword [edi]
  1960.         jmp     make_resource_name_directory
  1961.       resource_name_directory_done:
  1962.         mov     ebx,-1
  1963.       make_resource_id_directory:
  1964.         mov     esi,[free_additional_memory]
  1965.         mov     edx,10000h
  1966.       find_resource_id:
  1967.         cmp     dword [esi],0
  1968.         je      resource_id_ok
  1969.         push    esi
  1970.         cmp     [esi+4],ebp
  1971.         jne     check_next_resource_id
  1972.         add     esi,20
  1973.         call    skip_resource_name
  1974.         cmp     word [esi],0FFFFh
  1975.         jne     check_next_resource_id
  1976.         movzx   eax,word [esi+2]
  1977.         cmp     eax,ebx
  1978.         jle     check_next_resource_id
  1979.         cmp     eax,edx
  1980.         jg      check_next_resource_id
  1981.         mov     edx,eax
  1982.         mov     eax,[esp]
  1983.         mov     [eax+8],edi
  1984.       check_next_resource_id:
  1985.         pop     esi
  1986.         mov     eax,[esi+16]
  1987.         lea     esi,[esi+20+eax]
  1988.         jmp     find_resource_id
  1989.       resource_id_ok:
  1990.         cmp     edx,10000h
  1991.         je      resource_id_directory_done
  1992.         mov     ebx,edx
  1993.       make_resource_id_entry:
  1994.         mov     eax,[esp]
  1995.         inc     word [eax+14]
  1996.         lea     eax,[edi+8]
  1997.         cmp     eax,[tagged_blocks]
  1998.         jae     out_of_memory
  1999.         mov     eax,ebx
  2000.         stos    dword [edi]
  2001.         xor     eax,eax
  2002.         stos    dword [edi]
  2003.         jmp     make_resource_id_directory
  2004.       resource_id_directory_done:
  2005.         pop     eax
  2006.         mov     esi,ebp
  2007.         pop     ecx
  2008.         add     esi,8
  2009.         dec     cx
  2010.         jnz     make_resource_directories
  2011.       resource_directories_ok:
  2012.         shr     ecx,16
  2013.         jnz     make_resource_directories
  2014.         mov     esi,[resource_data]
  2015.         add     esi,10h
  2016.         movzx   eax,word [esi-4]
  2017.         movzx   edx,word [esi-2]
  2018.         add     eax,edx
  2019.         lea     esi,[esi+eax*8]
  2020.         push    edi                     ; address of language directories
  2021.       update_resource_directories:
  2022.         cmp     esi,[esp]
  2023.         je      resource_directories_updated
  2024.         add     esi,10h
  2025.         mov     ecx,[esi-4]
  2026.         or      cx,cx
  2027.         jz      language_directories_ok
  2028.       make_language_directories:
  2029.         push    ecx
  2030.         push    edi
  2031.         mov     edx,edi
  2032.         sub     edx,[resource_data]
  2033.         bts     edx,31
  2034.         mov     [esi+4],edx
  2035.         lea     eax,[edi+16]
  2036.         cmp     eax,[tagged_blocks]
  2037.         jae     out_of_memory
  2038.         xor     eax,eax
  2039.         stos    dword [edi]
  2040.         call    make_timestamp
  2041.         stos    dword [edi]
  2042.         xor     eax,eax
  2043.         stos    dword [edi]
  2044.         stos    dword [edi]
  2045.         mov     ebp,esi
  2046.         mov     ebx,-1
  2047.       make_language_id_directory:
  2048.         mov     esi,[free_additional_memory]
  2049.         mov     edx,10000h
  2050.       find_language_id:
  2051.         cmp     dword [esi],0
  2052.         je      language_id_ok
  2053.         push    esi
  2054.         cmp     [esi+8],ebp
  2055.         jne     check_next_language_id
  2056.         add     esi,20
  2057.         mov     eax,esi
  2058.         call    skip_resource_name
  2059.         call    skip_resource_name
  2060.         neg     eax
  2061.         add     eax,esi
  2062.         and     eax,11b
  2063.         add     esi,eax
  2064.       get_language_id:
  2065.         movzx   eax,word [esi+6]
  2066.         cmp     eax,ebx
  2067.         jle     check_next_language_id
  2068.         cmp     eax,edx
  2069.         jge     check_next_language_id
  2070.         mov     edx,eax
  2071.         mov     eax,[esp]
  2072.         mov     dword [value],eax
  2073.       check_next_language_id:
  2074.         pop     esi
  2075.         mov     eax,[esi+16]
  2076.         lea     esi,[esi+20+eax]
  2077.         jmp     find_language_id
  2078.       language_id_ok:
  2079.         cmp     edx,10000h
  2080.         je      language_id_directory_done
  2081.         mov     ebx,edx
  2082.       make_language_id_entry:
  2083.         mov     eax,[esp]
  2084.         inc     word [eax+14]
  2085.         lea     eax,[edi+8]
  2086.         cmp     eax,[tagged_blocks]
  2087.         jae     out_of_memory
  2088.         mov     eax,ebx
  2089.         stos    dword [edi]
  2090.         mov     eax,dword [value]
  2091.         stos    dword [edi]
  2092.         jmp     make_language_id_directory
  2093.       language_id_directory_done:
  2094.         pop     eax
  2095.         mov     esi,ebp
  2096.         pop     ecx
  2097.         add     esi,8
  2098.         dec     cx
  2099.         jnz     make_language_directories
  2100.       language_directories_ok:
  2101.         shr     ecx,16
  2102.         jnz     make_language_directories
  2103.         jmp     update_resource_directories
  2104.       resource_directories_updated:
  2105.         mov     esi,[resource_data]
  2106.         push    edi
  2107.       make_name_strings:
  2108.         add     esi,10h
  2109.         movzx   eax,word [esi-2]
  2110.         movzx   ecx,word [esi-4]
  2111.         add     eax,ecx
  2112.         lea     eax,[esi+eax*8]
  2113.         push    eax
  2114.         or      ecx,ecx
  2115.         jz      string_entries_processed
  2116.       process_string_entries:
  2117.         push    ecx
  2118.         mov     edx,edi
  2119.         sub     edx,[resource_data]
  2120.         bts     edx,31
  2121.         xchg    [esi],edx
  2122.         mov     ebx,edi
  2123.         xor     ax,ax
  2124.         stos    word [edi]
  2125.       copy_string_data:
  2126.         lea     eax,[edi+2]
  2127.         cmp     eax,[tagged_blocks]
  2128.         jae     out_of_memory
  2129.         mov     ax,[edx]
  2130.         or      ax,ax
  2131.         jz      string_data_copied
  2132.         stos    word [edi]
  2133.         inc     word [ebx]
  2134.         add     edx,2
  2135.         jmp     copy_string_data
  2136.       string_data_copied:
  2137.         add     esi,8
  2138.         pop     ecx
  2139.         loop    process_string_entries
  2140.       string_entries_processed:
  2141.         pop     esi
  2142.         cmp     esi,[esp]
  2143.         jb      make_name_strings
  2144.         mov     eax,edi
  2145.         sub     eax,[resource_data]
  2146.         test    al,11b
  2147.         jz      resource_strings_alignment_ok
  2148.         xor     ax,ax
  2149.         stos    word [edi]
  2150.       resource_strings_alignment_ok:
  2151.         pop     edx
  2152.         pop     ebx                     ; address of language directories
  2153.         mov     ebp,edi
  2154.       update_language_directories:
  2155.         add     ebx,10h
  2156.         movzx   eax,word [ebx-2]
  2157.         movzx   ecx,word [ebx-4]
  2158.         add     ecx,eax
  2159.       make_data_records:
  2160.         push    ecx
  2161.         mov     esi,edi
  2162.         sub     esi,[resource_data]
  2163.         xchg    esi,[ebx+4]
  2164.         lea     eax,[edi+16]
  2165.         cmp     eax,[tagged_blocks]
  2166.         jae     out_of_memory
  2167.         mov     eax,esi
  2168.         stos    dword [edi]
  2169.         mov     eax,[esi+12]
  2170.         stos    dword [edi]
  2171.         xor     eax,eax
  2172.         stos    dword [edi]
  2173.         stos    dword [edi]
  2174.         pop     ecx
  2175.         add     ebx,8
  2176.         loop    make_data_records
  2177.         cmp     ebx,edx
  2178.         jb      update_language_directories
  2179.         pop     ebx                     ; file handle
  2180.         mov     esi,ebp
  2181.         mov     ebp,edi
  2182.       update_data_records:
  2183.         push    ebp
  2184.         mov     ecx,edi
  2185.         mov     eax,[current_section]
  2186.         sub     ecx,[eax+14h]
  2187.         add     ecx,[eax+0Ch]
  2188.         xchg    ecx,[esi]
  2189.         mov     edx,[ecx]
  2190.         xor     al,al
  2191.         call    lseek
  2192.         mov     edx,edi
  2193.         mov     ecx,[esi+4]
  2194.         add     edi,ecx
  2195.         cmp     edi,[tagged_blocks]
  2196.         ja      out_of_memory
  2197.         call    read
  2198.         mov     eax,edi
  2199.         sub     eax,[resource_data]
  2200.         and     eax,11b
  2201.         jz      resource_data_alignment_ok
  2202.         mov     ecx,4
  2203.         sub     ecx,eax
  2204.         xor     al,al
  2205.         rep     stos byte [edi]
  2206.       resource_data_alignment_ok:
  2207.         pop     ebp
  2208.         add     esi,16
  2209.         cmp     esi,ebp
  2210.         jb      update_data_records
  2211.         pop     esi
  2212.         call    close
  2213.         mov     eax,edi
  2214.         sub     eax,[resource_data]
  2215.         mov     [resource_size],eax
  2216.       resource_done:
  2217.         ret
  2218. close_pe:
  2219.         call    close_pe_section
  2220.         mov     edx,[code_start]
  2221.         mov     [edx+50h],eax
  2222.         call    make_timestamp
  2223.         mov     edx,[code_start]
  2224.         mov     [edx+8],eax
  2225.         mov     eax,[number_of_sections]
  2226.         mov     [edx+6],ax
  2227.         imul    eax,28h
  2228.         movzx   ecx,word [edx+14h]
  2229.         lea     eax,[eax+18h+ecx]
  2230.         add     eax,[stub_size]
  2231.         mov     ecx,[edx+3Ch]
  2232.         dec     ecx
  2233.         add     eax,ecx
  2234.         not     ecx
  2235.         and     eax,ecx
  2236.         cmp     eax,[edx+54h]
  2237.         je      pe_sections_ok
  2238.         or      [next_pass_needed],-1
  2239.       pe_sections_ok:
  2240.         xor     ecx,ecx
  2241.         add     edx,78h
  2242.         test    [format_flags],4
  2243.         jz      process_directories
  2244.         add     edx,10h
  2245.       process_directories:
  2246.         mov     eax,[edx+ecx*8]
  2247.         or      eax,eax
  2248.         jz      directory_ok
  2249.         cmp     dword [edx+ecx*8+4],-1
  2250.         jne     directory_ok
  2251.       section_data:
  2252.         mov     ebx,[edx+ecx*8]
  2253.         mov     eax,[ebx+0Ch]
  2254.         mov     [edx+ecx*8],eax         ; directory rva
  2255.         mov     eax,[ebx+8]
  2256.         mov     [edx+ecx*8+4],eax       ; directory size
  2257.       directory_ok:
  2258.         inc     cl
  2259.         cmp     cl,10h
  2260.         jb      process_directories
  2261.         cmp     dword [edx+5*8],0
  2262.         jne     finish_pe_relocations
  2263.         mov     eax,[number_of_relocations]
  2264.         shl     eax,2
  2265.         sub     [free_additional_memory],eax
  2266.         btr     [resolver_flags],0
  2267.         jnc     pe_relocations_ok
  2268.         or      [next_pass_needed],-1
  2269.         jmp     pe_relocations_ok
  2270.       finish_pe_relocations:
  2271.         push    edi
  2272.         mov     edi,[reserved_fixups]
  2273.         call    make_fixups
  2274.         pop     edi
  2275.         add     [actual_fixups_size],eax
  2276.         cmp     eax,[reserved_fixups_size]
  2277.         je      pe_relocations_ok
  2278.         or      [next_pass_needed],-1
  2279.       pe_relocations_ok:
  2280.         mov     ebx,[code_start]
  2281.         sub     ebx,[stub_size]
  2282.         mov     ecx,edi
  2283.         sub     ecx,ebx
  2284.         mov     ebp,ecx
  2285.         shr     ecx,1
  2286.         xor     eax,eax
  2287.         cdq
  2288.       calculate_checksum:
  2289.         mov     dx,[ebx]
  2290.         add     eax,edx
  2291.         mov     dx,ax
  2292.         shr     eax,16
  2293.         add     eax,edx
  2294.         add     ebx,2
  2295.         loop    calculate_checksum
  2296.         add     eax,ebp
  2297.         mov     ebx,[code_start]
  2298.         mov     [ebx+58h],eax
  2299.         ret
  2300.  
  2301. format_coff:
  2302.         mov     eax,[additional_memory]
  2303.         mov     [symbols_stream],eax
  2304.         mov     ebx,eax
  2305.         add     eax,20h
  2306.         cmp     eax,[structures_buffer]
  2307.         jae     out_of_memory
  2308.         mov     [free_additional_memory],eax
  2309.         xor     eax,eax
  2310.         mov     [ebx],al
  2311.         mov     [ebx+4],eax
  2312.         mov     [ebx+8],edi
  2313.         mov     al,4
  2314.         mov     [ebx+10h],eax
  2315.         mov     al,60h
  2316.         bt      [format_flags],0
  2317.         jnc     flat_section_flags_ok
  2318.         or      eax,0E0000000h
  2319.       flat_section_flags_ok:
  2320.         mov     dword [ebx+14h],eax
  2321.         mov     [current_section],ebx
  2322.         xor     eax,eax
  2323.         mov     [number_of_sections],eax
  2324.         mov     edx,ebx
  2325.         call    init_addressing_space
  2326.         mov     [ebx+14h],edx
  2327.         mov     byte [ebx+9],2
  2328.         mov     [code_type],32
  2329.         test    [format_flags],8
  2330.         jz      format_defined
  2331.         mov     byte [ebx+9],4
  2332.         mov     [code_type],64
  2333.         jmp     format_defined
  2334. coff_section:
  2335.         call    close_coff_section
  2336.         mov     ebx,[free_additional_memory]
  2337.         lea     eax,[ebx+20h]
  2338.         cmp     eax,[structures_buffer]
  2339.         jae     out_of_memory
  2340.         mov     [free_additional_memory],eax
  2341.         mov     [current_section],ebx
  2342.         inc     [number_of_sections]
  2343.         xor     eax,eax
  2344.         mov     [ebx],al
  2345.         mov     [ebx+8],edi
  2346.         mov     [ebx+10h],eax
  2347.         mov     [ebx+14h],eax
  2348.         mov     edx,ebx
  2349.         call    create_addressing_space
  2350.         xchg    edx,ebx
  2351.         mov     [edx+14h],ebx
  2352.         mov     byte [edx+9],2
  2353.         test    [format_flags],8
  2354.         jz      coff_labels_type_ok
  2355.         mov     byte [edx+9],4
  2356.       coff_labels_type_ok:
  2357.         lods    word [esi]
  2358.         cmp     ax,'('
  2359.         jne     invalid_argument
  2360.         mov     [ebx+4],esi
  2361.         mov     ecx,[esi]
  2362.         lea     esi,[esi+4+ecx+1]
  2363.         cmp     ecx,8
  2364.         ja      name_too_long
  2365.       coff_section_flags:
  2366.         cmp     byte [esi],8Ch
  2367.         je      coff_section_alignment
  2368.         cmp     byte [esi],19h
  2369.         jne     coff_section_settings_ok
  2370.         inc     esi
  2371.         lods    byte [esi]
  2372.         bt      [format_flags],0
  2373.         jc      coff_section_flag_ok
  2374.         cmp     al,7
  2375.         ja      invalid_argument
  2376.       coff_section_flag_ok:
  2377.         mov     cl,al
  2378.         mov     eax,1
  2379.         shl     eax,cl
  2380.         test    dword [ebx+14h],eax
  2381.         jnz     setting_already_specified
  2382.         or      dword [ebx+14h],eax
  2383.         jmp     coff_section_flags
  2384.       coff_section_alignment:
  2385.         bt      [format_flags],0
  2386.         jnc     invalid_argument
  2387.         inc     esi
  2388.         lods    byte [esi]
  2389.         cmp     al,'('
  2390.         jne     invalid_argument
  2391.         cmp     byte [esi],'.'
  2392.         je      invalid_value
  2393.         push    ebx
  2394.         call    get_count_value
  2395.         pop     ebx
  2396.         mov     edx,eax
  2397.         dec     edx
  2398.         test    eax,edx
  2399.         jnz     invalid_value
  2400.         or      eax,eax
  2401.         jz      invalid_value
  2402.         cmp     eax,2000h
  2403.         ja      invalid_value
  2404.         bsf     edx,eax
  2405.         inc     edx
  2406.         shl     edx,20
  2407.         or      [ebx+14h],edx
  2408.         xchg    [ebx+10h],eax
  2409.         or      eax,eax
  2410.         jnz     setting_already_specified
  2411.         jmp     coff_section_flags
  2412.       coff_section_settings_ok:
  2413.         cmp     dword [ebx+10h],0
  2414.         jne     instruction_assembled
  2415.         mov     dword [ebx+10h],4
  2416.         bt      [format_flags],0
  2417.         jnc     instruction_assembled
  2418.         or      dword [ebx+14h],300000h
  2419.         jmp     instruction_assembled
  2420.       close_coff_section:
  2421.         mov     ebx,[current_section]
  2422.         mov     eax,edi
  2423.         mov     edx,[ebx+8]
  2424.         sub     eax,edx
  2425.         mov     [ebx+0Ch],eax
  2426.         xor     eax,