2 * COFF file handling for TCC
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
24 #define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
25 #define MAX_STR_TABLE 1000000
26 AOUTHDR o_filehdr
; /* OPTIONAL (A.OUT) FILE HEADER */
28 SCNHDR section_header
[MAXNSCNS
];
30 #define MAX_FUNCS 1000
31 #define MAX_FUNC_NAME_LENGTH 128
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
];
41 int OutputTheSection(Section
* sect
);
42 short int GetCoffFlags(const char *s
);
43 void SortSymbolTable(void);
44 Section
*FindSection(TCCState
* s1
, const char *sname
);
46 int C67_main_entry_point
;
48 int FindCoffSymbolIndex(const char *func_name
);
61 unsigned short lineno
;
62 unsigned short nentries
;
70 unsigned short lineno
;
71 unsigned short dummy1
;
74 unsigned short dummy4
;
77 ST_FUNC
int tcc_output_coff(TCCState
*s1
, FILE *f
)
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;
88 Coff_str_table
= pCoff_str_table
= NULL
;
90 stext
= FindSection(s1
, ".text");
91 sdata
= FindSection(s1
, ".data");
92 sbss
= FindSection(s1
, ".bss");
94 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
95 coff_nb_syms
= FindCoffSymbolIndex("XXXXXXXXXX1");
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 */
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 */
113 // create all the section headers
115 file_pointer
= FILHSZ
+ sizeof(AOUTHDR
);
117 CoffTextSectionNo
= -1;
119 for (i
= 1; i
< s1
->nb_sections
; i
++) {
120 coff_sec
= §ion_header
[i
];
121 tcc_sect
= s1
->sections
[i
];
123 if (OutputTheSection(tcc_sect
)) {
126 if (CoffTextSectionNo
== -1 && tcc_sect
== stext
)
127 CoffTextSectionNo
= NSectionsToOutput
; // rem which coff sect number the .text sect is
129 strcpy(coff_sec
->s_name
, tcc_sect
->name
); /* section name */
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 */
142 file_pointer
+= sizeof(SCNHDR
);
146 file_hdr
.f_nscns
= NSectionsToOutput
; /* number of sections */
148 // now loop through and determine file pointer locations
152 for (i
= 1; i
< s1
->nb_sections
; i
++) {
153 coff_sec
= §ion_header
[i
];
154 tcc_sect
= s1
->sections
[i
];
156 if (OutputTheSection(tcc_sect
)) {
158 coff_sec
->s_scnptr
= file_pointer
; /* file ptr to raw data for section */
159 file_pointer
+= coff_sec
->s_size
;
163 // now loop through and determine file pointer locations
164 // for the relocation data
166 for (i
= 1; i
< s1
->nb_sections
; i
++) {
167 coff_sec
= §ion_header
[i
];
168 tcc_sect
= s1
->sections
[i
];
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
);
179 // now loop through and determine file pointer locations
180 // for the line number data
182 for (i
= 1; i
< s1
->nb_sections
; i
++) {
183 coff_sec
= §ion_header
[i
];
184 tcc_sect
= s1
->sections
[i
];
186 coff_sec
->s_nlnno
= 0;
187 coff_sec
->s_lnnoptr
= 0;
189 if (s1
->do_debug
&& tcc_sect
== stext
) {
190 // count how many line nos data
192 // also find association between source file name and function
193 // so we can sort the symbol table
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
;
204 coff_sec
->s_lnnoptr
= file_pointer
; /* file ptr to linno */
210 last_func_name
[0] = '\0';
211 last_pc
= 0xffffffff;
213 sym
= (Stab_Sym
*) stab_section
->data
+ 1;
215 (Stab_Sym
*) (stab_section
->data
+
216 stab_section
->data_offset
);
219 while (sym
< sym_end
) {
220 switch (sym
->n_type
) {
221 /* function start or end */
223 if (sym
->n_strx
== 0) {
227 file_pointer
+= LINESZ
;
229 pc
= sym
->n_value
+ func_addr
;
232 EndAddress
[nFuncs
] = pc
;
233 FuncEntries
[nFuncs
] =
235 LineNoFilePtr
[nFuncs
]) / LINESZ
- 1;
236 LastLineNo
[nFuncs
++] = last_line_num
+ 1;
238 // beginning of function
240 LineNoFilePtr
[nFuncs
] = file_pointer
;
242 file_pointer
+= LINESZ
;
245 (const char *) stabstr_section
->data
+
248 p
= strchr(str
, ':');
250 pstrcpy(func_name
, sizeof(func_name
), str
);
251 pstrcpy(Func
[nFuncs
], sizeof(func_name
), 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';
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]);
265 func_addr
= sym
->n_value
;
269 /* line number info */
271 pc
= sym
->n_value
+ func_addr
;
274 last_line_num
= sym
->n_desc
;
277 strcpy(last_func_name
, func_name
);
280 file_pointer
+= LINESZ
;
285 (const char *) stabstr_section
->data
+ sym
->n_strx
;
287 if (incl_index
< INCLUDE_STACK_SIZE
) {
288 incl_files
[incl_index
++] = str
;
296 if (sym
->n_strx
== 0) {
297 incl_index
= 0; /* end of translation unit */
300 (const char *) stabstr_section
->data
+
302 /* do not add path */
304 if (len
> 0 && str
[len
- 1] != '/')
315 file_hdr
.f_symptr
= file_pointer
; /* file pointer to symtab */
318 file_hdr
.f_nsyms
= coff_nb_syms
; /* number of symtab entries */
320 file_hdr
.f_nsyms
= 0;
322 file_pointer
+= file_hdr
.f_nsyms
* SYMNMLEN
;
324 // OK now we are all set to write the file
327 fwrite(&file_hdr
, FILHSZ
, 1, f
);
328 fwrite(&o_filehdr
, sizeof(o_filehdr
), 1, f
);
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
];
335 if (OutputTheSection(tcc_sect
)) {
336 fwrite(coff_sec
, sizeof(SCNHDR
), 1, f
);
341 for (i
= 1; i
< s1
->nb_sections
; i
++) {
342 coff_sec
= §ion_header
[i
];
343 tcc_sect
= s1
->sections
[i
];
345 if (OutputTheSection(tcc_sect
)) {
346 fwrite(tcc_sect
->data
, tcc_sect
->data_offset
, 1, f
);
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
];
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
);
365 // group the symbols in order of filename, func1, func2, etc
366 // finally global symbols
371 // write line no data
373 for (i
= 1; i
< s1
->nb_sections
; i
++) {
374 coff_sec
= §ion_header
[i
];
375 tcc_sect
= s1
->sections
[i
];
377 if (s1
->do_debug
&& tcc_sect
== stext
) {
378 // count how many line nos data
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
;
393 last_func_name
[0] = '\0';
396 sym
= (Stab_Sym
*) stab_section
->data
+ 1;
398 (Stab_Sym
*) (stab_section
->data
+
399 stab_section
->data_offset
);
401 while (sym
< sym_end
) {
402 switch (sym
->n_type
) {
403 /* function start or end */
405 if (sym
->n_strx
== 0) {
408 CoffLineNo
.l_addr
.l_paddr
= last_pc
;
409 CoffLineNo
.l_lnno
= last_line_num
+ 1;
410 fwrite(&CoffLineNo
, 6, 1, f
);
412 pc
= sym
->n_value
+ func_addr
;
416 // beginning of function
419 (const char *) stabstr_section
->data
+
423 p
= strchr(str
, ':');
425 pstrcpy(func_name
, sizeof(func_name
), 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';
433 func_addr
= sym
->n_value
;
437 // output a function begin
439 CoffLineNo
.l_addr
.l_symndx
=
440 FindCoffSymbolIndex(func_name
);
441 CoffLineNo
.l_lnno
= 0;
443 fwrite(&CoffLineNo
, 6, 1, f
);
447 /* line number info */
449 pc
= sym
->n_value
+ func_addr
;
453 strcpy(last_func_name
, func_name
);
455 // output a line reference
457 CoffLineNo
.l_addr
.l_paddr
= last_pc
;
459 if (last_line_num
== -1) {
460 CoffLineNo
.l_lnno
= sym
->n_desc
;
462 CoffLineNo
.l_lnno
= last_line_num
+ 1;
465 fwrite(&CoffLineNo
, 6, 1, f
);
468 last_line_num
= sym
->n_desc
;
475 (const char *) stabstr_section
->data
+ sym
->n_strx
;
477 if (incl_index
< INCLUDE_STACK_SIZE
) {
478 incl_files
[incl_index
++] = str
;
486 if (sym
->n_strx
== 0) {
487 incl_index
= 0; /* end of translation unit */
490 (const char *) stabstr_section
->data
+
492 /* do not add path */
494 if (len
> 0 && str
[len
- 1] != '/')
504 // write symbol table
517 Coff_str_table
= (char *) tcc_malloc(MAX_STR_TABLE
);
518 pCoff_str_table
= Coff_str_table
;
521 p
= (Elf32_Sym
*) symtab_section
->data
;
524 for (i
= 0; i
< nb_syms
; i
++) {
526 name
= symtab_section
->link
->data
+ p
->st_name
;
528 for (k
= 0; k
< 8; k
++)
529 csym
._n
._n_name
[k
] = 0;
531 if (strlen(name
) <= 8) {
532 strcpy(csym
._n
._n_name
, name
);
534 if (pCoff_str_table
- Coff_str_table
+ strlen(name
) >
536 tcc_error("String table too large");
538 csym
._n
._n_n
._n_zeroes
= 0;
539 csym
._n
._n_n
._n_offset
=
540 pCoff_str_table
- Coff_str_table
+ 4;
542 strcpy(pCoff_str_table
, name
);
543 pCoff_str_table
+= strlen(name
) + 1; // skip over null
547 if (p
->st_info
== 4) {
548 // put a filename symbol
549 csym
.n_value
= 33; // ?????
550 csym
.n_scnum
= N_DEBUG
;
552 csym
.n_sclass
= C_FILE
;
554 fwrite(&csym
, 18, 1, f
);
557 } else if (p
->st_info
== 0x12) {
558 // find the function data
560 for (k
= 0; k
< nFuncs
; k
++) {
561 if (strcmp(name
, Func
[k
]) == 0)
566 tcc_error("debug info can't find function: %s", name
);
568 // put a Function Name
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
;
575 fwrite(&csym
, 18, 1, f
);
580 auxfunc
.size
= EndAddress
[k
] - p
->st_value
;
581 auxfunc
.fileptr
= LineNoFilePtr
[k
];
582 auxfunc
.nextsym
= n
+ 6; // tktk
584 fwrite(&auxfunc
, 18, 1, f
);
588 strcpy(csym
._n
._n_name
, ".bf");
589 csym
.n_value
= p
->st_value
; // physical address
590 csym
.n_scnum
= CoffTextSectionNo
;
592 csym
.n_sclass
= C_FCN
;
594 fwrite(&csym
, 18, 1, f
);
600 auxbf
.nentries
= FuncEntries
[k
];
601 auxbf
.localframe
= 0;
602 auxbf
.nextentry
= n
+ 6;
604 fwrite(&auxbf
, 18, 1, f
);
608 strcpy(csym
._n
._n_name
, ".ef");
609 csym
.n_value
= EndAddress
[k
]; // physical address
610 csym
.n_scnum
= CoffTextSectionNo
;
612 csym
.n_sclass
= C_FCN
;
614 fwrite(&csym
, 18, 1, f
);
619 auxef
.lineno
= LastLineNo
[k
];
624 fwrite(&auxef
, 18, 1, f
);
629 // try an put some type info
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
;
647 csym
.n_type
= T_INT
; // just mark as a label
648 csym
.n_sclass
= C_LABEL
;
652 csym
.n_value
= p
->st_value
;
655 fwrite(&csym
, 18, 1, f
);
662 fwrite(&auxfunc
, 18, 1, f
);
673 // write string table
675 // first write the size
676 i
= pCoff_str_table
- Coff_str_table
;
679 // then write the strings
680 fwrite(Coff_str_table
, i
, 1, f
);
682 tcc_free(Coff_str_table
);
690 // group the symbols in order of filename, func1, func2, etc
691 // finally global symbols
693 void SortSymbolTable(void)
696 Elf32_Sym
*p
, *p2
, *NewTable
;
699 NewTable
= (Elf32_Sym
*) tcc_malloc(nb_syms
* sizeof(Elf32_Sym
));
701 p
= (Elf32_Sym
*) symtab_section
->data
;
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
708 for (i
= 0; i
< nb_syms
; i
++) {
709 if (p
->st_info
== 4) {
710 name
= (char *) symtab_section
->link
->data
+ p
->st_name
;
712 // this is a file symbol, copy it over
716 p2
= (Elf32_Sym
*) symtab_section
->data
;
718 for (j
= 0; j
< nb_syms
; j
++) {
719 if (p2
->st_info
== 0x12) {
720 // this is a func symbol
723 (char *) symtab_section
->link
->data
+ p2
->st_name
;
725 // find the function data index
727 for (k
= 0; k
< nFuncs
; k
++) {
728 if (strcmp(name2
, Func
[k
]) == 0)
733 tcc_error("debug (sort) info can't find function: %s", name2
);
736 if (strcmp(AssociatedFile
[k
], name
) == 0) {
737 // yes they match copy it over
748 // now all the filename and func symbols should have been copied over
749 // copy all the rest over (all except file and funcs)
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) {
760 tcc_error("Internal Compiler error, debug info");
764 p
= (Elf32_Sym
*) symtab_section
->data
;
765 for (i
= 0; i
< nb_syms
; i
++) {
773 int FindCoffSymbolIndex(const char *func_name
)
779 p
= (Elf32_Sym
*) symtab_section
->data
;
781 for (i
= 0; i
< nb_syms
; i
++) {
783 name
= (char *) symtab_section
->link
->data
+ p
->st_name
;
785 if (p
->st_info
== 4) {
786 // put a filename symbol
788 } else if (p
->st_info
== 0x12) {
790 if (strcmp(func_name
, name
) == 0)
795 // put a Function Name
814 return n
; // total number of symbols
817 int OutputTheSection(Section
* sect
)
819 const char *s
= sect
->name
;
821 if (!strcmp(s
, ".text"))
823 else if (!strcmp(s
, ".data"))
829 short int GetCoffFlags(const char *s
)
831 if (!strcmp(s
, ".text"))
832 return STYP_TEXT
| STYP_DATA
| STYP_ALIGN
| 0x400;
833 else if (!strcmp(s
, ".data"))
835 else if (!strcmp(s
, ".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;
845 Section
*FindSection(TCCState
* s1
, const char *sname
)
850 for (i
= 1; i
< s1
->nb_sections
; i
++) {
853 if (!strcmp(sname
, s
->name
))
857 tcc_error("could not find section %s", sname
);
861 ST_FUNC
int tcc_load_coff(TCCState
* s1
, int fd
)
863 // tktk TokenSym *ts;
866 unsigned int str_size
;
867 char *Coff_str_table
, *name
;
871 FILHDR file_hdr
; /* FILE HEADER STRUCTURE */
873 f
= fdopen(fd
, "rb");
875 tcc_error("Unable to open .out file for input");
878 if (fread(&file_hdr
, FILHSZ
, 1, f
) != 1)
879 tcc_error("error reading .out file for input");
881 if (fread(&o_filehdr
, sizeof(o_filehdr
), 1, f
) != 1)
882 tcc_error("error reading .out file for input");
884 // first read the string table
886 if (fseek(f
, file_hdr
.f_symptr
+ file_hdr
.f_nsyms
* SYMESZ
, SEEK_SET
))
887 tcc_error("error reading .out file for input");
889 if (fread(&str_size
, sizeof(int), 1, f
) != 1)
890 tcc_error("error reading .out file for input");
893 Coff_str_table
= (char *) tcc_malloc(str_size
);
895 if (fread(Coff_str_table
, str_size
- 4, 1, f
) != 1)
896 tcc_error("error reading .out file for input");
898 // read/process all the symbols
900 // seek back to symbols
902 if (fseek(f
, file_hdr
.f_symptr
, SEEK_SET
))
903 tcc_error("error reading .out file for input");
905 for (i
= 0; i
< file_hdr
.f_nsyms
; i
++) {
906 if (fread(&csym
, SYMESZ
, 1, f
) != 1)
907 tcc_error("error reading .out file for input");
909 if (csym
._n
._n_n
._n_zeroes
== 0) {
910 name
= Coff_str_table
+ csym
._n
._n_n
._n_offset
- 4;
912 name
= csym
._n
._n_name
;
915 for (k
= 0; k
< 8; k
++)
923 // if (strcmp("_DAC_Buffer",name)==0) // tktk
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
931 // strip off any leading underscore (except for other main routine)
933 if (name
[0] == '_' && strcmp(name
, "_main") != 0)
936 tcc_add_symbol(s1
, name
, (void*)(uintptr_t)csym
.n_value
);
938 // skip any aux records
940 if (csym
.n_numaux
== 1) {
941 if (fread(&csym
, SYMESZ
, 1, f
) != 1)
942 tcc_error("error reading .out file for input");