Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. ; flat assembler core
  3. ; Copyright (c) 1999-2020, 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.       duplicate_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     duplicate_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.         mov     ebx,eax
  330.         call    store_label_reference
  331.         mov     eax,ebx
  332.         mov     ebx,[free_additional_memory]
  333.         lea     edx,[ebx+10h]
  334.         cmp     edx,[structures_buffer]
  335.         jae     out_of_memory
  336.         mov     [free_additional_memory],edx
  337.         mov     [ebx+8],eax
  338.         mov     eax,[current_line]
  339.         mov     [ebx+0Ch],eax
  340.         lods    byte [esi]
  341.         cmp     al,86h
  342.         jne     invalid_argument
  343.         lods    word [esi]
  344.         cmp     ax,'('
  345.         jne     invalid_argument
  346.         mov     [ebx+4],esi
  347.         lods    dword [esi]
  348.         lea     esi,[esi+eax+1]
  349.         mov     al,[base_code]
  350.         mov     [ebx],al
  351.         jmp     instruction_assembled
  352. extrn_directive:
  353.         mov     al,[output_format]
  354.         cmp     al,4
  355.         je      extrn_allowed
  356.         cmp     al,5
  357.         jne     illegal_instruction
  358.         bt      [format_flags],0
  359.         jc      illegal_instruction
  360.       extrn_allowed:
  361.         lods    word [esi]
  362.         cmp     ax,'('
  363.         jne     invalid_argument
  364.         mov     ebx,esi
  365.         lods    dword [esi]
  366.         lea     esi,[esi+eax+1]
  367.         mov     edx,[free_additional_memory]
  368.         lea     eax,[edx+0Ch]
  369.         cmp     eax,[structures_buffer]
  370.         jae     out_of_memory
  371.         mov     [free_additional_memory],eax
  372.         mov     byte [edx],80h
  373.         mov     [edx+4],ebx
  374.         lods    byte [esi]
  375.         cmp     al,86h
  376.         jne     invalid_argument
  377.         lods    byte [esi]
  378.         cmp     al,2
  379.         jne     invalid_argument
  380.         lods    dword [esi]
  381.         cmp     eax,0Fh
  382.         jb      invalid_use_of_symbol
  383.         je      reserved_word_used_as_symbol
  384.         inc     esi
  385.         mov     ebx,eax
  386.         xor     ah,ah
  387.         lods    byte [esi]
  388.         cmp     al,':'
  389.         je      get_extrn_size
  390.         dec     esi
  391.         cmp     al,11h
  392.         jne     extrn_size_ok
  393.       get_extrn_size:
  394.         lods    word [esi]
  395.         cmp     al,11h
  396.         jne     invalid_argument
  397.       extrn_size_ok:
  398.         mov     [address_symbol],edx
  399.         mov     [label_size],ah
  400.         movzx   ecx,ah
  401.         mov     [edx+8],ecx
  402.         xor     eax,eax
  403.         xor     edx,edx
  404.         xor     ebp,ebp
  405.         mov     [address_sign],0
  406.         mov     ch,2
  407.         test    [format_flags],8
  408.         jz      make_free_label
  409.         mov     ch,4
  410.         jmp     make_free_label
  411. mark_relocation:
  412.         cmp     [value_type],0
  413.         je      relocation_ok
  414.         mov     ebp,[addressing_space]
  415.         test    byte [ds:ebp+0Ah],1
  416.         jnz     relocation_ok
  417.         cmp     [output_format],2
  418.         je      mark_mz_relocation
  419.         cmp     [output_format],3
  420.         je      mark_pe_relocation
  421.         cmp     [output_format],4
  422.         je      mark_coff_relocation
  423.         cmp     [output_format],5
  424.         je      mark_elf_relocation
  425.       relocation_ok:
  426.         ret
  427. close_pass:
  428.         mov     al,[output_format]
  429.         cmp     al,3
  430.         je      close_pe
  431.         cmp     al,4
  432.         je      close_coff
  433.         cmp     al,5
  434.         je      close_elf
  435.         ret
  436.  
  437. format_mz:
  438.         mov     edx,[additional_memory]
  439.         push    edi
  440.         mov     edi,edx
  441.         mov     ecx,1Ch shr 2
  442.         xor     eax,eax
  443.         rep     stos dword [edi]
  444.         mov     [free_additional_memory],edi
  445.         pop     edi
  446.         mov     word [edx+0Ch],0FFFFh
  447.         mov     word [edx+10h],1000h
  448.         mov     [code_type],16
  449.         jmp     format_defined
  450. mark_mz_relocation:
  451.         push    eax ebx
  452.         inc     word [number_of_relocations]
  453.         jz      format_limitations_exceeded
  454.         mov     ebx,[free_additional_memory]
  455.         mov     eax,edi
  456.         sub     eax,[code_start]
  457.         mov     [ebx],ax
  458.         shr     eax,16
  459.         shl     ax,12
  460.         mov     [ebx+2],ax
  461.         cmp     word [ebx],0FFFFh
  462.         jne     mz_relocation_ok
  463.         inc     word [ebx+2]
  464.         sub     word [ebx],10h
  465.       mz_relocation_ok:
  466.         add     ebx,4
  467.         cmp     ebx,[structures_buffer]
  468.         jae     out_of_memory
  469.         mov     [free_additional_memory],ebx
  470.         pop     ebx eax
  471.         ret
  472. mz_segment:
  473.         lods    byte [esi]
  474.         cmp     al,2
  475.         jne     invalid_argument
  476.         lods    dword [esi]
  477.         cmp     eax,0Fh
  478.         jb      invalid_use_of_symbol
  479.         je      reserved_word_used_as_symbol
  480.         inc     esi
  481.         mov     ebx,eax
  482.         mov     eax,edi
  483.         sub     eax,[code_start]
  484.         mov     ecx,0Fh
  485.         add     eax,0Fh
  486.         and     eax,1111b
  487.         sub     ecx,eax
  488.         mov     edx,edi
  489.         xor     eax,eax
  490.         rep     stos byte [edi]
  491.         mov     eax,edx
  492.         call    undefined_data
  493.         push    ebx
  494.         call    create_addressing_space
  495.         pop     ebx
  496.         mov     eax,edi
  497.         sub     eax,[code_start]
  498.         shr     eax,4
  499.         cmp     eax,10000h
  500.         jae     value_out_of_range
  501.         mov     edx,eax
  502.         mov     al,16
  503.         cmp     byte [esi],13h
  504.         jne     segment_type_ok
  505.         inc     esi
  506.         lods    byte [esi]
  507.       segment_type_ok:
  508.         mov     [code_type],al
  509.         mov     eax,edx
  510.         mov     ch,1
  511.         mov     [address_sign],0
  512.         xor     edx,edx
  513.         xor     ebp,ebp
  514.         mov     [label_size],0
  515.         mov     [address_symbol],edx
  516.         jmp     make_free_label
  517. mz_entry:
  518.         lods    byte [esi]
  519.         cmp     al,'('
  520.         jne     invalid_argument
  521.         call    get_word_value
  522.         cmp     [value_type],1
  523.         je      initial_cs_ok
  524.         call    recoverable_invalid_address
  525.       initial_cs_ok:
  526.         mov     edx,[additional_memory]
  527.         mov     [edx+16h],ax
  528.         lods    byte [esi]
  529.         cmp     al,':'
  530.         jne     invalid_argument
  531.         lods    byte [esi]
  532.         cmp     al,'('
  533.         jne     invalid_argument
  534.         ja      invalid_address
  535.         call    get_word_value
  536.         cmp     [value_type],0
  537.         jne     invalid_use_of_symbol
  538.         mov     edx,[additional_memory]
  539.         mov     [edx+14h],ax
  540.         jmp     instruction_assembled
  541.       recoverable_invalid_address:
  542.         cmp     [error_line],0
  543.         jne     ignore_invalid_address
  544.         push    [current_line]
  545.         pop     [error_line]
  546.         mov     [error],invalid_address
  547.       ignore_invalid_address:
  548.         ret
  549. mz_stack:
  550.         lods    byte [esi]
  551.         cmp     al,'('
  552.         jne     invalid_argument
  553.         call    get_word_value
  554.         cmp     byte [esi],':'
  555.         je      stack_pointer
  556.         cmp     ax,10h
  557.         jb      invalid_value
  558.         cmp     [value_type],0
  559.         jne     invalid_use_of_symbol
  560.         mov     edx,[additional_memory]
  561.         mov     [edx+10h],ax
  562.         jmp     instruction_assembled
  563.       stack_pointer:
  564.         cmp     [value_type],1
  565.         je      initial_ss_ok
  566.         call    recoverable_invalid_address
  567.       initial_ss_ok:
  568.         mov     edx,[additional_memory]
  569.         mov     [edx+0Eh],ax
  570.         lods    byte [esi]
  571.         cmp     al,':'
  572.         jne     invalid_argument
  573.         lods    byte [esi]
  574.         cmp     al,'('
  575.         jne     invalid_argument
  576.         call    get_word_value
  577.         cmp     [value_type],0
  578.         jne     invalid_use_of_symbol
  579.         mov     edx,[additional_memory]
  580.         mov     [edx+10h],ax
  581.         bts     [format_flags],4
  582.         jmp     instruction_assembled
  583. mz_heap:
  584.         cmp     [output_format],2
  585.         jne     illegal_instruction
  586.         lods    byte [esi]
  587.         call    get_size_operator
  588.         cmp     ah,1
  589.         je      invalid_value
  590.         cmp     ah,2
  591.         ja      invalid_value
  592.         cmp     al,'('
  593.         jne     invalid_argument
  594.         call    get_word_value
  595.         cmp     [value_type],0
  596.         jne     invalid_use_of_symbol
  597.         mov     edx,[additional_memory]
  598.         mov     [edx+0Ch],ax
  599.         jmp     instruction_assembled
  600. write_mz_header:
  601.         mov     edx,[additional_memory]
  602.         bt      [format_flags],4
  603.         jc      mz_stack_ok
  604.         mov     eax,[real_code_size]
  605.         dec     eax
  606.         shr     eax,4
  607.         inc     eax
  608.         mov     [edx+0Eh],ax
  609.         shl     eax,4
  610.         movzx   ecx,word [edx+10h]
  611.         add     eax,ecx
  612.         mov     [real_code_size],eax
  613.       mz_stack_ok:
  614.         mov     edi,[free_additional_memory]
  615.         mov     eax,[number_of_relocations]
  616.         shl     eax,2
  617.         add     eax,1Ch
  618.         sub     edi,eax
  619.         xchg    edi,[free_additional_memory]
  620.         mov     ecx,0Fh
  621.         add     eax,0Fh
  622.         and     eax,1111b
  623.         sub     ecx,eax
  624.         xor     al,al
  625.         rep     stos byte [edi]
  626.         sub     edi,[free_additional_memory]
  627.         mov     ecx,edi
  628.         shr     edi,4
  629.         mov     word [edx],'MZ'         ; signature
  630.         mov     [edx+8],di              ; header size in paragraphs
  631.         mov     eax,[number_of_relocations]
  632.         mov     [edx+6],ax              ; number of relocation entries
  633.         mov     eax,[code_size]
  634.         add     eax,ecx
  635.         mov     esi,eax
  636.         shr     esi,9
  637.         and     eax,1FFh
  638.         inc     si
  639.         or      ax,ax
  640.         jnz     mz_size_ok
  641.         dec     si
  642.       mz_size_ok:
  643.         mov     [edx+2],ax              ; number of bytes in last page
  644.         mov     [edx+4],si              ; number of pages
  645.         mov     eax,[real_code_size]
  646.         dec     eax
  647.         shr     eax,4
  648.         inc     eax
  649.         mov     esi,[code_size]
  650.         dec     esi
  651.         shr     esi,4
  652.         inc     esi
  653.         sub     eax,esi
  654.         mov     [edx+0Ah],ax            ; minimum memory in addition to code
  655.         add     [edx+0Ch],ax            ; maximum memory in addition to code
  656.         salc
  657.         mov     ah,al
  658.         or      [edx+0Ch],ax
  659.         mov     word [edx+18h],1Ch      ; offset of relocation table
  660.         add     [written_size],ecx
  661.         call    write
  662.         jc      write_failed
  663.         ret
  664.  
  665. make_stub:
  666.         mov     [stub_file],edx
  667.         or      edx,edx
  668.         jnz     stub_from_file
  669.         push    esi
  670.         mov     edx,edi
  671.         xor     eax,eax
  672.         mov     ecx,20h
  673.         rep     stos dword [edi]
  674.         mov     eax,40h+default_stub_end-default_stub
  675.         mov     cx,100h+default_stub_end-default_stub
  676.         mov     word [edx],'MZ'
  677.         mov     byte [edx+4],1
  678.         mov     word [edx+2],ax
  679.         mov     byte [edx+8],4
  680.         mov     byte [edx+0Ah],10h
  681.         mov     word [edx+0Ch],0FFFFh
  682.         mov     word [edx+10h],cx
  683.         mov     word [edx+3Ch],ax
  684.         mov     byte [edx+18h],40h
  685.         lea     edi,[edx+40h]
  686.         mov     esi,default_stub
  687.         mov     ecx,default_stub_end-default_stub
  688.         rep     movs byte [edi],[esi]
  689.         pop     esi
  690.         jmp     stub_ok
  691.       default_stub:
  692.         use16
  693.         push    cs
  694.         pop     ds
  695.         mov     dx,stub_message-default_stub
  696.         mov     ah,9
  697.         int     21h
  698.         mov     ax,4C01h
  699.         int     21h
  700.       stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
  701.         rq      1
  702.       default_stub_end:
  703.         use32
  704.       stub_from_file:
  705.         push    esi
  706.         mov     esi,edx
  707.         call    open_binary_file
  708.         mov     edx,edi
  709.         mov     ecx,1Ch
  710.         mov     esi,edx
  711.         call    read
  712.         jc      binary_stub
  713.         cmp     word [esi],'MZ'
  714.         jne     binary_stub
  715.         add     edi,1Ch
  716.         movzx   ecx,word [esi+6]
  717.         add     ecx,11b
  718.         and     ecx,not 11b
  719.         add     ecx,(40h-1Ch) shr 2
  720.         lea     eax,[edi+ecx*4]
  721.         cmp     edi,[tagged_blocks]
  722.         jae     out_of_memory
  723.         xor     eax,eax
  724.         rep     stos dword [edi]
  725.         mov     edx,40h
  726.         xchg    dx,[esi+18h]
  727.         xor     al,al
  728.         call    lseek
  729.         movzx   ecx,word [esi+6]
  730.         shl     ecx,2
  731.         lea     edx,[esi+40h]
  732.         call    read
  733.         mov     edx,edi
  734.         sub     edx,esi
  735.         shr     edx,4
  736.         xchg    dx,[esi+8]
  737.         shl     edx,4
  738.         xor     al,al
  739.         call    lseek
  740.         movzx   ecx,word [esi+4]
  741.         dec     ecx
  742.         shl     ecx,9
  743.         movzx   edx,word [esi+2]
  744.         test    edx,edx
  745.         jnz     stub_header_size_ok
  746.         mov     dx,200h
  747.      stub_header_size_ok:
  748.         add     ecx,edx
  749.         mov     edx,edi
  750.         sub     ecx,eax
  751.         je      read_stub_code
  752.         jb      stub_code_ok
  753.         push    ecx
  754.         dec     ecx
  755.         shr     ecx,3
  756.         inc     ecx
  757.         shl     ecx,1
  758.         lea     eax,[edi+ecx*4]
  759.         cmp     eax,[tagged_blocks]
  760.         jae     out_of_memory
  761.         xor     eax,eax
  762.         rep     stos dword [edi]
  763.         pop     ecx
  764.      read_stub_code:
  765.         call    read
  766.      stub_code_ok:
  767.         call    close
  768.         mov     edx,edi
  769.         sub     edx,esi
  770.         mov     ax,dx
  771.         and     ax,1FFh
  772.         mov     [esi+2],ax
  773.         dec     edx
  774.         shr     edx,9
  775.         inc     edx
  776.         mov     [esi+4],dx
  777.         mov     eax,edi
  778.         sub     eax,esi
  779.         mov     [esi+3Ch],eax
  780.         pop     esi
  781.       stub_ok:
  782.         ret
  783.       binary_stub:
  784.         mov     esi,edi
  785.         mov     ecx,40h shr 2
  786.         xor     eax,eax
  787.         rep     stos dword [edi]
  788.         mov     al,2
  789.         xor     edx,edx
  790.         call    lseek
  791.         push    eax
  792.         xor     al,al
  793.         xor     edx,edx
  794.         call    lseek
  795.         mov     ecx,[esp]
  796.         add     ecx,40h+111b
  797.         and     ecx,not 111b
  798.         mov     ax,cx
  799.         and     ax,1FFh
  800.         mov     [esi+2],ax
  801.         lea     eax,[ecx+1FFh]
  802.         shr     eax,9
  803.         mov     [esi+4],ax
  804.         mov     [esi+3Ch],ecx
  805.         sub     ecx,40h
  806.         mov     eax,10000h
  807.         sub     eax,ecx
  808.         jbe     binary_heap_ok
  809.         shr     eax,4
  810.         mov     [esi+0Ah],ax
  811.       binary_heap_ok:
  812.         mov     word [esi],'MZ'
  813.         mov     byte [esi+8],4
  814.         mov     ax,0FFFFh
  815.         mov     [esi+0Ch],ax
  816.         dec     ax
  817.         mov     [esi+10h],ax
  818.         sub     ax,0Eh
  819.         mov     [esi+0Eh],ax
  820.         mov     [esi+16h],ax
  821.         mov     word [esi+14h],100h
  822.         mov     byte [esi+18h],40h
  823.         mov     eax,[tagged_blocks]
  824.         sub     eax,ecx
  825.         cmp     edi,eax
  826.         jae     out_of_memory
  827.         mov     edx,edi
  828.         shr     ecx,2
  829.         xor     eax,eax
  830.         rep     stos dword [edi]
  831.         pop     ecx
  832.         call    read
  833.         call    close
  834.         pop     esi
  835.         ret
  836.  
  837. format_pe:
  838.         xor     edx,edx
  839.         mov     [machine],14Ch
  840.         mov     [subsystem],3
  841.         mov     [subsystem_version],3 + 10 shl 16
  842.         mov     [image_base],400000h
  843.         and     [image_base_high],0
  844.         test    [format_flags],8
  845.         jz      pe_settings
  846.         mov     [machine],8664h
  847.         mov     [subsystem_version],5 + 0 shl 16
  848.       pe_settings:
  849.         cmp     byte [esi],84h
  850.         je      get_stub_name
  851.         cmp     byte [esi],80h
  852.         je      get_pe_base
  853.         cmp     byte [esi],1Bh
  854.         jne     pe_settings_ok
  855.         lods    byte [esi]
  856.         lods    byte [esi]
  857.         test    al,80h+40h
  858.         jz      subsystem_setting
  859.         cmp     al,80h
  860.         je      dll_flag
  861.         cmp     al,81h
  862.         je      wdm_flag
  863.         cmp     al,82h
  864.         je      large_flag
  865.         cmp     al,83h
  866.         je      nx_flag
  867.         jmp     pe_settings
  868.       dll_flag:
  869.         bts     [format_flags],8
  870.         jc      setting_already_specified
  871.         jmp     pe_settings
  872.       wdm_flag:
  873.         bts     [format_flags],9
  874.         jc      setting_already_specified
  875.         jmp     pe_settings
  876.       large_flag:
  877.         bts     [format_flags],11
  878.         jc      setting_already_specified
  879.         test    [format_flags],8
  880.         jnz     invalid_argument
  881.         jmp     pe_settings
  882.       nx_flag:
  883.         bts     [format_flags],12
  884.         jc      setting_already_specified
  885.         jmp     pe_settings
  886.       subsystem_setting:
  887.         bts     [format_flags],7
  888.         jc      setting_already_specified
  889.         and     ax,3Fh
  890.         mov     [subsystem],ax
  891.         cmp     ax,10
  892.         jb      subsystem_type_ok
  893.         or      [format_flags],4
  894.       subsystem_type_ok:
  895.         cmp     byte [esi],'('
  896.         jne     pe_settings
  897.         inc     esi
  898.         cmp     byte [esi],'.'
  899.         jne     invalid_value
  900.         inc     esi
  901.         push    edx
  902.         cmp     byte [esi+11],0
  903.         jne     invalid_value
  904.         cmp     byte [esi+10],2
  905.         ja      invalid_value
  906.         mov     dx,[esi+8]
  907.         cmp     dx,8000h
  908.         je      zero_version
  909.         mov     eax,[esi+4]
  910.         cmp     dx,7
  911.         jg      invalid_value
  912.         mov     cx,7
  913.         sub     cx,dx
  914.         mov     eax,[esi+4]
  915.         shr     eax,cl
  916.         mov     ebx,eax
  917.         shr     ebx,24
  918.         cmp     bl,100
  919.         jae     invalid_value
  920.         and     eax,0FFFFFFh
  921.         mov     ecx,100
  922.         mul     ecx
  923.         shrd    eax,edx,24
  924.         jnc     version_value_ok
  925.         inc     eax
  926.       version_value_ok:
  927.         shl     eax,16
  928.         mov     ax,bx
  929.         jmp     subsystem_version_ok
  930.       zero_version:
  931.         xor     eax,eax
  932.       subsystem_version_ok:
  933.         pop     edx
  934.         add     esi,13
  935.         mov     [subsystem_version],eax
  936.         jmp     pe_settings
  937.       get_pe_base:
  938.         bts     [format_flags],10
  939.         jc      setting_already_specified
  940.         lods    word [esi]
  941.         cmp     ah,'('
  942.         jne     invalid_argument
  943.         cmp     byte [esi],'.'
  944.         je      invalid_value
  945.         push    edx edi
  946.         add     edi,[stub_size]
  947.         test    [format_flags],4
  948.         jnz     get_peplus_base
  949.         call    get_dword_value
  950.         mov     [image_base],eax
  951.         jmp     pe_base_ok
  952.       get_peplus_base:
  953.         call    get_qword_value
  954.         mov     [image_base],eax
  955.         mov     [image_base_high],edx
  956.       pe_base_ok:
  957.         pop     edi edx
  958.         cmp     [value_type],0
  959.         jne     invalid_use_of_symbol
  960.         cmp     byte [esi],84h
  961.         jne     pe_settings_ok
  962.       get_stub_name:
  963.         lods    byte [esi]
  964.         lods    word [esi]
  965.         cmp     ax,'('
  966.         jne     invalid_argument
  967.         lods    dword [esi]
  968.         mov     edx,esi
  969.         add     esi,eax
  970.         inc     esi
  971.       pe_settings_ok:
  972.         mov     ebp,[stub_size]
  973.         or      ebp,ebp
  974.         jz      make_pe_stub
  975.         cmp     edx,[stub_file]
  976.         je      pe_stub_ok
  977.         sub     edi,[stub_size]
  978.         mov     [code_start],edi
  979.       make_pe_stub:
  980.         call    make_stub
  981.         mov     eax,edi
  982.         sub     eax,[code_start]
  983.         mov     [stub_size],eax
  984.         mov     [code_start],edi
  985.         mov     ebp,eax
  986.       pe_stub_ok:
  987.         mov     edx,edi
  988.         mov     ecx,18h+0E0h
  989.         test    [format_flags],4
  990.         jz      zero_pe_header
  991.         add     ecx,10h
  992.       zero_pe_header:
  993.         add     ebp,ecx
  994.         shr     ecx,2
  995.         xor     eax,eax
  996.         rep     stos dword [edi]
  997.         mov     word [edx],'PE'         ; signature
  998.         mov     ax,[machine]
  999.         mov     word [edx+4],ax
  1000.         mov     byte [edx+38h+1],10h    ; section alignment
  1001.         mov     byte [edx+3Ch+1],2      ; file alignment
  1002.         mov     byte [edx+40h],1        ; OS version
  1003.         mov     eax,[subsystem_version]
  1004.         mov     [edx+48h],eax
  1005.         mov     ax,[subsystem]
  1006.         mov     [edx+5Ch],ax
  1007.         cmp     ax,1
  1008.         jne     pe_alignment_ok
  1009.         mov     eax,20h
  1010.         mov     dword [edx+38h],eax
  1011.         mov     dword [edx+3Ch],eax
  1012.       pe_alignment_ok:
  1013.         mov     word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8
  1014.         test    [format_flags],4
  1015.         jnz     init_peplus_specific
  1016.         mov     byte [edx+14h],0E0h     ; size of optional header
  1017.         mov     dword [edx+16h],10B010Fh; flags and magic value
  1018.         mov     eax,[image_base]
  1019.         mov     [edx+34h],eax
  1020.         mov     byte [edx+60h+1],10h    ; stack reserve
  1021.         mov     byte [edx+64h+1],10h    ; stack commit
  1022.         mov     byte [edx+68h+2],1      ; heap reserve
  1023.         mov     byte [edx+74h],16       ; number of directories
  1024.         jmp     pe_header_ok
  1025.       init_peplus_specific:
  1026.         mov     byte [edx+14h],0F0h     ; size of optional header
  1027.         mov     dword [edx+16h],20B002Fh; flags and magic value
  1028.         mov     eax,[image_base]
  1029.         mov     [edx+30h],eax
  1030.         mov     eax,[image_base_high]
  1031.         mov     [edx+34h],eax
  1032.         mov     byte [edx+60h+1],10h    ; stack reserve
  1033.         mov     byte [edx+68h+1],10h    ; stack commit
  1034.         mov     byte [edx+70h+2],1      ; heap reserve
  1035.         mov     byte [edx+84h],16       ; number of directories
  1036.       pe_header_ok:
  1037.         bsf     ecx,[edx+3Ch]
  1038.         imul    ebx,[number_of_sections],28h
  1039.         or      ebx,ebx
  1040.         jnz     reserve_space_for_section_headers
  1041.         mov     ebx,28h
  1042.       reserve_space_for_section_headers:
  1043.         add     ebx,ebp
  1044.         dec     ebx
  1045.         shr     ebx,cl
  1046.         inc     ebx
  1047.         shl     ebx,cl
  1048.         sub     ebx,ebp
  1049.         mov     ecx,ebx
  1050.         mov     eax,[tagged_blocks]
  1051.         sub     eax,ecx
  1052.         cmp     edi,eax
  1053.         jae     out_of_memory
  1054.         shr     ecx,2
  1055.         xor     eax,eax
  1056.         rep     stos dword [edi]
  1057.         mov     eax,edi
  1058.         sub     eax,[code_start]
  1059.         add     eax,[stub_size]
  1060.         mov     [edx+54h],eax           ; size of headers
  1061.         mov     ecx,[edx+38h]
  1062.         dec     ecx
  1063.         add     eax,ecx
  1064.         not     ecx
  1065.         and     eax,ecx
  1066.         bt      [format_flags],8
  1067.         jc      pe_entry_init_ok
  1068.         mov     [edx+28h],eax           ; entry point rva
  1069.       pe_entry_init_ok:
  1070.         and     [number_of_sections],0
  1071.         movzx   ebx,word [edx+14h]
  1072.         lea     ebx,[edx+18h+ebx]
  1073.         mov     [current_section],ebx
  1074.         mov     dword [ebx],'.fla'
  1075.         mov     dword [ebx+4],'t'
  1076.         mov     [ebx+14h],edi
  1077.         mov     [ebx+0Ch],eax
  1078.         mov     dword [ebx+24h],0E0000060h
  1079.         xor     ecx,ecx
  1080.         xor     bl,bl
  1081.         not     eax
  1082.         not     ecx
  1083.         not     bl
  1084.         add     eax,1
  1085.         adc     ecx,0
  1086.         adc     bl,0
  1087.         add     eax,edi
  1088.         adc     ecx,0
  1089.         adc     bl,0
  1090.         test    [format_flags],4
  1091.         jnz     peplus_org
  1092.         sub     eax,[edx+34h]
  1093.         sbb     ecx,0
  1094.         sbb     bl,0
  1095.         jmp     pe_org_ok
  1096.       peplus_org:
  1097.         sub     eax,[edx+30h]
  1098.         sbb     ecx,[edx+34h]
  1099.         sbb     bl,0
  1100.       pe_org_ok:
  1101.         test    [format_flags],8
  1102.         jnz     pe64_code
  1103.         mov     bh,2
  1104.         mov     [code_type],32
  1105.         jmp     pe_code_type_ok
  1106.       pe64_code:
  1107.         mov     bh,4
  1108.         mov     [code_type],64
  1109.       pe_code_type_ok:
  1110.         bt      [resolver_flags],0
  1111.         jc      pe_labels_type_ok
  1112.         xor     bh,bh
  1113.       pe_labels_type_ok:
  1114.         push    eax ebx
  1115.         call    init_addressing_space
  1116.         mov     ebp,ebx
  1117.         pop     ebx eax
  1118.         mov     [ds:ebp],eax
  1119.         mov     [ds:ebp+4],ecx
  1120.         mov     [ds:ebp+8],bx
  1121.         mov     [ds:ebp+18h],edi
  1122.         bt      [format_flags],8
  1123.         jnc     dll_flag_ok
  1124.         or      byte [edx+16h+1],20h
  1125.       dll_flag_ok:
  1126.         bt      [format_flags],9
  1127.         jnc     wdm_flag_ok
  1128.         or      byte [edx+5Eh+1],20h
  1129.       wdm_flag_ok:
  1130.         bt      [format_flags],11
  1131.         jnc     large_flag_ok
  1132.         or      byte [edx+16h],20h
  1133.       large_flag_ok:
  1134.         bt      [format_flags],12
  1135.         jnc     nx_ok
  1136.         or      byte [edx+5Eh+1],1
  1137.       nx_ok:
  1138.         jmp     format_defined
  1139. pe_section:
  1140.         call    close_pe_section
  1141.         push    eax ebx
  1142.         call    create_addressing_space
  1143.         mov     ebp,ebx
  1144.         pop     ebx eax
  1145.         bts     [format_flags],5
  1146.         lea     ecx,[ebx+28h]
  1147.         add     edx,[edx+54h]
  1148.         sub     edx,[stub_size]
  1149.         cmp     ecx,edx
  1150.         jbe     new_section
  1151.         lea     ebx,[edx-28h]
  1152.         or      [next_pass_needed],-1
  1153.         push    edi
  1154.         mov     edi,ebx
  1155.         mov     ecx,28h shr 4
  1156.         xor     eax,eax
  1157.         rep     stos dword [edi]
  1158.         pop     edi
  1159.       new_section:
  1160.         mov     [ebx+0Ch],eax
  1161.         lods    word [esi]
  1162.         cmp     ax,'('
  1163.         jne     invalid_argument
  1164.         lea     edx,[esi+4]
  1165.         mov     ecx,[esi]
  1166.         lea     esi,[esi+4+ecx+1]
  1167.         cmp     ecx,8
  1168.         ja      name_too_long
  1169.         xor     eax,eax
  1170.         mov     [ebx],eax
  1171.         mov     [ebx+4],eax
  1172.         push    esi edi
  1173.         mov     edi,ebx
  1174.         mov     esi,edx
  1175.         rep     movs byte [edi],[esi]
  1176.         pop     edi esi
  1177.         and     dword [ebx+24h],0
  1178.         mov     [ebx+14h],edi
  1179.         mov     edx,[code_start]
  1180.         mov     eax,edi
  1181.         xor     ecx,ecx
  1182.         sub     eax,[ebx+0Ch]
  1183.         sbb     ecx,0
  1184.         sbb     byte [ds:ebp+8],0
  1185.         mov     byte [ds:ebp+9],2
  1186.         mov     [code_type],32
  1187.         test    [format_flags],8
  1188.         jz      pe_section_code_type_ok
  1189.         mov     byte [ds:ebp+9],4
  1190.         mov     [code_type],64
  1191.       pe_section_code_type_ok:
  1192.         test    [format_flags],4
  1193.         jnz     peplus_section_org
  1194.         sub     eax,[edx+34h]
  1195.         sbb     ecx,0
  1196.         sbb     byte [ds:ebp+8],0
  1197.         bt      [resolver_flags],0
  1198.         jc      pe_section_org_ok
  1199.         mov     byte [ds:ebp+9],0
  1200.         jmp     pe_section_org_ok
  1201.       peplus_section_org:
  1202.         sub     eax,[edx+30h]
  1203.         sbb     ecx,[edx+34h]
  1204.         sbb     byte [ds:ebp+8],0
  1205.         bt      [resolver_flags],0
  1206.         jc      pe_section_org_ok
  1207.         mov     byte [ds:ebp+9],0
  1208.       pe_section_org_ok:
  1209.         mov     [ds:ebp],eax
  1210.         mov     [ds:ebp+4],ecx
  1211.         mov     [ds:ebp+18h],edi
  1212.       get_section_flags:
  1213.         lods    byte [esi]
  1214.         cmp     al,1Ah
  1215.         je      set_directory
  1216.         cmp     al,19h
  1217.         je      section_flag
  1218.         dec     esi
  1219.         jmp     instruction_assembled
  1220.       set_directory:
  1221.         movzx   eax,byte [esi]
  1222.         inc     esi
  1223.         mov     ecx,ebx
  1224.         test    [format_flags],4
  1225.         jnz     peplus_directory
  1226.         xchg    ecx,[edx+78h+eax*8]
  1227.         mov     dword [edx+78h+eax*8+4],-1
  1228.         jmp     pe_directory_set
  1229.       peplus_directory:
  1230.         xchg    ecx,[edx+88h+eax*8]
  1231.         mov     dword [edx+88h+eax*8+4],-1
  1232.       pe_directory_set:
  1233.         or      ecx,ecx
  1234.         jnz     data_already_defined
  1235.         push    ebx edx
  1236.         call    generate_pe_data
  1237.         pop     edx ebx
  1238.         jmp     get_section_flags
  1239.       section_flag:
  1240.         lods    byte [esi]
  1241.         cmp     al,9
  1242.         je      invalid_argument
  1243.         cmp     al,11
  1244.         je      invalid_argument
  1245.         mov     cl,al
  1246.         mov     eax,1
  1247.         shl     eax,cl
  1248.         test    dword [ebx+24h],eax
  1249.         jnz     setting_already_specified
  1250.         or      dword [ebx+24h],eax
  1251.         jmp     get_section_flags
  1252.       close_pe_section:
  1253.         mov     ebx,[current_section]
  1254.         mov     edx,[code_start]
  1255.         mov     eax,edi
  1256.         sub     eax,[ebx+14h]
  1257.         jnz     finish_section
  1258.         bt      [format_flags],5
  1259.         jc      finish_section
  1260.         mov     eax,[ebx+0Ch]
  1261.         ret
  1262.       finish_section:
  1263.         mov     [ebx+8],eax
  1264.         cmp     edi,[undefined_data_end]
  1265.         jne     align_section
  1266.         cmp     dword [edx+38h],1000h
  1267.         jb      align_section
  1268.         mov     edi,[undefined_data_start]
  1269.       align_section:
  1270.         and     [undefined_data_end],0
  1271.         mov     ebp,edi
  1272.         sub     ebp,[ebx+14h]
  1273.         mov     ecx,[edx+3Ch]
  1274.         dec     ecx
  1275.         lea     eax,[ebp+ecx]
  1276.         not     ecx
  1277.         and     eax,ecx
  1278.         mov     [ebx+10h],eax
  1279.         sub     eax,ebp
  1280.         mov     ecx,eax
  1281.         xor     al,al
  1282.         rep     stos byte [edi]
  1283.         mov     eax,[code_start]
  1284.         sub     eax,[stub_size]
  1285.         sub     [ebx+14h],eax
  1286.         mov     ecx,[ebx+10h]
  1287.         test    byte [ebx+24h],20h
  1288.         jz      pe_code_sum_ok
  1289.         add     [edx+1Ch],ecx
  1290.         cmp     dword [edx+2Ch],0
  1291.         jne     pe_code_sum_ok
  1292.         mov     eax,[ebx+0Ch]
  1293.         mov     [edx+2Ch],eax
  1294.       pe_code_sum_ok:
  1295.         test    byte [ebx+24h],40h
  1296.         jz      pe_data_sum_ok
  1297.         add     [edx+20h],ecx
  1298.         test    [format_flags],4
  1299.         jnz     pe_data_sum_ok
  1300.         cmp     dword [edx+30h],0
  1301.         jne     pe_data_sum_ok
  1302.         mov     eax,[ebx+0Ch]
  1303.         mov     [edx+30h],eax
  1304.       pe_data_sum_ok:
  1305.         mov     eax,[ebx+8]
  1306.         or      eax,eax
  1307.         jz      udata_ok
  1308.         cmp     dword [ebx+10h],0
  1309.         jne     udata_ok
  1310.         or      byte [ebx+24h],80h
  1311.         add     [edx+24h],ecx
  1312.       udata_ok:
  1313.         mov     ecx,[edx+38h]
  1314.         dec     ecx
  1315.         add     eax,ecx
  1316.         not     ecx
  1317.         and     eax,ecx
  1318.         add     eax,[ebx+0Ch]
  1319.         add     ebx,28h
  1320.         mov     [current_section],ebx
  1321.         inc     word [number_of_sections]
  1322.         jz      format_limitations_exceeded
  1323.         ret
  1324. data_directive:
  1325.         cmp     [output_format],3
  1326.         jne     illegal_instruction
  1327.         lods    byte [esi]
  1328.         cmp     al,1Ah
  1329.         je      predefined_data_type
  1330.         cmp     al,'('
  1331.         jne     invalid_argument
  1332.         call    get_byte_value
  1333.         cmp     al,16
  1334.         jb      data_type_ok
  1335.         jmp     invalid_value
  1336.       predefined_data_type:
  1337.         movzx   eax,byte [esi]
  1338.         inc     esi
  1339.       data_type_ok:
  1340.         mov     ebx,[current_section]
  1341.         mov     ecx,edi
  1342.         sub     ecx,[ebx+14h]
  1343.         add     ecx,[ebx+0Ch]
  1344.         mov     edx,[code_start]
  1345.         test    [format_flags],4
  1346.         jnz     peplus_data
  1347.         xchg    ecx,[edx+78h+eax*8]
  1348.         jmp     init_pe_data
  1349.       peplus_data:
  1350.         xchg    ecx,[edx+88h+eax*8]
  1351.       init_pe_data:
  1352.         or      ecx,ecx
  1353.         jnz     data_already_defined
  1354.         call    allocate_structure_data
  1355.         mov     word [ebx],data_directive-instruction_handler
  1356.         mov     [ebx+2],al
  1357.         mov     edx,[current_line]
  1358.         mov     [ebx+4],edx
  1359.         call    generate_pe_data
  1360.         jmp     instruction_assembled
  1361.       end_data:
  1362.         cmp     [output_format],3
  1363.         jne     illegal_instruction
  1364.         call    find_structure_data
  1365.         jc      unexpected_instruction
  1366.         movzx   eax,byte [ebx+2]
  1367.         mov     edx,[current_section]
  1368.         mov     ecx,edi
  1369.         sub     ecx,[edx+14h]
  1370.         add     ecx,[edx+0Ch]
  1371.         mov     edx,[code_start]
  1372.         test    [format_flags],4
  1373.         jnz     end_peplus_data
  1374.         sub     ecx,[edx+78h+eax*8]
  1375.         mov     [edx+78h+eax*8+4],ecx
  1376.         jmp     remove_structure_data
  1377.       end_peplus_data:
  1378.         sub     ecx,[edx+88h+eax*8]
  1379.         mov     [edx+88h+eax*8+4],ecx
  1380.         jmp     remove_structure_data
  1381. pe_entry:
  1382.         lods    byte [esi]
  1383.         cmp     al,'('
  1384.         jne     invalid_argument
  1385.         cmp     byte [esi],'.'
  1386.         je      invalid_value
  1387.         test    [format_flags],8
  1388.         jnz     pe64_entry
  1389.         call    get_dword_value
  1390.         mov     bl,2
  1391.         bt      [resolver_flags],0
  1392.         jc      check_pe_entry_label_type
  1393.         xor     bl,bl
  1394.       check_pe_entry_label_type:
  1395.         cmp     [value_type],bl
  1396.         je      pe_entry_ok
  1397.         call    recoverable_invalid_address
  1398.       pe_entry_ok:
  1399.         cdq
  1400.         test    [format_flags],4
  1401.         jnz     pe64_entry_type_ok
  1402.         mov     edx,[code_start]
  1403.         sub     eax,[edx+34h]
  1404.         mov     [edx+28h],eax
  1405.         jmp     instruction_assembled
  1406.       pe64_entry:
  1407.         call    get_qword_value
  1408.         mov     bl,4
  1409.         bt      [resolver_flags],0
  1410.         jc      check_pe64_entry_label_type
  1411.         xor     bl,bl
  1412.       check_pe64_entry_label_type:
  1413.         cmp     [value_type],bl
  1414.         je      pe64_entry_type_ok
  1415.         call    recoverable_invalid_address
  1416.       pe64_entry_type_ok:
  1417.         mov     ecx,[code_start]
  1418.         sub     eax,[ecx+30h]
  1419.         sbb     edx,[ecx+34h]
  1420.         jz      pe64_entry_range_ok
  1421.         call    recoverable_overflow
  1422.       pe64_entry_range_ok:
  1423.         mov     [ecx+28h],eax
  1424.         jmp     instruction_assembled
  1425. pe_stack:
  1426.         lods    byte [esi]
  1427.         cmp     al,'('
  1428.         jne     invalid_argument
  1429.         cmp     byte [esi],'.'
  1430.         je      invalid_value
  1431.         test    [format_flags],4
  1432.         jnz     peplus_stack
  1433.         call    get_count_value
  1434.         mov     edx,[code_start]
  1435.         mov     [edx+60h],eax
  1436.         cmp     byte [esi],','
  1437.         jne     default_stack_commit
  1438.         lods    byte [esi]
  1439.         lods    byte [esi]
  1440.         cmp     al,'('
  1441.         jne     invalid_argument
  1442.         cmp     byte [esi],'.'
  1443.         je      invalid_value
  1444.         call    get_count_value
  1445.         mov     edx,[code_start]
  1446.         mov     [edx+64h],eax
  1447.         cmp     eax,[edx+60h]
  1448.         ja      value_out_of_range
  1449.         jmp     instruction_assembled
  1450.       default_stack_commit:
  1451.         mov     dword [edx+64h],1000h
  1452.         mov     eax,[edx+60h]
  1453.         cmp     eax,1000h
  1454.         ja      instruction_assembled
  1455.         mov     dword [edx+64h],eax
  1456.         jmp     instruction_assembled
  1457.       peplus_stack:
  1458.         call    get_qword_value
  1459.         cmp     [value_type],0
  1460.         jne     invalid_use_of_symbol
  1461.         mov     ecx,[code_start]
  1462.         mov     [ecx+60h],eax
  1463.         mov     [ecx+64h],edx
  1464.         cmp     byte [esi],','
  1465.         jne     default_peplus_stack_commit
  1466.         lods    byte [esi]
  1467.         lods    byte [esi]
  1468.         cmp     al,'('
  1469.         jne     invalid_argument
  1470.         cmp     byte [esi],'.'
  1471.         je      invalid_value
  1472.         call    get_qword_value
  1473.         cmp     [value_type],0
  1474.         jne     invalid_use_of_symbol
  1475.         mov     ecx,[code_start]
  1476.         mov     [ecx+68h],eax
  1477.         mov     [ecx+6Ch],edx
  1478.         cmp     edx,[ecx+64h]
  1479.         ja      value_out_of_range
  1480.         jb      instruction_assembled
  1481.         cmp     eax,[ecx+60h]
  1482.         ja      value_out_of_range
  1483.         jmp     instruction_assembled
  1484.       default_peplus_stack_commit:
  1485.         mov     dword [ecx+68h],1000h
  1486.         cmp     dword [ecx+64h],0
  1487.         jne     instruction_assembled
  1488.         mov     eax,[ecx+60h]
  1489.         cmp     eax,1000h
  1490.         ja      instruction_assembled
  1491.         mov     dword [ecx+68h],eax
  1492.         jmp     instruction_assembled
  1493. pe_heap:
  1494.         lods    byte [esi]
  1495.         cmp     al,'('
  1496.         jne     invalid_argument
  1497.         cmp     byte [esi],'.'
  1498.         je      invalid_value
  1499.         test    [format_flags],4
  1500.         jnz     peplus_heap
  1501.         call    get_count_value
  1502.         mov     edx,[code_start]
  1503.         mov     [edx+68h],eax
  1504.         cmp     byte [esi],','
  1505.         jne     instruction_assembled
  1506.         lods    byte [esi]
  1507.         lods    byte [esi]
  1508.         cmp     al,'('
  1509.         jne     invalid_argument
  1510.         cmp     byte [esi],'.'
  1511.         je      invalid_value
  1512.         call    get_count_value
  1513.         mov     edx,[code_start]
  1514.         mov     [edx+6Ch],eax
  1515.         cmp     eax,[edx+68h]
  1516.         ja      value_out_of_range
  1517.         jmp     instruction_assembled
  1518.       peplus_heap:
  1519.         call    get_qword_value
  1520.         cmp     [value_type],0
  1521.         jne     invalid_use_of_symbol
  1522.         mov     ecx,[code_start]
  1523.         mov     [ecx+70h],eax
  1524.         mov     [ecx+74h],edx
  1525.         cmp     byte [esi],','
  1526.         jne     instruction_assembled
  1527.         lods    byte [esi]
  1528.         lods    byte [esi]
  1529.         cmp     al,'('
  1530.         jne     invalid_argument
  1531.         cmp     byte [esi],'.'
  1532.         je      invalid_value
  1533.         call    get_qword_value
  1534.         cmp     [value_type],0
  1535.         jne     invalid_use_of_symbol
  1536.         mov     ecx,[code_start]
  1537.         mov     [ecx+78h],eax
  1538.         mov     [ecx+7Ch],edx
  1539.         cmp     edx,[ecx+74h]
  1540.         ja      value_out_of_range
  1541.         jb      instruction_assembled
  1542.         cmp     eax,[ecx+70h]
  1543.         ja      value_out_of_range
  1544.         jmp     instruction_assembled
  1545. mark_pe_relocation:
  1546.         push    eax ebx
  1547.         test    [format_flags],4
  1548.         jz      check_standard_pe_relocation_type
  1549.         cmp     [value_type],4
  1550.         je      pe_relocation_type_ok
  1551.       check_standard_pe_relocation_type:
  1552.         cmp     [value_type],2
  1553.         je      pe_relocation_type_ok
  1554.         call    recoverable_misuse
  1555.       pe_relocation_type_ok:
  1556.         mov     ebx,[current_section]
  1557.         mov     eax,edi
  1558.         sub     eax,[ebx+14h]
  1559.         add     eax,[ebx+0Ch]
  1560.         mov     ebx,[free_additional_memory]
  1561.         inc     [number_of_relocations]
  1562.         add     ebx,5
  1563.         cmp     ebx,[structures_buffer]
  1564.         jae     out_of_memory
  1565.         mov     [free_additional_memory],ebx
  1566.         mov     [ebx-5],eax
  1567.         cmp     [value_type],2
  1568.         je      fixup_32bit
  1569.         mov     byte [ebx-1],0Ah
  1570.         jmp     fixup_ok
  1571.       fixup_32bit:
  1572.         mov     byte [ebx-1],3
  1573.       fixup_ok:
  1574.         pop     ebx eax
  1575.         ret
  1576. generate_pe_data:
  1577.         cmp     al,2
  1578.         je      make_pe_resource
  1579.         cmp     al,5
  1580.         je      make_pe_fixups
  1581.         ret
  1582. make_pe_fixups:
  1583.         mov     edx,[code_start]
  1584.         and     byte [edx+16h],not 1
  1585.         or      byte [edx+5Eh],40h
  1586.         bts     [resolver_flags],0
  1587.         jc      fixups_ready
  1588.         or      [next_pass_needed],-1
  1589.       fixups_ready:
  1590.         and     [last_fixup_base],0
  1591.         call    make_fixups
  1592.         xchg    eax,[actual_fixups_size]
  1593.         sub     eax,[actual_fixups_size]
  1594.         ja      reserve_forward_fixups
  1595.         xor     eax,eax
  1596.       reserve_forward_fixups:
  1597.         mov     [reserved_fixups],edi
  1598.         add     edi,eax
  1599.         mov     [reserved_fixups_size],eax
  1600.         ret
  1601.       make_fixups:
  1602.         push    esi
  1603.         xor     ecx,ecx
  1604.         xchg    ecx,[number_of_relocations]
  1605.         mov     esi,[free_additional_memory]
  1606.         lea     eax,[ecx*5]
  1607.         sub     esi,eax
  1608.         mov     [free_additional_memory],esi
  1609.         mov     edx,[last_fixup_base]
  1610.         mov     ebx,[last_fixup_header]
  1611.         mov     ebp,edi
  1612.         jecxz   fixups_done
  1613.       make_fixup:
  1614.         cmp     [esi],edx
  1615.         jb      store_fixup
  1616.         mov     eax,edi
  1617.         sub     eax,ebp
  1618.         test    eax,11b
  1619.         jz      fixups_block
  1620.         xor     ax,ax
  1621.         stos    word [edi]
  1622.         add     dword [ebx],2
  1623.       fixups_block:
  1624.         mov     eax,edx
  1625.         add     edx,1000h
  1626.         cmp     [esi],edx
  1627.         jae     fixups_block
  1628.         stos    dword [edi]
  1629.         mov     ebx,edi
  1630.         mov     eax,8
  1631.         stos    dword [edi]
  1632.       store_fixup:
  1633.         add     dword [ebx],2
  1634.         mov     ah,[esi+1]
  1635.         and     ah,0Fh
  1636.         mov     al,[esi+4]
  1637.         shl     al,4
  1638.         or      ah,al
  1639.         mov     al,[esi]
  1640.         stos    word [edi]
  1641.         add     esi,5
  1642.         loop    make_fixup
  1643.       fixups_done:
  1644.         mov     [last_fixup_base],edx
  1645.         mov     [last_fixup_header],ebx
  1646.         pop     esi
  1647.         mov     eax,edi
  1648.         sub     eax,ebp
  1649.         ret
  1650. make_pe_resource:
  1651.         cmp     byte [esi],82h
  1652.         jne     resource_done
  1653.         inc     esi
  1654.         lods    word [esi]
  1655.         cmp     ax,'('
  1656.         jne     invalid_argument
  1657.         lods    dword [esi]
  1658.         mov     edx,esi
  1659.         lea     esi,[esi+eax+1]
  1660.         cmp     [next_pass_needed],0
  1661.         je      resource_from_file
  1662.         cmp     [current_pass],0
  1663.         jne     reserve_space_for_resource
  1664.         and     [resource_size],0
  1665.       reserve_space_for_resource:
  1666.         add     edi,[resource_size]
  1667.         cmp     edi,[tagged_blocks]
  1668.         ja      out_of_memory
  1669.         jmp     resource_done
  1670.       resource_from_file:
  1671.         push    esi
  1672.         mov     esi,edx
  1673.         call    open_binary_file
  1674.         push    ebx
  1675.         mov     esi,[free_additional_memory]
  1676.         lea     eax,[esi+20h]
  1677.         cmp     eax,[structures_buffer]
  1678.         ja      out_of_memory
  1679.         mov     edx,esi
  1680.         mov     ecx,20h
  1681.         call    read
  1682.         jc      invalid_file_format
  1683.         xor     eax,eax
  1684.         cmp     [esi],eax
  1685.         jne     invalid_file_format
  1686.         mov     ax,0FFFFh
  1687.         cmp     [esi+8],eax
  1688.         jne     invalid_file_format
  1689.         cmp     [esi+12],eax
  1690.         jne     invalid_file_format
  1691.         mov     eax,20h
  1692.         cmp     [esi+4],eax
  1693.         jne     invalid_file_format
  1694.       read_resource_headers:
  1695.         test    eax,11b
  1696.         jz      resource_file_alignment_ok
  1697.         mov     edx,4
  1698.         and     eax,11b
  1699.         sub     edx,eax
  1700.         mov     al,1
  1701.         call    lseek
  1702.         jc      resource_headers_ok
  1703.       resource_file_alignment_ok:
  1704.         mov     [esi],eax
  1705.         lea     edx,[esi+12]
  1706.         mov     ecx,8
  1707.         call    read
  1708.         jc      resource_headers_ok
  1709.         mov     ecx,[esi+16]
  1710.         add     [esi],ecx
  1711.         lea     edx,[esi+20]
  1712.         sub     ecx,8
  1713.         mov     [esi+16],ecx
  1714.         lea     eax,[edx+ecx]
  1715.         cmp     eax,[structures_buffer]
  1716.         ja      out_of_memory
  1717.         call    read
  1718.         jc      invalid_file_format
  1719.         mov     edx,[esi]
  1720.         add     edx,[esi+12]
  1721.         mov     eax,[esi+16]
  1722.         lea     ecx,[esi+20]
  1723.         lea     esi,[ecx+eax]
  1724.         add     ecx,2
  1725.         cmp     word [ecx-2],0FFFFh
  1726.         je      resource_header_type_ok
  1727.       check_resource_header_type:
  1728.         cmp     ecx,esi
  1729.         jae     invalid_file_format
  1730.         cmp     word [ecx],0
  1731.         je      resource_header_type_ok
  1732.         add     ecx,2
  1733.         jmp     check_resource_header_type
  1734.       resource_header_type_ok:
  1735.         add     ecx,2
  1736.         cmp     word [ecx],0FFFFh
  1737.         je      resource_header_name_ok
  1738.       check_resource_header_name:
  1739.         cmp     ecx,esi
  1740.         jae     invalid_file_format
  1741.         cmp     word [ecx],0
  1742.         je      resource_header_name_ok
  1743.         add     ecx,2
  1744.         jmp     check_resource_header_name
  1745.       resource_header_name_ok:
  1746.         xor     al,al
  1747.         call    lseek
  1748.         jnc     read_resource_headers
  1749.       resource_headers_ok:
  1750.         cmp     esi,[free_additional_memory]
  1751.         je      invalid_file_format
  1752.         xor     eax,eax
  1753.         mov     [esi],eax
  1754.         mov     [resource_data],edi
  1755.         lea     eax,[edi+16]
  1756.         cmp     eax,[tagged_blocks]
  1757.         jae     out_of_memory
  1758.         xor     eax,eax
  1759.         stos    dword [edi]
  1760.         call    make_timestamp
  1761.         stos    dword [edi]
  1762.         xor     eax,eax
  1763.         stos    dword [edi]
  1764.         stos    dword [edi]
  1765.         xor     ebx,ebx
  1766.       make_type_name_directory:
  1767.         mov     esi,[free_additional_memory]
  1768.         xor     edx,edx
  1769.       find_type_name:
  1770.         cmp     dword [esi],0
  1771.         je      type_name_ok
  1772.         add     esi,20
  1773.         cmp     word [esi],0FFFFh
  1774.         je      check_next_type_name
  1775.         or      ebx,ebx
  1776.         jz      check_this_type_name
  1777.         xor     ecx,ecx
  1778.       compare_with_previous_type_name:
  1779.         mov     ax,[esi+ecx]
  1780.         cmp     ax,[ebx+ecx]
  1781.         ja      check_this_type_name
  1782.         jb      check_next_type_name
  1783.         add     ecx,2
  1784.         mov     ax,[esi+ecx]
  1785.         or      ax,[ebx+ecx]
  1786.         jnz     compare_with_previous_type_name
  1787.         jmp     check_next_type_name
  1788.       check_this_type_name:
  1789.         or      edx,edx
  1790.         jz      type_name_found
  1791.         xor     ecx,ecx
  1792.       compare_with_current_type_name:
  1793.         mov     ax,[esi+ecx]
  1794.         cmp     ax,[edx+ecx]
  1795.         ja      check_next_type_name
  1796.         jb      type_name_found
  1797.         add     ecx,2
  1798.         mov     ax,[esi+ecx]
  1799.         or      ax,[edx+ecx]
  1800.         jnz     compare_with_current_type_name
  1801.         jmp     same_type_name
  1802.       type_name_found:
  1803.         mov     edx,esi
  1804.       same_type_name:
  1805.         mov     [esi-16],edi
  1806.       check_next_type_name:
  1807.         mov     eax,[esi-4]
  1808.         add     esi,eax
  1809.         jmp     find_type_name
  1810.       type_name_ok:
  1811.         or      edx,edx
  1812.         jz      type_name_directory_done
  1813.         mov     ebx,edx
  1814.       make_type_name_entry:
  1815.         mov     eax,[resource_data]
  1816.         inc     word [eax+12]
  1817.         lea     eax,[edi+8]
  1818.         cmp     eax,[tagged_blocks]
  1819.         jae     out_of_memory
  1820.         mov     eax,ebx
  1821.         stos    dword [edi]
  1822.         xor     eax,eax
  1823.         stos    dword [edi]
  1824.         jmp     make_type_name_directory
  1825.       type_name_directory_done:
  1826.         mov     ebx,-1
  1827.       make_type_id_directory:
  1828.         mov     esi,[free_additional_memory]
  1829.         mov     edx,10000h
  1830.       find_type_id:
  1831.         cmp     dword [esi],0
  1832.         je      type_id_ok
  1833.         add     esi,20
  1834.         cmp     word [esi],0FFFFh
  1835.         jne     check_next_type_id
  1836.         movzx   eax,word [esi+2]
  1837.         cmp     eax,ebx
  1838.         jle     check_next_type_id
  1839.         cmp     eax,edx
  1840.         jg      check_next_type_id
  1841.         mov     edx,eax
  1842.         mov     [esi-16],edi
  1843.       check_next_type_id:
  1844.         mov     eax,[esi-4]
  1845.         add     esi,eax
  1846.         jmp     find_type_id
  1847.       type_id_ok:
  1848.         cmp     edx,10000h
  1849.         je      type_id_directory_done
  1850.         mov     ebx,edx
  1851.       make_type_id_entry:
  1852.         mov     eax,[resource_data]
  1853.         inc     word [eax+14]
  1854.         lea     eax,[edi+8]
  1855.         cmp     eax,[tagged_blocks]
  1856.         jae     out_of_memory
  1857.         mov     eax,ebx
  1858.         stos    dword [edi]
  1859.         xor     eax,eax
  1860.         stos    dword [edi]
  1861.         jmp     make_type_id_directory
  1862.       type_id_directory_done:
  1863.         mov     esi,[resource_data]
  1864.         add     esi,10h
  1865.         mov     ecx,[esi-4]
  1866.         or      cx,cx
  1867.         jz      resource_directories_ok
  1868.       make_resource_directories:
  1869.         push    ecx
  1870.         push    edi
  1871.         mov     edx,edi
  1872.         sub     edx,[resource_data]
  1873.         bts     edx,31
  1874.         mov     [esi+4],edx
  1875.         lea     eax,[edi+16]
  1876.         cmp     eax,[tagged_blocks]
  1877.         jae     out_of_memory
  1878.         xor     eax,eax
  1879.         stos    dword [edi]
  1880.         call    make_timestamp
  1881.         stos    dword [edi]
  1882.         xor     eax,eax
  1883.         stos    dword [edi]
  1884.         stos    dword [edi]
  1885.         mov     ebp,esi
  1886.         xor     ebx,ebx
  1887.       make_resource_name_directory:
  1888.         mov     esi,[free_additional_memory]
  1889.         xor     edx,edx
  1890.       find_resource_name:
  1891.         cmp     dword [esi],0
  1892.         je      resource_name_ok
  1893.         push    esi
  1894.         cmp     [esi+4],ebp
  1895.         jne     check_next_resource_name
  1896.         add     esi,20
  1897.         call    skip_resource_name
  1898.         cmp     word [esi],0FFFFh
  1899.         je      check_next_resource_name
  1900.         or      ebx,ebx
  1901.         jz      check_this_resource_name
  1902.         xor     ecx,ecx
  1903.       compare_with_previous_resource_name:
  1904.         mov     ax,[esi+ecx]
  1905.         cmp     ax,[ebx+ecx]
  1906.         ja      check_this_resource_name
  1907.         jb      check_next_resource_name
  1908.         add     ecx,2
  1909.         mov     ax,[esi+ecx]
  1910.         or      ax,[ebx+ecx]
  1911.         jnz     compare_with_previous_resource_name
  1912.         jmp     check_next_resource_name
  1913.       skip_resource_name:
  1914.         cmp     word [esi],0FFFFh
  1915.         jne     skip_unicode_string
  1916.         add     esi,4
  1917.         ret
  1918.       skip_unicode_string:
  1919.         add     esi,2
  1920.         cmp     word [esi-2],0
  1921.         jne     skip_unicode_string
  1922.         ret
  1923.       check_this_resource_name:
  1924.         or      edx,edx
  1925.         jz      resource_name_found
  1926.         xor     ecx,ecx
  1927.       compare_with_current_resource_name:
  1928.         mov     ax,[esi+ecx]
  1929.         cmp     ax,[edx+ecx]
  1930.         ja      check_next_resource_name
  1931.         jb      resource_name_found
  1932.         add     ecx,2
  1933.         mov     ax,[esi+ecx]
  1934.         or      ax,[edx+ecx]
  1935.         jnz     compare_with_current_resource_name
  1936.         jmp     same_resource_name
  1937.       resource_name_found:
  1938.         mov     edx,esi
  1939.       same_resource_name:
  1940.         mov     eax,[esp]
  1941.         mov     [eax+8],edi
  1942.       check_next_resource_name:
  1943.         pop     esi
  1944.         mov     eax,[esi+16]
  1945.         lea     esi,[esi+20+eax]
  1946.         jmp     find_resource_name
  1947.       resource_name_ok:
  1948.         or      edx,edx
  1949.         jz      resource_name_directory_done
  1950.         mov     ebx,edx
  1951.       make_resource_name_entry:
  1952.         mov     eax,[esp]
  1953.         inc     word [eax+12]
  1954.         lea     eax,[edi+8]
  1955.         cmp     eax,[tagged_blocks]
  1956.         jae     out_of_memory
  1957.         mov     eax,ebx
  1958.         stos    dword [edi]
  1959.         xor     eax,eax
  1960.         stos    dword [edi]
  1961.         jmp     make_resource_name_directory
  1962.       resource_name_directory_done:
  1963.         mov     ebx,-1
  1964.       make_resource_id_directory:
  1965.         mov     esi,[free_additional_memory]
  1966.         mov     edx,10000h
  1967.       find_resource_id:
  1968.         cmp     dword [esi],0
  1969.         je      resource_id_ok
  1970.         push    esi
  1971.         cmp     [esi+4],ebp
  1972.         jne     check_next_resource_id
  1973.         add     esi,20
  1974.         call    skip_resource_name
  1975.         cmp     word [esi],0FFFFh
  1976.         jne     check_next_resource_id
  1977.         movzx   eax,word [esi+2]
  1978.         cmp     eax,ebx
  1979.         jle     check_next_resource_id
  1980.         cmp     eax,edx
  1981.         jg      check_next_resource_id
  1982.         mov     edx,eax
  1983.         mov     eax,[esp]
  1984.         mov     [eax+8],edi
  1985.       check_next_resource_id:
  1986.         pop     esi
  1987.         mov     eax,[esi+16]
  1988.         lea     esi,[esi+20+eax]
  1989.         jmp     find_resource_id
  1990.       resource_id_ok:
  1991.         cmp     edx,10000h
  1992.         je      resource_id_directory_done
  1993.         mov     ebx,edx
  1994.       make_resource_id_entry:
  1995.         mov     eax,[esp]
  1996.         inc     word [eax+14]
  1997.         lea     eax,[edi+8]
  1998.         cmp     eax,[tagged_blocks]
  1999.         jae     out_of_memory
  2000.         mov     eax,ebx
  2001.         stos    dword [edi]
  2002.         xor     eax,eax
  2003.         stos    dword [edi]
  2004.         jmp     make_resource_id_directory
  2005.       resource_id_directory_done:
  2006.         pop     eax
  2007.         mov     esi,ebp
  2008.         pop     ecx
  2009.         add     esi,8
  2010.         dec     cx
  2011.         jnz     make_resource_directories
  2012.       resource_directories_ok:
  2013.         shr     ecx,16
  2014.         jnz     make_resource_directories
  2015.         mov     esi,[resource_data]
  2016.         add     esi,10h
  2017.         movzx   eax,word [esi-4]
  2018.         movzx   edx,word [esi-2]
  2019.         add     eax,edx
  2020.         lea     esi,[esi+eax*8]
  2021.         push    edi                     ; address of language directories
  2022.       update_resource_directories:
  2023.         cmp     esi,[esp]
  2024.         je      resource_directories_updated
  2025.         add     esi,10h
  2026.         mov     ecx,[esi-4]
  2027.         or      cx,cx
  2028.         jz      language_directories_ok
  2029.       make_language_directories:
  2030.         push    ecx
  2031.         push    edi
  2032.         mov     edx,edi
  2033.         sub     edx,[resource_data]
  2034.         bts     edx,31
  2035.         mov     [esi+4],edx
  2036.         lea     eax,[edi+16]
  2037.         cmp     eax,[tagged_blocks]
  2038.         jae     out_of_memory
  2039.         xor     eax,eax
  2040.         stos    dword [edi]
  2041.         call    make_timestamp
  2042.         stos    dword [edi]
  2043.         xor     eax,eax
  2044.         stos    dword [edi]
  2045.         stos    dword [edi]
  2046.         mov     ebp,esi
  2047.         mov     ebx,-1
  2048.       make_language_id_directory:
  2049.         mov     esi,[free_additional_memory]
  2050.         mov     edx,10000h
  2051.       find_language_id:
  2052.         cmp     dword [esi],0
  2053.         je      language_id_ok
  2054.         push    esi
  2055.         cmp     [esi+8],ebp
  2056.         jne     check_next_language_id
  2057.         add     esi,20
  2058.         mov     eax,esi
  2059.         call    skip_resource_name
  2060.         call    skip_resource_name
  2061.         neg     eax
  2062.         add     eax,esi
  2063.         and     eax,11b
  2064.         add     esi,eax
  2065.       get_language_id:
  2066.         movzx   eax,word [esi+6]
  2067.         cmp     eax,ebx
  2068.         jle     check_next_language_id
  2069.         cmp     eax,edx
  2070.         jge     check_next_language_id
  2071.         mov     edx,eax
  2072.         mov     eax,[esp]
  2073.         mov     dword [value],eax
  2074.       check_next_language_id:
  2075.         pop     esi
  2076.         mov     eax,[esi+16]
  2077.         lea     esi,[esi+20+eax]
  2078.         jmp     find_language_id
  2079.       language_id_ok:
  2080.         cmp     edx,10000h
  2081.         je      language_id_directory_done
  2082.         mov     ebx,edx
  2083.       make_language_id_entry:
  2084.         mov     eax,[esp]
  2085.         inc     word [eax+14]
  2086.         lea     eax,[edi+8]
  2087.         cmp     eax,[tagged_blocks]
  2088.         jae     out_of_memory
  2089.         mov     eax,ebx
  2090.         stos    dword [edi]
  2091.         mov     eax,dword [value]
  2092.         stos    dword [edi]
  2093.         jmp     make_language_id_directory
  2094.       language_id_directory_done:
  2095.         pop     eax
  2096.         mov     esi,ebp
  2097.         pop     ecx
  2098.         add     esi,8
  2099.         dec     cx
  2100.         jnz     make_language_directories
  2101.       language_directories_ok:
  2102.         shr     ecx,16
  2103.         jnz     make_language_directories
  2104.         jmp     update_resource_directories
  2105.       resource_directories_updated:
  2106.         mov     esi,[resource_data]
  2107.         push    edi
  2108.       make_name_strings:
  2109.         add     esi,10h
  2110.         movzx   eax,word [esi-2]
  2111.         movzx   ecx,word [esi-4]
  2112.         add     eax,ecx
  2113.         lea     eax,[esi+eax*8]
  2114.         push    eax
  2115.         or      ecx,ecx
  2116.         jz      string_entries_processed
  2117.       process_string_entries:
  2118.         push    ecx
  2119.         mov     edx,edi
  2120.         sub     edx,[resource_data]
  2121.         bts     edx,31
  2122.         xchg    [esi],edx
  2123.         mov     ebx,edi
  2124.         xor     ax,ax
  2125.         stos    word [edi]
  2126.       copy_string_data:
  2127.         lea     eax,[edi+2]
  2128.         cmp     eax,[tagged_blocks]
  2129.         jae     out_of_memory
  2130.         mov     ax,[edx]
  2131.         or      ax,ax
  2132.         jz      string_data_copied
  2133.         stos    word [edi]
  2134.         inc     word [ebx]
  2135.         add     edx,2
  2136.         jmp     copy_string_data
  2137.       string_data_copied:
  2138.         add     esi,8
  2139.         pop     ecx
  2140.         loop    process_string_entries
  2141.       string_entries_processed:
  2142.         pop     esi
  2143.         cmp     esi,[esp]
  2144.         jb      make_name_strings
  2145.         mov     eax,edi
  2146.         sub     eax,[resource_data]
  2147.         test    al,11b
  2148.         jz      resource_strings_alignment_ok
  2149.         xor     ax,ax
  2150.         stos    word [edi]
  2151.       resource_strings_alignment_ok:
  2152.         pop     edx
  2153.         pop     ebx                     ; address of language directories
  2154.         mov     ebp,edi
  2155.       update_language_directories:
  2156.         add     ebx,10h
  2157.         movzx   eax,word [ebx-2]
  2158.         movzx   ecx,word [ebx-4]
  2159.         add     ecx,eax
  2160.       make_data_records:
  2161.         push    ecx
  2162.         mov     esi,edi
  2163.         sub     esi,[resource_data]
  2164.         xchg    esi,[ebx+4]
  2165.         lea     eax,[edi+16]
  2166.         cmp     eax,[tagged_blocks]
  2167.         jae     out_of_memory
  2168.         mov     eax,esi
  2169.         stos    dword [edi]
  2170.         mov     eax,[esi+12]
  2171.         stos    dword [edi]
  2172.         xor     eax,eax
  2173.         stos    dword [edi]
  2174.         stos    dword [edi]
  2175.         pop     ecx
  2176.         add     ebx,8
  2177.         loop    make_data_records
  2178.         cmp     ebx,edx
  2179.         jb      update_language_directories
  2180.         pop     ebx                     ; file handle
  2181.         mov     esi,ebp
  2182.         mov     ebp,edi
  2183.       update_data_records:
  2184.         push    ebp
  2185.         mov     ecx,edi
  2186.         mov     eax,[current_section]
  2187.         sub     ecx,[eax+14h]
  2188.         add     ecx,[eax+0Ch]
  2189.         xchg    ecx,[esi]
  2190.         mov     edx,[ecx]
  2191.         xor     al,al
  2192.         call    lseek
  2193.         mov     edx,edi
  2194.         mov     ecx,[esi+4]
  2195.         add     edi,ecx
  2196.         cmp     edi,[tagged_blocks]
  2197.         ja      out_of_memory
  2198.         call    read
  2199.         mov     eax,edi
  2200.         sub     eax,[resource_data]
  2201.         and     eax,11b
  2202.         jz      resource_data_alignment_ok
  2203.         mov     ecx,4
  2204.         sub     ecx,eax
  2205.         xor     al,al
  2206.         rep     stos byte [edi]
  2207.       resource_data_alignment_ok:
  2208.         pop     ebp
  2209.         add     esi,16
  2210.         cmp     esi,ebp
  2211.         jb      update_data_records
  2212.         pop     esi
  2213.         call    close
  2214.         mov     eax,edi
  2215.         sub     eax,[resource_data]
  2216.         mov     [resource_size],eax
  2217.       resource_done:
  2218.         ret
  2219. close_pe:
  2220.         call    close_pe_section
  2221.         mov     edx,[code_start]
  2222.         mov     [edx+50h],eax
  2223.         call    make_timestamp
  2224.         mov     edx,[code_start]
  2225.         mov     [edx+8],eax
  2226.         mov     eax,[number_of_sections]
  2227.         mov     [edx+6],ax
  2228.         imul    eax,28h
  2229.         movzx   ecx,word [edx+14h]
  2230.         lea     eax,[eax+18h+ecx]
  2231.         add     eax,[stub_size]
  2232.         mov     ecx,[edx+3Ch]
  2233.         dec     ecx
  2234.         add     eax,ecx
  2235.         not     ecx
  2236.         and     eax,ecx
  2237.         cmp     eax,[edx+54h]
  2238.         je      pe_sections_ok
  2239.         or      [next_pass_needed],-1
  2240.       pe_sections_ok:
  2241.         xor     ecx,ecx
  2242.         add     edx,78h
  2243.         test    [format_flags],4
  2244.         jz      process_directories
  2245.         add     edx,10h
  2246.       process_directories:
  2247.         mov     eax,[edx+ecx*8]
  2248.         or      eax,eax
  2249.         jz      directory_ok
  2250.         cmp     dword [edx+ecx*8+4],-1
  2251.         jne     directory_ok
  2252.       section_data:
  2253.         mov     ebx,[edx+ecx*8]
  2254.         mov     eax,[ebx+0Ch]
  2255.         mov     [edx+ecx*8],eax         ; directory rva
  2256.         mov     eax,[ebx+8]
  2257.         mov     [edx+ecx*8+4],eax       ; directory size
  2258.       directory_ok:
  2259.         inc     cl
  2260.         cmp     cl,10h
  2261.         jb      process_directories
  2262.         cmp     dword [edx+5*8],0
  2263.         jne     finish_pe_relocations
  2264.         mov     eax,[number_of_relocations]
  2265.         shl     eax,2
  2266.         sub     [free_additional_memory],eax
  2267.         btr     [resolver_flags],0
  2268.         jnc     pe_relocations_ok
  2269.         or      [next_pass_needed],-1
  2270.         jmp     pe_relocations_ok
  2271.       finish_pe_relocations:
  2272.         push    edi
  2273.         mov     edi,[reserved_fixups]
  2274.         call    make_fixups
  2275.         pop     edi
  2276.         add     [actual_fixups_size],eax
  2277.         cmp     eax,[reserved_fixups_size]
  2278.         je      pe_relocations_ok
  2279.         or      [next_pass_needed],-1
  2280.       pe_relocations_ok:
  2281.         mov     ebx,[code_start]
  2282.         sub     ebx,[stub_size]
  2283.         mov     ecx,edi
  2284.         sub     ecx,ebx
  2285.         mov     ebp,ecx
  2286.         shr     ecx,1
  2287.         xor     eax,eax
  2288.         cdq
  2289.       calculate_checksum:
  2290.         mov     dx,[ebx]
  2291.         add     eax,edx
  2292.         mov     dx,ax
  2293.         shr     eax,16
  2294.         add     eax,edx
  2295.         add     ebx,2
  2296.         loop    calculate_checksum
  2297.         add     eax,ebp
  2298.         mov     ebx,[code_start]
  2299.         mov     [ebx+58h],eax
  2300.         ret
  2301.  
  2302. format_coff:
  2303.         mov     eax,[additional_memory]
  2304.         mov     [symbols_stream],eax
  2305.         mov     ebx,eax
  2306.         add     eax,20h
  2307.         cmp     eax,[structures_buffer]
  2308.         jae     out_of_memory
  2309.         mov     [free_additional_memory],eax
  2310.         xor     eax,eax
  2311.         mov     [ebx],al
  2312.         mov     [ebx+4],eax
  2313.         mov     [ebx+8],edi
  2314.         mov     al,4
  2315.         mov     [ebx+10h],eax
  2316.         mov     al,60h
  2317.         bt      [format_flags],0
  2318.         jnc     flat_section_flags_ok
  2319.         or      eax,0E0000000h
  2320.       flat_section_flags_ok:
  2321.         mov     dword [ebx+14h],eax
  2322.         mov     [current_section],ebx
  2323.         xor     eax,eax
  2324.         mov     [number_of_sections],eax
  2325.         mov     edx,ebx
  2326.         call    init_addressing_space
  2327.         mov     [ebx+14h],edx
  2328.         mov     byte [ebx+9],2
  2329.         mov     [code_type],32
  2330.         test    [format_flags],8
  2331.         jz      format_defined
  2332.         mov     byte [ebx+9],4
  2333.         mov     [code_type],64
  2334.         jmp     format_defined
  2335. coff_section:
  2336.         call    close_coff_section
  2337.         mov     ebx,[free_additional_memory]
  2338.         lea     eax,[ebx+20h]
  2339.         cmp     eax,[structures_buffer]
  2340.         jae     out_of_memory
  2341.         mov     [free_additional_memory],eax
  2342.         mov     [current_section],ebx
  2343.         inc     [number_of_sections]
  2344.         xor     eax,eax
  2345.         mov     [ebx],al
  2346.         mov     [ebx+8],edi
  2347.         mov     [ebx+10h],eax
  2348.         mov     [ebx+14h],eax
  2349.         mov     edx,ebx
  2350.         call    create_addressing_space
  2351.         xchg    edx,ebx
  2352.         mov     [edx+14h],ebx
  2353.         mov     byte [edx+9],2
  2354.         test    [format_flags],8
  2355.         jz      coff_labels_type_ok
  2356.         mov     byte [edx+9],4
  2357.       coff_labels_type_ok:
  2358.         lods    word [esi]
  2359.         cmp     ax,'('
  2360.         jne     invalid_argument
  2361.         mov     [ebx+4],esi
  2362.         mov     ecx,[esi]
  2363.         lea     esi,[esi+4+ecx+1]
  2364.         cmp     ecx,8
  2365.         ja      name_too_long
  2366.       coff_section_flags:
  2367.         cmp     byte [esi],8Ch
  2368.         je      coff_section_alignment
  2369.         cmp     byte [esi],19h
  2370.         jne     coff_section_settings_ok
  2371.         inc     esi
  2372.         lods    byte [esi]
  2373.         bt      [format_flags],0
  2374.         jc      coff_section_flag_ok
  2375.         cmp     al,7
  2376.         ja      invalid_argument
  2377.       coff_section_flag_ok:
  2378.         mov     cl,al
  2379.         mov     eax,1
  2380.         shl     eax,cl
  2381.         test    dword [ebx+14h],eax
  2382.         jnz     setting_already_specified
  2383.         or      dword [ebx+14h],eax
  2384.         jmp     coff_section_flags
  2385.       coff_section_alignment:
  2386.         bt      [format_flags],0
  2387.         jnc     invalid_argument
  2388.         inc     esi
  2389.         lods    byte [esi]
  2390.         cmp     al,'('
  2391.         jne     invalid_argument
  2392.         cmp     byte [esi],'.'
  2393.         je      invalid_value
  2394.         push    ebx
  2395.         call    get_count_value
  2396.         pop     ebx
  2397.         mov     edx,eax
  2398.         dec     edx
  2399.         test    eax,edx
  2400.         jnz     invalid_value
  2401.         or      eax,eax
  2402.         jz      invalid_value
  2403.         cmp     eax,2000h
  2404.         ja      invalid_value
  2405.         bsf     edx,eax
  2406.         inc     edx
  2407.         shl     edx,20
  2408.         or      [ebx+14h],edx
  2409.         xchg    [ebx+10h],eax
  2410.         or      eax,eax
  2411.         jnz     setting_already_specified
  2412.         jmp     coff_section_flags
  2413.       coff_section_settings_ok:
  2414.         cmp     dword [ebx+10h],0
  2415.         jne     instruction_assembled
  2416.         mov     dword [ebx+10h],4
  2417.         bt      [format_flags],0
  2418.         jnc     instruction_assembled
  2419.         or      dword [ebx+14h],300000h
  2420.         jmp     instruction_assembled
  2421.       close_coff_section:
  2422.         mov     ebx,[current_section]
  2423.         mov     eax,edi
  2424.         mov     edx,[ebx+8]
  2425.         sub     eax,edx
  2426.         mov     [ebx+0Ch],eax
  2427.         xor     eax,eax
  2428.         xchg    [undefined_data_end],eax
  2429.         cmp     eax,edi
  2430.         jne     coff_section_ok
  2431.         cmp     edx,[undefined_data_start]
  2432.         jne     coff_section_ok
  2433.         mov     edi,edx
  2434.         or      byte [ebx+14h],80h
  2435.       coff_section_ok:
  2436.         ret
  2437. mark_coff_relocation:
  2438.         cmp     [value_type],3
  2439.         je      coff_relocation_relative
  2440.         push    ebx eax
  2441.         test    [format_flags],8
  2442.         jnz     coff_64bit_relocation
  2443.         mov     al,6
  2444.         cmp     [value_type],2
  2445.         je      coff_relocation
  2446.         cmp     [value_type],5
  2447.         jne     invalid_use_of_symbol
  2448.         inc     al
  2449.         jmp     coff_relocation
  2450.       coff_64bit_relocation:
  2451.         mov     al,1
  2452.         cmp     [value_type],4
  2453.         je      coff_relocation
  2454.         mov     al,2
  2455.         cmp     [value_type],2
  2456.         je      coff_relocation
  2457.         cmp     [value_type],5
  2458.         jne     invalid_use_of_symbol
  2459.         inc     al
  2460.         jmp     coff_relocation
  2461.       coff_relocation_relative:
  2462.         push    ebx
  2463.         bt      [format_flags],0
  2464.         jnc     relative_ok
  2465.         mov     ebx,[current_section]
  2466.         mov     ebx,[ebx+8]
  2467.         sub     ebx,edi
  2468.         sub     eax,ebx
  2469.         add     eax,4
  2470.       relative_ok:
  2471.         mov     ebx,[addressing_space]
  2472.         push    eax
  2473.         mov     al,20
  2474.         test    [format_flags],8
  2475.         jnz     relative_coff_64bit_relocation
  2476.         cmp     byte [ebx+9],2
  2477.         jne     invalid_use_of_symbol
  2478.         jmp     coff_relocation
  2479.       relative_coff_64bit_relocation:
  2480.         mov     al,4
  2481.         cmp     byte [ebx+9],4
  2482.         jne     invalid_use_of_symbol
  2483.       coff_relocation:
  2484.         mov     ebx,[free_additional_memory]
  2485.         add     ebx,0Ch
  2486.         cmp     ebx,[structures_buffer]
  2487.         jae     out_of_memory
  2488.         mov     [free_additional_memory],ebx
  2489.         mov     byte [ebx-0Ch],al
  2490.         mov     eax,[current_section]
  2491.         mov     eax,[eax+8]
  2492.         neg     eax
  2493.         add     eax,edi
  2494.         mov     [ebx-0Ch+4],eax
  2495.         mov     eax,[symbol_identifier]
  2496.         mov     [ebx-0Ch+8],eax
  2497.         pop     eax ebx
  2498.         ret
  2499. close_coff:
  2500.         call    close_coff_section
  2501.         cmp     [next_pass_needed],0
  2502.         je      coff_closed
  2503.         mov     eax,[symbols_stream]
  2504.         mov     [free_additional_memory],eax
  2505.       coff_closed:
  2506.         ret
  2507. coff_formatter:
  2508.         sub     edi,[code_start]
  2509.         mov     [code_size],edi
  2510.         call    prepare_default_section
  2511.         mov     edi,[free_additional_memory]
  2512.         mov     ebx,edi
  2513.         mov     ecx,28h shr 2
  2514.         imul    ecx,[number_of_sections]
  2515.         add     ecx,14h shr 2
  2516.         lea     eax,[edi+ecx*4]
  2517.         cmp     eax,[structures_buffer]
  2518.         jae     out_of_memory
  2519.         xor     eax,eax
  2520.         rep     stos dword [edi]
  2521.         mov     word [ebx],14Ch
  2522.         test    [format_flags],8
  2523.         jz      coff_magic_ok
  2524.         mov     word [ebx],8664h
  2525.       coff_magic_ok:
  2526.         mov     word [ebx+12h],104h
  2527.         bt      [format_flags],0
  2528.         jnc     coff_flags_ok
  2529.         or      byte [ebx+12h],80h
  2530.       coff_flags_ok:
  2531.         push    ebx
  2532.         call    make_timestamp
  2533.         pop     ebx
  2534.         mov     [ebx+4],eax
  2535.         mov     eax,[number_of_sections]
  2536.         mov     [ebx+2],ax
  2537.         mov     esi,[symbols_stream]
  2538.         xor     eax,eax
  2539.         xor     ecx,ecx
  2540.       enumerate_symbols:
  2541.         cmp     esi,[free_additional_memory]
  2542.         je      symbols_enumerated
  2543.         mov     dl,[esi]
  2544.         or      dl,dl
  2545.         jz      enumerate_section
  2546.         cmp     dl,0C0h
  2547.         jae     enumerate_public
  2548.         cmp     dl,80h
  2549.         jae     enumerate_extrn
  2550.         add     esi,0Ch
  2551.         jmp     enumerate_symbols
  2552.       enumerate_section:
  2553.         mov     edx,eax
  2554.         shl     edx,8
  2555.         mov     [esi],edx
  2556.         inc     eax
  2557.         inc     ecx
  2558.         mov     [esi+1Eh],cx
  2559.         add     esi,20h
  2560.         jmp     enumerate_symbols
  2561.       enumerate_public:
  2562.         mov     edx,eax
  2563.         shl     edx,8
  2564.         mov     dl,[esi]
  2565.         mov     [esi],edx
  2566.         mov     edx,[esi+8]
  2567.         add     esi,10h
  2568.         inc     eax
  2569.         cmp     byte [edx+11],0
  2570.         je      enumerate_symbols
  2571.         mov     edx,[edx+20]
  2572.         cmp     byte [edx],0C0h
  2573.         jae     enumerate_symbols
  2574.         cmp     byte [edx],80h
  2575.         jb      enumerate_symbols
  2576.         inc     eax
  2577.         jmp     enumerate_symbols
  2578.       enumerate_extrn:
  2579.         mov     edx,eax
  2580.         shl     edx,8
  2581.         mov     dl,[esi]
  2582.         mov     [esi],edx
  2583.         add     esi,0Ch
  2584.         inc     eax
  2585.         jmp     enumerate_symbols
  2586.       prepare_default_section:
  2587.         mov     ebx,[symbols_stream]
  2588.         cmp     dword [ebx+0Ch],0
  2589.         jne     default_section_ok
  2590.         cmp     [number_of_sections],0
  2591.         je      default_section_ok
  2592.         mov     edx,ebx
  2593.       find_references_to_default_section:
  2594.         cmp     ebx,[free_additional_memory]
  2595.         jne     check_reference
  2596.         add     [symbols_stream],20h
  2597.         ret
  2598.       check_reference:
  2599.         mov     al,[ebx]
  2600.         or      al,al
  2601.         jz      skip_other_section
  2602.         cmp     al,0C0h
  2603.         jae     check_public_reference
  2604.         cmp     al,80h
  2605.         jae     next_reference
  2606.         cmp     edx,[ebx+8]
  2607.         je      default_section_ok
  2608.       next_reference:
  2609.         add     ebx,0Ch
  2610.         jmp     find_references_to_default_section
  2611.       check_public_reference:
  2612.         mov     eax,[ebx+8]
  2613.         add     ebx,10h
  2614.         test    byte [eax+8],1
  2615.         jz      find_references_to_default_section
  2616.         mov     cx,[current_pass]
  2617.         cmp     cx,[eax+16]
  2618.         jne     find_references_to_default_section
  2619.         cmp     edx,[eax+20]
  2620.         je      default_section_ok
  2621.         jmp     find_references_to_default_section
  2622.       skip_other_section:
  2623.         add     ebx,20h
  2624.         jmp     find_references_to_default_section
  2625.       default_section_ok:
  2626.         inc     [number_of_sections]
  2627.         ret
  2628.       symbols_enumerated:
  2629.         mov     [ebx+0Ch],eax
  2630.         mov     ebp,edi
  2631.         sub     ebp,ebx
  2632.         push    ebp
  2633.         lea     edi,[ebx+14h]
  2634.         mov     esi,[symbols_stream]
  2635.       find_section:
  2636.         cmp     esi,[free_additional_memory]
  2637.         je      sections_finished
  2638.         mov     al,[esi]
  2639.         or      al,al
  2640.         jz      section_found
  2641.         add     esi,0Ch
  2642.         cmp     al,0C0h
  2643.         jb      find_section
  2644.         add     esi,4
  2645.         jmp     find_section
  2646.       section_found:
  2647.         push    esi edi
  2648.         mov     esi,[esi+4]
  2649.         or      esi,esi
  2650.         jz      default_section
  2651.         mov     ecx,[esi]
  2652.         add     esi,4
  2653.         rep     movs byte [edi],[esi]
  2654.         jmp     section_name_ok
  2655.       default_section:
  2656.         mov     al,'.'
  2657.         stos    byte [edi]
  2658.         mov     eax,'flat'
  2659.         stos    dword [edi]
  2660.       section_name_ok:
  2661.         pop     edi esi
  2662.         mov     eax,[esi+0Ch]
  2663.         mov     [edi+10h],eax
  2664.         mov     eax,[esi+14h]
  2665.         mov     [edi+24h],eax
  2666.         test    al,80h
  2667.         jnz     section_ptr_ok
  2668.         mov     eax,[esi+8]
  2669.         sub     eax,[code_start]
  2670.         add     eax,ebp
  2671.         mov     [edi+14h],eax
  2672.       section_ptr_ok:
  2673.         mov     ebx,[code_start]
  2674.         mov     edx,[code_size]
  2675.         add     ebx,edx
  2676.         add     edx,ebp
  2677.         xor     ecx,ecx
  2678.         add     esi,20h
  2679.       find_relocations:
  2680.         cmp     esi,[free_additional_memory]
  2681.         je      section_relocations_done
  2682.         mov     al,[esi]
  2683.         or      al,al
  2684.         jz      section_relocations_done
  2685.         cmp     al,80h
  2686.         jb      add_relocation
  2687.         cmp     al,0C0h
  2688.         jb      next_relocation
  2689.         add     esi,10h
  2690.         jmp     find_relocations
  2691.       add_relocation:
  2692.         lea     eax,[ebx+0Ah]
  2693.         cmp     eax,[tagged_blocks]
  2694.         ja      out_of_memory
  2695.         mov     eax,[esi+4]
  2696.         mov     [ebx],eax
  2697.         mov     eax,[esi+8]
  2698.         mov     eax,[eax]
  2699.         shr     eax,8
  2700.         mov     [ebx+4],eax
  2701.         movzx   ax,byte [esi]
  2702.         mov     [ebx+8],ax
  2703.         add     ebx,0Ah
  2704.         inc     ecx
  2705.       next_relocation:
  2706.         add     esi,0Ch
  2707.         jmp     find_relocations
  2708.       section_relocations_done:
  2709.         cmp     ecx,10000h
  2710.         jb      section_relocations_count_16bit
  2711.         bt      [format_flags],0
  2712.         jnc     format_limitations_exceeded
  2713.         mov     word [edi+20h],0FFFFh
  2714.         or      dword [edi+24h],1000000h
  2715.         mov     [edi+18h],edx
  2716.         push    esi edi
  2717.         push    ecx
  2718.         lea     esi,[ebx-1]
  2719.         add     ebx,0Ah
  2720.         lea     edi,[ebx-1]
  2721.         imul    ecx,0Ah
  2722.         std
  2723.         rep     movs byte [edi],[esi]
  2724.         cld
  2725.         pop     ecx
  2726.         inc     esi
  2727.         inc     ecx
  2728.         mov     [esi],ecx
  2729.         xor     eax,eax
  2730.         mov     [esi+4],eax
  2731.         mov     [esi+8],ax
  2732.         pop     edi esi
  2733.         jmp     section_relocations_ok
  2734.       section_relocations_count_16bit:
  2735.         mov     [edi+20h],cx
  2736.         jcxz    section_relocations_ok
  2737.         mov     [edi+18h],edx
  2738.       section_relocations_ok:
  2739.         sub     ebx,[code_start]
  2740.         mov     [code_size],ebx
  2741.         add     edi,28h
  2742.         jmp     find_section
  2743.       sections_finished:
  2744.         mov     edx,[free_additional_memory]
  2745.         mov     ebx,[code_size]
  2746.         add     ebp,ebx
  2747.         mov     [edx+8],ebp
  2748.         add     ebx,[code_start]
  2749.         mov     edi,ebx
  2750.         mov     ecx,[edx+0Ch]
  2751.         imul    ecx,12h shr 1
  2752.         xor     eax,eax
  2753.         shr     ecx,1
  2754.         jnc     zero_symbols_table
  2755.         stos    word [edi]
  2756.       zero_symbols_table:
  2757.         rep     stos dword [edi]
  2758.         mov     edx,edi
  2759.         stos    dword [edi]
  2760.         mov     esi,[symbols_stream]
  2761.       make_symbols_table:
  2762.         cmp     esi,[free_additional_memory]
  2763.         je      symbols_table_ok
  2764.         mov     al,[esi]
  2765.         cmp     al,0C0h
  2766.         jae     add_public_symbol
  2767.         cmp     al,80h
  2768.         jae     add_extrn_symbol
  2769.         or      al,al
  2770.         jz      add_section_symbol
  2771.         add     esi,0Ch
  2772.         jmp     make_symbols_table
  2773.       add_section_symbol:
  2774.         call    store_symbol_name
  2775.         movzx   eax,word [esi+1Eh]
  2776.         mov     [ebx+0Ch],ax
  2777.         mov     byte [ebx+10h],3
  2778.         add     esi,20h
  2779.         add     ebx,12h
  2780.         jmp     make_symbols_table
  2781.       add_extrn_symbol:
  2782.         call    store_symbol_name
  2783.         mov     byte [ebx+10h],2
  2784.         add     esi,0Ch
  2785.         add     ebx,12h
  2786.         jmp     make_symbols_table
  2787.       add_public_symbol:
  2788.         call    store_symbol_name
  2789.         mov     eax,[esi+0Ch]
  2790.         mov     [current_line],eax
  2791.         mov     eax,[esi+8]
  2792.         test    byte [eax+8],1
  2793.         jz      undefined_coff_public
  2794.         mov     cx,[current_pass]
  2795.         cmp     cx,[eax+16]
  2796.         jne     undefined_coff_public
  2797.         mov     cl,[eax+11]
  2798.         or      cl,cl
  2799.         jz      public_constant
  2800.         test    [format_flags],8
  2801.         jnz     check_64bit_public_symbol
  2802.         cmp     cl,2
  2803.         je      public_symbol_type_ok
  2804.         jmp     invalid_use_of_symbol
  2805.       undefined_coff_public:
  2806.         mov     [error_info],eax
  2807.         jmp     undefined_symbol
  2808.       check_64bit_public_symbol:
  2809.         cmp     cl,4
  2810.         jne     invalid_use_of_symbol
  2811.       public_symbol_type_ok:
  2812.         mov     ecx,[eax+20]
  2813.         cmp     byte [ecx],80h
  2814.         je      alias_symbol
  2815.         cmp     byte [ecx],0
  2816.         jne     invalid_use_of_symbol
  2817.         mov     cx,[ecx+1Eh]
  2818.         mov     [ebx+0Ch],cx
  2819.       public_symbol_section_ok:
  2820.         movzx   ecx,byte [eax+9]
  2821.         shr     cl,1
  2822.         and     cl,1
  2823.         neg     ecx
  2824.         cmp     ecx,[eax+4]
  2825.         jne     value_out_of_range
  2826.         xor     ecx,[eax]
  2827.         js      value_out_of_range
  2828.         mov     eax,[eax]
  2829.         mov     [ebx+8],eax
  2830.         mov     al,2
  2831.         cmp     byte [esi],0C0h
  2832.         je      store_symbol_class
  2833.         inc     al
  2834.         cmp     byte [esi],0C1h
  2835.         je      store_symbol_class
  2836.         mov     al,105
  2837.       store_symbol_class:
  2838.         mov     byte [ebx+10h],al
  2839.         add     esi,10h
  2840.         add     ebx,12h
  2841.         jmp     make_symbols_table
  2842.       alias_symbol:
  2843.         bt      [format_flags],0
  2844.         jnc     invalid_use_of_symbol
  2845.         mov     ecx,[eax]
  2846.         or      ecx,[eax+4]
  2847.         jnz     invalid_use_of_symbol
  2848.         mov     byte [ebx+10h],69h
  2849.         mov     byte [ebx+11h],1
  2850.         add     ebx,12h
  2851.         mov     ecx,[eax+20]
  2852.         mov     ecx,[ecx]
  2853.         shr     ecx,8
  2854.         mov     [ebx],ecx
  2855.         mov     byte [ebx+4],3
  2856.         add     esi,10h
  2857.         add     ebx,12h
  2858.         jmp     make_symbols_table
  2859.       public_constant:
  2860.         mov     word [ebx+0Ch],0FFFFh
  2861.         jmp     public_symbol_section_ok
  2862.       symbols_table_ok:
  2863.         mov     eax,edi
  2864.         sub     eax,edx
  2865.         mov     [edx],eax
  2866.         sub     edi,[code_start]
  2867.         mov     [code_size],edi
  2868.         and     [written_size],0
  2869.         mov     edx,[output_file]
  2870.         call    create
  2871.         jc      write_failed
  2872.         mov     edx,[free_additional_memory]
  2873.         pop     ecx
  2874.         add     [written_size],ecx
  2875.         call    write
  2876.         jc      write_failed
  2877.         jmp     write_output
  2878.       store_symbol_name:
  2879.         push    esi
  2880.         mov     esi,[esi+4]
  2881.         or      esi,esi
  2882.         jz      default_name
  2883.         lods    dword [esi]
  2884.         mov     ecx,eax
  2885.         cmp     ecx,8
  2886.         ja      add_string
  2887.         push    edi
  2888.         mov     edi,ebx
  2889.         rep     movs byte [edi],[esi]
  2890.         pop     edi esi
  2891.         ret
  2892.       default_name:
  2893.         mov     dword [ebx],'.fla'
  2894.         mov     dword [ebx+4],'t'
  2895.         pop     esi
  2896.         ret
  2897.       add_string:
  2898.         mov     eax,edi
  2899.         sub     eax,edx
  2900.         mov     [ebx+4],eax
  2901.         inc     ecx
  2902.         rep     movs byte [edi],[esi]
  2903.         pop     esi
  2904.         ret
  2905.  
  2906. format_elf:
  2907.         test    [format_flags],8
  2908.         jnz     format_elf64
  2909.         mov     edx,edi
  2910.         mov     ecx,34h shr 2
  2911.         lea     eax,[edi+ecx*4]
  2912.         cmp     eax,[tagged_blocks]
  2913.         jae     out_of_memory
  2914.         xor     eax,eax
  2915.         rep     stos dword [edi]
  2916.         mov     dword [edx],7Fh + 'ELF' shl 8
  2917.         mov     al,1
  2918.         mov     [edx+4],al
  2919.         mov     [edx+5],al
  2920.         mov     [edx+6],al
  2921.         mov     [edx+14h],al
  2922.         mov     byte [edx+12h],3
  2923.         mov     byte [edx+28h],34h
  2924.         mov     byte [edx+2Eh],28h
  2925.         mov     [code_type],32
  2926.         mov     byte [edx+10h],2
  2927.         cmp     word [esi],1D19h
  2928.         je      format_elf_exe
  2929.         mov     byte [edx+10h],3
  2930.         cmp     word [esi],021Eh
  2931.         je      format_elf_exe
  2932.       elf_header_ok:
  2933.         mov     byte [edx+10h],1
  2934.         mov     eax,[additional_memory]
  2935.         mov     [symbols_stream],eax
  2936.         mov     ebx,eax
  2937.         add     eax,20h
  2938.         cmp     eax,[structures_buffer]
  2939.         jae     out_of_memory
  2940.         mov     [free_additional_memory],eax
  2941.         xor     eax,eax
  2942.         mov     [current_section],ebx
  2943.         mov     [number_of_sections],eax
  2944.         mov     [ebx],al
  2945.         mov     [ebx+4],eax
  2946.         mov     [ebx+8],edi
  2947.         mov     al,111b
  2948.         mov     [ebx+14h],eax
  2949.         mov     al,4
  2950.         mov     [ebx+10h],eax
  2951.         mov     edx,ebx
  2952.         call    init_addressing_space
  2953.         xchg    edx,ebx
  2954.         mov     [edx+14h],ebx
  2955.         mov     byte [edx+9],2
  2956.         test    [format_flags],8
  2957.         jz      format_defined
  2958.         mov     byte [edx+9],4
  2959.         mov     byte [ebx+10h],8
  2960.         jmp     format_defined
  2961.       format_elf64:
  2962.         mov     edx,edi
  2963.         mov     ecx,40h shr 2
  2964.         lea     eax,[edi+ecx*4]
  2965.         cmp     eax,[tagged_blocks]
  2966.         jae     out_of_memory
  2967.         xor     eax,eax
  2968.         rep     stos dword [edi]
  2969.         mov     dword [edx],7Fh + 'ELF' shl 8
  2970.         mov     al,1
  2971.         mov     [edx+5],al
  2972.         mov     [edx+6],al
  2973.         mov     [edx+14h],al
  2974.         mov     byte [edx+4],2
  2975.         mov     byte [edx+12h],62
  2976.         mov     byte [edx+34h],40h
  2977.         mov     byte [edx+3Ah],40h
  2978.         mov     [code_type],64
  2979.         mov     byte [edx+10h],2
  2980.         cmp     word [esi],1D19h
  2981.         je      format_elf64_exe
  2982.         mov     byte [edx+10h],3
  2983.         cmp     word [esi],021Eh
  2984.         je      format_elf64_exe
  2985.         jmp     elf_header_ok
  2986. elf_section:
  2987.         bt      [format_flags],0
  2988.         jc      illegal_instruction
  2989.         call    close_coff_section
  2990.         mov     ebx,[free_additional_memory]
  2991.         lea     eax,[ebx+20h]
  2992.         cmp     eax,[structures_buffer]
  2993.         jae     out_of_memory
  2994.         mov     [free_additional_memory],eax
  2995.         mov     [current_section],ebx
  2996.         inc     word [number_of_sections]
  2997.         jz      format_limitations_exceeded
  2998.         xor     eax,eax
  2999.         mov     [ebx],al
  3000.         mov     [ebx+8],edi
  3001.         mov     [ebx+10h],eax
  3002.         mov     al,10b
  3003.         mov     [ebx+14h],eax
  3004.         mov     edx,ebx
  3005.         call    create_addressing_space
  3006.         xchg    edx,ebx
  3007.         mov     [edx+14h],ebx
  3008.         mov     byte [edx+9],2
  3009.         test    [format_flags],8
  3010.         jz      elf_labels_type_ok
  3011.         mov     byte [edx+9],4
  3012.       elf_labels_type_ok:
  3013.         lods    word [esi]
  3014.         cmp     ax,'('
  3015.         jne     invalid_argument
  3016.         mov     [ebx+4],esi
  3017.         mov     ecx,[esi]
  3018.         lea     esi,[esi+4+ecx+1]
  3019.       elf_section_flags:
  3020.         cmp     byte [esi],8Ch
  3021.         je      elf_section_alignment
  3022.         cmp     byte [esi],19h
  3023.         jne     elf_section_settings_ok
  3024.         inc     esi
  3025.         lods    byte [esi]
  3026.         sub     al,28
  3027.         xor     al,11b
  3028.         test    al,not 10b
  3029.         jnz     invalid_argument
  3030.         mov     cl,al
  3031.         mov     al,1
  3032.         shl     al,cl
  3033.         test    byte [ebx+14h],al
  3034.         jnz     setting_already_specified
  3035.         or      byte [ebx+14h],al
  3036.         jmp     elf_section_flags
  3037.       elf_section_alignment:
  3038.         inc     esi
  3039.         lods    byte [esi]
  3040.         cmp     al,'('
  3041.         jne     invalid_argument
  3042.         cmp     byte [esi],'.'
  3043.         je      invalid_value
  3044.         push    ebx
  3045.         call    get_count_value
  3046.         pop     ebx
  3047.         mov     edx,eax
  3048.         dec     edx
  3049.         test    eax,edx
  3050.         jnz     invalid_value
  3051.         or      eax,eax
  3052.         jz      invalid_value
  3053.         xchg    [ebx+10h],eax
  3054.         or      eax,eax
  3055.         jnz     setting_already_specified
  3056.         jmp     elf_section_flags
  3057.       elf_section_settings_ok:
  3058.         cmp     dword [ebx+10h],0
  3059.         jne     instruction_assembled
  3060.         mov     dword [ebx+10h],4
  3061.         test    [format_flags],8
  3062.         jz      instruction_assembled
  3063.         mov     byte [ebx+10h],8
  3064.         jmp     instruction_assembled
  3065. mark_elf_relocation:
  3066.         test    [format_flags],1
  3067.         jnz     invalid_use_of_symbol
  3068.         push    ebx
  3069.         mov     ebx,[addressing_space]
  3070.         cmp     [value_type],3
  3071.         je      elf_relocation_relative
  3072.         cmp     [value_type],7
  3073.         je      elf_relocation_relative
  3074.         push    eax
  3075.         cmp     [value_type],5
  3076.         je      elf_gotoff_relocation
  3077.         ja      invalid_use_of_symbol
  3078.         mov     al,1                    ; R_386_32 / R_AMD64_64
  3079.         test    [format_flags],8
  3080.         jz      coff_relocation
  3081.         cmp     [value_type],4
  3082.         je      coff_relocation
  3083.         mov     al,11                   ; R_AMD64_32S
  3084.         jmp     coff_relocation
  3085.       elf_gotoff_relocation:
  3086.         test    [format_flags],8
  3087.         jnz     invalid_use_of_symbol
  3088.         mov     al,9                    ; R_386_GOTOFF
  3089.         jmp     coff_relocation
  3090.       elf_relocation_relative:
  3091.         cmp     byte [ebx+9],0
  3092.         je      invalid_use_of_symbol
  3093.         mov     ebx,[current_section]
  3094.         mov     ebx,[ebx+8]
  3095.         sub     ebx,edi
  3096.         sub     eax,ebx
  3097.         push    eax
  3098.         mov     al,2                    ; R_386_PC32 / R_AMD64_PC32
  3099.         cmp     [value_type],3
  3100.         je      coff_relocation
  3101.         mov     al,4                    ; R_386_PLT32 / R_AMD64_PLT32
  3102.         jmp     coff_relocation
  3103. close_elf:
  3104.         bt      [format_flags],0
  3105.         jc      close_elf_exe
  3106.         call    close_coff_section
  3107.         cmp     [next_pass_needed],0
  3108.         je      elf_closed
  3109.         mov     eax,[symbols_stream]
  3110.         mov     [free_additional_memory],eax
  3111.       elf_closed:
  3112.         ret
  3113. elf_formatter:
  3114.         mov     ecx,edi
  3115.         sub     ecx,[code_start]
  3116.         neg     ecx
  3117.         and     ecx,111b
  3118.         test    [format_flags],8
  3119.         jnz     align_elf_structures
  3120.         and     ecx,11b
  3121.       align_elf_structures:
  3122.         xor     al,al
  3123.         rep     stos byte [edi]
  3124.         push    edi
  3125.         call    prepare_default_section
  3126.         mov     esi,[symbols_stream]
  3127.         mov     edi,[free_additional_memory]
  3128.         xor     eax,eax
  3129.         mov     ecx,4
  3130.         rep     stos dword [edi]
  3131.         test    [format_flags],8
  3132.         jz      find_first_section
  3133.         mov     ecx,2
  3134.         rep     stos dword [edi]
  3135.       find_first_section:
  3136.         mov     al,[esi]
  3137.         or      al,al
  3138.         jz      first_section_found
  3139.         cmp     al,0C0h
  3140.         jb      skip_other_symbol
  3141.         add     esi,4
  3142.       skip_other_symbol:
  3143.         add     esi,0Ch
  3144.         jmp     find_first_section
  3145.       first_section_found:
  3146.         mov     ebx,esi
  3147.         mov     ebp,esi
  3148.         add     esi,20h
  3149.         xor     ecx,ecx
  3150.         xor     edx,edx
  3151.       find_next_section:
  3152.         cmp     esi,[free_additional_memory]
  3153.         je      make_section_symbol
  3154.         mov     al,[esi]
  3155.         or      al,al
  3156.         jz      make_section_symbol
  3157.         cmp     al,0C0h
  3158.         jae     skip_public
  3159.         cmp     al,80h
  3160.         jae     skip_extrn
  3161.         or      byte [ebx+14h],40h
  3162.       skip_extrn:
  3163.         add     esi,0Ch
  3164.         jmp     find_next_section
  3165.       skip_public:
  3166.         add     esi,10h
  3167.         jmp     find_next_section
  3168.       make_section_symbol:
  3169.         mov     eax,edi
  3170.         xchg    eax,[ebx+4]
  3171.         stos    dword [edi]
  3172.         test    [format_flags],8
  3173.         jnz     elf64_section_symbol
  3174.         xor     eax,eax
  3175.         stos    dword [edi]
  3176.         stos    dword [edi]
  3177.         call    store_section_index
  3178.         jmp     section_symbol_ok
  3179.       store_section_index:
  3180.         inc     ecx
  3181.         mov     eax,ecx
  3182.         shl     eax,8
  3183.         mov     [ebx],eax
  3184.         inc     dx
  3185.         jz      format_limitations_exceeded
  3186.         mov     eax,edx
  3187.         shl     eax,16
  3188.         mov     al,3
  3189.         test    byte [ebx+14h],40h
  3190.         jz      section_index_ok
  3191.         or      ah,-1
  3192.         inc     dx
  3193.         jz      format_limitations_exceeded
  3194.       section_index_ok:
  3195.         stos    dword [edi]
  3196.         ret
  3197.       elf64_section_symbol:
  3198.         call    store_section_index
  3199.         xor     eax,eax
  3200.         stos    dword [edi]
  3201.         stos    dword [edi]
  3202.         stos    dword [edi]
  3203.         stos    dword [edi]
  3204.       section_symbol_ok:
  3205.         mov     ebx,esi
  3206.         add     esi,20h
  3207.         cmp     ebx,[free_additional_memory]
  3208.         jne     find_next_section
  3209.         inc     dx
  3210.         jz      format_limitations_exceeded
  3211.         mov     [current_section],edx
  3212.         mov     esi,[symbols_stream]
  3213.       find_other_symbols:
  3214.         cmp     esi,[free_additional_memory]
  3215.         je      elf_symbol_table_ok
  3216.         mov     al,[esi]
  3217.         or      al,al
  3218.         jz      skip_section
  3219.         cmp     al,0C0h
  3220.         jae     make_public_symbol
  3221.         cmp     al,80h
  3222.         jae     make_extrn_symbol
  3223.         add     esi,0Ch
  3224.         jmp     find_other_symbols
  3225.       skip_section:
  3226.         add     esi,20h
  3227.         jmp     find_other_symbols
  3228.       make_public_symbol:
  3229.         mov     eax,[esi+0Ch]
  3230.         mov     [current_line],eax
  3231.         cmp     byte [esi],0C0h
  3232.         jne     invalid_argument
  3233.         mov     ebx,[esi+8]
  3234.         test    byte [ebx+8],1
  3235.         jz      undefined_public
  3236.         mov     ax,[current_pass]
  3237.         cmp     ax,[ebx+16]
  3238.         jne     undefined_public
  3239.         mov     dl,[ebx+11]
  3240.         or      dl,dl
  3241.         jz      public_absolute
  3242.         mov     eax,[ebx+20]
  3243.         cmp     byte [eax],0
  3244.         jne     invalid_use_of_symbol
  3245.         mov     eax,[eax+4]
  3246.         test    [format_flags],8
  3247.         jnz     elf64_public
  3248.         cmp     dl,2
  3249.         jne     invalid_use_of_symbol
  3250.         mov     dx,[eax+0Eh]
  3251.         jmp     section_for_public_ok
  3252.       undefined_public:
  3253.         mov     [error_info],ebx
  3254.         jmp     undefined_symbol
  3255.       elf64_public:
  3256.         cmp     dl,4
  3257.         jne     invalid_use_of_symbol
  3258.         mov     dx,[eax+6]
  3259.         jmp     section_for_public_ok
  3260.       public_absolute:
  3261.         mov     dx,0FFF1h
  3262.       section_for_public_ok:
  3263.         mov     eax,[esi+4]
  3264.         stos    dword [edi]
  3265.         test    [format_flags],8
  3266.         jnz     elf64_public_symbol
  3267.         movzx   eax,byte [ebx+9]
  3268.         shr     al,1
  3269.         and     al,1
  3270.         neg     eax
  3271.         cmp     eax,[ebx+4]
  3272.         jne     value_out_of_range
  3273.         xor     eax,[ebx]
  3274.         js      value_out_of_range
  3275.         mov     eax,[ebx]
  3276.         stos    dword [edi]
  3277.         xor     eax,eax
  3278.         mov     al,[ebx+10]
  3279.         stos    dword [edi]
  3280.         mov     eax,edx
  3281.         shl     eax,16
  3282.         mov     al,10h
  3283.         cmp     byte [ebx+10],0
  3284.         je      elf_public_function
  3285.         or      al,1
  3286.         jmp     store_elf_public_info
  3287.       elf_public_function:
  3288.         or      al,2
  3289.       store_elf_public_info:
  3290.         stos    dword [edi]
  3291.         jmp     public_symbol_ok
  3292.       elf64_public_symbol:
  3293.         mov     eax,edx
  3294.         shl     eax,16
  3295.         mov     al,10h
  3296.         cmp     byte [ebx+10],0
  3297.         je      elf64_public_function
  3298.         or      al,1
  3299.         jmp     store_elf64_public_info
  3300.       elf64_public_function:
  3301.         or      al,2
  3302.       store_elf64_public_info:
  3303.         stos    dword [edi]
  3304.         mov     al,[ebx+9]
  3305.         shl     eax,31-1
  3306.         xor     eax,[ebx+4]
  3307.         js      value_out_of_range
  3308.         mov     eax,[ebx]
  3309.         stos    dword [edi]
  3310.         mov     eax,[ebx+4]
  3311.         stos    dword [edi]
  3312.         mov     al,[ebx+10]
  3313.         stos    dword [edi]
  3314.         xor     al,al
  3315.         stos    dword [edi]
  3316.       public_symbol_ok:
  3317.         inc     ecx
  3318.         mov     eax,ecx
  3319.         shl     eax,8
  3320.         mov     al,0C0h
  3321.         mov     [esi],eax
  3322.         add     esi,10h
  3323.         jmp     find_other_symbols
  3324.       make_extrn_symbol:
  3325.         mov     eax,[esi+4]
  3326.         stos    dword [edi]
  3327.         test    [format_flags],8
  3328.         jnz     elf64_extrn_symbol
  3329.         xor     eax,eax
  3330.         stos    dword [edi]
  3331.         mov     eax,[esi+8]
  3332.         stos    dword [edi]
  3333.         mov     eax,10h
  3334.         stos    dword [edi]
  3335.         jmp     extrn_symbol_ok
  3336.       elf64_extrn_symbol:
  3337.         mov     eax,10h
  3338.         stos    dword [edi]
  3339.         xor     al,al
  3340.         stos    dword [edi]
  3341.         stos    dword [edi]
  3342.         mov     eax,[esi+8]
  3343.         stos    dword [edi]
  3344.         xor     eax,eax
  3345.         stos    dword [edi]
  3346.       extrn_symbol_ok:
  3347.         inc     ecx
  3348.         mov     eax,ecx
  3349.         shl     eax,8
  3350.         mov     al,80h
  3351.         mov     [esi],eax
  3352.         add     esi,0Ch
  3353.         jmp     find_other_symbols
  3354.       elf_symbol_table_ok:
  3355.         mov     edx,edi
  3356.         mov     ebx,[free_additional_memory]
  3357.         xor     al,al
  3358.         stos    byte [edi]
  3359.         add     edi,16
  3360.         mov     [edx+1],edx
  3361.         add     ebx,10h
  3362.         test    [format_flags],8
  3363.         jz      make_string_table
  3364.         add     ebx,8
  3365.       make_string_table:
  3366.         cmp     ebx,edx
  3367.         je      elf_string_table_ok
  3368.         test    [format_flags],8
  3369.         jnz     make_elf64_string
  3370.         cmp     byte [ebx+0Dh],0
  3371.         je      rel_prefix_ok
  3372.         mov     byte [ebx+0Dh],0
  3373.         mov     eax,'.rel'
  3374.         stos    dword [edi]
  3375.       rel_prefix_ok:
  3376.         mov     esi,edi
  3377.         sub     esi,edx
  3378.         xchg    esi,[ebx]
  3379.         add     ebx,10h
  3380.       make_elf_string:
  3381.         or      esi,esi
  3382.         jz      default_string
  3383.         lods    dword [esi]
  3384.         mov     ecx,eax
  3385.         rep     movs byte [edi],[esi]
  3386.         xor     al,al
  3387.         stos    byte [edi]
  3388.         jmp     make_string_table
  3389.       make_elf64_string:
  3390.         cmp     byte [ebx+5],0
  3391.         je      elf64_rel_prefix_ok
  3392.         mov     byte [ebx+5],0
  3393.         mov     eax,'.rel'
  3394.         stos    dword [edi]
  3395.         mov     al,'a'
  3396.         stos    byte [edi]
  3397.       elf64_rel_prefix_ok:
  3398.         mov     esi,edi
  3399.         sub     esi,edx
  3400.         xchg    esi,[ebx]
  3401.         add     ebx,18h
  3402.         jmp     make_elf_string
  3403.       default_string:
  3404.         mov     eax,'.fla'
  3405.         stos    dword [edi]
  3406.         mov     ax,'t'
  3407.         stos    word [edi]
  3408.         jmp     make_string_table
  3409.       elf_string_table_ok:
  3410.         mov     [edx+1+8],edi
  3411.         mov     ebx,[code_start]
  3412.         mov     eax,edi
  3413.         sub     eax,[free_additional_memory]
  3414.         xor     ecx,ecx
  3415.         sub     ecx,eax
  3416.         test    [format_flags],8
  3417.         jnz     finish_elf64_header
  3418.         and     ecx,11b
  3419.         add     eax,ecx
  3420.         mov     [ebx+20h],eax
  3421.         mov     eax,[current_section]
  3422.         inc     ax
  3423.         jz      format_limitations_exceeded
  3424.         mov     [ebx+32h],ax
  3425.         inc     ax
  3426.         jz      format_limitations_exceeded
  3427.         mov     [ebx+30h],ax
  3428.         jmp     elf_header_finished
  3429.       finish_elf64_header:
  3430.         and     ecx,111b
  3431.         add     eax,ecx
  3432.         mov     [ebx+28h],eax
  3433.         mov     eax,[current_section]
  3434.         inc     ax
  3435.         jz      format_limitations_exceeded
  3436.         mov     [ebx+3Eh],ax
  3437.         inc     ax
  3438.         jz      format_limitations_exceeded
  3439.         mov     [ebx+3Ch],ax
  3440.       elf_header_finished:
  3441.         xor     eax,eax
  3442.         add     ecx,10*4
  3443.         rep     stos byte [edi]
  3444.         test    [format_flags],8
  3445.         jz      elf_null_section_ok
  3446.         mov     ecx,6*4
  3447.         rep     stos byte [edi]
  3448.       elf_null_section_ok:
  3449.         mov     esi,ebp
  3450.         xor     ecx,ecx
  3451.       make_section_entry:
  3452.         mov     ebx,edi
  3453.         mov     eax,[esi+4]
  3454.         mov     eax,[eax]
  3455.         stos    dword [edi]
  3456.         mov     eax,1
  3457.         cmp     dword [esi+0Ch],0
  3458.         je      bss_section
  3459.         test    byte [esi+14h],80h
  3460.         jz      section_type_ok
  3461.       bss_section:
  3462.         mov     al,8
  3463.       section_type_ok:
  3464.         stos    dword [edi]
  3465.         mov     eax,[esi+14h]
  3466.         and     al,3Fh
  3467.         call    store_elf_machine_word
  3468.         xor     eax,eax
  3469.         call    store_elf_machine_word
  3470.         mov     eax,[esi+8]
  3471.         mov     [image_base],eax
  3472.         sub     eax,[code_start]
  3473.         call    store_elf_machine_word
  3474.         mov     eax,[esi+0Ch]
  3475.         call    store_elf_machine_word
  3476.         xor     eax,eax
  3477.         stos    dword [edi]
  3478.         stos    dword [edi]
  3479.         mov     eax,[esi+10h]
  3480.         call    store_elf_machine_word
  3481.         xor     eax,eax
  3482.         call    store_elf_machine_word
  3483.         inc     ecx
  3484.         add     esi,20h
  3485.         xchg    edi,[esp]
  3486.         mov     ebp,edi
  3487.       convert_relocations:
  3488.         cmp     esi,[free_additional_memory]
  3489.         je      relocations_converted
  3490.         mov     al,[esi]
  3491.         or      al,al
  3492.         jz      relocations_converted
  3493.         cmp     al,80h
  3494.         jb      make_relocation_entry
  3495.         cmp     al,0C0h
  3496.         jb      relocation_entry_ok
  3497.         add     esi,10h
  3498.         jmp     convert_relocations
  3499.       make_relocation_entry:
  3500.         test    [format_flags],8
  3501.         jnz     make_elf64_relocation_entry
  3502.         mov     eax,[esi+4]
  3503.         stos    dword [edi]
  3504.         mov     eax,[esi+8]
  3505.         mov     eax,[eax]
  3506.         mov     al,[esi]
  3507.         stos    dword [edi]
  3508.         jmp     relocation_entry_ok
  3509.       make_elf64_relocation_entry:
  3510.         mov     eax,[esi+4]
  3511.         stos    dword [edi]
  3512.         xor     eax,eax
  3513.         stos    dword [edi]
  3514.         movzx   eax,byte [esi]
  3515.         stos    dword [edi]
  3516.         mov     eax,[esi+8]
  3517.         mov     eax,[eax]
  3518.         shr     eax,8
  3519.         stos    dword [edi]
  3520.         xor     eax,eax
  3521.         push    edx
  3522.         mov     edx,[esi+4]
  3523.         add     edx,[image_base]
  3524.         xchg    eax,[edx]
  3525.         stos    dword [edi]
  3526.         cmp     byte [esi],1
  3527.         je      addend_64bit
  3528.         pop     edx
  3529.         sar     eax,31
  3530.         stos    dword [edi]
  3531.         jmp     relocation_entry_ok
  3532.       addend_64bit:
  3533.         xor     eax,eax
  3534.         xchg    eax,[edx+4]
  3535.         stos    dword [edi]
  3536.         pop     edx
  3537.       relocation_entry_ok:
  3538.         add     esi,0Ch
  3539.         jmp     convert_relocations
  3540.       store_elf_machine_word:
  3541.         stos    dword [edi]
  3542.         test    [format_flags],8
  3543.         jz      elf_machine_word_ok
  3544.         and     dword [edi],0
  3545.         add     edi,4
  3546.       elf_machine_word_ok:
  3547.         ret
  3548.       relocations_converted:
  3549.         cmp     edi,ebp
  3550.         xchg    edi,[esp]
  3551.         je      rel_section_ok
  3552.         mov     eax,[ebx]
  3553.         sub     eax,4
  3554.         test    [format_flags],8
  3555.         jz      store_relocations_name_offset
  3556.         dec     eax
  3557.       store_relocations_name_offset:
  3558.         stos    dword [edi]
  3559.         test    [format_flags],8
  3560.         jnz     rela_section
  3561.         mov     eax,9
  3562.         jmp     store_relocations_type
  3563.       rela_section:
  3564.         mov     eax,4
  3565.       store_relocations_type:
  3566.         stos    dword [edi]
  3567.         xor     al,al
  3568.         call    store_elf_machine_word
  3569.         call    store_elf_machine_word
  3570.         mov     eax,ebp
  3571.         sub     eax,[code_start]
  3572.         call    store_elf_machine_word
  3573.         mov     eax,[esp]
  3574.         sub     eax,ebp
  3575.         call    store_elf_machine_word
  3576.         mov     eax,[current_section]
  3577.         stos    dword [edi]
  3578.         mov     eax,ecx
  3579.         stos    dword [edi]
  3580.         inc     ecx
  3581.         test    [format_flags],8
  3582.         jnz     finish_elf64_rela_section
  3583.         mov     eax,4
  3584.         stos    dword [edi]
  3585.         mov     al,8
  3586.         stos    dword [edi]
  3587.         jmp     rel_section_ok
  3588.       finish_elf64_rela_section:
  3589.         mov     eax,8
  3590.         stos    dword [edi]
  3591.         xor     al,al
  3592.         stos    dword [edi]
  3593.         mov     al,24
  3594.         stos    dword [edi]
  3595.         xor     al,al
  3596.         stos    dword [edi]
  3597.       rel_section_ok:
  3598.         cmp     esi,[free_additional_memory]
  3599.         jne     make_section_entry
  3600.         pop     eax
  3601.         mov     ebx,[code_start]
  3602.         sub     eax,ebx
  3603.         mov     [code_size],eax
  3604.         mov     ecx,20h
  3605.         test    [format_flags],8
  3606.         jz      adjust_elf_section_headers_offset
  3607.         mov     ecx,28h
  3608.       adjust_elf_section_headers_offset:
  3609.         add     [ebx+ecx],eax
  3610.         mov     eax,1
  3611.         stos    dword [edi]
  3612.         mov     al,2
  3613.         stos    dword [edi]
  3614.         xor     al,al
  3615.         call    store_elf_machine_word
  3616.         call    store_elf_machine_word
  3617.         mov     eax,[code_size]
  3618.         call    store_elf_machine_word
  3619.         mov     eax,[edx+1]
  3620.         sub     eax,[free_additional_memory]
  3621.         call    store_elf_machine_word
  3622.         mov     eax,[current_section]
  3623.         inc     eax
  3624.         stos    dword [edi]
  3625.         mov     eax,[number_of_sections]
  3626.         inc     eax
  3627.         stos    dword [edi]
  3628.         test    [format_flags],8
  3629.         jnz     finish_elf64_sym_section
  3630.         mov     eax,4
  3631.         stos    dword [edi]
  3632.         mov     al,10h
  3633.         stos    dword [edi]
  3634.         jmp     sym_section_ok
  3635.       finish_elf64_sym_section:
  3636.         mov     eax,8
  3637.         stos    dword [edi]
  3638.         xor     al,al
  3639.         stos    dword [edi]
  3640.         mov     al,18h
  3641.         stos    dword [edi]
  3642.         xor     al,al
  3643.         stos    dword [edi]
  3644.       sym_section_ok:
  3645.         mov     al,1+8
  3646.         stos    dword [edi]
  3647.         mov     al,3
  3648.         stos    dword [edi]
  3649.         xor     al,al
  3650.         call    store_elf_machine_word
  3651.         call    store_elf_machine_word
  3652.         mov     eax,[edx+1]
  3653.         sub     eax,[free_additional_memory]
  3654.         add     eax,[code_size]
  3655.         call    store_elf_machine_word
  3656.         mov     eax,[edx+1+8]
  3657.         sub     eax,[edx+1]
  3658.         call    store_elf_machine_word
  3659.         xor     eax,eax
  3660.         stos    dword [edi]
  3661.         stos    dword [edi]
  3662.         mov     al,1
  3663.         call    store_elf_machine_word
  3664.         xor     eax,eax
  3665.         call    store_elf_machine_word
  3666.         mov     eax,'tab'
  3667.         mov     dword [edx+1],'.sym'
  3668.         mov     [edx+1+4],eax
  3669.         mov     dword [edx+1+8],'.str'
  3670.         mov     [edx+1+8+4],eax
  3671.         mov     [resource_data],edx
  3672.         mov     [written_size],0
  3673.         mov     edx,[output_file]
  3674.         call    create
  3675.         jc      write_failed
  3676.         call    write_code
  3677.         mov     ecx,edi
  3678.         mov     edx,[free_additional_memory]
  3679.         sub     ecx,edx
  3680.         add     [written_size],ecx
  3681.         call    write
  3682.         jc      write_failed
  3683.         jmp     output_written
  3684.  
  3685. format_elf_exe:
  3686.         add     esi,2
  3687.         or      [format_flags],1
  3688.         cmp     byte [esi],'('
  3689.         jne     elf_exe_brand_ok
  3690.         inc     esi
  3691.         cmp     byte [esi],'.'
  3692.         je      invalid_value
  3693.         push    edx
  3694.         call    get_byte_value
  3695.         cmp     [value_type],0
  3696.         jne     invalid_use_of_symbol
  3697.         pop     edx
  3698.         mov     [edx+7],al
  3699.       elf_exe_brand_ok:
  3700.         mov     [image_base],8048000h
  3701.         cmp     byte [esi],80h
  3702.         jne     elf_exe_base_ok
  3703.         lods    word [esi]
  3704.         cmp     ah,'('
  3705.         jne     invalid_argument
  3706.         cmp     byte [esi],'.'
  3707.         je      invalid_value
  3708.         push    edx
  3709.         call    get_dword_value
  3710.         cmp     [value_type],0
  3711.         jne     invalid_use_of_symbol
  3712.         mov     [image_base],eax
  3713.         pop     edx
  3714.       elf_exe_base_ok:
  3715.         mov     byte [edx+2Ah],20h
  3716.         mov     ebx,edi
  3717.         mov     ecx,20h shr 2
  3718.         cmp     [current_pass],0
  3719.         je      init_elf_segments
  3720.         imul    ecx,[number_of_sections]
  3721.       init_elf_segments:
  3722.         xor     eax,eax
  3723.         rep     stos dword [edi]
  3724.         and     [number_of_sections],0
  3725.         mov     byte [ebx],1
  3726.         mov     word [ebx+1Ch],1000h
  3727.         mov     byte [ebx+18h],111b
  3728.         mov     ebp,[image_base]
  3729.         and     dword [ebx+4],0
  3730.         mov     [ebx+8],ebp
  3731.         mov     [ebx+0Ch],ebp
  3732.         mov     eax,edi
  3733.         sub     eax,[code_start]
  3734.         add     eax,ebp
  3735.         mov     [edx+18h],eax
  3736.         and     [image_base_high],0
  3737.       elf_exe_addressing_setup:
  3738.         call    init_addressing_space
  3739.         call    setup_elf_exe_labels_type
  3740.         mov     eax,[code_start]
  3741.         xor     edx,edx
  3742.         xor     cl,cl
  3743.         sub     eax,[image_base]
  3744.         sbb     edx,[image_base_high]
  3745.         sbb     cl,0
  3746.         mov     [ebx],eax
  3747.         mov     [ebx+4],edx
  3748.         mov     [ebx+8],cl
  3749.         mov     [symbols_stream],edi
  3750.         jmp     format_defined
  3751.       format_elf64_exe:
  3752.         add     esi,2
  3753.         or      [format_flags],1
  3754.         cmp     byte [esi],'('
  3755.         jne     elf64_exe_brand_ok
  3756.         inc     esi
  3757.         cmp     byte [esi],'.'
  3758.         je      invalid_value
  3759.         push    edx
  3760.         call    get_byte_value
  3761.         cmp     [value_type],0
  3762.         jne     invalid_use_of_symbol
  3763.         pop     edx
  3764.         mov     [edx+7],al
  3765.       elf64_exe_brand_ok:
  3766.         mov     [image_base],400000h
  3767.         and     [image_base_high],0
  3768.         cmp     byte [esi],80h
  3769.         jne     elf64_exe_base_ok
  3770.         lods    word [esi]
  3771.         cmp     ah,'('
  3772.         jne     invalid_argument
  3773.         cmp     byte [esi],'.'
  3774.         je      invalid_value
  3775.         push    edx
  3776.         call    get_qword_value
  3777.         cmp     [value_type],0
  3778.         jne     invalid_use_of_symbol
  3779.         mov     [image_base],eax
  3780.         mov     [image_base_high],edx
  3781.         pop     edx
  3782.       elf64_exe_base_ok:
  3783.         mov     byte [edx+36h],38h
  3784.         mov     ebx,edi
  3785.         mov     ecx,38h shr 2
  3786.         cmp     [current_pass],0
  3787.         je      init_elf64_segments
  3788.         imul    ecx,[number_of_sections]
  3789.       init_elf64_segments:
  3790.         xor     eax,eax
  3791.         rep     stos dword [edi]
  3792.         and     [number_of_sections],0
  3793.         mov     byte [ebx],1
  3794.         mov     word [ebx+30h],1000h
  3795.         mov     byte [ebx+4],111b
  3796.         mov     ebp,[image_base]
  3797.         mov     ecx,[image_base_high]
  3798.         and     dword [ebx+8],0
  3799.         mov     [ebx+10h],ebp
  3800.         mov     [ebx+10h+4],ecx
  3801.         mov     [ebx+18h],ebp
  3802.         mov     [ebx+18h+4],ecx
  3803.         mov     eax,edi
  3804.         sub     eax,[code_start]
  3805.         add     eax,ebp
  3806.         adc     ecx,0
  3807.         mov     [edx+18h],eax
  3808.         mov     [edx+18h+4],ecx
  3809.         jmp     elf_exe_addressing_setup
  3810.       setup_elf_exe_labels_type:
  3811.         mov     eax,[code_start]
  3812.         cmp     byte [eax+10h],3
  3813.         jne     elf_exe_labels_type_ok
  3814.         mov     byte [ebx+9],2
  3815.         test    [format_flags],8
  3816.         jz      elf_exe_labels_type_ok
  3817.         mov     byte [ebx+9],4
  3818.       elf_exe_labels_type_ok:
  3819.         ret
  3820. elf_entry:
  3821.         lods    byte [esi]
  3822.         cmp     al,'('
  3823.         jne     invalid_argument
  3824.         cmp     byte [esi],'.'
  3825.         je      invalid_value
  3826.         test    [format_flags],8
  3827.         jnz     elf64_entry
  3828.         call    get_dword_value
  3829.         mov     edx,[code_start]
  3830.         mov     [edx+18h],eax
  3831.         jmp     instruction_assembled
  3832.       elf64_entry:
  3833.         call    get_qword_value
  3834.         mov     ebx,[code_start]
  3835.         mov     [ebx+18h],eax
  3836.         mov     [ebx+1Ch],edx
  3837.         jmp     instruction_assembled
  3838. elf_segment:
  3839.         bt      [format_flags],0
  3840.         jnc     illegal_instruction
  3841.         test    [format_flags],8
  3842.         jnz     elf64_segment
  3843.         call    close_elf_segment
  3844.         push    eax
  3845.         call    create_addressing_space
  3846.         call    setup_elf_exe_labels_type
  3847.         mov     ebp,ebx
  3848.         mov     ebx,[number_of_sections]
  3849.         shl     ebx,5
  3850.         add     ebx,[code_start]
  3851.         add     ebx,34h
  3852.         cmp     ebx,[symbols_stream]
  3853.         jb      new_elf_segment
  3854.         mov     ebx,[symbols_stream]
  3855.         sub     ebx,20h
  3856.         or      [next_pass_needed],-1
  3857.       new_elf_segment:
  3858.         mov     byte [ebx],1
  3859.         and     dword [ebx+18h],0
  3860.         mov     word [ebx+1Ch],1000h
  3861.       elf_segment_flags:
  3862.         cmp     byte [esi],1Eh
  3863.         je      elf_segment_type
  3864.         cmp     byte [esi],19h
  3865.         jne     elf_segment_flags_ok
  3866.         lods    word [esi]
  3867.         sub     ah,28
  3868.         jbe     invalid_argument
  3869.         cmp     ah,1
  3870.         je      mark_elf_segment_flag
  3871.         cmp     ah,3
  3872.         ja      invalid_argument
  3873.         xor     ah,1
  3874.         cmp     ah,2
  3875.         je      mark_elf_segment_flag
  3876.         inc     ah
  3877.       mark_elf_segment_flag:
  3878.         test    [ebx+18h],ah
  3879.         jnz     setting_already_specified
  3880.         or      [ebx+18h],ah
  3881.         jmp     elf_segment_flags
  3882.       elf_segment_type:
  3883.         cmp     byte [ebx],1
  3884.         jne     setting_already_specified
  3885.         lods    word [esi]
  3886.         mov     ecx,[number_of_sections]
  3887.         jecxz   elf_segment_type_ok
  3888.         mov     edx,[code_start]
  3889.         add     edx,34h
  3890.       scan_elf_segment_types:
  3891.         cmp     edx,[symbols_stream]
  3892.         jae     elf_segment_type_ok
  3893.         cmp     [edx],ah
  3894.         je      data_already_defined
  3895.         add     edx,20h
  3896.         loop    scan_elf_segment_types
  3897.       elf_segment_type_ok:
  3898.         mov     [ebx],ah
  3899.         mov     word [ebx+1Ch],1
  3900.         cmp     ah,50h
  3901.         jb      elf_segment_flags
  3902.         or      dword [ebx],6474E500h
  3903.         jmp     elf_segment_flags
  3904.       elf_segment_flags_ok:
  3905.         pop     edx
  3906.         cmp     byte [ebx],1
  3907.         jne     no_elf_segment_merging
  3908.         cmp     [merge_segment],0
  3909.         jne     merge_elf_segment
  3910.       no_elf_segment_merging:
  3911.         mov     eax,edi
  3912.         sub     eax,[code_start]
  3913.         mov     [ebx+4],eax
  3914.         and     eax,0FFFh
  3915.         add     eax,edx
  3916.         mov     [ebx+8],eax
  3917.         mov     [ebx+0Ch],eax
  3918.         xor     edx,edx
  3919.       elf_segment_addressing_setup:
  3920.         xor     cl,cl
  3921.         not     eax
  3922.         not     edx
  3923.         not     cl
  3924.         add     eax,1
  3925.         adc     edx,0
  3926.         adc     cl,0
  3927.         add     eax,edi
  3928.         adc     edx,0
  3929.         adc     cl,0
  3930.         mov     [ds:ebp],eax
  3931.         mov     [ds:ebp+4],edx
  3932.         mov     [ds:ebp+8],cl
  3933.         inc     [number_of_sections]
  3934.         jmp     instruction_assembled
  3935.       merge_elf_segment:
  3936.         xor     ecx,ecx
  3937.         xchg    ecx,[merge_segment]
  3938.         cmp     ecx,-1
  3939.         je      merge_elf_header
  3940.         mov     eax,[ecx+8]
  3941.         mov     ecx,[ecx+4]
  3942.       elf_segment_separated_base:
  3943.         mov     [ebx+8],eax
  3944.         mov     [ebx+0Ch],eax
  3945.         mov     [ebx+4],ecx
  3946.         sub     eax,ecx
  3947.         add     eax,edi
  3948.         sub     eax,[code_start]
  3949.         xor     edx,edx
  3950.         jmp     elf_segment_addressing_setup
  3951.       merge_elf_header:
  3952.         mov     eax,[image_base]
  3953.         xor     ecx,ecx
  3954.         jmp     elf_segment_separated_base
  3955.       close_elf_segment:
  3956.         cmp     [number_of_sections],0
  3957.         jne     finish_elf_segment
  3958.         cmp     edi,[symbols_stream]
  3959.         jne     first_elf_segment_ok
  3960.         or      [merge_segment],-1
  3961.         mov     eax,[image_base]
  3962.         ret
  3963.       first_elf_segment_ok:
  3964.         and     [merge_segment],0
  3965.         inc     [number_of_sections]
  3966.       finish_elf_segment:
  3967.         mov     ebx,[number_of_sections]
  3968.         dec     ebx
  3969.         shl     ebx,5
  3970.         add     ebx,[code_start]
  3971.         add     ebx,34h
  3972.         mov     eax,edi
  3973.         sub     eax,[code_start]
  3974.         sub     eax,[ebx+4]
  3975.         mov     edx,edi
  3976.         cmp     edi,[undefined_data_end]
  3977.         jne     elf_segment_size_ok
  3978.         cmp     byte [ebx],1
  3979.         jne     elf_segment_size_ok
  3980.         mov     edi,[undefined_data_start]
  3981.       elf_segment_size_ok:
  3982.         mov     [ebx+14h],eax
  3983.         add     eax,edi
  3984.         sub     eax,edx
  3985.         mov     [ebx+10h],eax
  3986.         and     [undefined_data_end],0
  3987.         mov     eax,[ebx+8]
  3988.         cmp     byte [ebx],1
  3989.         je      elf_segment_position_move_and_align
  3990.         cmp     [merge_segment],0
  3991.         jne     elf_segment_position_move
  3992.         cmp     byte [ebx],4
  3993.         je      elf_segment_position_ok
  3994.         cmp     byte [ebx],51h
  3995.         je      elf_segment_position_ok
  3996.         mov     [merge_segment],ebx
  3997.       elf_segment_position_move:
  3998.         add     eax,[ebx+14h]
  3999.         jmp     elf_segment_position_ok
  4000.       elf_segment_position_move_and_align:
  4001.         add     eax,[ebx+14h]
  4002.         add     eax,0FFFh
  4003.       elf_segment_position_ok:
  4004.         and     eax,not 0FFFh
  4005.         ret
  4006.       elf64_segment:
  4007.         call    close_elf64_segment
  4008.         push    eax edx
  4009.         call    create_addressing_space
  4010.         call    setup_elf_exe_labels_type
  4011.         mov     ebp,ebx
  4012.         mov     ebx,[number_of_sections]
  4013.         imul    ebx,38h
  4014.         add     ebx,[code_start]
  4015.         add     ebx,40h
  4016.         cmp     ebx,[symbols_stream]
  4017.         jb      new_elf64_segment
  4018.         or      [next_pass_needed],-1
  4019.       new_elf64_segment:
  4020.         mov     byte [ebx],1
  4021.         and     dword [ebx+4],0
  4022.         mov     word [ebx+30h],1000h
  4023.       elf64_segment_flags:
  4024.         cmp     byte [esi],1Eh
  4025.         je      elf64_segment_type
  4026.         cmp     byte [esi],19h
  4027.         jne     elf64_segment_flags_ok
  4028.         lods    word [esi]
  4029.         sub     ah,28
  4030.         jbe     invalid_argument
  4031.         cmp     ah,1
  4032.         je      mark_elf64_segment_flag
  4033.         cmp     ah,3
  4034.         ja      invalid_argument
  4035.         xor     ah,1
  4036.         cmp     ah,2
  4037.         je      mark_elf64_segment_flag
  4038.         inc     ah
  4039.       mark_elf64_segment_flag:
  4040.         test    [ebx+4],ah
  4041.         jnz     setting_already_specified
  4042.         or      [ebx+4],ah
  4043.         jmp     elf64_segment_flags
  4044.       elf64_segment_type:
  4045.         cmp     byte [ebx],1
  4046.         jne     setting_already_specified
  4047.         lods    word [esi]
  4048.         mov     ecx,[number_of_sections]
  4049.         jecxz   elf64_segment_type_ok
  4050.         mov     edx,[code_start]
  4051.         add     edx,40h
  4052.       scan_elf64_segment_types:
  4053.         cmp     edx,[symbols_stream]
  4054.         jae     elf64_segment_type_ok
  4055.         cmp     [edx],ah
  4056.         je      data_already_defined
  4057.         add     edx,38h
  4058.         loop    scan_elf64_segment_types
  4059.       elf64_segment_type_ok:
  4060.         mov     [ebx],ah
  4061.         mov     word [ebx+30h],1
  4062.         cmp     ah,50h
  4063.         jb      elf64_segment_flags
  4064.         or      dword [ebx],6474E500h
  4065.         jmp     elf64_segment_flags
  4066.       elf64_segment_flags_ok:
  4067.         pop     edx eax
  4068.         cmp     byte [ebx],1
  4069.         jne     no_elf64_segment_merging
  4070.         cmp     [merge_segment],0
  4071.         jne     merge_elf64_segment
  4072.       no_elf64_segment_merging:
  4073.         mov     ecx,edi
  4074.         sub     ecx,[code_start]
  4075.         mov     [ebx+8],ecx
  4076.         and     ecx,0FFFh
  4077.         add     eax,ecx
  4078.         adc     edx,0
  4079.         mov     [ebx+10h],eax
  4080.         mov     [ebx+10h+4],edx
  4081.         mov     [ebx+18h],eax
  4082.         mov     [ebx+18h+4],edx
  4083.         jmp     elf_segment_addressing_setup
  4084.       merge_elf64_segment:
  4085.         xor     ecx,ecx
  4086.         xchg    ecx,[merge_segment]
  4087.         cmp     ecx,-1
  4088.         je      merge_elf64_header
  4089.         mov     eax,[ecx+10h]
  4090.         mov     edx,[ecx+10h+4]
  4091.         mov     ecx,[ecx+8]
  4092.       elf64_segment_separated_base:
  4093.         mov     [ebx+10h],eax
  4094.         mov     [ebx+10h+4],edx
  4095.         mov     [ebx+18h],eax
  4096.         mov     [ebx+18h+4],edx
  4097.         mov     [ebx+8],ecx
  4098.         neg     ecx
  4099.         add     ecx,edi
  4100.         sub     ecx,[code_start]
  4101.         add     eax,ecx
  4102.         adc     edx,0
  4103.         jmp     elf_segment_addressing_setup
  4104.       merge_elf64_header:
  4105.         mov     eax,[image_base]
  4106.         mov     edx,[image_base_high]
  4107.         xor     ecx,ecx
  4108.         jmp     elf64_segment_separated_base
  4109.       close_elf64_segment:
  4110.         cmp     [number_of_sections],0
  4111.         jne     finish_elf64_segment
  4112.         cmp     edi,[symbols_stream]
  4113.         jne     first_elf64_segment_ok
  4114.         or      [merge_segment],-1
  4115.         mov     eax,[image_base]
  4116.         mov     edx,[image_base_high]
  4117.         ret
  4118.       first_elf64_segment_ok:
  4119.         and     [merge_segment],0
  4120.         inc     [number_of_sections]
  4121.       finish_elf64_segment:
  4122.         mov     ebx,[number_of_sections]
  4123.         dec     ebx
  4124.         imul    ebx,38h
  4125.         add     ebx,[code_start]
  4126.         add     ebx,40h
  4127.         mov     eax,edi
  4128.         sub     eax,[code_start]
  4129.         sub     eax,[ebx+8]
  4130.         mov     edx,edi
  4131.         cmp     edi,[undefined_data_end]
  4132.         jne     elf64_segment_size_ok
  4133.         cmp     byte [ebx],1
  4134.         jne     elf64_segment_size_ok
  4135.         mov     edi,[undefined_data_start]
  4136.       elf64_segment_size_ok:
  4137.         mov     [ebx+28h],eax
  4138.         add     eax,edi
  4139.         sub     eax,edx
  4140.         mov     [ebx+20h],eax
  4141.         and     [undefined_data_end],0
  4142.         mov     eax,[ebx+10h]
  4143.         mov     edx,[ebx+10h+4]
  4144.         cmp     byte [ebx],1
  4145.         je      elf64_segment_position_move_and_align
  4146.         cmp     [merge_segment],0
  4147.         jne     elf64_segment_position_move
  4148.         cmp     byte [ebx],4
  4149.         je      elf64_segment_position_ok
  4150.         cmp     byte [ebx],51h
  4151.         je      elf64_segment_position_ok
  4152.         mov     [merge_segment],ebx
  4153.       elf64_segment_position_move:
  4154.         add     eax,[ebx+28h]
  4155.         adc     edx,0
  4156.         jmp     elf64_segment_position_ok
  4157.       elf64_segment_position_move_and_align:
  4158.         add     eax,[ebx+28h]
  4159.         adc     edx,0
  4160.         add     eax,0FFFh
  4161.         adc     edx,0
  4162.       elf64_segment_position_ok:
  4163.         and     eax,not 0FFFh
  4164.         ret
  4165. close_elf_exe:
  4166.         test    [format_flags],8
  4167.         jnz     close_elf64_exe
  4168.         call    close_elf_segment
  4169.         mov     edx,[code_start]
  4170.         mov     eax,[number_of_sections]
  4171.         mov     byte [edx+1Ch],34h
  4172.         mov     [edx+2Ch],ax
  4173.         shl     eax,5
  4174.         add     eax,edx
  4175.         add     eax,34h
  4176.         cmp     eax,[symbols_stream]
  4177.         je      elf_exe_ok
  4178.         or      [next_pass_needed],-1
  4179.       elf_exe_ok:
  4180.         ret
  4181.       close_elf64_exe:
  4182.         call    close_elf64_segment
  4183.         mov     edx,[code_start]
  4184.         mov     eax,[number_of_sections]
  4185.         mov     byte [edx+20h],40h
  4186.         mov     [edx+38h],ax
  4187.         imul    eax,38h
  4188.         add     eax,edx
  4189.         add     eax,40h
  4190.         cmp     eax,[symbols_stream]
  4191.         je      elf64_exe_ok
  4192.         or      [next_pass_needed],-1
  4193.       elf64_exe_ok:
  4194.         ret
  4195.