Subversion Repositories Kolibri OS

Rev

Rev 4478 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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