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
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
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
);
60 unsigned short lineno
;
61 unsigned short nentries
;
69 unsigned short lineno
;
70 unsigned short dummy1
;
73 unsigned short dummy4
;
76 int tcc_output_coff(TCCState
*s1
, FILE *f
)
81 char *Coff_str_table
, *pCoff_str_table
;
82 int CoffTextSectionNo
, coff_nb_syms
;
83 FILHDR file_hdr
; /* FILE HEADER STRUCTURE */
84 Section
*stext
, *sdata
, *sbss
;
85 int i
, NSectionsToOutput
= 0;
87 Coff_str_table
= pCoff_str_table
= NULL
;
89 stext
= FindSection(s1
, ".text");
90 sdata
= FindSection(s1
, ".data");
91 sbss
= FindSection(s1
, ".bss");
93 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
94 coff_nb_syms
= FindCoffSymbolIndex("XXXXXXXXXX1");
96 file_hdr
.f_magic
= COFF_C67_MAGIC
; /* magic number */
97 file_hdr
.f_timdat
= 0; /* time & date stamp */
98 file_hdr
.f_opthdr
= sizeof(AOUTHDR
); /* sizeof(optional hdr) */
99 file_hdr
.f_flags
= 0x1143; /* flags (copied from what code composer does) */
100 file_hdr
.f_TargetID
= 0x99; /* for C6x = 0x0099 */
102 o_filehdr
.magic
= 0x0108; /* see magic.h */
103 o_filehdr
.vstamp
= 0x0190; /* version stamp */
104 o_filehdr
.tsize
= stext
->data_offset
; /* text size in bytes, padded to FW bdry */
105 o_filehdr
.dsize
= sdata
->data_offset
; /* initialized data " " */
106 o_filehdr
.bsize
= sbss
->data_offset
; /* uninitialized data " " */
107 o_filehdr
.entrypt
= C67_main_entry_point
; /* entry pt. */
108 o_filehdr
.text_start
= stext
->sh_addr
; /* base of text used for this file */
109 o_filehdr
.data_start
= sdata
->sh_addr
; /* base of data used for this file */
112 // create all the section headers
114 file_pointer
= FILHSZ
+ sizeof(AOUTHDR
);
116 CoffTextSectionNo
= -1;
118 for (i
= 1; i
< s1
->nb_sections
; i
++) {
119 coff_sec
= §ion_header
[i
];
120 tcc_sect
= s1
->sections
[i
];
122 if (OutputTheSection(tcc_sect
)) {
125 if (CoffTextSectionNo
== -1 && tcc_sect
== stext
)
126 CoffTextSectionNo
= NSectionsToOutput
; // rem which coff sect number the .text sect is
128 strcpy(coff_sec
->s_name
, tcc_sect
->name
); /* section name */
130 coff_sec
->s_paddr
= tcc_sect
->sh_addr
; /* physical address */
131 coff_sec
->s_vaddr
= tcc_sect
->sh_addr
; /* virtual address */
132 coff_sec
->s_size
= tcc_sect
->data_offset
; /* section size */
133 coff_sec
->s_scnptr
= 0; /* file ptr to raw data for section */
134 coff_sec
->s_relptr
= 0; /* file ptr to relocation */
135 coff_sec
->s_lnnoptr
= 0; /* file ptr to line numbers */
136 coff_sec
->s_nreloc
= 0; /* number of relocation entries */
137 coff_sec
->s_flags
= GetCoffFlags(coff_sec
->s_name
); /* flags */
138 coff_sec
->s_reserved
= 0; /* reserved byte */
139 coff_sec
->s_page
= 0; /* memory page id */
141 file_pointer
+= sizeof(SCNHDR
);
145 file_hdr
.f_nscns
= NSectionsToOutput
; /* number of sections */
147 // now loop through and determine file pointer locations
151 for (i
= 1; i
< s1
->nb_sections
; i
++) {
152 coff_sec
= §ion_header
[i
];
153 tcc_sect
= s1
->sections
[i
];
155 if (OutputTheSection(tcc_sect
)) {
157 coff_sec
->s_scnptr
= file_pointer
; /* file ptr to raw data for section */
158 file_pointer
+= coff_sec
->s_size
;
162 // now loop through and determine file pointer locations
163 // for the relocation data
165 for (i
= 1; i
< s1
->nb_sections
; i
++) {
166 coff_sec
= §ion_header
[i
];
167 tcc_sect
= s1
->sections
[i
];
169 if (OutputTheSection(tcc_sect
)) {
170 // put relocations data
171 if (coff_sec
->s_nreloc
> 0) {
172 coff_sec
->s_relptr
= file_pointer
; /* file ptr to relocation */
173 file_pointer
+= coff_sec
->s_nreloc
* sizeof(struct reloc
);
178 // now loop through and determine file pointer locations
179 // for the line number data
181 for (i
= 1; i
< s1
->nb_sections
; i
++) {
182 coff_sec
= §ion_header
[i
];
183 tcc_sect
= s1
->sections
[i
];
185 coff_sec
->s_nlnno
= 0;
186 coff_sec
->s_lnnoptr
= 0;
188 if (s1
->do_debug
&& tcc_sect
== stext
) {
189 // count how many line nos data
191 // also find association between source file name and function
192 // so we can sort the symbol table
195 Stab_Sym
*sym
, *sym_end
;
196 char func_name
[MAX_FUNC_NAME_LENGTH
],
197 last_func_name
[MAX_FUNC_NAME_LENGTH
];
198 unsigned long func_addr
, last_pc
, pc
;
199 const char *incl_files
[INCLUDE_STACK_SIZE
];
200 int incl_index
, len
, last_line_num
;
203 coff_sec
->s_lnnoptr
= file_pointer
; /* file ptr to linno */
209 last_func_name
[0] = '\0';
210 last_pc
= 0xffffffff;
212 sym
= (Stab_Sym
*) stab_section
->data
+ 1;
214 (Stab_Sym
*) (stab_section
->data
+
215 stab_section
->data_offset
);
218 while (sym
< sym_end
) {
219 switch (sym
->n_type
) {
220 /* function start or end */
222 if (sym
->n_strx
== 0) {
226 file_pointer
+= LINESZ
;
228 pc
= sym
->n_value
+ func_addr
;
231 EndAddress
[nFuncs
] = pc
;
232 FuncEntries
[nFuncs
] =
234 LineNoFilePtr
[nFuncs
]) / LINESZ
- 1;
235 LastLineNo
[nFuncs
++] = last_line_num
+ 1;
237 // beginning of function
239 LineNoFilePtr
[nFuncs
] = file_pointer
;
241 file_pointer
+= LINESZ
;
244 (const char *) stabstr_section
->data
+
247 p
= strchr(str
, ':');
249 pstrcpy(func_name
, sizeof(func_name
), str
);
250 pstrcpy(Func
[nFuncs
], sizeof(func_name
), str
);
253 if (len
> sizeof(func_name
) - 1)
254 len
= sizeof(func_name
) - 1;
255 memcpy(func_name
, str
, len
);
256 memcpy(Func
[nFuncs
], str
, len
);
257 func_name
[len
] = '\0';
260 // save the file that it came in so we can sort later
261 pstrcpy(AssociatedFile
[nFuncs
], sizeof(func_name
),
262 incl_files
[incl_index
- 1]);
264 func_addr
= sym
->n_value
;
268 /* line number info */
270 pc
= sym
->n_value
+ func_addr
;
273 last_line_num
= sym
->n_desc
;
276 strcpy(last_func_name
, func_name
);
279 file_pointer
+= LINESZ
;
284 (const char *) stabstr_section
->data
+ sym
->n_strx
;
286 if (incl_index
< INCLUDE_STACK_SIZE
) {
287 incl_files
[incl_index
++] = str
;
295 if (sym
->n_strx
== 0) {
296 incl_index
= 0; /* end of translation unit */
299 (const char *) stabstr_section
->data
+
301 /* do not add path */
303 if (len
> 0 && str
[len
- 1] != '/')
314 file_hdr
.f_symptr
= file_pointer
; /* file pointer to symtab */
317 file_hdr
.f_nsyms
= coff_nb_syms
; /* number of symtab entries */
319 file_hdr
.f_nsyms
= 0;
321 file_pointer
+= file_hdr
.f_nsyms
* SYMNMLEN
;
323 // OK now we are all set to write the file
326 fwrite(&file_hdr
, FILHSZ
, 1, f
);
327 fwrite(&o_filehdr
, sizeof(o_filehdr
), 1, f
);
329 // write section headers
330 for (i
= 1; i
< s1
->nb_sections
; i
++) {
331 coff_sec
= §ion_header
[i
];
332 tcc_sect
= s1
->sections
[i
];
334 if (OutputTheSection(tcc_sect
)) {
335 fwrite(coff_sec
, sizeof(SCNHDR
), 1, f
);
340 for (i
= 1; i
< s1
->nb_sections
; i
++) {
341 coff_sec
= §ion_header
[i
];
342 tcc_sect
= s1
->sections
[i
];
344 if (OutputTheSection(tcc_sect
)) {
345 fwrite(tcc_sect
->data
, tcc_sect
->data_offset
, 1, f
);
349 // write relocation data
350 for (i
= 1; i
< s1
->nb_sections
; i
++) {
351 coff_sec
= §ion_header
[i
];
352 tcc_sect
= s1
->sections
[i
];
354 if (OutputTheSection(tcc_sect
)) {
355 // put relocations data
356 if (coff_sec
->s_nreloc
> 0) {
357 fwrite(tcc_sect
->reloc
,
358 coff_sec
->s_nreloc
* sizeof(struct reloc
), 1, f
);
364 // group the symbols in order of filename, func1, func2, etc
365 // finally global symbols
370 // write line no data
372 for (i
= 1; i
< s1
->nb_sections
; i
++) {
373 coff_sec
= §ion_header
[i
];
374 tcc_sect
= s1
->sections
[i
];
376 if (s1
->do_debug
&& tcc_sect
== stext
) {
377 // count how many line nos data
380 Stab_Sym
*sym
, *sym_end
;
381 char func_name
[128], last_func_name
[128];
382 unsigned long func_addr
, last_pc
, pc
;
383 const char *incl_files
[INCLUDE_STACK_SIZE
];
384 int incl_index
, len
, last_line_num
;
392 last_func_name
[0] = '\0';
395 sym
= (Stab_Sym
*) stab_section
->data
+ 1;
397 (Stab_Sym
*) (stab_section
->data
+
398 stab_section
->data_offset
);
400 while (sym
< sym_end
) {
401 switch (sym
->n_type
) {
402 /* function start or end */
404 if (sym
->n_strx
== 0) {
407 CoffLineNo
.l_addr
.l_paddr
= last_pc
;
408 CoffLineNo
.l_lnno
= last_line_num
+ 1;
409 fwrite(&CoffLineNo
, 6, 1, f
);
411 pc
= sym
->n_value
+ func_addr
;
415 // beginning of function
418 (const char *) stabstr_section
->data
+
422 p
= strchr(str
, ':');
424 pstrcpy(func_name
, sizeof(func_name
), str
);
427 if (len
> sizeof(func_name
) - 1)
428 len
= sizeof(func_name
) - 1;
429 memcpy(func_name
, str
, len
);
430 func_name
[len
] = '\0';
432 func_addr
= sym
->n_value
;
436 // output a function begin
438 CoffLineNo
.l_addr
.l_symndx
=
439 FindCoffSymbolIndex(func_name
);
440 CoffLineNo
.l_lnno
= 0;
442 fwrite(&CoffLineNo
, 6, 1, f
);
446 /* line number info */
448 pc
= sym
->n_value
+ func_addr
;
452 strcpy(last_func_name
, func_name
);
454 // output a line reference
456 CoffLineNo
.l_addr
.l_paddr
= last_pc
;
458 if (last_line_num
== -1) {
459 CoffLineNo
.l_lnno
= sym
->n_desc
;
461 CoffLineNo
.l_lnno
= last_line_num
+ 1;
464 fwrite(&CoffLineNo
, 6, 1, f
);
467 last_line_num
= sym
->n_desc
;
474 (const char *) stabstr_section
->data
+ sym
->n_strx
;
476 if (incl_index
< INCLUDE_STACK_SIZE
) {
477 incl_files
[incl_index
++] = str
;
485 if (sym
->n_strx
== 0) {
486 incl_index
= 0; /* end of translation unit */
489 (const char *) stabstr_section
->data
+
491 /* do not add path */
493 if (len
> 0 && str
[len
- 1] != '/')
503 // write symbol table
516 Coff_str_table
= (char *) tcc_malloc(MAX_STR_TABLE
);
517 pCoff_str_table
= Coff_str_table
;
520 p
= (Elf32_Sym
*) symtab_section
->data
;
523 for (i
= 0; i
< nb_syms
; i
++) {
525 name
= symtab_section
->link
->data
+ p
->st_name
;
527 for (k
= 0; k
< 8; k
++)
528 csym
._n
._n_name
[k
] = 0;
530 if (strlen(name
) <= 8) {
531 strcpy(csym
._n
._n_name
, name
);
533 if (pCoff_str_table
- Coff_str_table
+ strlen(name
) >
535 error("String table too large");
537 csym
._n
._n_n
._n_zeroes
= 0;
538 csym
._n
._n_n
._n_offset
=
539 pCoff_str_table
- Coff_str_table
+ 4;
541 strcpy(pCoff_str_table
, name
);
542 pCoff_str_table
+= strlen(name
) + 1; // skip over null
546 if (p
->st_info
== 4) {
547 // put a filename symbol
548 csym
.n_value
= 33; // ?????
549 csym
.n_scnum
= N_DEBUG
;
551 csym
.n_sclass
= C_FILE
;
553 fwrite(&csym
, 18, 1, f
);
556 } else if (p
->st_info
== 0x12) {
557 // find the function data
559 for (k
= 0; k
< nFuncs
; k
++) {
560 if (strcmp(name
, Func
[k
]) == 0)
567 sprintf(s
, "debug info can't find function: %s", name
);
571 // put a Function Name
573 csym
.n_value
= p
->st_value
; // physical address
574 csym
.n_scnum
= CoffTextSectionNo
;
575 csym
.n_type
= MKTYPE(T_INT
, DT_FCN
, 0, 0, 0, 0, 0);
576 csym
.n_sclass
= C_EXT
;
578 fwrite(&csym
, 18, 1, f
);
583 auxfunc
.size
= EndAddress
[k
] - p
->st_value
;
584 auxfunc
.fileptr
= LineNoFilePtr
[k
];
585 auxfunc
.nextsym
= n
+ 6; // tktk
587 fwrite(&auxfunc
, 18, 1, f
);
591 strcpy(csym
._n
._n_name
, ".bf");
592 csym
.n_value
= p
->st_value
; // physical address
593 csym
.n_scnum
= CoffTextSectionNo
;
595 csym
.n_sclass
= C_FCN
;
597 fwrite(&csym
, 18, 1, f
);
603 auxbf
.nentries
= FuncEntries
[k
];
604 auxbf
.localframe
= 0;
605 auxbf
.nextentry
= n
+ 6;
607 fwrite(&auxbf
, 18, 1, f
);
611 strcpy(csym
._n
._n_name
, ".ef");
612 csym
.n_value
= EndAddress
[k
]; // physical address
613 csym
.n_scnum
= CoffTextSectionNo
;
615 csym
.n_sclass
= C_FCN
;
617 fwrite(&csym
, 18, 1, f
);
622 auxef
.lineno
= LastLineNo
[k
];
627 fwrite(&auxef
, 18, 1, f
);
632 // try an put some type info
634 if ((p
->st_other
& VT_BTYPE
) == VT_DOUBLE
) {
635 csym
.n_type
= T_DOUBLE
; // int
636 csym
.n_sclass
= C_EXT
;
637 } else if ((p
->st_other
& VT_BTYPE
) == VT_FLOAT
) {
638 csym
.n_type
= T_FLOAT
;
639 csym
.n_sclass
= C_EXT
;
640 } else if ((p
->st_other
& VT_BTYPE
) == VT_INT
) {
641 csym
.n_type
= T_INT
; // int
642 csym
.n_sclass
= C_EXT
;
643 } else if ((p
->st_other
& VT_BTYPE
) == VT_SHORT
) {
644 csym
.n_type
= T_SHORT
;
645 csym
.n_sclass
= C_EXT
;
646 } else if ((p
->st_other
& VT_BTYPE
) == VT_BYTE
) {
647 csym
.n_type
= T_CHAR
;
648 csym
.n_sclass
= C_EXT
;
650 csym
.n_type
= T_INT
; // just mark as a label
651 csym
.n_sclass
= C_LABEL
;
655 csym
.n_value
= p
->st_value
;
658 fwrite(&csym
, 18, 1, f
);
665 fwrite(&auxfunc
, 18, 1, f
);
676 // write string table
678 // first write the size
679 i
= pCoff_str_table
- Coff_str_table
;
682 // then write the strings
683 fwrite(Coff_str_table
, i
, 1, f
);
685 tcc_free(Coff_str_table
);
693 // group the symbols in order of filename, func1, func2, etc
694 // finally global symbols
696 void SortSymbolTable(void)
699 Elf32_Sym
*p
, *p2
, *NewTable
;
702 NewTable
= (Elf32_Sym
*) tcc_malloc(nb_syms
* sizeof(Elf32_Sym
));
704 p
= (Elf32_Sym
*) symtab_section
->data
;
707 // find a file symbol, copy it over
708 // then scan the whole symbol list and copy any function
709 // symbols that match the file association
711 for (i
= 0; i
< nb_syms
; i
++) {
712 if (p
->st_info
== 4) {
713 name
= (char *) symtab_section
->link
->data
+ p
->st_name
;
715 // this is a file symbol, copy it over
719 p2
= (Elf32_Sym
*) symtab_section
->data
;
721 for (j
= 0; j
< nb_syms
; j
++) {
722 if (p2
->st_info
== 0x12) {
723 // this is a func symbol
726 (char *) symtab_section
->link
->data
+ p2
->st_name
;
728 // find the function data index
730 for (k
= 0; k
< nFuncs
; k
++) {
731 if (strcmp(name2
, Func
[k
]) == 0)
739 "debug (sort) info can't find function: %s",
745 if (strcmp(AssociatedFile
[k
], name
) == 0) {
746 // yes they match copy it over
757 // now all the filename and func symbols should have been copied over
758 // copy all the rest over (all except file and funcs)
760 p
= (Elf32_Sym
*) symtab_section
->data
;
761 for (i
= 0; i
< nb_syms
; i
++) {
762 if (p
->st_info
!= 4 && p
->st_info
!= 0x12) {
769 error("Internal Compiler error, debug info");
773 p
= (Elf32_Sym
*) symtab_section
->data
;
774 for (i
= 0; i
< nb_syms
; i
++) {
782 int FindCoffSymbolIndex(const char *func_name
)
788 p
= (Elf32_Sym
*) symtab_section
->data
;
790 for (i
= 0; i
< nb_syms
; i
++) {
792 name
= (char *) symtab_section
->link
->data
+ p
->st_name
;
794 if (p
->st_info
== 4) {
795 // put a filename symbol
797 } else if (p
->st_info
== 0x12) {
799 if (strcmp(func_name
, name
) == 0)
804 // put a Function Name
823 return n
; // total number of symbols
826 BOOL
OutputTheSection(Section
* sect
)
828 const char *s
= sect
->name
;
830 if (!strcmp(s
, ".text"))
832 else if (!strcmp(s
, ".data"))
838 short int GetCoffFlags(const char *s
)
840 if (!strcmp(s
, ".text"))
841 return STYP_TEXT
| STYP_DATA
| STYP_ALIGN
| 0x400;
842 else if (!strcmp(s
, ".data"))
844 else if (!strcmp(s
, ".bss"))
846 else if (!strcmp(s
, ".stack"))
847 return STYP_BSS
| STYP_ALIGN
| 0x200;
848 else if (!strcmp(s
, ".cinit"))
849 return STYP_COPY
| STYP_DATA
| STYP_ALIGN
| 0x200;
854 Section
*FindSection(TCCState
* s1
, const char *sname
)
859 for (i
= 1; i
< s1
->nb_sections
; i
++) {
862 if (!strcmp(sname
, s
->name
))
866 error("could not find section %s", sname
);
870 int tcc_load_coff(TCCState
* s1
, int fd
)
872 // tktk TokenSym *ts;
875 unsigned int str_size
;
876 char *Coff_str_table
, *name
;
880 FILHDR file_hdr
; /* FILE HEADER STRUCTURE */
882 f
= fdopen(fd
, "rb");
884 error("Unable to open .out file for input");
887 if (fread(&file_hdr
, FILHSZ
, 1, f
) != 1)
888 error("error reading .out file for input");
890 if (fread(&o_filehdr
, sizeof(o_filehdr
), 1, f
) != 1)
891 error("error reading .out file for input");
893 // first read the string table
895 if (fseek(f
, file_hdr
.f_symptr
+ file_hdr
.f_nsyms
* SYMESZ
, SEEK_SET
))
896 error("error reading .out file for input");
898 if (fread(&str_size
, sizeof(int), 1, f
) != 1)
899 error("error reading .out file for input");
902 Coff_str_table
= (char *) tcc_malloc(str_size
);
904 if (fread(Coff_str_table
, str_size
- 4, 1, f
) != 1)
905 error("error reading .out file for input");
907 // read/process all the symbols
909 // seek back to symbols
911 if (fseek(f
, file_hdr
.f_symptr
, SEEK_SET
))
912 error("error reading .out file for input");
914 for (i
= 0; i
< file_hdr
.f_nsyms
; i
++) {
915 if (fread(&csym
, SYMESZ
, 1, f
) != 1)
916 error("error reading .out file for input");
918 if (csym
._n
._n_n
._n_zeroes
== 0) {
919 name
= Coff_str_table
+ csym
._n
._n_n
._n_offset
- 4;
921 name
= csym
._n
._n_name
;
924 for (k
= 0; k
< 8; k
++)
932 // if (strcmp("_DAC_Buffer",name)==0) // tktk
935 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
936 (csym
.n_type
== 0x18 && csym
.n_sclass
== 0x2) || // pointer to structure
937 (csym
.n_type
== 0x7 && csym
.n_sclass
== 0x2) || // doubles
938 (csym
.n_type
== 0x6 && csym
.n_sclass
== 0x2)) // floats
940 // strip off any leading underscore (except for other main routine)
942 if (name
[0] == '_' && strcmp(name
, "_main") != 0)
945 tcc_add_symbol(s1
, name
, (void*)csym
.n_value
);
947 // skip any aux records
949 if (csym
.n_numaux
== 1) {
950 if (fread(&csym
, SYMESZ
, 1, f
) != 1)
951 error("error reading .out file for input");