Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
145 halyavin 1
/*
2
 *  COFF file handling for TCC
3
 *
4
 *  Copyright (c) 2003, 2004 TK
5
 *  Copyright (c) 2004 Fabrice Bellard
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
 
6429 siemargl 22
#include "tcc.h"
23
 
145 halyavin 24
#define MAXNSCNS 255		/* MAXIMUM NUMBER OF SECTIONS         */
25
#define MAX_STR_TABLE 1000000
26
AOUTHDR o_filehdr;		/* OPTIONAL (A.OUT) FILE HEADER       */
27
 
28
SCNHDR section_header[MAXNSCNS];
29
 
30
#define MAX_FUNCS 1000
31
#define MAX_FUNC_NAME_LENGTH 128
32
 
33
int nFuncs;
34
char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
35
char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
36
int LineNoFilePtr[MAX_FUNCS];
37
int EndAddress[MAX_FUNCS];
38
int LastLineNo[MAX_FUNCS];
39
int FuncEntries[MAX_FUNCS];
40
 
6429 siemargl 41
int OutputTheSection(Section * sect);
145 halyavin 42
short int GetCoffFlags(const char *s);
43
void SortSymbolTable(void);
44
Section *FindSection(TCCState * s1, const char *sname);
45
 
46
int C67_main_entry_point;
47
 
48
int FindCoffSymbolIndex(const char *func_name);
49
int nb_syms;
50
 
51
typedef struct {
52
    long tag;
53
    long size;
54
    long fileptr;
55
    long nextsym;
56
    short int dummy;
57
} AUXFUNC;
58
 
59
typedef struct {
60
    long regmask;
61
    unsigned short lineno;
62
    unsigned short nentries;
63
    int localframe;
64
    int nextentry;
65
    short int dummy;
66
} AUXBF;
67
 
68
typedef struct {
69
    long dummy;
70
    unsigned short lineno;
71
    unsigned short dummy1;
72
    int dummy2;
73
    int dummy3;
74
    unsigned short dummy4;
75
} AUXEF;
76
 
6429 siemargl 77
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
145 halyavin 78
{
79
    Section *tcc_sect;
80
    SCNHDR *coff_sec;
81
    int file_pointer;
82
    char *Coff_str_table, *pCoff_str_table;
83
    int CoffTextSectionNo, coff_nb_syms;
84
    FILHDR file_hdr;		/* FILE HEADER STRUCTURE              */
85
    Section *stext, *sdata, *sbss;
86
    int i, NSectionsToOutput = 0;
87
 
6429 siemargl 88
    Coff_str_table = pCoff_str_table = NULL;
89
 
145 halyavin 90
    stext = FindSection(s1, ".text");
91
    sdata = FindSection(s1, ".data");
92
    sbss = FindSection(s1, ".bss");
93
 
94
    nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
95
    coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
96
 
97
    file_hdr.f_magic = COFF_C67_MAGIC;	/* magic number */
98
    file_hdr.f_timdat = 0;	/* time & date stamp */
99
    file_hdr.f_opthdr = sizeof(AOUTHDR);	/* sizeof(optional hdr) */
100
    file_hdr.f_flags = 0x1143;	/* flags (copied from what code composer does) */
101
    file_hdr.f_TargetID = 0x99;	/* for C6x = 0x0099 */
102
 
103
    o_filehdr.magic = 0x0108;	/* see magic.h                          */
104
    o_filehdr.vstamp = 0x0190;	/* version stamp                        */
105
    o_filehdr.tsize = stext->data_offset;	/* text size in bytes, padded to FW bdry */
106
    o_filehdr.dsize = sdata->data_offset;	/* initialized data "  "                */
107
    o_filehdr.bsize = sbss->data_offset;	/* uninitialized data "   "             */
108
    o_filehdr.entrypt = C67_main_entry_point;	/* entry pt.                          */
109
    o_filehdr.text_start = stext->sh_addr;	/* base of text used for this file      */
110
    o_filehdr.data_start = sdata->sh_addr;	/* base of data used for this file      */
111
 
112
 
113
    // create all the section headers
114
 
115
    file_pointer = FILHSZ + sizeof(AOUTHDR);
116
 
117
    CoffTextSectionNo = -1;
118
 
119
    for (i = 1; i < s1->nb_sections; i++) {
120
	coff_sec = §ion_header[i];
121
	tcc_sect = s1->sections[i];
122
 
123
	if (OutputTheSection(tcc_sect)) {
124
	    NSectionsToOutput++;
125
 
126
	    if (CoffTextSectionNo == -1 && tcc_sect == stext)
127
		CoffTextSectionNo = NSectionsToOutput;	// rem which coff sect number the .text sect is
128
 
129
	    strcpy(coff_sec->s_name, tcc_sect->name);	/* section name */
130
 
131
	    coff_sec->s_paddr = tcc_sect->sh_addr;	/* physical address */
132
	    coff_sec->s_vaddr = tcc_sect->sh_addr;	/* virtual address */
133
	    coff_sec->s_size = tcc_sect->data_offset;	/* section size */
134
	    coff_sec->s_scnptr = 0;	/* file ptr to raw data for section */
135
	    coff_sec->s_relptr = 0;	/* file ptr to relocation */
136
	    coff_sec->s_lnnoptr = 0;	/* file ptr to line numbers */
137
	    coff_sec->s_nreloc = 0;	/* number of relocation entries */
138
	    coff_sec->s_flags = GetCoffFlags(coff_sec->s_name);	/* flags */
139
	    coff_sec->s_reserved = 0;	/* reserved byte */
140
	    coff_sec->s_page = 0;	/* memory page id */
141
 
142
	    file_pointer += sizeof(SCNHDR);
143
	}
144
    }
145
 
146
    file_hdr.f_nscns = NSectionsToOutput;	/* number of sections */
147
 
148
    // now loop through and determine file pointer locations
149
    // for the raw data
150
 
151
 
152
    for (i = 1; i < s1->nb_sections; i++) {
153
	coff_sec = §ion_header[i];
154
	tcc_sect = s1->sections[i];
155
 
156
	if (OutputTheSection(tcc_sect)) {
157
	    // put raw data
158
	    coff_sec->s_scnptr = file_pointer;	/* file ptr to raw data for section */
159
	    file_pointer += coff_sec->s_size;
160
	}
161
    }
162
 
163
    // now loop through and determine file pointer locations
164
    // for the relocation data
165
 
166
    for (i = 1; i < s1->nb_sections; i++) {
167
	coff_sec = §ion_header[i];
168
	tcc_sect = s1->sections[i];
169
 
170
	if (OutputTheSection(tcc_sect)) {
171
	    // put relocations data
172
	    if (coff_sec->s_nreloc > 0) {
173
		coff_sec->s_relptr = file_pointer;	/* file ptr to relocation */
174
		file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
175
	    }
176
	}
177
    }
178
 
179
    // now loop through and determine file pointer locations
180
    // for the line number data
181
 
182
    for (i = 1; i < s1->nb_sections; i++) {
183
	coff_sec = §ion_header[i];
184
	tcc_sect = s1->sections[i];
185
 
186
	coff_sec->s_nlnno = 0;
187
	coff_sec->s_lnnoptr = 0;
188
 
6429 siemargl 189
	if (s1->do_debug && tcc_sect == stext) {
145 halyavin 190
	    // count how many line nos data
191
 
192
	    // also find association between source file name and function
193
	    // so we can sort the symbol table
194
 
195
 
196
	    Stab_Sym *sym, *sym_end;
197
	    char func_name[MAX_FUNC_NAME_LENGTH],
198
		last_func_name[MAX_FUNC_NAME_LENGTH];
199
	    unsigned long func_addr, last_pc, pc;
200
	    const char *incl_files[INCLUDE_STACK_SIZE];
201
	    int incl_index, len, last_line_num;
202
	    const char *str, *p;
203
 
204
	    coff_sec->s_lnnoptr = file_pointer;	/* file ptr to linno */
205
 
206
 
207
	    func_name[0] = '\0';
208
	    func_addr = 0;
209
	    incl_index = 0;
210
	    last_func_name[0] = '\0';
211
	    last_pc = 0xffffffff;
212
	    last_line_num = 1;
213
	    sym = (Stab_Sym *) stab_section->data + 1;
214
	    sym_end =
215
		(Stab_Sym *) (stab_section->data +
216
			      stab_section->data_offset);
217
 
218
	    nFuncs = 0;
219
	    while (sym < sym_end) {
220
		switch (sym->n_type) {
221
		    /* function start or end */
222
		case N_FUN:
223
		    if (sym->n_strx == 0) {
224
			// end of function
225
 
226
			coff_sec->s_nlnno++;
227
			file_pointer += LINESZ;
228
 
229
			pc = sym->n_value + func_addr;
230
			func_name[0] = '\0';
231
			func_addr = 0;
232
			EndAddress[nFuncs] = pc;
233
			FuncEntries[nFuncs] =
234
			    (file_pointer -
235
			     LineNoFilePtr[nFuncs]) / LINESZ - 1;
236
			LastLineNo[nFuncs++] = last_line_num + 1;
237
		    } else {
238
			// beginning of function
239
 
240
			LineNoFilePtr[nFuncs] = file_pointer;
241
			coff_sec->s_nlnno++;
242
			file_pointer += LINESZ;
243
 
244
			str =
245
			    (const char *) stabstr_section->data +
246
			    sym->n_strx;
247
 
248
			p = strchr(str, ':');
249
			if (!p) {
250
			    pstrcpy(func_name, sizeof(func_name), str);
251
			    pstrcpy(Func[nFuncs], sizeof(func_name), str);
252
			} else {
253
			    len = p - str;
254
			    if (len > sizeof(func_name) - 1)
255
				len = sizeof(func_name) - 1;
256
			    memcpy(func_name, str, len);
257
			    memcpy(Func[nFuncs], str, len);
258
			    func_name[len] = '\0';
259
			}
260
 
261
			// save the file that it came in so we can sort later
262
			pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
263
				incl_files[incl_index - 1]);
264
 
265
			func_addr = sym->n_value;
266
		    }
267
		    break;
268
 
269
		    /* line number info */
270
		case N_SLINE:
271
		    pc = sym->n_value + func_addr;
272
 
273
		    last_pc = pc;
274
		    last_line_num = sym->n_desc;
275
 
276
		    /* XXX: slow! */
277
		    strcpy(last_func_name, func_name);
278
 
279
		    coff_sec->s_nlnno++;
280
		    file_pointer += LINESZ;
281
		    break;
282
		    /* include files */
283
		case N_BINCL:
284
		    str =
285
			(const char *) stabstr_section->data + sym->n_strx;
286
		  add_incl:
287
		    if (incl_index < INCLUDE_STACK_SIZE) {
288
			incl_files[incl_index++] = str;
289
		    }
290
		    break;
291
		case N_EINCL:
292
		    if (incl_index > 1)
293
			incl_index--;
294
		    break;
295
		case N_SO:
296
		    if (sym->n_strx == 0) {
297
			incl_index = 0;	/* end of translation unit */
298
		    } else {
299
			str =
300
			    (const char *) stabstr_section->data +
301
			    sym->n_strx;
302
			/* do not add path */
303
			len = strlen(str);
304
			if (len > 0 && str[len - 1] != '/')
305
			    goto add_incl;
306
		    }
307
		    break;
308
		}
309
		sym++;
310
	    }
311
	}
312
 
313
    }
314
 
315
    file_hdr.f_symptr = file_pointer;	/* file pointer to symtab */
316
 
6429 siemargl 317
    if (s1->do_debug)
145 halyavin 318
	file_hdr.f_nsyms = coff_nb_syms;	/* number of symtab entries */
319
    else
320
	file_hdr.f_nsyms = 0;
321
 
322
    file_pointer += file_hdr.f_nsyms * SYMNMLEN;
323
 
324
    // OK now we are all set to write the file
325
 
326
 
327
    fwrite(&file_hdr, FILHSZ, 1, f);
328
    fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
329
 
330
    // write section headers
331
    for (i = 1; i < s1->nb_sections; i++) {
332
	coff_sec = §ion_header[i];
333
	tcc_sect = s1->sections[i];
334
 
335
	if (OutputTheSection(tcc_sect)) {
336
	    fwrite(coff_sec, sizeof(SCNHDR), 1, f);
337
	}
338
    }
339
 
340
    // write raw data
341
    for (i = 1; i < s1->nb_sections; i++) {
342
	coff_sec = §ion_header[i];
343
	tcc_sect = s1->sections[i];
344
 
345
	if (OutputTheSection(tcc_sect)) {
346
	    fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
347
	}
348
    }
349
 
350
    // write relocation data
351
    for (i = 1; i < s1->nb_sections; i++) {
352
	coff_sec = §ion_header[i];
353
	tcc_sect = s1->sections[i];
354
 
355
	if (OutputTheSection(tcc_sect)) {
356
	    // put relocations data
357
	    if (coff_sec->s_nreloc > 0) {
358
		fwrite(tcc_sect->reloc,
359
		       coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
360
	    }
361
	}
362
    }
363
 
364
 
365
    // group the symbols in order of filename, func1, func2, etc
366
    // finally global symbols
367
 
6429 siemargl 368
    if (s1->do_debug)
145 halyavin 369
	SortSymbolTable();
370
 
371
    // write line no data
372
 
373
    for (i = 1; i < s1->nb_sections; i++) {
374
	coff_sec = §ion_header[i];
375
	tcc_sect = s1->sections[i];
376
 
6429 siemargl 377
	if (s1->do_debug && tcc_sect == stext) {
145 halyavin 378
	    // count how many line nos data
379
 
380
 
381
	    Stab_Sym *sym, *sym_end;
382
	    char func_name[128], last_func_name[128];
383
	    unsigned long func_addr, last_pc, pc;
384
	    const char *incl_files[INCLUDE_STACK_SIZE];
385
	    int incl_index, len, last_line_num;
386
	    const char *str, *p;
387
 
388
	    LINENO CoffLineNo;
389
 
390
	    func_name[0] = '\0';
391
	    func_addr = 0;
392
	    incl_index = 0;
393
	    last_func_name[0] = '\0';
394
	    last_pc = 0;
395
	    last_line_num = 1;
396
	    sym = (Stab_Sym *) stab_section->data + 1;
397
	    sym_end =
398
		(Stab_Sym *) (stab_section->data +
399
			      stab_section->data_offset);
400
 
401
	    while (sym < sym_end) {
402
		switch (sym->n_type) {
403
		    /* function start or end */
404
		case N_FUN:
405
		    if (sym->n_strx == 0) {
406
			// end of function
407
 
408
			CoffLineNo.l_addr.l_paddr = last_pc;
409
			CoffLineNo.l_lnno = last_line_num + 1;
410
			fwrite(&CoffLineNo, 6, 1, f);
411
 
412
			pc = sym->n_value + func_addr;
413
			func_name[0] = '\0';
414
			func_addr = 0;
415
		    } else {
416
			// beginning of function
417
 
418
			str =
419
			    (const char *) stabstr_section->data +
420
			    sym->n_strx;
421
 
422
 
423
			p = strchr(str, ':');
424
			if (!p) {
425
			    pstrcpy(func_name, sizeof(func_name), str);
426
			} else {
427
			    len = p - str;
428
			    if (len > sizeof(func_name) - 1)
429
				len = sizeof(func_name) - 1;
430
			    memcpy(func_name, str, len);
431
			    func_name[len] = '\0';
432
			}
433
			func_addr = sym->n_value;
434
			last_pc = func_addr;
435
			last_line_num = -1;
436
 
437
			// output a function begin
438
 
439
			CoffLineNo.l_addr.l_symndx =
440
			    FindCoffSymbolIndex(func_name);
441
			CoffLineNo.l_lnno = 0;
442
 
443
			fwrite(&CoffLineNo, 6, 1, f);
444
		    }
445
		    break;
446
 
447
		    /* line number info */
448
		case N_SLINE:
449
		    pc = sym->n_value + func_addr;
450
 
451
 
452
		    /* XXX: slow! */
453
		    strcpy(last_func_name, func_name);
454
 
455
		    // output a line reference
456
 
457
		    CoffLineNo.l_addr.l_paddr = last_pc;
458
 
459
		    if (last_line_num == -1) {
460
			CoffLineNo.l_lnno = sym->n_desc;
461
		    } else {
462
			CoffLineNo.l_lnno = last_line_num + 1;
463
		    }
464
 
465
		    fwrite(&CoffLineNo, 6, 1, f);
466
 
467
		    last_pc = pc;
468
		    last_line_num = sym->n_desc;
469
 
470
		    break;
471
 
472
		    /* include files */
473
		case N_BINCL:
474
		    str =
475
			(const char *) stabstr_section->data + sym->n_strx;
476
		  add_incl2:
477
		    if (incl_index < INCLUDE_STACK_SIZE) {
478
			incl_files[incl_index++] = str;
479
		    }
480
		    break;
481
		case N_EINCL:
482
		    if (incl_index > 1)
483
			incl_index--;
484
		    break;
485
		case N_SO:
486
		    if (sym->n_strx == 0) {
487
			incl_index = 0;	/* end of translation unit */
488
		    } else {
489
			str =
490
			    (const char *) stabstr_section->data +
491
			    sym->n_strx;
492
			/* do not add path */
493
			len = strlen(str);
494
			if (len > 0 && str[len - 1] != '/')
495
			    goto add_incl2;
496
		    }
497
		    break;
498
		}
499
		sym++;
500
	    }
501
	}
502
    }
503
 
504
    // write symbol table
6429 siemargl 505
    if (s1->do_debug) {
145 halyavin 506
	int k;
507
	struct syment csym;
508
	AUXFUNC auxfunc;
509
	AUXBF auxbf;
510
	AUXEF auxef;
511
	int i;
512
	Elf32_Sym *p;
513
	const char *name;
514
	int nstr;
515
	int n = 0;
516
 
517
	Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
518
	pCoff_str_table = Coff_str_table;
519
	nstr = 0;
520
 
521
	p = (Elf32_Sym *) symtab_section->data;
522
 
523
 
524
	for (i = 0; i < nb_syms; i++) {
525
 
526
	    name = symtab_section->link->data + p->st_name;
527
 
528
	    for (k = 0; k < 8; k++)
529
		csym._n._n_name[k] = 0;
530
 
531
	    if (strlen(name) <= 8) {
532
		strcpy(csym._n._n_name, name);
533
	    } else {
534
		if (pCoff_str_table - Coff_str_table + strlen(name) >
535
		    MAX_STR_TABLE - 1)
6429 siemargl 536
		    tcc_error("String table too large");
145 halyavin 537
 
538
		csym._n._n_n._n_zeroes = 0;
539
		csym._n._n_n._n_offset =
540
		    pCoff_str_table - Coff_str_table + 4;
541
 
542
		strcpy(pCoff_str_table, name);
543
		pCoff_str_table += strlen(name) + 1;	// skip over null
544
		nstr++;
545
	    }
546
 
547
	    if (p->st_info == 4) {
548
		// put a filename symbol
549
		csym.n_value = 33;	// ?????
550
		csym.n_scnum = N_DEBUG;
551
		csym.n_type = 0;
552
		csym.n_sclass = C_FILE;
553
		csym.n_numaux = 0;
554
		fwrite(&csym, 18, 1, f);
555
		n++;
556
 
557
	    } else if (p->st_info == 0x12) {
558
		// find the function data
559
 
560
		for (k = 0; k < nFuncs; k++) {
561
		    if (strcmp(name, Func[k]) == 0)
562
			break;
563
		}
564
 
565
		if (k >= nFuncs) {
6429 siemargl 566
		    tcc_error("debug info can't find function: %s", name);
145 halyavin 567
		}
568
		// put a Function Name
569
 
570
		csym.n_value = p->st_value;	// physical address
571
		csym.n_scnum = CoffTextSectionNo;
572
		csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
573
		csym.n_sclass = C_EXT;
574
		csym.n_numaux = 1;
575
		fwrite(&csym, 18, 1, f);
576
 
577
		// now put aux info
578
 
579
		auxfunc.tag = 0;
580
		auxfunc.size = EndAddress[k] - p->st_value;
581
		auxfunc.fileptr = LineNoFilePtr[k];
582
		auxfunc.nextsym = n + 6;	// tktk
583
		auxfunc.dummy = 0;
584
		fwrite(&auxfunc, 18, 1, f);
585
 
586
		// put a .bf
587
 
588
		strcpy(csym._n._n_name, ".bf");
589
		csym.n_value = p->st_value;	// physical address
590
		csym.n_scnum = CoffTextSectionNo;
591
		csym.n_type = 0;
592
		csym.n_sclass = C_FCN;
593
		csym.n_numaux = 1;
594
		fwrite(&csym, 18, 1, f);
595
 
596
		// now put aux info
597
 
598
		auxbf.regmask = 0;
599
		auxbf.lineno = 0;
600
		auxbf.nentries = FuncEntries[k];
601
		auxbf.localframe = 0;
602
		auxbf.nextentry = n + 6;
603
		auxbf.dummy = 0;
604
		fwrite(&auxbf, 18, 1, f);
605
 
606
		// put a .ef
607
 
608
		strcpy(csym._n._n_name, ".ef");
609
		csym.n_value = EndAddress[k];	// physical address
610
		csym.n_scnum = CoffTextSectionNo;
611
		csym.n_type = 0;
612
		csym.n_sclass = C_FCN;
613
		csym.n_numaux = 1;
614
		fwrite(&csym, 18, 1, f);
615
 
616
		// now put aux info
617
 
618
		auxef.dummy = 0;
619
		auxef.lineno = LastLineNo[k];
620
		auxef.dummy1 = 0;
621
		auxef.dummy2 = 0;
622
		auxef.dummy3 = 0;
623
		auxef.dummy4 = 0;
624
		fwrite(&auxef, 18, 1, f);
625
 
626
		n += 6;
627
 
628
	    } else {
629
		// try an put some type info
630
 
631
		if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
632
		    csym.n_type = T_DOUBLE;	// int
633
		    csym.n_sclass = C_EXT;
634
		} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
635
		    csym.n_type = T_FLOAT;
636
		    csym.n_sclass = C_EXT;
637
		} else if ((p->st_other & VT_BTYPE) == VT_INT) {
638
		    csym.n_type = T_INT;	// int
639
		    csym.n_sclass = C_EXT;
640
		} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
641
		    csym.n_type = T_SHORT;
642
		    csym.n_sclass = C_EXT;
643
		} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
644
		    csym.n_type = T_CHAR;
645
		    csym.n_sclass = C_EXT;
646
		} else {
647
		    csym.n_type = T_INT;	// just mark as a label
648
		    csym.n_sclass = C_LABEL;
649
		}
650
 
651
 
652
		csym.n_value = p->st_value;
653
		csym.n_scnum = 2;
654
		csym.n_numaux = 1;
655
		fwrite(&csym, 18, 1, f);
656
 
657
		auxfunc.tag = 0;
658
		auxfunc.size = 0x20;
659
		auxfunc.fileptr = 0;
660
		auxfunc.nextsym = 0;
661
		auxfunc.dummy = 0;
662
		fwrite(&auxfunc, 18, 1, f);
663
		n++;
664
		n++;
665
 
666
	    }
667
 
668
	    p++;
669
	}
670
    }
671
 
6429 siemargl 672
    if (s1->do_debug) {
145 halyavin 673
	// write string table
674
 
675
	// first write the size
676
	i = pCoff_str_table - Coff_str_table;
677
	fwrite(&i, 4, 1, f);
678
 
679
	// then write the strings
680
	fwrite(Coff_str_table, i, 1, f);
681
 
682
	tcc_free(Coff_str_table);
683
    }
684
 
685
    return 0;
686
}
687
 
688
 
689
 
690
// group the symbols in order of filename, func1, func2, etc
691
// finally global symbols
692
 
693
void SortSymbolTable(void)
694
{
695
    int i, j, k, n = 0;
696
    Elf32_Sym *p, *p2, *NewTable;
697
    char *name, *name2;
698
 
699
    NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
700
 
701
    p = (Elf32_Sym *) symtab_section->data;
702
 
703
 
704
    // find a file symbol, copy it over
705
    // then scan the whole symbol list and copy any function
706
    // symbols that match the file association
707
 
708
    for (i = 0; i < nb_syms; i++) {
709
	if (p->st_info == 4) {
710
	    name = (char *) symtab_section->link->data + p->st_name;
711
 
712
	    // this is a file symbol, copy it over
713
 
714
	    NewTable[n++] = *p;
715
 
716
	    p2 = (Elf32_Sym *) symtab_section->data;
717
 
718
	    for (j = 0; j < nb_syms; j++) {
719
		if (p2->st_info == 0x12) {
720
		    // this is a func symbol
721
 
722
		    name2 =
723
			(char *) symtab_section->link->data + p2->st_name;
724
 
725
		    // find the function data index
726
 
727
		    for (k = 0; k < nFuncs; k++) {
728
			if (strcmp(name2, Func[k]) == 0)
729
			    break;
730
		    }
731
 
732
		    if (k >= nFuncs) {
6429 siemargl 733
                        tcc_error("debug (sort) info can't find function: %s", name2);
145 halyavin 734
		    }
735
 
736
		    if (strcmp(AssociatedFile[k], name) == 0) {
737
			// yes they match copy it over
738
 
739
			NewTable[n++] = *p2;
740
		    }
741
		}
742
		p2++;
743
	    }
744
	}
745
	p++;
746
    }
747
 
748
    // now all the filename and func symbols should have been copied over
749
    // copy all the rest over (all except file and funcs)
750
 
751
    p = (Elf32_Sym *) symtab_section->data;
752
    for (i = 0; i < nb_syms; i++) {
753
	if (p->st_info != 4 && p->st_info != 0x12) {
754
	    NewTable[n++] = *p;
755
	}
756
	p++;
757
    }
758
 
759
    if (n != nb_syms)
6429 siemargl 760
	tcc_error("Internal Compiler error, debug info");
145 halyavin 761
 
762
    // copy it all back
763
 
764
    p = (Elf32_Sym *) symtab_section->data;
765
    for (i = 0; i < nb_syms; i++) {
766
	*p++ = NewTable[i];
767
    }
768
 
769
    tcc_free(NewTable);
770
}
771
 
772
 
773
int FindCoffSymbolIndex(const char *func_name)
774
{
775
    int i, n = 0;
776
    Elf32_Sym *p;
777
    char *name;
778
 
779
    p = (Elf32_Sym *) symtab_section->data;
780
 
781
    for (i = 0; i < nb_syms; i++) {
782
 
783
	name = (char *) symtab_section->link->data + p->st_name;
784
 
785
	if (p->st_info == 4) {
786
	    // put a filename symbol
787
	    n++;
788
	} else if (p->st_info == 0x12) {
789
 
790
	    if (strcmp(func_name, name) == 0)
791
		return n;
792
 
793
	    n += 6;
794
 
795
	    // put a Function Name
796
 
797
	    // now put aux info
798
 
799
	    // put a .bf
800
 
801
	    // now put aux info
802
 
803
	    // put a .ef
804
 
805
	    // now put aux info
806
 
807
	} else {
808
	    n += 2;
809
	}
810
 
811
	p++;
812
    }
813
 
814
    return n;			// total number of symbols
815
}
816
 
6429 siemargl 817
int OutputTheSection(Section * sect)
145 halyavin 818
{
819
    const char *s = sect->name;
820
 
821
    if (!strcmp(s, ".text"))
6429 siemargl 822
	return 1;
145 halyavin 823
    else if (!strcmp(s, ".data"))
6429 siemargl 824
	return 1;
145 halyavin 825
    else
826
	return 0;
827
}
828
 
829
short int GetCoffFlags(const char *s)
830
{
831
    if (!strcmp(s, ".text"))
832
	return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
833
    else if (!strcmp(s, ".data"))
834
	return STYP_DATA;
835
    else if (!strcmp(s, ".bss"))
836
	return STYP_BSS;
837
    else if (!strcmp(s, ".stack"))
838
	return STYP_BSS | STYP_ALIGN | 0x200;
839
    else if (!strcmp(s, ".cinit"))
840
	return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
841
    else
842
	return 0;
843
}
844
 
845
Section *FindSection(TCCState * s1, const char *sname)
846
{
847
    Section *s;
848
    int i;
849
 
850
    for (i = 1; i < s1->nb_sections; i++) {
851
	s = s1->sections[i];
852
 
853
	if (!strcmp(sname, s->name))
854
	    return s;
855
    }
856
 
6429 siemargl 857
    tcc_error("could not find section %s", sname);
145 halyavin 858
    return 0;
859
}
860
 
6429 siemargl 861
ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
145 halyavin 862
{
863
// tktk TokenSym *ts;
864
 
865
    FILE *f;
866
    unsigned int str_size;
867
    char *Coff_str_table, *name;
868
    int i, k;
869
    struct syment csym;
870
    char name2[9];
871
    FILHDR file_hdr;		/* FILE HEADER STRUCTURE              */
872
 
873
    f = fdopen(fd, "rb");
874
    if (!f) {
6429 siemargl 875
	tcc_error("Unable to open .out file for input");
145 halyavin 876
    }
877
 
878
    if (fread(&file_hdr, FILHSZ, 1, f) != 1)
6429 siemargl 879
	tcc_error("error reading .out file for input");
145 halyavin 880
 
881
    if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
6429 siemargl 882
	tcc_error("error reading .out file for input");
145 halyavin 883
 
884
    // first read the string table
885
 
886
    if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
6429 siemargl 887
	tcc_error("error reading .out file for input");
145 halyavin 888
 
889
    if (fread(&str_size, sizeof(int), 1, f) != 1)
6429 siemargl 890
	tcc_error("error reading .out file for input");
145 halyavin 891
 
892
 
893
    Coff_str_table = (char *) tcc_malloc(str_size);
894
 
895
    if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
6429 siemargl 896
	tcc_error("error reading .out file for input");
145 halyavin 897
 
898
    // read/process all the symbols
899
 
900
    // seek back to symbols
901
 
902
    if (fseek(f, file_hdr.f_symptr, SEEK_SET))
6429 siemargl 903
	tcc_error("error reading .out file for input");
145 halyavin 904
 
905
    for (i = 0; i < file_hdr.f_nsyms; i++) {
906
	if (fread(&csym, SYMESZ, 1, f) != 1)
6429 siemargl 907
	    tcc_error("error reading .out file for input");
145 halyavin 908
 
909
	if (csym._n._n_n._n_zeroes == 0) {
910
	    name = Coff_str_table + csym._n._n_n._n_offset - 4;
911
	} else {
912
	    name = csym._n._n_name;
913
 
914
	    if (name[7] != 0) {
915
		for (k = 0; k < 8; k++)
916
		    name2[k] = name[k];
917
 
918
		name2[8] = 0;
919
 
920
		name = name2;
921
	    }
922
	}
923
//              if (strcmp("_DAC_Buffer",name)==0)  // tktk
924
//                      name[0]=0;
925
 
926
	if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) ||	// structures
927
	    (csym.n_type == 0x18 && csym.n_sclass == 0x2) ||	// pointer to structure
928
	    (csym.n_type == 0x7 && csym.n_sclass == 0x2) ||	// doubles
929
	    (csym.n_type == 0x6 && csym.n_sclass == 0x2))	// floats
930
	{
931
	    // strip off any leading underscore (except for other main routine)
932
 
933
	    if (name[0] == '_' && strcmp(name, "_main") != 0)
934
		name++;
935
 
6429 siemargl 936
	    tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
145 halyavin 937
	}
938
	// skip any aux records
939
 
940
	if (csym.n_numaux == 1) {
941
	    if (fread(&csym, SYMESZ, 1, f) != 1)
6429 siemargl 942
		tcc_error("error reading .out file for input");
145 halyavin 943
	    i++;
944
	}
945
    }
946
 
947
    return 0;
948
}