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 stext
= FindSection(s1
, ".text");
88 sdata
= FindSection(s1
, ".data");
89 sbss
= FindSection(s1
, ".bss");
91 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
92 coff_nb_syms
= FindCoffSymbolIndex("XXXXXXXXXX1");
94 file_hdr
.f_magic
= COFF_C67_MAGIC
; /* magic number */
95 file_hdr
.f_timdat
= 0; /* time & date stamp */
96 file_hdr
.f_opthdr
= sizeof(AOUTHDR
); /* sizeof(optional hdr) */
97 file_hdr
.f_flags
= 0x1143; /* flags (copied from what code composer does) */
98 file_hdr
.f_TargetID
= 0x99; /* for C6x = 0x0099 */
100 o_filehdr
.magic
= 0x0108; /* see magic.h */
101 o_filehdr
.vstamp
= 0x0190; /* version stamp */
102 o_filehdr
.tsize
= stext
->data_offset
; /* text size in bytes, padded to FW bdry */
103 o_filehdr
.dsize
= sdata
->data_offset
; /* initialized data " " */
104 o_filehdr
.bsize
= sbss
->data_offset
; /* uninitialized data " " */
105 o_filehdr
.entrypt
= C67_main_entry_point
; /* entry pt. */
106 o_filehdr
.text_start
= stext
->sh_addr
; /* base of text used for this file */
107 o_filehdr
.data_start
= sdata
->sh_addr
; /* base of data used for this file */
110 // create all the section headers
112 file_pointer
= FILHSZ
+ sizeof(AOUTHDR
);
114 CoffTextSectionNo
= -1;
116 for (i
= 1; i
< s1
->nb_sections
; i
++) {
117 coff_sec
= §ion_header
[i
];
118 tcc_sect
= s1
->sections
[i
];
120 if (OutputTheSection(tcc_sect
)) {
123 if (CoffTextSectionNo
== -1 && tcc_sect
== stext
)
124 CoffTextSectionNo
= NSectionsToOutput
; // rem which coff sect number the .text sect is
126 strcpy(coff_sec
->s_name
, tcc_sect
->name
); /* section name */
128 coff_sec
->s_paddr
= tcc_sect
->sh_addr
; /* physical address */
129 coff_sec
->s_vaddr
= tcc_sect
->sh_addr
; /* virtual address */
130 coff_sec
->s_size
= tcc_sect
->data_offset
; /* section size */
131 coff_sec
->s_scnptr
= 0; /* file ptr to raw data for section */
132 coff_sec
->s_relptr
= 0; /* file ptr to relocation */
133 coff_sec
->s_lnnoptr
= 0; /* file ptr to line numbers */
134 coff_sec
->s_nreloc
= 0; /* number of relocation entries */
135 coff_sec
->s_flags
= GetCoffFlags(coff_sec
->s_name
); /* flags */
136 coff_sec
->s_reserved
= 0; /* reserved byte */
137 coff_sec
->s_page
= 0; /* memory page id */
139 file_pointer
+= sizeof(SCNHDR
);
143 file_hdr
.f_nscns
= NSectionsToOutput
; /* number of sections */
145 // now loop through and determine file pointer locations
149 for (i
= 1; i
< s1
->nb_sections
; i
++) {
150 coff_sec
= §ion_header
[i
];
151 tcc_sect
= s1
->sections
[i
];
153 if (OutputTheSection(tcc_sect
)) {
155 coff_sec
->s_scnptr
= file_pointer
; /* file ptr to raw data for section */
156 file_pointer
+= coff_sec
->s_size
;
160 // now loop through and determine file pointer locations
161 // for the relocation data
163 for (i
= 1; i
< s1
->nb_sections
; i
++) {
164 coff_sec
= §ion_header
[i
];
165 tcc_sect
= s1
->sections
[i
];
167 if (OutputTheSection(tcc_sect
)) {
168 // put relocations data
169 if (coff_sec
->s_nreloc
> 0) {
170 coff_sec
->s_relptr
= file_pointer
; /* file ptr to relocation */
171 file_pointer
+= coff_sec
->s_nreloc
* sizeof(struct reloc
);
176 // now loop through and determine file pointer locations
177 // for the line number data
179 for (i
= 1; i
< s1
->nb_sections
; i
++) {
180 coff_sec
= §ion_header
[i
];
181 tcc_sect
= s1
->sections
[i
];
183 coff_sec
->s_nlnno
= 0;
184 coff_sec
->s_lnnoptr
= 0;
186 if (do_debug
&& tcc_sect
== stext
) {
187 // count how many line nos data
189 // also find association between source file name and function
190 // so we can sort the symbol table
193 Stab_Sym
*sym
, *sym_end
;
194 char func_name
[MAX_FUNC_NAME_LENGTH
],
195 last_func_name
[MAX_FUNC_NAME_LENGTH
];
196 unsigned long func_addr
, last_pc
, pc
;
197 const char *incl_files
[INCLUDE_STACK_SIZE
];
198 int incl_index
, len
, last_line_num
;
201 coff_sec
->s_lnnoptr
= file_pointer
; /* file ptr to linno */
207 last_func_name
[0] = '\0';
208 last_pc
= 0xffffffff;
210 sym
= (Stab_Sym
*) stab_section
->data
+ 1;
212 (Stab_Sym
*) (stab_section
->data
+
213 stab_section
->data_offset
);
216 while (sym
< sym_end
) {
217 switch (sym
->n_type
) {
218 /* function start or end */
220 if (sym
->n_strx
== 0) {
224 file_pointer
+= LINESZ
;
226 pc
= sym
->n_value
+ func_addr
;
229 EndAddress
[nFuncs
] = pc
;
230 FuncEntries
[nFuncs
] =
232 LineNoFilePtr
[nFuncs
]) / LINESZ
- 1;
233 LastLineNo
[nFuncs
++] = last_line_num
+ 1;
235 // beginning of function
237 LineNoFilePtr
[nFuncs
] = file_pointer
;
239 file_pointer
+= LINESZ
;
242 (const char *) stabstr_section
->data
+
245 p
= strchr(str
, ':');
247 pstrcpy(func_name
, sizeof(func_name
), str
);
248 pstrcpy(Func
[nFuncs
], sizeof(func_name
), str
);
251 if (len
> sizeof(func_name
) - 1)
252 len
= sizeof(func_name
) - 1;
253 memcpy(func_name
, str
, len
);
254 memcpy(Func
[nFuncs
], str
, len
);
255 func_name
[len
] = '\0';
258 // save the file that it came in so we can sort later
259 pstrcpy(AssociatedFile
[nFuncs
], sizeof(func_name
),
260 incl_files
[incl_index
- 1]);
262 func_addr
= sym
->n_value
;
266 /* line number info */
268 pc
= sym
->n_value
+ func_addr
;
271 last_line_num
= sym
->n_desc
;
274 strcpy(last_func_name
, func_name
);
277 file_pointer
+= LINESZ
;
282 (const char *) stabstr_section
->data
+ sym
->n_strx
;
284 if (incl_index
< INCLUDE_STACK_SIZE
) {
285 incl_files
[incl_index
++] = str
;
293 if (sym
->n_strx
== 0) {
294 incl_index
= 0; /* end of translation unit */
297 (const char *) stabstr_section
->data
+
299 /* do not add path */
301 if (len
> 0 && str
[len
- 1] != '/')
312 file_hdr
.f_symptr
= file_pointer
; /* file pointer to symtab */
315 file_hdr
.f_nsyms
= coff_nb_syms
; /* number of symtab entries */
317 file_hdr
.f_nsyms
= 0;
319 file_pointer
+= file_hdr
.f_nsyms
* SYMNMLEN
;
321 // OK now we are all set to write the file
324 fwrite(&file_hdr
, FILHSZ
, 1, f
);
325 fwrite(&o_filehdr
, sizeof(o_filehdr
), 1, f
);
327 // write section headers
328 for (i
= 1; i
< s1
->nb_sections
; i
++) {
329 coff_sec
= §ion_header
[i
];
330 tcc_sect
= s1
->sections
[i
];
332 if (OutputTheSection(tcc_sect
)) {
333 fwrite(coff_sec
, sizeof(SCNHDR
), 1, f
);
338 for (i
= 1; i
< s1
->nb_sections
; i
++) {
339 coff_sec
= §ion_header
[i
];
340 tcc_sect
= s1
->sections
[i
];
342 if (OutputTheSection(tcc_sect
)) {
343 fwrite(tcc_sect
->data
, tcc_sect
->data_offset
, 1, f
);
347 // write relocation data
348 for (i
= 1; i
< s1
->nb_sections
; i
++) {
349 coff_sec
= §ion_header
[i
];
350 tcc_sect
= s1
->sections
[i
];
352 if (OutputTheSection(tcc_sect
)) {
353 // put relocations data
354 if (coff_sec
->s_nreloc
> 0) {
355 fwrite(tcc_sect
->reloc
,
356 coff_sec
->s_nreloc
* sizeof(struct reloc
), 1, f
);
362 // group the symbols in order of filename, func1, func2, etc
363 // finally global symbols
368 // write line no data
370 for (i
= 1; i
< s1
->nb_sections
; i
++) {
371 coff_sec
= §ion_header
[i
];
372 tcc_sect
= s1
->sections
[i
];
374 if (do_debug
&& tcc_sect
== stext
) {
375 // count how many line nos data
378 Stab_Sym
*sym
, *sym_end
;
379 char func_name
[128], last_func_name
[128];
380 unsigned long func_addr
, last_pc
, pc
;
381 const char *incl_files
[INCLUDE_STACK_SIZE
];
382 int incl_index
, len
, last_line_num
;
390 last_func_name
[0] = '\0';
393 sym
= (Stab_Sym
*) stab_section
->data
+ 1;
395 (Stab_Sym
*) (stab_section
->data
+
396 stab_section
->data_offset
);
398 while (sym
< sym_end
) {
399 switch (sym
->n_type
) {
400 /* function start or end */
402 if (sym
->n_strx
== 0) {
405 CoffLineNo
.l_addr
.l_paddr
= last_pc
;
406 CoffLineNo
.l_lnno
= last_line_num
+ 1;
407 fwrite(&CoffLineNo
, 6, 1, f
);
409 pc
= sym
->n_value
+ func_addr
;
413 // beginning of function
416 (const char *) stabstr_section
->data
+
420 p
= strchr(str
, ':');
422 pstrcpy(func_name
, sizeof(func_name
), str
);
425 if (len
> sizeof(func_name
) - 1)
426 len
= sizeof(func_name
) - 1;
427 memcpy(func_name
, str
, len
);
428 func_name
[len
] = '\0';
430 func_addr
= sym
->n_value
;
434 // output a function begin
436 CoffLineNo
.l_addr
.l_symndx
=
437 FindCoffSymbolIndex(func_name
);
438 CoffLineNo
.l_lnno
= 0;
440 fwrite(&CoffLineNo
, 6, 1, f
);
444 /* line number info */
446 pc
= sym
->n_value
+ func_addr
;
450 strcpy(last_func_name
, func_name
);
452 // output a line reference
454 CoffLineNo
.l_addr
.l_paddr
= last_pc
;
456 if (last_line_num
== -1) {
457 CoffLineNo
.l_lnno
= sym
->n_desc
;
459 CoffLineNo
.l_lnno
= last_line_num
+ 1;
462 fwrite(&CoffLineNo
, 6, 1, f
);
465 last_line_num
= sym
->n_desc
;
472 (const char *) stabstr_section
->data
+ sym
->n_strx
;
474 if (incl_index
< INCLUDE_STACK_SIZE
) {
475 incl_files
[incl_index
++] = str
;
483 if (sym
->n_strx
== 0) {
484 incl_index
= 0; /* end of translation unit */
487 (const char *) stabstr_section
->data
+
489 /* do not add path */
491 if (len
> 0 && str
[len
- 1] != '/')
501 // write symbol table
514 Coff_str_table
= (char *) tcc_malloc(MAX_STR_TABLE
);
515 pCoff_str_table
= Coff_str_table
;
518 p
= (Elf32_Sym
*) symtab_section
->data
;
521 for (i
= 0; i
< nb_syms
; i
++) {
523 name
= symtab_section
->link
->data
+ p
->st_name
;
525 for (k
= 0; k
< 8; k
++)
526 csym
._n
._n_name
[k
] = 0;
528 if (strlen(name
) <= 8) {
529 strcpy(csym
._n
._n_name
, name
);
531 if (pCoff_str_table
- Coff_str_table
+ strlen(name
) >
533 error("String table too large");
535 csym
._n
._n_n
._n_zeroes
= 0;
536 csym
._n
._n_n
._n_offset
=
537 pCoff_str_table
- Coff_str_table
+ 4;
539 strcpy(pCoff_str_table
, name
);
540 pCoff_str_table
+= strlen(name
) + 1; // skip over null
544 if (p
->st_info
== 4) {
545 // put a filename symbol
546 csym
.n_value
= 33; // ?????
547 csym
.n_scnum
= N_DEBUG
;
549 csym
.n_sclass
= C_FILE
;
551 fwrite(&csym
, 18, 1, f
);
554 } else if (p
->st_info
== 0x12) {
555 // find the function data
557 for (k
= 0; k
< nFuncs
; k
++) {
558 if (strcmp(name
, Func
[k
]) == 0)
565 sprintf(s
, "debug info can't find function: %s", name
);
569 // put a Function Name
571 csym
.n_value
= p
->st_value
; // physical address
572 csym
.n_scnum
= CoffTextSectionNo
;
573 csym
.n_type
= MKTYPE(T_INT
, DT_FCN
, 0, 0, 0, 0, 0);
574 csym
.n_sclass
= C_EXT
;
576 fwrite(&csym
, 18, 1, f
);
581 auxfunc
.size
= EndAddress
[k
] - p
->st_value
;
582 auxfunc
.fileptr
= LineNoFilePtr
[k
];
583 auxfunc
.nextsym
= n
+ 6; // tktk
585 fwrite(&auxfunc
, 18, 1, f
);
589 strcpy(csym
._n
._n_name
, ".bf");
590 csym
.n_value
= p
->st_value
; // physical address
591 csym
.n_scnum
= CoffTextSectionNo
;
593 csym
.n_sclass
= C_FCN
;
595 fwrite(&csym
, 18, 1, f
);
601 auxbf
.nentries
= FuncEntries
[k
];
602 auxbf
.localframe
= 0;
603 auxbf
.nextentry
= n
+ 6;
605 fwrite(&auxbf
, 18, 1, f
);
609 strcpy(csym
._n
._n_name
, ".ef");
610 csym
.n_value
= EndAddress
[k
]; // physical address
611 csym
.n_scnum
= CoffTextSectionNo
;
613 csym
.n_sclass
= C_FCN
;
615 fwrite(&csym
, 18, 1, f
);
620 auxef
.lineno
= LastLineNo
[k
];
625 fwrite(&auxef
, 18, 1, f
);
630 // try an put some type info
632 if ((p
->st_other
& VT_BTYPE
) == VT_DOUBLE
) {
633 csym
.n_type
= T_DOUBLE
; // int
634 csym
.n_sclass
= C_EXT
;
635 } else if ((p
->st_other
& VT_BTYPE
) == VT_FLOAT
) {
636 csym
.n_type
= T_FLOAT
;
637 csym
.n_sclass
= C_EXT
;
638 } else if ((p
->st_other
& VT_BTYPE
) == VT_INT
) {
639 csym
.n_type
= T_INT
; // int
640 csym
.n_sclass
= C_EXT
;
641 } else if ((p
->st_other
& VT_BTYPE
) == VT_SHORT
) {
642 csym
.n_type
= T_SHORT
;
643 csym
.n_sclass
= C_EXT
;
644 } else if ((p
->st_other
& VT_BTYPE
) == VT_BYTE
) {
645 csym
.n_type
= T_CHAR
;
646 csym
.n_sclass
= C_EXT
;
648 csym
.n_type
= T_INT
; // just mark as a label
649 csym
.n_sclass
= C_LABEL
;
653 csym
.n_value
= p
->st_value
;
656 fwrite(&csym
, 18, 1, f
);
663 fwrite(&auxfunc
, 18, 1, f
);
674 // write string table
676 // first write the size
677 i
= pCoff_str_table
- Coff_str_table
;
680 // then write the strings
681 fwrite(Coff_str_table
, i
, 1, f
);
683 tcc_free(Coff_str_table
);
691 // group the symbols in order of filename, func1, func2, etc
692 // finally global symbols
694 void SortSymbolTable(void)
697 Elf32_Sym
*p
, *p2
, *NewTable
;
700 NewTable
= (Elf32_Sym
*) tcc_malloc(nb_syms
* sizeof(Elf32_Sym
));
702 p
= (Elf32_Sym
*) symtab_section
->data
;
705 // find a file symbol, copy it over
706 // then scan the whole symbol list and copy any function
707 // symbols that match the file association
709 for (i
= 0; i
< nb_syms
; i
++) {
710 if (p
->st_info
== 4) {
711 name
= (char *) symtab_section
->link
->data
+ p
->st_name
;
713 // this is a file symbol, copy it over
717 p2
= (Elf32_Sym
*) symtab_section
->data
;
719 for (j
= 0; j
< nb_syms
; j
++) {
720 if (p2
->st_info
== 0x12) {
721 // this is a func symbol
724 (char *) symtab_section
->link
->data
+ p2
->st_name
;
726 // find the function data index
728 for (k
= 0; k
< nFuncs
; k
++) {
729 if (strcmp(name2
, Func
[k
]) == 0)
737 "debug (sort) info can't find function: %s",
743 if (strcmp(AssociatedFile
[k
], name
) == 0) {
744 // yes they match copy it over
755 // now all the filename and func symbols should have been copied over
756 // copy all the rest over (all except file and funcs)
758 p
= (Elf32_Sym
*) symtab_section
->data
;
759 for (i
= 0; i
< nb_syms
; i
++) {
760 if (p
->st_info
!= 4 && p
->st_info
!= 0x12) {
767 error("Internal Compiler error, debug info");
771 p
= (Elf32_Sym
*) symtab_section
->data
;
772 for (i
= 0; i
< nb_syms
; i
++) {
780 int FindCoffSymbolIndex(const char *func_name
)
786 p
= (Elf32_Sym
*) symtab_section
->data
;
788 for (i
= 0; i
< nb_syms
; i
++) {
790 name
= (char *) symtab_section
->link
->data
+ p
->st_name
;
792 if (p
->st_info
== 4) {
793 // put a filename symbol
795 } else if (p
->st_info
== 0x12) {
797 if (strcmp(func_name
, name
) == 0)
802 // put a Function Name
821 return n
; // total number of symbols
824 BOOL
OutputTheSection(Section
* sect
)
826 const char *s
= sect
->name
;
828 if (!strcmp(s
, ".text"))
830 else if (!strcmp(s
, ".data"))
836 short int GetCoffFlags(const char *s
)
838 if (!strcmp(s
, ".text"))
839 return STYP_TEXT
| STYP_DATA
| STYP_ALIGN
| 0x400;
840 else if (!strcmp(s
, ".data"))
842 else if (!strcmp(s
, ".bss"))
844 else if (!strcmp(s
, ".stack"))
845 return STYP_BSS
| STYP_ALIGN
| 0x200;
846 else if (!strcmp(s
, ".cinit"))
847 return STYP_COPY
| STYP_DATA
| STYP_ALIGN
| 0x200;
852 Section
*FindSection(TCCState
* s1
, const char *sname
)
857 for (i
= 1; i
< s1
->nb_sections
; i
++) {
860 if (!strcmp(sname
, s
->name
))
864 error("could not find section %s", sname
);
868 int tcc_load_coff(TCCState
* s1
, int fd
)
870 // tktk TokenSym *ts;
873 unsigned int str_size
;
874 char *Coff_str_table
, *name
;
878 FILHDR file_hdr
; /* FILE HEADER STRUCTURE */
880 f
= fdopen(fd
, "rb");
882 error("Unable to open .out file for input");
885 if (fread(&file_hdr
, FILHSZ
, 1, f
) != 1)
886 error("error reading .out file for input");
888 if (fread(&o_filehdr
, sizeof(o_filehdr
), 1, f
) != 1)
889 error("error reading .out file for input");
891 // first read the string table
893 if (fseek(f
, file_hdr
.f_symptr
+ file_hdr
.f_nsyms
* SYMESZ
, SEEK_SET
))
894 error("error reading .out file for input");
896 if (fread(&str_size
, sizeof(int), 1, f
) != 1)
897 error("error reading .out file for input");
900 Coff_str_table
= (char *) tcc_malloc(str_size
);
902 if (fread(Coff_str_table
, str_size
- 4, 1, f
) != 1)
903 error("error reading .out file for input");
905 // read/process all the symbols
907 // seek back to symbols
909 if (fseek(f
, file_hdr
.f_symptr
, SEEK_SET
))
910 error("error reading .out file for input");
912 for (i
= 0; i
< file_hdr
.f_nsyms
; i
++) {
913 if (fread(&csym
, SYMESZ
, 1, f
) != 1)
914 error("error reading .out file for input");
916 if (csym
._n
._n_n
._n_zeroes
== 0) {
917 name
= Coff_str_table
+ csym
._n
._n_n
._n_offset
- 4;
919 name
= csym
._n
._n_name
;
922 for (k
= 0; k
< 8; k
++)
930 // if (strcmp("_DAC_Buffer",name)==0) // tktk
933 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
934 (csym
.n_type
== 0x18 && csym
.n_sclass
== 0x2) || // pointer to structure
935 (csym
.n_type
== 0x7 && csym
.n_sclass
== 0x2) || // doubles
936 (csym
.n_type
== 0x6 && csym
.n_sclass
== 0x2)) // floats
938 // strip off any leading underscore (except for other main routine)
940 if (name
[0] == '_' && strcmp(name
, "_main") != 0)
943 tcc_add_symbol(s1
, name
, csym
.n_value
);
945 // skip any aux records
947 if (csym
.n_numaux
== 1) {
948 if (fread(&csym
, SYMESZ
, 1, f
) != 1)
949 error("error reading .out file for input");