Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6446 GerdtR 1
#include "tok.h"
2
 
3
4
 
5
 
6
 
7
 Создание PE формата
8
 
9
 
10
 
11
12
 
13
             0x04,0x00,0x0F,0x00,0xFF,0xFF,0x00,0x00,
14
 
15
             0x40,0x00,0x1A,0x00,0x00,0x00,0x00,0x00,
16
 
17
						 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18
 
19
             0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
20
 
21
 
22
 
23
             0x21,0xB8,0x01,0x4C,0xCD,0x21,0x46,0x6F,
24
 
25
						 0x6F,0x6E,0x6C,0x79,0x21,0x0D,0x0A,0x24};
26
 
27
#define SIZESTUB2 12
28
 
29
              0x20,0x43,0x2D,0x2D};
30
 
31
 
32
 
33
int numexport=0;
34
 
35
unsigned long vsizeheader=0x1000; //виртуальный размер заголовка.
36
 
37
int filingzerope;
38
 
39
struct listexport *lexport=NULL;
40
 
41
 
42
 
43
unsigned long  Align(unsigned long size,unsigned long val)
44
 
45
	if(val<2)return size;
46
 
47
	return (size+val)&(~val);
48
 
49
50
 
51
 
52
 
53
void PrintMem(void *mem)
54
 
55
unsigned char *m,*n;
56
 
57
	m=(unsigned char *)mem;
58
 
59
		n=m;
60
 
61
			printf("%02X ",*m);
62
 
63
		}
64
 
65
			char c=*n;
66
 
67
			if(c<0x20||c>0x7e)c='.';
68
 
69
		}
70
 
71
	}
72
 
73
74
 
75
 
76
 
77
DLLLIST *newdll=listdll;	//начало списка DLL
78
 
79
idrec *rec=listapi->recapi;
80
 
81
	}
82
 
83
 
84
 
85
{
86
 
87
//скорректировать адреса из таблицы перемещений
88
 
89
	if(listdll!=NULL){	//есть api-проц
90
 
91
		numdll=numapi=0;
92
 
93
			unsigned short numapiprocdll=0;	//число используемых в библиотеке процедур
94
 
95
				idrec *rec=(listapi+i)->recapi;
96
 
97
 
98
 
99
					if((postbuf+j)->num==idnum){
100
 
101
							useapi=API_JMP;	//флаг взведем
102
 
103
 
104
 
105
						else if((postbuf+j)->type==CALL_32I){
106
 
107
							numrel++;
108
 
109
					}
110
 
111
				if(useapi==API_JMP){	// процедура вызывалась
112
 
113
					outptr+=2;
114
 
115
					AddReloc(CS);	//добавить ее в табл перемещений
116
 
117
					outptr+=4;
118
 
119
					numapiprocdll++;	//число использованых процедур в этой DLL
120
 
121
				else if(useapi==API_FAST){
122
 
123
					numapiprocdll++;	//число использованых процедур в этой DLL
124
 
125
				rec->recrm=useapi;	//тип вызова api; 0 - not used
126
 
127
					free(rec->newid);	//список параметров больше не нужен
128
 
129
				}
130
 
131
			newdll->num=numapiprocdll;	//исправить число реально использ процедур
132
 
133
				free(newdll->list);	//удалить список процедур.
134
 
135
			else numdll++;
136
 
137
			newdll=newdll->next;
138
 
139
		}
140
 
141
	outptrdata=outptr;
142
 
143
144
 
145
 
146
 
147
char *importblock=NULL;
148
 
149
char *exportblock=NULL;
150
 
151
              sizebss=0,sizeRes=0;
152
 
153
unsigned int posrel=0,sizeimport=0,startimportname=0,sizeexport=0,sizeres=0,
154
 
155
unsigned int sizehead;	//размер заголовка
156
 
157
unsigned int relocnum=0;	//номер секции перемещений
158
 
159
unsigned int codenum=0;	//номер секции кода
160
 
161
	if(hout==NULL)return -1;
162
 
163
		vsize=Align(outptr+(wbss==FALSE?postsize:0),OBJECTALIGN);//виртуальный размер секции кода
164
 
165
 
166
 
167
//	sizehead=((postsize&&wbss)?2:1)*sizeof(OBJECT_ENTRY);
168
 
169
	OBJECT_ENTRY *objentry=(OBJECT_ENTRY *)MALLOC(sizehead);//тавлица объектов
170
 
171
//секция .bss
172
 
173
		numobj++;     //увеличиваем число объектов
174
 
175
		strcpy(objentry->name,".bss"); //имя секции
176
 
177
		objentry->pOffset=objentry->psize=0;
178
 
179
		objentry->sectionRVA=vsizeheader;
180
 
181
	strcpy((objentry+codenum)->name,"CODE");	//ее имя
182
 
183
	(objentry+codenum)->psize=psize;          //размер секции в файле
184
 
185
	(objentry+codenum)->sectionRVA=vsizeheader+sizebss;//виртуальный адрес секции в памяти
186
 
187
	if(numapi!=0){	//есть вызовы api-процедур созд секцию импорта
188
 
189
			importnum=numobj;
190
 
191
		}
192
 
193
			//реальный размер секции
194
 
195
		sizeimport=Align(startimportname,FILEALIGN);	//размер секции в памяти
196
 
197
		memset(importblock,0,sizeimport);	//очистить ее
198
 
199
		unsigned long sn,sn1;
200
 
201
		for(int i=0;;i++){
202
 
203
			if(newdll==NULL)break;	//завершить цикл если список dll пуст
204
 
205
			*(long *)&importblock[i*20+12]=startsec+startimportname;
206
 
207
			*(long *)&importblock[i*20+16]=startsec+sn+(shortimport==0?(numdll+numapi)*4:0);
208
 
209
			unsigned int lenn=strlen(newdll->name)+1;
210
 
211
				sizeimport+=FILEALIGN;	//увеличить размер секции
212
 
213
				memset(importblock+sizeimport-FILEALIGN,0,FILEALIGN);
214
 
215
			strcpy(&importblock[startimportname],newdll->name);
216
 
217
			for(int n=0,t=0;nnum;n++,t++){
218
 
219
				idrec *rec=(listapi+t)->recapi;
220
 
221
				newadr=ImageBase+startsec+sn1+(shortimport==0?(numdll+numapi)*4:0);
222
 
223
				else{
224
 
225
						if((postbuf+j)->num==(unsigned long)rec->recnumber&&(postbuf+j)->type==CALL_32I){
226
 
227
						}
228
 
229
				}
230
 
231
					*(long *)&importblock[sn1]=rec->recsib|0x80000000;
232
 
233
				}
234
 
235
					if((startimportname%2)==1)importblock[startimportname++]=0;
236
 
237
					if(shortimport==0)*(long *)&importblock[sn1+(numdll+numapi)*4]=startsec+startimportname;
238
 
239
					else strcpy((char *)string2,rec->recid);
240
 
241
					if((lenn+startimportname+4)>=sizeimport){
242
 
243
						importblock=(char *)REALLOC(importblock,sizeimport);
244
 
245
					}
246
 
247
					startimportname+=2;
248
 
249
					startimportname+=lenn;
250
 
251
				sn1+=4;
252
 
253
			if(newdll->next==NULL)break;
254
 
255
			sn1+=4;
256
 
257
		importblock[startimportname++]=0;
258
 
259
		if(!WinMonoBlock){	//если не единый блок
260
 
261
			(objentry+importnum)->vsize=sizeImport=Align(sizeimport,OBJECTALIGN);
262
 
263
			(objentry+importnum)->flags=0xC0000040;
264
 
265
		}
266
 
267
	}
268
 
269
	if(numexport!=0){
270
 
271
			exportnum=numobj;
272
 
273
		}
274
 
275
		startexportname=sizeof(EXPORT_TABLE)+numexport*10;//реальный размер секции
276
 
277
		exportblock=(char *)MALLOC(sizeexport);	//память под нее
278
 
279
		*(long *)&exportblock[12]=startsece+startexportname;//адрес имени файла
280
 
281
		*(long *)&exportblock[20]=numexport;	//Num of Functions
282
 
283
		*(long *)&exportblock[28]=startsece+sizeof(EXPORT_TABLE);//Address Table RVA
284
 
285
 
286
 
287
		strcpy((char *)string2,(char *)rawfilename);
288
 
289
		if(oname==NULL)oname=(char *)string2;
290
 
291
		sprintf((char *)string,"%s.%s",oname,outext);
292
 
293
		if((lenn+startexportname+1)>=sizeexport){
294
 
295
			exportblock=(char *)REALLOC(exportblock,sizeexport);
296
 
297
		}
298
 
7626 siemargl 299
		startexportname+=lenn;
6446 GerdtR 300
 
301
			*(long *)&exportblock[sizeof(EXPORT_TABLE)+i*4]=(lexport+i)->address+vsizeheader+sizebss;	//адреса функций
302
 
303
			*(short *)&exportblock[sizeof(EXPORT_TABLE)+numexport*8+i*2]=(short)i;	//ординалы имен
304
 
305
			if((lenn+startexportname+1)>=sizeexport){
306
 
307
				exportblock=(char *)REALLOC(exportblock,sizeexport);
308
 
309
			}
310
 
311
			startexportname+=lenn;
312
 
313
		free(lexport);//освободим уже не нужный блок
314
 
315
			strcpy((objentry+exportnum)->name,".edata"); //имя секции
316
 
317
			(objentry+exportnum)->psize=sizeexport;
318
 
319
			(objentry+exportnum)->sectionRVA=startsece;
320
 
321
		else sizeexport=sizeExport=Align(startexportname,4);
322
 
323
324
 
325
		if(WinMonoBlock==FALSE){	//если не единый блок
326
 
327
			numobj++;                     //увеличить число объектов
328
 
329
		startsecres=vsizeheader+vsize+sizeImport+sizebss+sizeExport;//начало секции в памяти
330
 
331
		if(MakeRes(startsecres,&resrel))free(resrel);
332
 
333
			strcpy((objentry+resnum)->name,".rsrc"); //имя секции
334
 
335
			(objentry+resnum)->psize=sizeres=Align(curposbuf,FILEALIGN);
336
 
337
			(objentry+resnum)->sectionRVA=startsecres;
338
 
339
		else sizeres=Align(curposbuf,4);
340
 
341
342
 
343
	if((FixUpTable==TRUE&&numrel!=0)/*||numexport!=0*/){//создать секцию перемещения
344
 
345
			relocnum=numobj;
346
 
347
		}
348
 
349
			Align(sizeimport+sizeexport+outptr+(wbss==FALSE?postsize:0)+sizebss+sizeres,OBJECTALIGN);
350
 
351
		//физический размер секции таблицы перемещений
352
 
353
		sizeReloc=Align(sizereloc,OBJECTALIGN);//виртуальный размер этой секции
354
 
355
		memset(relocblock,0,sizereloc);	//очистить ее
356
 
357
		unsigned int startrsec=0;	//адрес начала блока в секции перемещения
358
 
359
		posrel=8;
360
 
361
			unsigned char fr=FALSE;	//флаг элемента
362
 
363
				if(
364
 
365
						  (postbuf+i)->type==CALL_32I||
366
 
367
								&&
368
 
369
					*(short *)&relocblock[posrel]=(short)((postbuf+i)->loc%4096|0x3000);
370
 
371
					fr=TRUE;
372
 
373
			}
374
 
375
				posrel+=posrel%4;	//выравниваем
376
 
377
				*(long *)&relocblock[startrsec+4]=posrel-startrsec;	//размер куска
378
 
379
				posrel+=8;
380
 
381
			startblc+=4096;
382
 
383
		posrel-=8;
384
 
385
			strcpy((objentry+relocnum)->name,".reloc");	//имя секции
386
 
387
			(objentry+relocnum)->psize=sizereloc;        //размер секции в файле
388
 
389
			(objentry+relocnum)->sectionRVA=startsecr;   //виртуальный адрес секции в памяти
390
 
391
		else sizereloc=Align(posrel,4);
392
 
393
	if(WinMonoBlock){
394
 
395
		if(wbss==0){
396
 
397
				if((postbuf+i)->type==POST_VAR32)
398
 
399
			}
400
 
401
		psize+=outptr;
402
 
403
		filingzerope=(objentry+codenum)->psize=Align(psize,FILEALIGN);	//физический размер секции кода
404
 
405
		psize=(objentry+codenum)->psize;
406
 
407
		if(dllflag==FALSE)sizeReloc=0;
408
 
409
	PE_HEADER *peheader=(PE_HEADER *)MALLOC(sizeof(PE_HEADER));
410
 
411
	sizehead=Align(sizeof(PE_HEADER)+sizestub+(numobj+(numres!=0?0:1))*sizeof(OBJECT_ENTRY),FILEALIGN);
412
 
413
	peheader->sign='EP';
414
 
415
	peheader->sign='PE';
416
 
417
	peheader->cpu=0x14c;//(chip>=4?(chip>=5?0x14e:0x14D):0x14c);
418
 
419
	peheader->DLLflag=dllflag;
420
 
421
	peheader->NTheadsize=0xe0;
422
 
423
	peheader->Magic=0x10b;
424
 
425
	peheader->sizecode=psize;
426
 
427
	{
428
 
429
		temp=EntryPoint();
430
 
431
		else peheader->EntryRVA=vsizeheader+sizebss+temp;
432
 
433
	peheader->basecode=vsizeheader+sizebss;
434
 
435
	peheader->fileAlig=FILEALIGN;
436
 
437
	peheader->SubSysVer=4;
438
 
439
	peheader->headsize=sizehead;
440
 
441
			                vsize+	//размер кода
442
 
443
											sizeReloc+	//размер таблицы перемещения
444
 
445
											sizeRes+	//размер таблицы ресурсов
446
 
447
	peheader->SubSys=(short)(2+wconsole);	//GUIWIN
448
 
449
	peheader->stackComSize=stacksize;
450
 
451
	peheader->heapComSize=0x1000;//postsize;	//????
452
 
453
	if(!usestub){
454
 
455
		peheader->pCOFF=0x40;
456
 
457
	(objentry+codenum)->pOffset=sizehead;
458
 
459
		if(!WinMonoBlock)(objentry+importnum)->pOffset=sizehead+psize;
460
 
461
		peheader->importSize=startimportname;
462
 
463
	if(numexport){
464
 
465
		peheader->exportRVA=startsece;
466
 
467
	}
468
 
469
		if(!WinMonoBlock)(objentry+resnum)->pOffset=sizehead+psize+sizeimport+sizeexport;
470
 
471
		peheader->resourSize=curposbuf;
472
 
473
	if(posrel){
474
 
475
		else if(dllflag)(objentry+relocnum)->pOffset=sizehead+psize;
476
 
477
		peheader->fixupSize=posrel;
478
 
479
	if(fwrite(peheader,sizeof(PE_HEADER),1,hout)!=1){
480
 
481
		ErrWrite();
482
 
483
		hout=NULL;
484
 
485
	}
486
 
487
	ChSize(sizehead);
488
 
489
	outputcodestart=ftell(hout);
490
 
491
	if(!WinMonoBlock){
492
 
493
		ChSize(runfilesize);
494
 
495
	if(numapi){
496
 
497
		free(importblock);
498
 
499
	if(numexport){
500
 
501
		free(exportblock);
502
 
503
	if(numres){
504
 
505
		free(resbuf);
506
 
507
	if(posrel){
508
 
509
		if(fwrite(relocblock,sizereloc,1,hout)!=1)goto errwrite;
510
 
511
	}
512
 
513
		if(dllflag)runfilesize+=sizereloc;
514
 
515
 
516
 
517
	free(peheader);
518
 
519
	fclose(hout);
520
 
521
	ImageBase+=vsizeheader+sizebss;	//изм размер для листинга
522
 
523
}
524
 
525
void ChSize(long size)
526
 
527
char buf[256];
528
 
529
	memset(buf,0,256);
530
 
531
	while(delta>0){
532
 
533
		if(delta<256)ssave=delta;
534
 
535
		delta-=ssave;
536
 
537
}
538
 
539
int AlignCD(char segm,int val)	//выравнять данные или код
540
 
541
unsigned int a;
542
 
543
	if(a==0)val=0;
544
 
545
	a=0;
546
 
547
		segm==DS?opd(aligner):op(0x90);
548
 
549
		a++;
550
 
551
	return a;
552
 
553
554
 
555
{
556
 
557
		sizestub=SIZESTUB2;
558
 
559
		if(fwrite(stub2,SIZESTUB2,1,hout)!=1){
560
 
561
			return;
562
 
563
	}
564
 
565
//подсчитать число секций
566
 
567
		if(postsize)numrs++;
568
 
569
	}
570
 
571
		if(numapi)numrs++;	//есть вызовы api-процедур
572
 
573
		if((FixUpTable==TRUE&&posts)/*||numexport!=0*/)numrs++;	//создать секцию перемещения
574
 
575
	}
576
 
577
//размер загрузочного образа
578
 
579
}
580
 
581
void ImportName(char *name)
582
 
583
FILE *infile;
584
 
585
	PE_HEADER pe;
586
 
587
};
588
 
589
unsigned long ulexport;	//секция с експортом
590
 
591
unsigned long posdll;	//позиция секции в файле
592
 
593
unsigned long startname;	//начало имени
594
 
595
unsigned int i,j;
596
 
597
APIPROC *listapi;
598
 
599
		ErrOpenFile(name);
600
 
601
	}
602
 
603
	if(fread(&temp,4,1,infile)!=1){
604
 
605
		//fprintf(stderr,"Unable to read from file %s.\n",name);
		printf("Unable to read from file %s.\n",name);
606
 
607
		return;
608
 
609
	fseek(infile,0,SEEK_END);
610
 
611
		//fprintf(stderr,"Bad file %s.\n",name);
		printf("Bad file %s.\n",name);
612
 
613
		return;
614
 
615
	fseek(infile,temp,SEEK_SET);
616
 
617
	if(pe.sign!=
618
 
619
			'EP'
620
 
621
      'PE'
622
 
623
					){
624
 
625
		fclose(infile);
626
 
627
	}
628
 
629
		//fprintf(stderr,"No export directory on %s.\n",name);
		printf("No export directory on %s.\n",name);
630
 
631
		return;
632
 
633
	numobj=pe.numobj;
634
 
635
	while(numobj!=0){
636
 
637
		if((obj.sectionRVA+Align(obj.psize,temp))>ulexport)break;
638
 
639
	}
640
 
641
		//fprintf(stderr,"Bad object table in %s.\n",name);
		printf("Bad object table in %s.\n",name);
642
 
643
		return;
644
 
645
 
646
 
647
	if(fread(&numobj,4,1,infile)!=1)goto errread;
648
 
649
	if(fread(&nameadr,4,1,infile)!=1)goto errread;
650
 
651
	nameadr-=ulexport;
652
 
653
	fseek(infile,posdll+12,SEEK_SET);
654
 
655
	if(fread(&ordinalbase,4,1,infile)!=1)goto errread;
656
 
657
	j=0;
658
 
659
		if(fread(&string[j],1,1,infile)!=1)goto errread;
660
 
661
	newdll=FindDLL();
662
 
663
664
 
665
		fseek(infile,posdll+nameadr,SEEK_SET);
666
 
667
		fseek(infile,posdll+startname-ulexport,SEEK_SET);
668
 
669
		j=0;
670
 
671
		do{
672
 
673
			if(c=='@'){
674
 
675
				break;
676
 
677
			itok.name[j]=c;
678
 
679
		}while(j<=IDLENGTH&&c!=0);
680
 
681
 
682
 
683
				if(fread(&c,1,1,infile)!=1)goto errread;
684
 
685
			}while(isdigit(c));
686
 
687
		}
688
 
689
		searchvar(itok.name);
690
 
691
			fseek(infile,posdll+ordinallist,SEEK_SET);
692
 
693
			if(fread(&itok.sib,2,1,infile)!=1)goto errread;
694
 
695
			tok=tk_apiproc;
696
 
697
			itok.segm=NOT_DYNAMIC;
698
 
699
			if(newdll->num==0)listapi=(APIPROC *)MALLOC(sizeof(APIPROC));	//первая в списке
700
 
701
			(listapi+newdll->num)->recapi=addtotree(itok.name);
702
 
703
		}
704
 
705
		ordinallist+=2;
706
 
707
	newdll->list=listapi;
708
 
709
}
710
 
711
void CreatStub(char *name)
712
 
713
	sizestub=SIZESTUB;
714
 
715
	sprintf(&stub[STRVERS],"%s%s",compilerstr,__DATE__);
716
 
717
stdstub:
718
 
719
errwrite:
720
 
721
			return;
722
 
723
	}
724
 
725
EXE_DOS_HEADER exeheader;  // header for EXE format
726
 
727
		if((stubin=fopen(name,"rb"))==NULL){
728
 
729
			goto stdstub;
730
 
731
		if(fread(&exeheader,sizeof(EXE_DOS_HEADER),1,stubin)!=1){
732
 
733
			ErrReadStub();
734
 
735
			goto stdstub;
736
 
737
		if(exeheader.sign!=0x5A4D){
738
 
739
			//fprintf(stderr,"File %s can not be stub file.\n",name);
			printf("File %s can not be stub file.\n",name);
740
 
741
			goto stdstub;
742
 
743
		fseek(stubin,0,SEEK_END);
744
 
745
		unsigned long temp;
746
 
747
			fseek(stubin,0x3c,SEEK_SET);
748
 
749
			if(temp
750
 
751
				if(fread(&temp,4,1,stubin)!=1)goto errread;
752
 
753
#ifdef _WC_
754
 
755
					case 'EN':
756
 
757
					case 'XL':
758
 
759
					case 'PE':
760
 
761
					case 'LE':
762
 
763
#endif
764
 
765
				}
766
 
767
			exeheader.ofsreloc+=(unsigned short)0x20;
768
 
769
		else exeheader.ofsreloc=0x40;
770
 
771
		sizestub=Align(sizestub+32,8);
772
 
773
		exeheader.headsize+=(unsigned short)2;
774
 
775
		*(unsigned long *)&stub[STRVERS+28]=sizestub;
776
 
777
		CopyFile(stubin,hout);
778
 
779
	}
780
 
781
782
 
783
#define MAXNUMSYMBOL 128
784
 
785
#define MAXNUMRELOC 256
786
 
787
char *ListName;
788
 
789
IMAGE_SYMBOL *isymbol;
790
 
791
int segtext,segbss;
792
 
793
IMAGE_RELOCATION *treloc;
794
 
795
struct NAMEID{
796
 
797
	int id;
798
 
799
800
 
801
802
 
803
{
804
 
805
		maxsizelistname+=MAXLISTNAME;
806
 
807
	}
808
 
809
	sizelistName+=size+1;
810
 
811
812
 
813
{
814
 
815
	if(ptr!=NULL){
816
 
817
		if(ptr->rectok==tk_apiproc){
818
 
819
				if((postbuf+j)->num==(unsigned long)ptr->recnumber&&((postbuf+j)->type==CALL_32I||(postbuf+j)->type==CALL_32)){
820
 
821
				}
822
 
823
		}
824
 
825
				((ptr->rectok==tk_proc||ptr->rectok==tk_interruptproc)&&ptr->recsegm>=NOT_DYNAMIC)||
826
 
827
nameext:
828
 
829
				maxnumsymbol+=MAXNUMSYMBOL;
830
 
831
			 	memset(isymbol+maxnumsymbol*sizeof(IMAGE_SYMBOL)-MAXSIZESYMBOL,0,MAXSIZESYMBOL);	//очистить ее
832
 
833
			if(ptr->rectok==tk_apiproc||ptr->rectok==tk_undefproc||
834
 
835
			i=strlen(ptr->recid);
836
 
837
				(isymbol+numsymbol)->N.Name.Short=0;
838
 
839
				AddName(ptr->recid,i);
840
 
841
			else strncpy((isymbol+numsymbol)->N.sname,ptr->recid,i);
842
 
843
				(isymbol+numsymbol)->Value=ptr->recnumber;
844
 
845
				else (isymbol+numsymbol)->SectionNumber=(short)((ptr->recpost==0?textnum:bssnum)+1);
846
 
847
			else{
848
 
849
				(NameId+numextern)->id=numsymbol;
850
 
851
				if(numextern>=maxnumnameid){
852
 
853
					NameId=(NAMEID *)REALLOC(NameId,maxnumnameid*sizeof(NAMEID));
854
 
855
			}
856
 
857
			numsymbol++;
858
 
859
		CreatSymbolTable(ptr->left);
860
 
861
}
862
 
863
void FreeCoffBuf()
864
 
865
	free(ListName);
866
 
867
	free(NameId);
868
 
869
	fclose(hout);
870
 
871
}
872
 
873
void IncReloc()
874
 
875
	numreloc++;
876
 
877
		maxnumreloc+=MAXNUMRELOC;
878
 
879
	}
880
 
881
882
 
883
{
884
 
885
 		(treloc+numreloc)->VirtualAddress=(postbuf+j)->loc-startptr;
886
 
887
			switch((postbuf+j)->type){
888
 
889
				case POST_VAR32:
890
 
891
					(treloc+numreloc)->SymbolTableIndex=segbss;
892
 
893
				case FIX_VAR:
894
 
895
				case FIX_CODE:
896
 
897
					(treloc+numreloc)->Type=IMAGE_REL_I386_DIR32;
898
 
899
					break;
900
 
901
			IncReloc();
902
 
903
		else{
904
 
905
				if((NameId+i)->num==(postbuf+j)->num){
906
 
907
					else (treloc+numreloc)->Type=IMAGE_REL_I386_REL32;
908
 
909
					IncReloc();
910
 
911
				}
912
 
913
		}
914
 
915
	}
916
 
917
918
 
919
{
920
 
921
unsigned long sizehead,curobj,resnum,numresrel,segres,lastoffset,headernum;
922
 
923
int i;
924
 
925
char *codesecname;
926
 
927
	chead.cpu=0x14c;
928
 
929
	chead.date_time=0;
930
 
931
	/*if(header)*/numrs=2;
932
 
933
	if(wbss){
934
 
935
		else wbss=FALSE;
936
 
937
	if(numres)numrs++;	//ресурсы
938
 
939
	sizehead=numrs*sizeof(OBJECT_ENTRY);
940
 
941
	memset(objentry,0,sizehead);//очистить таблицу объектов
942
 
943
	lastoffset=sizehead+sizeof(COFF_HEADER);
944
 
945
		strcpy((objentry+curobj)->name,".version");
946
 
947
		(objentry+curobj)->psize=strlen(&stub[STRVERS])+1;
948
 
949
		(objentry+curobj)->flags=0x100A00;
950
 
951
		lastoffset+=(objentry+curobj)->psize;
952
 
953
//	}
954
 
955
	if(splitdata==FALSE)codesecname=".codedat";
956
 
957
	(objentry+curobj)->psize=outptr;
958
 
959
	(objentry+curobj)->flags=0xE0300060;
960
 
961
	textnum=curobj;
962
 
963
	if(wbss){
964
 
965
		(objentry+curobj)->psize=postsize;
966
 
967
		bssnum=curobj;
968
 
969
	}
970
 
971
		strcpy((objentry+curobj)->name,".rsrc$01");
972
 
973
		(objentry+curobj)->psize=curposbuf;
974
 
975
		resnum=curobj;
976
 
977
	sizelistName=0;numsymbol=0;
978
 
979
	isymbol=(IMAGE_SYMBOL *)MALLOC(MAXSIZESYMBOL);
980
 
981
	maxsizelistname=MAXLISTNAME;
982
 
983
	NameId=(NAMEID *)MALLOC(MAXSIZENAMEID);
984
 
985
	maxnumreloc=MAXNUMRELOC;
986
 
987
	strcpy(isymbol->N.sname,"@comp.id");
988
 
989
	isymbol->SectionNumber=-1;
990
 
991
	strcpy((isymbol+1)->N.sname,".file");
992
 
993
	(isymbol+1)->SectionNumber=-2;
994
 
995
	i=(strlen(startfileinfo->filename)-1)/sizeof(IMAGE_SYMBOL)+1;
996
 
997
	strcpy((isymbol+2)->N.sname,startfileinfo->filename);
998
 
999
	segtext=numsymbol;
1000
 
1001
	(isymbol+numsymbol)->SectionNumber=textnum+1;
1002
 
1003
	(isymbol+numsymbol)->NumberOfAuxSymbols=1;
1004
 
1005
	(isymbol+numsymbol)->N.Name.Short=outptr;
1006
 
1007
	if(wbss){
1008
 
1009
		strcpy((isymbol+numsymbol)->N.sname,".bss");
1010
 
1011
		(isymbol+numsymbol)->StorageClass=3;
1012
 
1013
		numsymbol++;
1014
 
1015
		numsymbol++;
1016
 
1017
		(isymbol+numsymbol)->SectionNumber=bssnum+1;
1018
 
1019
	}
1020
 
1021
	(isymbol+numsymbol)->SectionNumber=-1;
1022
 
1023
	numsymbol++;
1024
 
1025
		segres=numsymbol;
1026
 
1027
		(isymbol+numsymbol)->StorageClass=3;
1028
 
1029
		numsymbol++;
1030
 
1031
//	if(header){
1032
 
1033
		(isymbol+numsymbol)->SectionNumber=headernum+1;
1034
 
1035
		numsymbol++;
1036
 
1037
	CreatSymbolTable(treestart);
1038
 
1039
	(isymbol+segtext+1)->N.Name.Long=numreloc;
1040
 
1041
	if(numreloc){
1042
 
1043
		lastoffset+=sizeof(IMAGE_RELOCATION)*numreloc;
1044
 
1045
	if(numres){
1046
 
1047
 
1048
 
1049
			(objentry+resnum)->PointerToRelocations=lastoffset;
1050
 
1051
		}
1052
 
1053
	chead.COFFsize=numsymbol;
1054
 
1055
		chead.pCOFF=lastoffset;
1056
 
1057
	if(fwrite(&chead,sizeof(COFF_HEADER),1,hout)!=1){
1058
 
1059
		ErrWrite();
1060
 
1061
		if(resrel)free(resrel);
1062
 
1063
		return(-1);
1064
 
1065
	if(fwrite(objentry,sizehead,1,hout)!=1)goto errwrite;
1066
 
1067
		if(fwrite(&stub[STRVERS],(objentry+headernum)->psize,1,hout)!=1)goto errwrite;
1068
 
1069
	if(fwrite(output,outptr,1,hout)!=1)goto errwrite;	//блок кода
1070
 
1071
		if(fwrite(treloc,numreloc*sizeof(IMAGE_RELOCATION),1,hout)!=1)goto errwrite;
1072
 
1073
	if(numres){
1074
 
1075
 
1076
 
1077
			IMAGE_RELOCATION *rrel;
1078
 
1079
			for(i=0;i
1080
 
1081
				(rrel+i)->Type=IMAGE_REL_I386_DIR32NB;
1082
 
1083
			}
1084
 
1085
			free(rrel);
1086
 
1087
	}
1088
 
1089
		if(fwrite(isymbol,numsymbol*sizeof(IMAGE_SYMBOL),1,hout)!=1)goto errwrite;
1090
 
1091
			sizelistName+=4;
1092
 
1093
			if(fwrite(ListName,sizelistName-4,1,hout)!=1)goto errwrite;
1094
 
1095
		else{
1096
 
1097
			sizelistName+=4;
1098
 
1099
	}
1100
 
1101
	free(objentry);
1102
 
1103
	FreeCoffBuf();
1104
 
1105
 
1106
 
1107
>
1108
 
1109
>
1110
 
1111
>
1112
 
1113
>
1114
 
1115
>
1116
 
1117
>
1118
 
1119
>
1120
 
1121
>
1122
 
1123