fixed 'no base' modrm generation - better asm constraints handling
[tinycc.git] / tcccoff.c
blob7f60ccfbd964e2d753ef74fb63a8c71ef9743561
1 /*
2 * COFF file handling for TCC
3 *
4 * Copyright (c) 2003, 2004 TK
5 * Copyright (c) 2004 Fabrice Bellard
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.
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.
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
21 #include "coff.h"
23 #define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
24 #define MAX_STR_TABLE 1000000
25 AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
27 SCNHDR section_header[MAXNSCNS];
29 #define MAX_FUNCS 1000
30 #define MAX_FUNC_NAME_LENGTH 128
32 int nFuncs;
33 char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
34 char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
35 int LineNoFilePtr[MAX_FUNCS];
36 int EndAddress[MAX_FUNCS];
37 int LastLineNo[MAX_FUNCS];
38 int FuncEntries[MAX_FUNCS];
40 BOOL OutputTheSection(Section * sect);
41 short int GetCoffFlags(const char *s);
42 void SortSymbolTable(void);
43 Section *FindSection(TCCState * s1, const char *sname);
45 int C67_main_entry_point;
47 int FindCoffSymbolIndex(const char *func_name);
48 int nb_syms;
50 typedef struct {
51 long tag;
52 long size;
53 long fileptr;
54 long nextsym;
55 short int dummy;
56 } AUXFUNC;
58 typedef struct {
59 long regmask;
60 unsigned short lineno;
61 unsigned short nentries;
62 int localframe;
63 int nextentry;
64 short int dummy;
65 } AUXBF;
67 typedef struct {
68 long dummy;
69 unsigned short lineno;
70 unsigned short dummy1;
71 int dummy2;
72 int dummy3;
73 unsigned short dummy4;
74 } AUXEF;
76 int tcc_output_coff(TCCState *s1, const char *OutFile)
78 FILE *f;
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;
87 f = fopen(OutFile, "wb");
89 if (!f) {
90 error("Unable to open output file");
93 stext = FindSection(s1, ".text");
94 sdata = FindSection(s1, ".data");
95 sbss = FindSection(s1, ".bss");
97 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
98 coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
100 file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
101 file_hdr.f_timdat = 0; /* time & date stamp */
102 file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
103 file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
104 file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
106 o_filehdr.magic = 0x0108; /* see magic.h */
107 o_filehdr.vstamp = 0x0190; /* version stamp */
108 o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */
109 o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
110 o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
111 o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
112 o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
113 o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
116 // create all the section headers
118 int i, NSectionsToOutput = 0;
120 file_pointer = FILHSZ + sizeof(AOUTHDR);
122 CoffTextSectionNo = -1;
124 for (i = 1; i < s1->nb_sections; i++) {
125 coff_sec = &section_header[i];
126 tcc_sect = s1->sections[i];
128 if (OutputTheSection(tcc_sect)) {
129 NSectionsToOutput++;
131 if (CoffTextSectionNo == -1 && tcc_sect == stext)
132 CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is
134 strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
136 coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
137 coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
138 coff_sec->s_size = tcc_sect->data_offset; /* section size */
139 coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
140 coff_sec->s_relptr = 0; /* file ptr to relocation */
141 coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
142 coff_sec->s_nreloc = 0; /* number of relocation entries */
143 coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
144 coff_sec->s_reserved = 0; /* reserved byte */
145 coff_sec->s_page = 0; /* memory page id */
147 file_pointer += sizeof(SCNHDR);
151 file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
153 // now loop through and determine file pointer locations
154 // for the raw data
157 for (i = 1; i < s1->nb_sections; i++) {
158 coff_sec = &section_header[i];
159 tcc_sect = s1->sections[i];
161 if (OutputTheSection(tcc_sect)) {
162 // put raw data
163 coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */
164 file_pointer += coff_sec->s_size;
168 // now loop through and determine file pointer locations
169 // for the relocation data
171 for (i = 1; i < s1->nb_sections; i++) {
172 coff_sec = &section_header[i];
173 tcc_sect = s1->sections[i];
175 if (OutputTheSection(tcc_sect)) {
176 // put relocations data
177 if (coff_sec->s_nreloc > 0) {
178 coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
179 file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
184 // now loop through and determine file pointer locations
185 // for the line number data
187 for (i = 1; i < s1->nb_sections; i++) {
188 coff_sec = &section_header[i];
189 tcc_sect = s1->sections[i];
191 coff_sec->s_nlnno = 0;
192 coff_sec->s_lnnoptr = 0;
194 if (do_debug && tcc_sect == stext) {
195 // count how many line nos data
197 // also find association between source file name and function
198 // so we can sort the symbol table
201 Stab_Sym *sym, *sym_end;
202 char func_name[MAX_FUNC_NAME_LENGTH],
203 last_func_name[MAX_FUNC_NAME_LENGTH];
204 unsigned long func_addr, last_pc, pc;
205 const char *incl_files[INCLUDE_STACK_SIZE];
206 int incl_index, len, last_line_num;
207 const char *str, *p;
209 coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
212 func_name[0] = '\0';
213 func_addr = 0;
214 incl_index = 0;
215 last_func_name[0] = '\0';
216 last_pc = 0xffffffff;
217 last_line_num = 1;
218 sym = (Stab_Sym *) stab_section->data + 1;
219 sym_end =
220 (Stab_Sym *) (stab_section->data +
221 stab_section->data_offset);
223 nFuncs = 0;
224 while (sym < sym_end) {
225 switch (sym->n_type) {
226 /* function start or end */
227 case N_FUN:
228 if (sym->n_strx == 0) {
229 // end of function
231 coff_sec->s_nlnno++;
232 file_pointer += LINESZ;
234 pc = sym->n_value + func_addr;
235 func_name[0] = '\0';
236 func_addr = 0;
237 EndAddress[nFuncs] = pc;
238 FuncEntries[nFuncs] =
239 (file_pointer -
240 LineNoFilePtr[nFuncs]) / LINESZ;
241 LastLineNo[nFuncs++] = last_line_num + 1;
242 } else {
243 // beginning of function
245 LineNoFilePtr[nFuncs] = file_pointer;
246 coff_sec->s_nlnno++;
247 file_pointer += LINESZ;
249 str =
250 (const char *) stabstr_section->data +
251 sym->n_strx;
253 p = strchr(str, ':');
254 if (!p) {
255 pstrcpy(func_name, sizeof(func_name), str);
256 pstrcpy(Func[nFuncs], sizeof(func_name), str);
257 } else {
258 len = p - str;
259 if (len > sizeof(func_name) - 1)
260 len = sizeof(func_name) - 1;
261 memcpy(func_name, str, len);
262 memcpy(Func[nFuncs], str, len);
263 func_name[len] = '\0';
266 // save the file that it came in so we can sort later
267 pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
268 incl_files[incl_index - 1]);
270 func_addr = sym->n_value;
272 break;
274 /* line number info */
275 case N_SLINE:
276 pc = sym->n_value + func_addr;
278 last_pc = pc;
279 last_line_num = sym->n_desc;
281 /* XXX: slow! */
282 strcpy(last_func_name, func_name);
284 coff_sec->s_nlnno++;
285 file_pointer += LINESZ;
286 break;
287 /* include files */
288 case N_BINCL:
289 str =
290 (const char *) stabstr_section->data + sym->n_strx;
291 add_incl:
292 if (incl_index < INCLUDE_STACK_SIZE) {
293 incl_files[incl_index++] = str;
295 break;
296 case N_EINCL:
297 if (incl_index > 1)
298 incl_index--;
299 break;
300 case N_SO:
301 if (sym->n_strx == 0) {
302 incl_index = 0; /* end of translation unit */
303 } else {
304 str =
305 (const char *) stabstr_section->data +
306 sym->n_strx;
307 /* do not add path */
308 len = strlen(str);
309 if (len > 0 && str[len - 1] != '/')
310 goto add_incl;
312 break;
314 sym++;
320 file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
322 if (do_debug)
323 file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
324 else
325 file_hdr.f_nsyms = 0;
327 file_pointer += file_hdr.f_nsyms * SYMNMLEN;
329 // OK now we are all set to write the file
332 fwrite(&file_hdr, FILHSZ, 1, f);
333 fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
335 // write section headers
336 for (i = 1; i < s1->nb_sections; i++) {
337 coff_sec = &section_header[i];
338 tcc_sect = s1->sections[i];
340 if (OutputTheSection(tcc_sect)) {
341 fwrite(coff_sec, sizeof(SCNHDR), 1, f);
345 // write raw data
346 for (i = 1; i < s1->nb_sections; i++) {
347 coff_sec = &section_header[i];
348 tcc_sect = s1->sections[i];
350 if (OutputTheSection(tcc_sect)) {
351 fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
355 // write relocation data
356 for (i = 1; i < s1->nb_sections; i++) {
357 coff_sec = &section_header[i];
358 tcc_sect = s1->sections[i];
360 if (OutputTheSection(tcc_sect)) {
361 // put relocations data
362 if (coff_sec->s_nreloc > 0) {
363 fwrite(tcc_sect->reloc,
364 coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
370 // group the symbols in order of filename, func1, func2, etc
371 // finally global symbols
373 if (do_debug)
374 SortSymbolTable();
376 // write line no data
378 for (i = 1; i < s1->nb_sections; i++) {
379 coff_sec = &section_header[i];
380 tcc_sect = s1->sections[i];
382 if (do_debug && tcc_sect == stext) {
383 // count how many line nos data
386 Stab_Sym *sym, *sym_end;
387 char func_name[128], last_func_name[128];
388 unsigned long func_addr, last_pc, pc;
389 const char *incl_files[INCLUDE_STACK_SIZE];
390 int incl_index, len, last_line_num;
391 const char *str, *p;
393 LINENO CoffLineNo;
395 func_name[0] = '\0';
396 func_addr = 0;
397 incl_index = 0;
398 last_func_name[0] = '\0';
399 last_pc = 0;
400 last_line_num = 1;
401 sym = (Stab_Sym *) stab_section->data + 1;
402 sym_end =
403 (Stab_Sym *) (stab_section->data +
404 stab_section->data_offset);
406 while (sym < sym_end) {
407 switch (sym->n_type) {
408 /* function start or end */
409 case N_FUN:
410 if (sym->n_strx == 0) {
411 // end of function
413 CoffLineNo.l_addr.l_paddr = last_pc;
414 CoffLineNo.l_lnno = last_line_num + 1;
415 fwrite(&CoffLineNo, 6, 1, f);
417 pc = sym->n_value + func_addr;
418 func_name[0] = '\0';
419 func_addr = 0;
420 } else {
421 // beginning of function
423 str =
424 (const char *) stabstr_section->data +
425 sym->n_strx;
428 p = strchr(str, ':');
429 if (!p) {
430 pstrcpy(func_name, sizeof(func_name), str);
431 } else {
432 len = p - str;
433 if (len > sizeof(func_name) - 1)
434 len = sizeof(func_name) - 1;
435 memcpy(func_name, str, len);
436 func_name[len] = '\0';
438 func_addr = sym->n_value;
439 last_pc = func_addr;
440 last_line_num = -1;
442 // output a function begin
444 CoffLineNo.l_addr.l_symndx =
445 FindCoffSymbolIndex(func_name);
446 CoffLineNo.l_lnno = 0;
448 fwrite(&CoffLineNo, 6, 1, f);
450 break;
452 /* line number info */
453 case N_SLINE:
454 pc = sym->n_value + func_addr;
457 /* XXX: slow! */
458 strcpy(last_func_name, func_name);
460 // output a line reference
462 CoffLineNo.l_addr.l_paddr = last_pc;
464 if (last_line_num == -1) {
465 CoffLineNo.l_lnno = sym->n_desc;
466 } else {
467 CoffLineNo.l_lnno = last_line_num + 1;
470 fwrite(&CoffLineNo, 6, 1, f);
472 last_pc = pc;
473 last_line_num = sym->n_desc;
475 break;
477 /* include files */
478 case N_BINCL:
479 str =
480 (const char *) stabstr_section->data + sym->n_strx;
481 add_incl2:
482 if (incl_index < INCLUDE_STACK_SIZE) {
483 incl_files[incl_index++] = str;
485 break;
486 case N_EINCL:
487 if (incl_index > 1)
488 incl_index--;
489 break;
490 case N_SO:
491 if (sym->n_strx == 0) {
492 incl_index = 0; /* end of translation unit */
493 } else {
494 str =
495 (const char *) stabstr_section->data +
496 sym->n_strx;
497 /* do not add path */
498 len = strlen(str);
499 if (len > 0 && str[len - 1] != '/')
500 goto add_incl2;
502 break;
504 sym++;
509 // write symbol table
510 if (do_debug) {
511 int k;
512 struct syment csym;
513 AUXFUNC auxfunc;
514 AUXBF auxbf;
515 AUXEF auxef;
516 int i;
517 Elf32_Sym *p;
518 char *name;
519 char _name[MAX_FUNCS];
520 int nstr;
521 int n = 0;
523 Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
524 pCoff_str_table = Coff_str_table;
525 nstr = 0;
527 p = (Elf32_Sym *) symtab_section->data;
530 for (i = 0; i < nb_syms; i++) {
532 /* don't add underscores for Code Composer Version 2.xx */
534 #define ADD_UNDERSCORE 0
536 name = (char *) symtab_section->link->data + p->st_name;
538 #if ADD_UNDERSCORE
539 _name[0] = '_';
540 strcpy(_name + 1, name);
541 #else
542 strcpy(_name, name);
543 #endif
545 for (k = 0; k < 8; k++)
546 csym._n._n_name[k] = 0;
548 if (strlen(_name) <= 8) {
549 strcpy(csym._n._n_name, _name);
550 } else {
551 if (pCoff_str_table - Coff_str_table + strlen(_name) >
552 MAX_STR_TABLE - 1)
553 error("String table too large");
555 csym._n._n_n._n_zeroes = 0;
556 csym._n._n_n._n_offset =
557 pCoff_str_table - Coff_str_table + 4;
559 strcpy(pCoff_str_table, _name);
560 pCoff_str_table += strlen(_name) + 1; // skip over null
561 nstr++;
564 if (p->st_info == 4) {
565 // put a filename symbol
566 csym.n_value = 33; // ?????
567 csym.n_scnum = N_DEBUG;
568 csym.n_type = 0;
569 csym.n_sclass = C_FILE;
570 csym.n_numaux = 0;
571 fwrite(&csym, 18, 1, f);
572 n++;
574 } else if (p->st_info == 0x12) {
575 // find the function data
577 for (k = 0; k < nFuncs; k++) {
578 if (strcmp(name, Func[k]) == 0)
579 break;
582 if (k >= nFuncs) {
583 char s[256];
585 sprintf(s, "debug info can't find function: %s", name);
587 error(s);
589 // put a Function Name
591 csym.n_value = p->st_value; // physical address
592 csym.n_scnum = CoffTextSectionNo;
593 csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
594 csym.n_sclass = C_EXT;
595 csym.n_numaux = 1;
596 fwrite(&csym, 18, 1, f);
598 // now put aux info
600 auxfunc.tag = 0;
601 auxfunc.size = EndAddress[k] - p->st_value;
602 auxfunc.fileptr = LineNoFilePtr[k];
603 auxfunc.nextsym = n + 6; // tktk
604 auxfunc.dummy = 0;
605 fwrite(&auxfunc, 18, 1, f);
607 // put a .bf
609 strcpy(csym._n._n_name, ".bf");
610 csym.n_value = p->st_value; // physical address
611 csym.n_scnum = CoffTextSectionNo;
612 csym.n_type = 0;
613 csym.n_sclass = C_FCN;
614 csym.n_numaux = 1;
615 fwrite(&csym, 18, 1, f);
617 // now put aux info
619 auxbf.regmask = 0;
620 auxbf.lineno = 0;
621 auxbf.nentries = FuncEntries[k];
622 auxbf.localframe = 0;
623 auxbf.nextentry = n + 6;
624 auxbf.dummy = 0;
625 fwrite(&auxbf, 18, 1, f);
627 // put a .ef
629 strcpy(csym._n._n_name, ".ef");
630 csym.n_value = EndAddress[k]; // physical address
631 csym.n_scnum = CoffTextSectionNo;
632 csym.n_type = 0;
633 csym.n_sclass = C_FCN;
634 csym.n_numaux = 1;
635 fwrite(&csym, 18, 1, f);
637 // now put aux info
639 auxef.dummy = 0;
640 auxef.lineno = LastLineNo[k];
641 auxef.dummy1 = 0;
642 auxef.dummy2 = 0;
643 auxef.dummy3 = 0;
644 auxef.dummy4 = 0;
645 fwrite(&auxef, 18, 1, f);
647 n += 6;
649 } else {
650 // try an put some type info
652 if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
653 csym.n_type = T_DOUBLE; // int
654 csym.n_sclass = C_EXT;
655 } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
656 csym.n_type = T_FLOAT;
657 csym.n_sclass = C_EXT;
658 } else if ((p->st_other & VT_BTYPE) == VT_INT) {
659 csym.n_type = T_INT; // int
660 csym.n_sclass = C_EXT;
661 } else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
662 csym.n_type = T_SHORT;
663 csym.n_sclass = C_EXT;
664 } else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
665 csym.n_type = T_CHAR;
666 csym.n_sclass = C_EXT;
667 } else {
668 csym.n_type = T_INT; // just mark as a label
669 csym.n_sclass = C_LABEL;
673 csym.n_value = p->st_value;
674 csym.n_scnum = 2;
675 csym.n_numaux = 1;
676 fwrite(&csym, 18, 1, f);
678 auxfunc.tag = 0;
679 auxfunc.size = 0x20;
680 auxfunc.fileptr = 0;
681 auxfunc.nextsym = 0;
682 auxfunc.dummy = 0;
683 fwrite(&auxfunc, 18, 1, f);
684 n++;
685 n++;
689 p++;
693 if (do_debug) {
694 // write string table
696 // first write the size
697 i = pCoff_str_table - Coff_str_table;
698 fwrite(&i, 4, 1, f);
700 // then write the strings
701 fwrite(Coff_str_table, i, 1, f);
703 tcc_free(Coff_str_table);
706 fclose(f);
708 return 0;
713 // group the symbols in order of filename, func1, func2, etc
714 // finally global symbols
716 void SortSymbolTable(void)
718 int i, j, k, n = 0;
719 Elf32_Sym *p, *p2, *NewTable;
720 char *name, *name2;
722 NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
724 p = (Elf32_Sym *) symtab_section->data;
727 // find a file symbol, copy it over
728 // then scan the whole symbol list and copy any function
729 // symbols that match the file association
731 for (i = 0; i < nb_syms; i++) {
732 if (p->st_info == 4) {
733 name = (char *) symtab_section->link->data + p->st_name;
735 // this is a file symbol, copy it over
737 NewTable[n++] = *p;
739 p2 = (Elf32_Sym *) symtab_section->data;
741 for (j = 0; j < nb_syms; j++) {
742 if (p2->st_info == 0x12) {
743 // this is a func symbol
745 name2 =
746 (char *) symtab_section->link->data + p2->st_name;
748 // find the function data index
750 for (k = 0; k < nFuncs; k++) {
751 if (strcmp(name2, Func[k]) == 0)
752 break;
755 if (k >= nFuncs) {
756 char s[256];
758 sprintf(s,
759 "debug (sort) info can't find function: %s",
760 name2);
762 error(s);
765 if (strcmp(AssociatedFile[k], name) == 0) {
766 // yes they match copy it over
768 NewTable[n++] = *p2;
771 p2++;
774 p++;
777 // now all the filename and func symbols should have been copied over
778 // copy all the rest over (all except file and funcs)
780 p = (Elf32_Sym *) symtab_section->data;
781 for (i = 0; i < nb_syms; i++) {
782 if (p->st_info != 4 && p->st_info != 0x12) {
783 NewTable[n++] = *p;
785 p++;
788 if (n != nb_syms)
789 error("Internal Compiler error, debug info");
791 // copy it all back
793 p = (Elf32_Sym *) symtab_section->data;
794 for (i = 0; i < nb_syms; i++) {
795 *p++ = NewTable[i];
798 tcc_free(NewTable);
802 int FindCoffSymbolIndex(const char *func_name)
804 int i, n = 0;
805 Elf32_Sym *p;
806 char *name;
808 p = (Elf32_Sym *) symtab_section->data;
810 for (i = 0; i < nb_syms; i++) {
812 name = (char *) symtab_section->link->data + p->st_name;
814 if (p->st_info == 4) {
815 // put a filename symbol
816 n++;
817 } else if (p->st_info == 0x12) {
819 if (strcmp(func_name, name) == 0)
820 return n;
822 n += 6;
824 // put a Function Name
826 // now put aux info
828 // put a .bf
830 // now put aux info
832 // put a .ef
834 // now put aux info
836 } else {
837 n += 2;
840 p++;
843 return n; // total number of symbols
851 BOOL OutputTheSection(Section * sect)
853 const char *s = sect->name;
855 if (s == ".text")
856 return true;
857 else if (s == ".data")
858 return true;
859 else
860 return 0;
863 short int GetCoffFlags(const char *s)
865 if (s == ".text")
866 return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
867 else if (s == ".data")
868 return STYP_DATA;
869 else if (s == ".bss")
870 return STYP_BSS;
871 else if (s == ".stack")
872 return STYP_BSS | STYP_ALIGN | 0x200;
873 else if (s == ".cinit")
874 return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
875 else
876 return 0;
879 Section *FindSection(TCCState * s1, const char *sname)
881 Section *s;
882 int i;
884 for (i = 1; i < s1->nb_sections; i++) {
885 s = s1->sections[i];
887 if (!strcmp(sname, s->name))
888 return s;
891 error("could not find section %s", sname);
892 return 0;
895 int tcc_load_coff(TCCState * s1, int fd)
897 // tktk TokenSym *ts;
899 FILE *f;
900 unsigned int str_size;
901 char *Coff_str_table, *name;
902 int i, k;
903 struct syment csym;
904 char name2[9];
905 FILHDR file_hdr; /* FILE HEADER STRUCTURE */
907 f = fdopen(fd, "rb");
908 if (!f) {
909 error("Unable to open .out file for input");
912 if (fread(&file_hdr, FILHSZ, 1, f) != 1)
913 error("error reading .out file for input");
915 if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
916 error("error reading .out file for input");
918 // first read the string table
920 if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
921 error("error reading .out file for input");
923 if (fread(&str_size, sizeof(int), 1, f) != 1)
924 error("error reading .out file for input");
927 Coff_str_table = (char *) tcc_malloc(str_size);
929 if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
930 error("error reading .out file for input");
932 // read/process all the symbols
934 // seek back to symbols
936 if (fseek(f, file_hdr.f_symptr, SEEK_SET))
937 error("error reading .out file for input");
939 for (i = 0; i < file_hdr.f_nsyms; i++) {
940 if (fread(&csym, SYMESZ, 1, f) != 1)
941 error("error reading .out file for input");
943 if (csym._n._n_n._n_zeroes == 0) {
944 name = Coff_str_table + csym._n._n_n._n_offset - 4;
945 } else {
946 name = csym._n._n_name;
948 if (name[7] != 0) {
949 for (k = 0; k < 8; k++)
950 name2[k] = name[k];
952 name2[8] = 0;
954 name = name2;
957 // if (strcmp("_DAC_Buffer",name)==0) // tktk
958 // name[0]=0;
960 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
961 (csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure
962 (csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
963 (csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
965 // strip off any leading underscore (except for other main routine)
967 if (name[0] == '_' && strcmp(name, "_main") != 0)
968 name++;
970 tcc_add_symbol(s1, name, csym.n_value);
972 // skip any aux records
974 if (csym.n_numaux == 1) {
975 if (fread(&csym, SYMESZ, 1, f) != 1)
976 error("error reading .out file for input");
977 i++;
981 return 0;