Merge from vendor branch DIFFUTILS:
[dragonfly.git] / gnu / usr.bin / as / config / obj-coff.c
1 /* coff object file format
2    Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
3
4    This file is part of GAS.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "as.h"
21
22 #include "obstack.h"
23
24 lineno* lineno_rootP;
25
26 const short seg_N_TYPE[] = { /* in: segT   out: N_TYPE bits */
27         C_ABS_SECTION,
28         C_TEXT_SECTION,
29         C_DATA_SECTION,
30         C_BSS_SECTION,
31         C_UNDEF_SECTION,                /* SEG_UNKNOWN */
32         C_UNDEF_SECTION,                /* SEG_ABSENT */
33         C_UNDEF_SECTION,                /* SEG_PASS1 */
34         C_UNDEF_SECTION,                /* SEG_GOOF */
35         C_UNDEF_SECTION,                /* SEG_BIG */
36         C_UNDEF_SECTION,                /* SEG_DIFFERENCE */
37         C_DEBUG_SECTION,                /* SEG_DEBUG */
38         C_NTV_SECTION,          /* SEG_NTV */
39         C_PTV_SECTION,          /* SEG_PTV */
40         C_REGISTER_SECTION,     /* SEG_REGISTER */
41 };
42
43
44 /* Add 4 to the real value to get the index and compensate the negatives */
45
46 const segT N_TYPE_seg[32] =
47 {
48         SEG_PTV,                        /* C_PTV_SECTION == -4 */
49         SEG_NTV,                        /* C_NTV_SECTION == -3 */
50         SEG_DEBUG,                      /* C_DEBUG_SECTION == -2 */
51         SEG_ABSOLUTE,                   /* C_ABS_SECTION == -1 */
52         SEG_UNKNOWN,                    /* C_UNDEF_SECTION == 0 */
53         SEG_TEXT,                       /* C_TEXT_SECTION == 1 */
54         SEG_DATA,                       /* C_DATA_SECTION == 2 */
55         SEG_BSS,                        /* C_BSS_SECTION == 3 */
56         SEG_REGISTER,                   /* C_REGISTER_SECTION == 4 */
57         SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
58         SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,
59         SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF,SEG_GOOF
60     };
61
62 #if __STDC__ == 1
63
64 char *s_get_name(symbolS *s);
65 static symbolS *tag_find_or_make(char *name);
66 static symbolS* tag_find(char *name);
67 #ifdef BFD_HEADERS
68 static void obj_coff_section_header_append(char **where, struct internal_scnhdr *header);
69 #else
70 static void obj_coff_section_header_append(char **where, SCNHDR *header);
71 #endif
72 static void obj_coff_def(int what);
73 static void obj_coff_dim(void);
74 static void obj_coff_endef(void);
75 static void obj_coff_line(void);
76 static void obj_coff_ln(void);
77 static void obj_coff_scl(void);
78 static void obj_coff_size(void);
79 static void obj_coff_stab(int what);
80 static void obj_coff_tag(void);
81 static void obj_coff_type(void);
82 static void obj_coff_val(void);
83 static void tag_init(void);
84 static void tag_insert(char *name, symbolS *symbolP);
85
86 #else /* not __STDC__ */
87
88 char *s_get_name();
89 static symbolS *tag_find();
90 static symbolS *tag_find_or_make();
91 static void obj_coff_section_header_append();
92 static void obj_coff_def();
93 static void obj_coff_dim();
94 static void obj_coff_endef();
95 static void obj_coff_line();
96 static void obj_coff_ln();
97 static void obj_coff_scl();
98 static void obj_coff_size();
99 static void obj_coff_stab();
100 static void obj_coff_tag();
101 static void obj_coff_type();
102 static void obj_coff_val();
103 static void tag_init();
104 static void tag_insert();
105
106 #endif /* not __STDC__ */
107
108 static struct hash_control *tag_hash;
109 static symbolS *def_symbol_in_progress = NULL;
110
111 const pseudo_typeS obj_pseudo_table[] = {
112 #ifndef IGNORE_DEBUG
113         { "def",        obj_coff_def,           0       },
114         { "dim",        obj_coff_dim,           0       },
115         { "endef",      obj_coff_endef,         0       },
116         { "line",       obj_coff_line,          0       },
117         { "ln",         obj_coff_ln,            0       },
118         { "scl",        obj_coff_scl,           0       },
119         { "size",       obj_coff_size,          0       },
120         { "tag",        obj_coff_tag,           0       },
121         { "type",       obj_coff_type,          0       },
122         { "val",        obj_coff_val,           0       },
123 #else
124         { "def",        s_ignore,               0       },
125         { "dim",        s_ignore,               0       },
126         { "endef",      s_ignore,               0       },
127         { "line",       s_ignore,               0       },
128         { "ln",         s_ignore,               0       },
129         { "scl",        s_ignore,               0       },
130         { "size",       s_ignore,               0       },
131         { "tag",        s_ignore,               0       },
132         { "type",       s_ignore,               0       },
133         { "val",        s_ignore,               0       },
134 #endif /* ignore debug */
135
136         { "ident",      s_ignore,               0 }, /* we don't yet handle this. */
137
138
139         /* stabs aka a.out aka b.out directives for debug symbols.
140            Currently ignored silently.  Except for .line at which
141            we guess from context. */
142         { "desc",       s_ignore,               0       }, /* def */
143         /*      { "line",       s_ignore,               0       }, */ /* source code line number */
144         { "stabd",      obj_coff_stab,          'd'     }, /* stabs */
145         { "stabn",      obj_coff_stab,          'n'     }, /* stabs */
146         { "stabs",      obj_coff_stab,          's'     }, /* stabs */
147
148         /* stabs-in-coff (?) debug pseudos (ignored) */
149         { "optim",      s_ignore, 0 }, /* For sun386i cc (?) */
150         /* other stuff */
151         { "ABORT",      s_abort,                0 },
152
153         { NULL} /* end sentinel */
154 }; /* obj_pseudo_table */
155
156
157 /* obj dependant output values */
158 #ifdef BFD_HEADERS
159 static struct internal_scnhdr bss_section_header;
160 struct internal_scnhdr data_section_header;
161 struct internal_scnhdr text_section_header;
162 #else
163 static SCNHDR bss_section_header;
164 SCNHDR data_section_header;
165 SCNHDR text_section_header;
166 #endif
167 /* Relocation. */
168
169 static int reloc_compare(p1, p2)
170 #ifdef BFD_HEADERS
171 struct internal_reloc *p1, *p2;
172 #else
173 RELOC *p1, *p2;
174 #endif
175 {
176         return (int)(p1->r_vaddr - p2->r_vaddr);
177 }
178
179 /*
180  *              emit_relocations()
181  *
182  * Crawl along a fixS chain. Emit the segment's relocations.
183  */
184
185 void obj_emit_relocations(where, fixP, segment_address_in_file)
186 char **where;
187 fixS *fixP; /* Fixup chain for this segment. */
188 relax_addressT segment_address_in_file;
189 {
190 #ifdef BFD_HEADERS
191         struct internal_reloc *ri_table;
192 #else
193         RELOC *ri_table;
194 #endif
195         symbolS *symbolP;
196         int i, count;
197         fixS *p;
198
199         for (count = 0, p = fixP; p ; p = p->fx_next)
200             if (p->fx_addsy) count++;
201         if (!count)
202             return;
203
204 #ifdef BFD_HEADERS
205         ri_table = (struct internal_reloc *) calloc(sizeof(*ri_table),count);
206 #else
207         ri_table = (RELOC *) calloc(sizeof(*ri_table),count);
208 #endif
209         if (!ri_table)
210             as_fatal ("obj_emit_relocations: Could not malloc relocation table");
211
212 #ifdef TC_I960
213         callj_table = (char *)malloc (sizeof(char)*count);
214         if (!callj_table)
215             as_fatal ("obj_emit_relocations: Could not malloc callj table");
216 #endif
217
218         for (i = 0;  fixP;  fixP = fixP->fx_next) {
219                 if (symbolP = fixP->fx_addsy) {
220 #if defined(TC_M68K)
221                         ri_table[i].r_type = (fixP->fx_pcrel ?
222                                               (fixP->fx_size == 1 ? R_PCRBYTE :
223                                                fixP->fx_size == 2 ? R_PCRWORD :
224                                                R_PCRLONG):
225                                               (fixP->fx_size == 1 ? R_RELBYTE :
226                                                fixP->fx_size == 2 ? R_RELWORD :
227                                                R_RELLONG));
228 #elif defined(TC_I386)
229                         /* FIXME-SOON R_OFF8 & R_DIR16 are a vague guess, completly
230                            untested. */
231                         ri_table[i].r_type = (fixP->fx_pcrel ?
232                                               (fixP->fx_size == 1 ? R_PCRBYTE :
233                                                fixP->fx_size == 2 ? R_PCRWORD :
234                                                R_PCRLONG):
235                                               (fixP->fx_size == 1 ? R_OFF8 :
236                                                fixP->fx_size == 2 ? R_DIR16 :
237                                                R_DIR32));
238 #elif defined(TC_I960)
239                         ri_table[i].r_type = (fixP->fx_pcrel
240                                               ? R_IPRMED
241                                               : R_RELLONG);
242                         callj_table[i] =  fixP->fx_callj ? 1 : 0;
243 #elif defined(TC_A29K)
244                         ri_table[i].r_type = tc_coff_fix2rtype(fixP);
245
246 #else
247 #error            you lose
248 #endif /* TC_M68K || TC_I386 */
249                         ri_table[i].r_vaddr = (fixP->fx_frag->fr_address
250                                                + fixP->fx_where);
251                         /* If symbol associated to relocation entry is a bss symbol
252                            or undefined symbol just remember the index of the symbol.
253                            Otherwise store the index of the symbol describing the
254                            section the symbol belong to. This heuristic speeds up ld.
255                            */
256                         /* Local symbols can generate relocation information. In case
257                            of structure return for instance. But they have no symbol
258                            number because they won't be emitted in the final object.
259                            In the case where they are in the BSS section, this leads
260                            to an incorrect r_symndx.
261                            Under bsd the loader do not care if the symbol reference
262                            is incorrect. But the SYS V ld complains about this. To
263                            avoid this we associate the symbol to the associated
264                            section, *even* if it is the BSS section. */
265                         /* If someone can tell me why the other symbols of the bss
266                            section are not associated with the .bss section entry,
267                            I'd be gratefull. I guess that it has to do with the special
268                            nature of the .bss section. Or maybe this is because the
269                            bss symbols are declared in the common section and can
270                            be resized later. Can it break code some where ? */
271                         ri_table[i].r_symndx = (S_GET_SEGMENT(symbolP) == SEG_TEXT
272                                                 ? dot_text_symbol->sy_number
273                                                 : (S_GET_SEGMENT(symbolP) == SEG_DATA
274                                                    ? dot_data_symbol->sy_number
275                                                    : ((SF_GET_LOCAL(symbolP)
276                                                        ? dot_bss_symbol->sy_number
277                                                        : symbolP->sy_number)))); /* bss or undefined */
278
279                         /* md_ri_to_chars((char *) &ri, ri); */  /* Last step : write md f */
280
281                         i++;
282                 } /* if there's a symbol */
283         } /* for each fixP */
284
285         /*
286          * AIX ld prefer to have the reloc table with r_vaddr sorted.
287          * But sorting it should not hurt any other ld.
288          */
289         qsort (ri_table, count, sizeof(*ri_table), reloc_compare);
290
291         for (i = 0; i < count; i++)
292             {
293 #ifdef BFD_HEADERS
294                     *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i], *where);
295 # ifdef TC_A29K
296                     /* The 29k has a special kludge for the high 16 bit reloc.
297                        Two relocations are emmited, R_IHIHALF, and R_IHCONST.
298                        The second one doesn't contain a symbol, but uses the
299                        value for offset */
300                     if (ri_table[i].r_type == R_IHIHALF)
301                         {
302                                 /* now emit the second bit */
303                                 ri_table[i].r_type = R_IHCONST;
304                                 ri_table[i].r_symndx = fixP->fx_addnumber;
305                                 *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i],
306                                                                   *where);
307                         }
308 # endif /* TC_A29K */
309
310 #else /* not BFD_HEADERS */
311                     append(where, (char *) &ri_table[i], RELSZ);
312 #endif /* not BFD_HEADERS */
313
314 #ifdef TC_I960
315                     if (callj_table[i])
316                         {
317                                 ri_table[i].r_type = R_OPTCALL;
318 # ifdef BFD_HEADERS
319                                 *where += bfd_coff_swap_reloc_out(stdoutput, &ri_table[i],
320                                                                   *where);
321 # else
322                                 append(where, (char *) &ri_table[i], (unsigned long)RELSZ);
323 # endif /* BFD_HEADERS */
324                         } /* if it's a callj, do it again for the opcode */
325 #endif /* TC_I960 */
326             }
327
328         free (ri_table);
329 #ifdef TC_I960
330         free (callj_table);
331 #endif
332
333         return;
334 } /* obj_emit_relocations() */
335
336 /* Coff file generation & utilities */
337
338 #ifdef BFD_HEADERS
339 void obj_header_append(where, headers)
340 char **where;
341 object_headers *headers;
342 {
343         tc_headers_hook(headers);
344         *where += bfd_coff_swap_filehdr_out(stdoutput, &(headers->filehdr), *where);
345 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
346         *where += bfd_coff_swap_aouthdr_out(stdoutput, &(headers->aouthdr), *where);
347 #endif
348         obj_coff_section_header_append(where, &text_section_header);
349         obj_coff_section_header_append(where, &data_section_header);
350         obj_coff_section_header_append(where, &bss_section_header);
351
352 }
353
354 #else
355
356 void obj_header_append(where, headers)
357 char **where;
358 object_headers *headers;
359 {
360         tc_headers_hook(headers);
361
362 #ifdef CROSS_COMPILE
363         /* Eventually swap bytes for cross compilation for file header */
364         md_number_to_chars(*where, headers->filehdr.f_magic, sizeof(headers->filehdr.f_magic));
365         *where += sizeof(headers->filehdr.f_magic);
366         md_number_to_chars(*where, headers->filehdr.f_nscns, sizeof(headers->filehdr.f_nscns));
367         *where += sizeof(headers->filehdr.f_nscns);
368         md_number_to_chars(*where, headers->filehdr.f_timdat, sizeof(headers->filehdr.f_timdat));
369         *where += sizeof(headers->filehdr.f_timdat);
370         md_number_to_chars(*where, headers->filehdr.f_symptr, sizeof(headers->filehdr.f_symptr));
371         *where += sizeof(headers->filehdr.f_symptr);
372         md_number_to_chars(*where, headers->filehdr.f_nsyms, sizeof(headers->filehdr.f_nsyms));
373         *where += sizeof(headers->filehdr.f_nsyms);
374         md_number_to_chars(*where, headers->filehdr.f_opthdr, sizeof(headers->filehdr.f_opthdr));
375         *where += sizeof(headers->filehdr.f_opthdr);
376         md_number_to_chars(*where, headers->filehdr.f_flags, sizeof(headers->filehdr.f_flags));
377         *where += sizeof(headers->filehdr.f_flags);
378
379 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
380         /* Eventually swap bytes for cross compilation for a.out header */
381         md_number_to_chars(*where, headers->aouthdr.magic, sizeof(headers->aouthdr.magic));
382         *where += sizeof(headers->aouthdr.magic);
383         md_number_to_chars(*where, headers->aouthdr.vstamp, sizeof(headers->aouthdr.vstamp));
384         *where += sizeof(headers->aouthdr.vstamp);
385         md_number_to_chars(*where, headers->aouthdr.tsize, sizeof(headers->aouthdr.tsize));
386         *where += sizeof(headers->aouthdr.tsize);
387         md_number_to_chars(*where, headers->aouthdr.dsize, sizeof(headers->aouthdr.dsize));
388         *where += sizeof(headers->aouthdr.dsize);
389         md_number_to_chars(*where, headers->aouthdr.bsize, sizeof(headers->aouthdr.bsize));
390         *where += sizeof(headers->aouthdr.bsize);
391         md_number_to_chars(*where, headers->aouthdr.entry, sizeof(headers->aouthdr.entry));
392         *where += sizeof(headers->aouthdr.entry);
393         md_number_to_chars(*where, headers->aouthdr.text_start, sizeof(headers->aouthdr.text_start));
394         *where += sizeof(headers->aouthdr.text_start);
395         md_number_to_chars(*where, headers->aouthdr.data_start, sizeof(headers->aouthdr.data_start));
396         *where += sizeof(headers->aouthdr.data_start);
397         md_number_to_chars(*where, headers->aouthdr.tagentries, sizeof(headers->aouthdr.tagentries));
398         *where += sizeof(headers->aouthdr.tagentries);
399 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
400
401 #else /* CROSS_COMPILE */
402
403         append(where, (char *) &headers->filehdr, sizeof(headers->filehdr));
404 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
405         append(where, (char *) &headers->aouthdr, sizeof(headers->aouthdr));
406 #endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
407
408 #endif /* CROSS_COMPILE */
409
410         /* Output the section headers */
411         obj_coff_section_header_append(where, &text_section_header);
412         obj_coff_section_header_append(where, &data_section_header);
413         obj_coff_section_header_append(where, &bss_section_header);
414
415         return;
416 } /* obj_header_append() */
417 #endif
418 void obj_symbol_to_chars(where, symbolP)
419 char **where;
420 symbolS *symbolP;
421 {
422 #ifdef BFD_HEADERS
423         unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
424         unsigned int i;
425
426         if (S_GET_SEGMENT(symbolP) == SEG_REGISTER) {
427                 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
428         }
429         *where += bfd_coff_swap_sym_out(stdoutput, &symbolP->sy_symbol.ost_entry,
430                                         *where);
431
432         for (i = 0; i < numaux; i++)
433             {
434                     *where += bfd_coff_swap_aux_out(stdoutput,
435                                                     &symbolP->sy_symbol.ost_auxent[i],
436                                                     S_GET_DATA_TYPE(symbolP),
437                                                     S_GET_STORAGE_CLASS(symbolP),
438                                                     *where);
439             }
440
441 #else /* BFD_HEADERS */
442         SYMENT *syment = &symbolP->sy_symbol.ost_entry;
443         int i;
444         char numaux = syment->n_numaux;
445         unsigned short type = S_GET_DATA_TYPE(symbolP);
446
447 #ifdef CROSS_COMPILE
448         md_number_to_chars(*where, syment->n_value, sizeof(syment->n_value));
449         *where += sizeof(syment->n_value);
450         md_number_to_chars(*where, syment->n_scnum, sizeof(syment->n_scnum));
451         *where += sizeof(syment->n_scnum);
452         md_number_to_chars(*where, 0, sizeof(short)); /* pad n_flags */
453         *where += sizeof(short);
454         md_number_to_chars(*where, syment->n_type, sizeof(syment->n_type));
455         *where += sizeof(syment->n_type);
456         md_number_to_chars(*where, syment->n_sclass, sizeof(syment->n_sclass));
457         *where += sizeof(syment->n_sclass);
458         md_number_to_chars(*where, syment->n_numaux, sizeof(syment->n_numaux));
459         *where += sizeof(syment->n_numaux);
460 #else /* CROSS_COMPILE */
461         append(where, (char *) syment, sizeof(*syment));
462 #endif /* CROSS_COMPILE */
463
464         /* Should do the following : if (.file entry) MD(..)... else if (static entry) MD(..) */
465         if (numaux > OBJ_COFF_MAX_AUXENTRIES) {
466                 as_bad("Internal error? too many auxents for symbol");
467         } /* too many auxents */
468
469         for (i = 0; i < numaux; ++i) {
470 #ifdef CROSS_COMPILE
471 #if 0 /* This code has never been tested */
472                 /* The most common case, x_sym entry. */
473                 if ((SF_GET(symbolP) & (SF_FILE | SF_STATICS)) == 0) {
474                         md_number_to_chars(*where, auxP->x_sym.x_tagndx, sizeof(auxP->x_sym.x_tagndx));
475                         *where += sizeof(auxP->x_sym.x_tagndx);
476                         if (ISFCN(type)) {
477                                 md_number_to_chars(*where, auxP->x_sym.x_misc.x_fsize, sizeof(auxP->x_sym.x_misc.x_fsize));
478                                 *where += sizeof(auxP->x_sym.x_misc.x_fsize);
479                         } else {
480                                 md_number_to_chars(*where, auxP->x_sym.x_misc.x_lnno, sizeof(auxP->x_sym.x_misc.x_lnno));
481                                 *where += sizeof(auxP->x_sym.x_misc.x_lnno);
482                                 md_number_to_chars(*where, auxP->x_sym.x_misc.x_size, sizeof(auxP->x_sym.x_misc.x_size));
483                                 *where += sizeof(auxP->x_sym.x_misc.x_size);
484                         }
485                         if (ISARY(type)) {
486                                 register int index;
487                                 for (index = 0; index < DIMNUM; index++)
488                                     md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_ary.x_dimen[index], sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]));
489                                 *where += sizeof(auxP->x_sym.x_fcnary.x_ary.x_dimen[index]);
490                         } else {
491                                 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr));
492                                 *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_lnnoptr);
493                                 md_number_to_chars(*where, auxP->x_sym.x_fcnary.x_fcn.x_endndx, sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx));
494                                 *where += sizeof(auxP->x_sym.x_fcnary.x_fcn.x_endndx);
495                         }
496                         md_number_to_chars(*where, auxP->x_sym.x_tvndx, sizeof(auxP->x_sym.x_tvndx));
497                         *where += sizeof(auxP->x_sym.x_tvndx);
498                 } else if (SF_GET_FILE(symbolP)) { /* .file */
499                         ;
500                 } else if (SF_GET_STATICS(symbolP)) { /* .text, .data, .bss symbols */
501                         md_number_to_chars(*where, auxP->x_scn.x_scnlen, sizeof(auxP->x_scn.x_scnlen));
502                         *where += sizeof(auxP->x_scn.x_scnlen);
503                         md_number_to_chars(*where, auxP->x_scn.x_nreloc, sizeof(auxP->x_scn.x_nreloc));
504                         *where += sizeof(auxP->x_scn.x_nreloc);
505                         md_number_to_chars(*where, auxP->x_scn.x_nlinno, sizeof(auxP->x_scn.x_nlinno));
506                         *where += sizeof(auxP->x_scn.x_nlinno);
507                 }
508 #endif /* 0 */
509 #else /* CROSS_COMPILE */
510                 append(where, (char *) &symbolP->sy_symbol.ost_auxent[i], sizeof(symbolP->sy_symbol.ost_auxent[i]));
511 #endif /* CROSS_COMPILE */
512
513         }; /* for each aux in use */
514 #endif /* BFD_HEADERS */
515         return;
516 } /* obj_symbol_to_chars() */
517
518 #ifdef BFD_HEADERS
519 static void obj_coff_section_header_append(where, header)
520 char **where;
521 struct internal_scnhdr *header;
522 {
523         *where +=  bfd_coff_swap_scnhdr_out(stdoutput, header, *where);
524 }
525 #else
526 static void obj_coff_section_header_append(where, header)
527 char **where;
528 SCNHDR *header;
529 {
530 #ifdef CROSS_COMPILE
531         memcpy(*where, header->s_name, sizeof(header->s_name));
532         *where += sizeof(header->s_name);
533
534         md_number_to_chars(*where, header->s_paddr, sizeof(header->s_paddr));
535         *where += sizeof(header->s_paddr);
536
537         md_number_to_chars(*where, header->s_vaddr, sizeof(header->s_vaddr));
538         *where += sizeof(header->s_vaddr);
539
540         md_number_to_chars(*where, header->s_size, sizeof(header->s_size));
541         *where += sizeof(header->s_size);
542
543         md_number_to_chars(*where, header->s_scnptr, sizeof(header->s_scnptr));
544         *where += sizeof(header->s_scnptr);
545
546         md_number_to_chars(*where, header->s_relptr, sizeof(header->s_relptr));
547         *where += sizeof(header->s_relptr);
548
549         md_number_to_chars(*where, header->s_lnnoptr, sizeof(header->s_lnnoptr));
550         *where += sizeof(header->s_lnnoptr);
551
552         md_number_to_chars(*where, header->s_nreloc, sizeof(header->s_nreloc));
553         *where += sizeof(header->s_nreloc);
554
555         md_number_to_chars(*where, header->s_nlnno, sizeof(header->s_nlnno));
556         *where += sizeof(header->s_nlnno);
557
558         md_number_to_chars(*where, header->s_flags, sizeof(header->s_flags));
559         *where += sizeof(header->s_flags);
560
561 #ifdef TC_I960
562         md_number_to_chars(*where, header->s_align, sizeof(header->s_align));
563         *where += sizeof(header->s_align);
564 #endif /* TC_I960 */
565
566 #else /* CROSS_COMPILE */
567
568         append(where, (char *) header, sizeof(*header));
569
570 #endif /* CROSS_COMPILE */
571
572         return;
573 } /* obj_coff_section_header_append() */
574
575 #endif
576 void obj_emit_symbols(where, symbol_rootP)
577 char **where;
578 symbolS *symbol_rootP;
579 {
580         symbolS *symbolP;
581         /*
582          * Emit all symbols left in the symbol chain.
583          */
584         for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
585                 /* Used to save the offset of the name. It is used to point
586                    to the string in memory but must be a file offset. */
587                 register char * temp;
588
589                 tc_coff_symbol_emit_hook(symbolP);
590
591                 temp = S_GET_NAME(symbolP);
592                 if (SF_GET_STRING(symbolP)) {
593                         S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
594                         S_SET_ZEROES(symbolP, 0);
595                 } else {
596                         memset(symbolP->sy_symbol.ost_entry.n_name, '\0', SYMNMLEN);
597                         strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
598                 }
599                 obj_symbol_to_chars(where, symbolP);
600                 S_SET_NAME(symbolP,temp);
601         }
602 } /* obj_emit_symbols() */
603
604 /* Merge a debug symbol containing debug information into a normal symbol. */
605
606 void c_symbol_merge(debug, normal)
607 symbolS *debug;
608 symbolS *normal;
609 {
610         S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
611         S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
612
613         if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) {
614                 S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug));
615         } /* take the most we have */
616
617         if (S_GET_NUMBER_AUXILIARY(debug) > 0) {
618                 memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
619         } /* Move all the auxiliary information */
620
621         /* Move the debug flags. */
622         SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
623 } /* c_symbol_merge() */
624
625 static symbolS *previous_file_symbol = NULL;
626
627 void c_dot_file_symbol(filename)
628 char *filename;
629 {
630         symbolS* symbolP;
631
632         symbolP = symbol_new(".file",
633                              SEG_DEBUG,
634                              0,
635                              &zero_address_frag);
636
637         S_SET_STORAGE_CLASS(symbolP, C_FILE);
638         S_SET_NUMBER_AUXILIARY(symbolP, 1);
639         SA_SET_FILE_FNAME(symbolP, filename);
640         SF_SET_DEBUG(symbolP);
641         S_SET_VALUE(symbolP, (long) previous_file_symbol);
642
643         previous_file_symbol = symbolP;
644
645         /* Make sure that the symbol is first on the symbol chain */
646         if (symbol_rootP != symbolP) {
647                 if (symbolP == symbol_lastP) {
648                         symbol_lastP = symbol_lastP->sy_previous;
649                 } /* if it was the last thing on the list */
650
651                 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
652                 symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
653                 symbol_rootP = symbolP;
654         } /* if not first on the list */
655
656 } /* c_dot_file_symbol() */
657 /*
658  * Build a 'section static' symbol.
659  */
660
661 char *c_section_symbol(name, value, length, nreloc, nlnno)
662 char *name;
663 long value;
664 long length;
665 unsigned short nreloc;
666 unsigned short nlnno;
667 {
668         symbolS *symbolP;
669
670         symbolP = symbol_new(name,
671                              (name[1] == 't'
672                               ? SEG_TEXT
673                               : (name[1] == 'd'
674                                  ? SEG_DATA
675                                  : SEG_BSS)),
676                              value,
677                              &zero_address_frag);
678
679         S_SET_STORAGE_CLASS(symbolP, C_STAT);
680         S_SET_NUMBER_AUXILIARY(symbolP, 1);
681
682         SA_SET_SCN_SCNLEN(symbolP, length);
683         SA_SET_SCN_NRELOC(symbolP, nreloc);
684         SA_SET_SCN_NLINNO(symbolP, nlnno);
685
686         SF_SET_STATICS(symbolP);
687
688         return (char*)symbolP;
689 } /* c_section_symbol() */
690
691 void c_section_header(header,
692                       name,
693                       core_address,
694                       size,
695                       data_ptr,
696                       reloc_ptr,
697                       lineno_ptr,
698                       reloc_number,
699                       lineno_number,
700                       alignment)
701 #ifdef BFD_HEADERS
702 struct internal_scnhdr *header;
703 #else
704 SCNHDR *header;
705 #endif
706 char *name;
707 long core_address;
708 long size;
709 long data_ptr;
710 long reloc_ptr;
711 long lineno_ptr;
712 long reloc_number;
713 long lineno_number;
714 long alignment;
715 {
716         strncpy(header->s_name, name, 8);
717         header->s_paddr = header->s_vaddr = core_address;
718         header->s_scnptr = ((header->s_size = size) != 0) ? data_ptr : 0;
719         header->s_relptr = reloc_ptr;
720         header->s_lnnoptr = lineno_ptr;
721         header->s_nreloc = reloc_number;
722         header->s_nlnno = lineno_number;
723
724 #ifdef OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
725 #ifdef OBJ_COFF_BROKEN_ALIGNMENT
726         header->s_align = ((name[1] == 'b' || (size > 0)) ? 16 : 0);
727 #else
728         header->s_align = ((alignment == 0)
729                            ? 0
730                            : (1 << alignment));
731 #endif /* OBJ_COFF_BROKEN_ALIGNMENT */
732 #endif /* OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT */
733
734         header->s_flags = STYP_REG | (name[1] == 't'
735                                       ? STYP_TEXT
736                                       : (name[1] == 'd'
737                                          ? STYP_DATA
738                                          : (name[1] == 'b'
739                                             ? STYP_BSS
740                                             : STYP_INFO)));
741         return;
742 } /* c_section_header() */
743
744 /* Line number handling */
745
746 int function_lineoff = -1;      /* Offset in line#s where the last function
747                                    started (the odd entry for line #0) */
748 int text_lineno_number = 0;
749 int our_lineno_number = 0;      /* we use this to build pointers from .bf's
750                                    into the linetable.  It should match
751                                    exactly the values that are later
752                                    assigned in text_lineno_number by
753                                    write.c. */
754 lineno* lineno_lastP = (lineno*)0;
755
756 int
757     c_line_new(paddr, line_number, frag)
758 long paddr;
759 unsigned short line_number;
760 fragS* frag;
761 {
762         lineno* new_line = (lineno*)xmalloc(sizeof(lineno));
763
764         new_line->line.l_addr.l_paddr = paddr;
765         new_line->line.l_lnno = line_number;
766         new_line->frag = (char*)frag;
767         new_line->next = (lineno*)0;
768
769         if (lineno_rootP == (lineno*)0)
770             lineno_rootP = new_line;
771         else
772             lineno_lastP->next = new_line;
773         lineno_lastP = new_line;
774         return LINESZ * our_lineno_number++;
775 }
776
777 void obj_emit_lineno(where, line, file_start)
778 char **where;
779 lineno *line;
780 char *file_start;
781 {
782 #ifdef BFD_HEADERS
783         struct bfd_internal_lineno *line_entry;
784 #else
785         LINENO *line_entry;
786 #endif
787         for (; line; line = line->next) {
788                 line_entry = &line->line;
789
790                 /* FIXME-SOMEDAY Resolving the sy_number of function linno's used to be done in
791                    write_object_file() but their symbols need a fileptr to the lnno, so
792                    I moved this resolution check here.  xoxorich. */
793
794                 if (line_entry->l_lnno == 0) {
795                         /* There is a good chance that the symbol pointed to
796                            is not the one that will be emitted and that the
797                            sy_number is not accurate. */
798                         /*                      char *name; */
799                         symbolS *symbolP;
800
801                         symbolP = (symbolS *) line_entry->l_addr.l_symndx;
802
803                         line_entry->l_addr.l_symndx = symbolP->sy_number;
804                         symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_fcn.x_lnnoptr = *where - file_start;
805
806                 } /* if this is a function linno */
807 #ifdef BFD_HEADERS
808                 *where += bfd_coff_swap_lineno_out(stdoutput, line_entry, *where);
809 #else
810                 /* No matter which member of the union we process, they are
811                    both long. */
812 #ifdef CROSS_COMPILE
813                 md_number_to_chars(*where, line_entry->l_addr.l_paddr, sizeof(line_entry->l_addr.l_paddr));
814                 *where += sizeof(line_entry->l_addr.l_paddr);
815
816                 md_number_to_chars(*where, line_entry->l_lnno, sizeof(line_entry->l_lnno));
817                 *where += sizeof(line_entry->l_lnno);
818
819 #ifdef TC_I960
820                 **where = '0';
821                 ++*where;
822                 **where = '0';
823                 ++*where;
824 #endif /* TC_I960 */
825
826 #else /* CROSS_COMPILE */
827                 append(where, (char *) line_entry, LINESZ);
828 #endif /* CROSS_COMPILE */
829 #endif /* BFD_HEADERS */
830         } /* for each line number */
831
832         return ;
833 } /* obj_emit_lineno() */
834
835 void obj_symbol_new_hook(symbolP)
836 symbolS *symbolP;
837 {
838         char underscore = 0;      /* Symbol has leading _ */
839
840         /* Effective symbol */
841         /* Store the pointer in the offset. */
842         S_SET_ZEROES(symbolP, 0L);
843         S_SET_DATA_TYPE(symbolP, T_NULL);
844         S_SET_STORAGE_CLASS(symbolP, 0);
845         S_SET_NUMBER_AUXILIARY(symbolP, 0);
846         /* Additional information */
847         symbolP->sy_symbol.ost_flags = 0;
848         /* Auxiliary entries */
849         memset((char*) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ);
850
851 #ifdef STRIP_UNDERSCORE
852         /* Remove leading underscore at the beginning of the symbol.
853          * This is to be compatible with the standard librairies.
854          */
855         if (*S_GET_NAME(symbolP) == '_') {
856                 underscore = 1;
857                 S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1);
858         } /* strip underscore */
859 #endif /* STRIP_UNDERSCORE */
860
861         if (S_IS_STRING(symbolP))
862             SF_SET_STRING(symbolP);
863         if (!underscore && S_IS_LOCAL(symbolP))
864             SF_SET_LOCAL(symbolP);
865
866         return;
867 } /* obj_symbol_new_hook() */
868
869 /* stack stuff */
870 stack* stack_init(chunk_size, element_size)
871 unsigned long chunk_size;
872 unsigned long element_size;
873 {
874         stack* st;
875
876         if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0)
877             return (stack*)0;
878         if ((st->data = malloc(chunk_size)) == (char*)0) {
879                 free(st);
880                 return (stack*)0;
881         }
882         st->pointer = 0;
883         st->size = chunk_size;
884         st->chunk_size = chunk_size;
885         st->element_size = element_size;
886         return st;
887 } /* stack_init() */
888
889 void stack_delete(st)
890 stack* st;
891 {
892         free(st->data);
893         free(st);
894 }
895
896 char *stack_push(st, element)
897 stack *st;
898 char *element;
899 {
900         if (st->pointer + st->element_size >= st->size) {
901                 st->size += st->chunk_size;
902                 if ((st->data = xrealloc(st->data, st->size)) == (char*)0)
903                     return (char*)0;
904         }
905         memcpy(st->data + st->pointer, element, st->element_size);
906         st->pointer += st->element_size;
907         return st->data + st->pointer;
908 } /* stack_push() */
909
910 char* stack_pop(st)
911 stack* st;
912 {
913         if ((st->pointer -= st->element_size) < 0) {
914                 st->pointer = 0;
915                 return (char*)0;
916         }
917         return st->data + st->pointer;
918 }
919
920 char* stack_top(st)
921 stack* st;
922 {
923         return st->data + st->pointer - st->element_size;
924 }
925
926
927 /*
928  * Handle .ln directives.
929  */
930
931 static void obj_coff_ln() {
932         if (def_symbol_in_progress != NULL) {
933                 as_warn(".ln pseudo-op inside .def/.endef: ignored.");
934                 demand_empty_rest_of_line();
935                 return;
936         } /* wrong context */
937
938         c_line_new(obstack_next_free(&frags) - frag_now->fr_literal,
939                    get_absolute_expression(),
940                    frag_now);
941
942         demand_empty_rest_of_line();
943         return;
944 } /* obj_coff_line() */
945
946 /*
947  *                      def()
948  *
949  * Handle .def directives.
950  *
951  * One might ask : why can't we symbol_new if the symbol does not
952  * already exist and fill it with debug information.  Because of
953  * the C_EFCN special symbol. It would clobber the value of the
954  * function symbol before we have a chance to notice that it is
955  * a C_EFCN. And a second reason is that the code is more clear this
956  * way. (at least I think it is :-).
957  *
958  */
959
960 #define SKIP_SEMI_COLON()       while (*input_line_pointer++ != ';')
961 #define SKIP_WHITESPACES()      while (*input_line_pointer == ' ' || \
962                                        *input_line_pointer == '\t') \
963     input_line_pointer++;
964
965 static void obj_coff_def(what)
966 int what;
967 {
968         char name_end; /* Char after the end of name */
969         char *symbol_name; /* Name of the debug symbol */
970         char *symbol_name_copy; /* Temporary copy of the name */
971         unsigned int symbol_name_length;
972         /*$char*        directiveP;$ */         /* Name of the pseudo opcode */
973         /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
974         /*$char end = 0;$ */ /* If 1, stop parsing */
975
976         if (def_symbol_in_progress != NULL) {
977                 as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
978                 demand_empty_rest_of_line();
979                 return;
980         } /* if not inside .def/.endef */
981
982         SKIP_WHITESPACES();
983
984         def_symbol_in_progress = (symbolS *) obstack_alloc(&notes, sizeof(*def_symbol_in_progress));
985         memset(def_symbol_in_progress, '\0', sizeof(*def_symbol_in_progress));
986
987         symbol_name = input_line_pointer;
988         name_end = get_symbol_end();
989         symbol_name_length = strlen(symbol_name);
990         symbol_name_copy = xmalloc(symbol_name_length + 1);
991         strcpy(symbol_name_copy, symbol_name);
992
993         /* Initialize the new symbol */
994 #ifdef STRIP_UNDERSCORE
995         S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_'
996                                             ? symbol_name_copy + 1
997                                             : symbol_name_copy));
998 #else /* STRIP_UNDERSCORE */
999         S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
1000 #endif /* STRIP_UNDERSCORE */
1001         /* free(symbol_name_copy); */
1002         def_symbol_in_progress->sy_name_offset = ~0;
1003         def_symbol_in_progress->sy_number = ~0;
1004         def_symbol_in_progress->sy_frag = &zero_address_frag;
1005
1006         if (S_IS_STRING(def_symbol_in_progress)) {
1007                 SF_SET_STRING(def_symbol_in_progress);
1008         } /* "long" name */
1009
1010         *input_line_pointer = name_end;
1011
1012         demand_empty_rest_of_line();
1013         return;
1014 } /* obj_coff_def() */
1015
1016 unsigned int dim_index;
1017 static void obj_coff_endef() {
1018         symbolS *symbolP;
1019         /* DIM BUG FIX sac@cygnus.com */
1020         dim_index =0;
1021         if (def_symbol_in_progress == NULL) {
1022                 as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
1023                 demand_empty_rest_of_line();
1024                 return;
1025         } /* if not inside .def/.endef */
1026
1027         /* Set the section number according to storage class. */
1028         switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
1029         case C_STRTAG:
1030         case C_ENTAG:
1031         case C_UNTAG:
1032                 SF_SET_TAG(def_symbol_in_progress);
1033                 /* intentional fallthrough */
1034         case C_FILE:
1035         case C_TPDEF:
1036                 SF_SET_DEBUG(def_symbol_in_progress);
1037                 S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
1038                 break;
1039
1040         case C_EFCN:
1041                 SF_SET_LOCAL(def_symbol_in_progress);   /* Do not emit this symbol. */
1042                 /* intentional fallthrough */
1043         case C_BLOCK:
1044                 SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
1045                 /* intentional fallthrough */
1046         case C_FCN:
1047                 S_SET_SEGMENT(def_symbol_in_progress, SEG_TEXT);
1048
1049                 if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */
1050                         if (function_lineoff < 0) {
1051                                 fprintf(stderr, "`.bf' symbol without preceding function\n");
1052                         } /* missing function symbol */
1053                         SA_GET_SYM_LNNOPTR(def_symbol_in_progress) = function_lineoff;
1054                         SF_SET_PROCESS(def_symbol_in_progress); /* Will need relocating */
1055                         function_lineoff = -1;
1056                 }
1057                 break;
1058
1059 #ifdef C_AUTOARG
1060         case C_AUTOARG:
1061 #endif /* C_AUTOARG */
1062         case C_AUTO:
1063         case C_REG:
1064         case C_MOS:
1065         case C_MOE:
1066         case C_MOU:
1067         case C_ARG:
1068         case C_REGPARM:
1069         case C_FIELD:
1070         case C_EOS:
1071                 SF_SET_DEBUG(def_symbol_in_progress);
1072                 S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
1073                 break;
1074
1075         case C_EXT:
1076         case C_STAT:
1077         case C_LABEL:
1078                 /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
1079                 break;
1080
1081         case C_USTATIC:
1082         case C_EXTDEF:
1083         case C_ULABEL:
1084                 as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
1085                 break;
1086         } /* switch on storage class */
1087
1088         /* Now that we have built a debug symbol, try to
1089            find if we should merge with an existing symbol
1090            or not.  If a symbol is C_EFCN or SEG_ABSOLUTE or
1091            untagged SEG_DEBUG it never merges. */
1092
1093         /* Two cases for functions.  Either debug followed
1094            by definition or definition followed by debug.
1095            For definition first, we will merge the debug
1096            symbol into the definition.  For debug first, the
1097            lineno entry MUST point to the definition
1098            function or else it will point off into space
1099            when obj_crawl_symbol_chain() merges the debug
1100            symbol into the real symbol.  Therefor, let's
1101            presume the debug symbol is a real function
1102            reference. */
1103
1104         /* FIXME-SOON If for some reason the definition
1105            label/symbol is never seen, this will probably
1106            leave an undefined symbol at link time. */
1107
1108         if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN
1109             || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG
1110                 && !SF_GET_TAG(def_symbol_in_progress))
1111             || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE
1112             || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) {
1113
1114                 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
1115
1116         } else {
1117                 /* This symbol already exists, merge the
1118                    newly created symbol into the old one.
1119                    This is not mandatory. The linker can
1120                    handle duplicate symbols correctly. But I
1121                    guess that it save a *lot* of space if
1122                    the assembly file defines a lot of
1123                    symbols. [loic] */
1124
1125                 /* The debug entry (def_symbol_in_progress)
1126                    is merged into the previous definition. */
1127
1128                 c_symbol_merge(def_symbol_in_progress, symbolP);
1129                 /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
1130                 def_symbol_in_progress = symbolP;
1131
1132                 if (SF_GET_FUNCTION(def_symbol_in_progress)
1133                     || SF_GET_TAG(def_symbol_in_progress)) {
1134                         /* For functions, and tags, the symbol *must* be where the debug symbol
1135                            appears.  Move the existing symbol to the current place. */
1136                         /* If it already is at the end of the symbol list, do nothing */
1137                         if (def_symbol_in_progress != symbol_lastP) {
1138                                 symbol_remove(def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
1139                                 symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
1140                         } /* if not already in place */
1141                 } /* if function */
1142         } /* normal or mergable */
1143
1144         if (SF_GET_TAG(def_symbol_in_progress)
1145             && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) {
1146                 tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress);
1147         } /* If symbol is a {structure,union} tag, associate symbol to its name. */
1148
1149         if (SF_GET_FUNCTION(def_symbol_in_progress)) {
1150                 know(sizeof(def_symbol_in_progress) <= sizeof(long));
1151                 function_lineoff = c_line_new((long) def_symbol_in_progress, 0, &zero_address_frag);
1152                 SF_SET_PROCESS(def_symbol_in_progress);
1153
1154                 if (symbolP == NULL) {
1155                         /* That is, if this is the first
1156                            time we've seen the function... */
1157                         symbol_table_insert(def_symbol_in_progress);
1158                 } /* definition follows debug */
1159         } /* Create the line number entry pointing to the function being defined */
1160
1161         def_symbol_in_progress = NULL;
1162         demand_empty_rest_of_line();
1163         return;
1164 } /* obj_coff_endef() */
1165
1166 static void obj_coff_dim()
1167 {
1168         register int dim_index;
1169
1170         if (def_symbol_in_progress == NULL) {
1171                 as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
1172                 demand_empty_rest_of_line();
1173                 return;
1174         } /* if not inside .def/.endef */
1175
1176         S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1177
1178         for (dim_index = 0; dim_index < DIMNUM; dim_index++) {
1179                 SKIP_WHITESPACES();
1180                 SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
1181
1182                 switch (*input_line_pointer) {
1183
1184                 case ',':
1185                         input_line_pointer++;
1186                         break;
1187
1188                 default:
1189                         as_warn("badly formed .dim directive ignored");
1190                         /* intentional fallthrough */
1191                 case '\n':
1192                 case ';':
1193                         dim_index = DIMNUM;
1194                         break;
1195                 } /* switch on following character */
1196         } /* for each dimension */
1197
1198         demand_empty_rest_of_line();
1199         return;
1200 } /* obj_coff_dim() */
1201
1202 static void obj_coff_line() {
1203         if (def_symbol_in_progress == NULL) {
1204                 obj_coff_ln();
1205                 return;
1206         } /* if it looks like a stabs style line */
1207
1208         S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1209         SA_SET_SYM_LNNO(def_symbol_in_progress, get_absolute_expression());
1210
1211         demand_empty_rest_of_line();
1212         return;
1213 } /* obj_coff_line() */
1214
1215 static void obj_coff_size() {
1216         if (def_symbol_in_progress == NULL) {
1217                 as_warn(".size pseudo-op used outside of .def/.endef ignored.");
1218                 demand_empty_rest_of_line();
1219                 return;
1220         } /* if not inside .def/.endef */
1221
1222         S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1223         SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression());
1224         demand_empty_rest_of_line();
1225         return;
1226 } /* obj_coff_size() */
1227
1228 static void obj_coff_scl() {
1229         if (def_symbol_in_progress == NULL) {
1230                 as_warn(".scl pseudo-op used outside of .def/.endef ignored.");
1231                 demand_empty_rest_of_line();
1232                 return;
1233         } /* if not inside .def/.endef */
1234
1235         S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
1236         demand_empty_rest_of_line();
1237         return;
1238 } /* obj_coff_scl() */
1239
1240 static void obj_coff_tag() {
1241         char *symbol_name;
1242         char name_end;
1243
1244         if (def_symbol_in_progress == NULL) {
1245                 as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
1246                 demand_empty_rest_of_line();
1247                 return;
1248         } /* if not inside .def/.endef */
1249
1250         S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
1251         symbol_name = input_line_pointer;
1252         name_end = get_symbol_end();
1253
1254         /* Assume that the symbol referred to by .tag is always defined. */
1255         /* This was a bad assumption.  I've added find_or_make. xoxorich. */
1256         SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name));
1257         if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) {
1258                 as_warn("tag not found for .tag %s", symbol_name);
1259         } /* not defined */
1260
1261         SF_SET_TAGGED(def_symbol_in_progress);
1262         *input_line_pointer = name_end;
1263
1264         demand_empty_rest_of_line();
1265         return;
1266 } /* obj_coff_tag() */
1267
1268 static void obj_coff_type() {
1269         if (def_symbol_in_progress == NULL) {
1270                 as_warn(".type pseudo-op used outside of .def/.endef ignored.");
1271                 demand_empty_rest_of_line();
1272                 return;
1273         } /* if not inside .def/.endef */
1274
1275         S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
1276
1277         if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) &&
1278             S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) {
1279                 SF_SET_FUNCTION(def_symbol_in_progress);
1280         } /* is a function */
1281
1282         demand_empty_rest_of_line();
1283         return;
1284 } /* obj_coff_type() */
1285
1286 static void obj_coff_val() {
1287         if (def_symbol_in_progress == NULL) {
1288                 as_warn(".val pseudo-op used outside of .def/.endef ignored.");
1289                 demand_empty_rest_of_line();
1290                 return;
1291         } /* if not inside .def/.endef */
1292
1293         if (is_name_beginner(*input_line_pointer)) {
1294                 char *symbol_name = input_line_pointer;
1295                 char name_end = get_symbol_end();
1296
1297                 if (!strcmp(symbol_name, ".")) {
1298                         def_symbol_in_progress->sy_frag = frag_now;
1299                         S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal);
1300                         /* If the .val is != from the .def (e.g. statics) */
1301                 } else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) {
1302                         def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name);
1303
1304                         /* If the segment is undefined when the forward
1305                            reference is solved, then copy the segment id
1306                            from the forward symbol. */
1307                         SF_SET_GET_SEGMENT(def_symbol_in_progress);
1308                 }
1309                 /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
1310                 *input_line_pointer = name_end;
1311         } else {
1312                 S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
1313         } /* if symbol based */
1314
1315         demand_empty_rest_of_line();
1316         return;
1317 } /* obj_coff_val() */
1318
1319 /*
1320  * Maintain a list of the tagnames of the structres.
1321  */
1322
1323 static void tag_init() {
1324         tag_hash = hash_new();
1325         return ;
1326 } /* tag_init() */
1327
1328 static void tag_insert(name, symbolP)
1329 char *name;
1330 symbolS *symbolP;
1331 {
1332         register char * error_string;
1333
1334         if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) {
1335                 as_fatal("Inserting \"%s\" into structure table failed: %s",
1336                          name, error_string);
1337         }
1338         return ;
1339 } /* tag_insert() */
1340
1341 static symbolS *tag_find_or_make(name)
1342 char *name;
1343 {
1344         symbolS *symbolP;
1345
1346         if ((symbolP = tag_find(name)) == NULL) {
1347                 symbolP = symbol_new(name,
1348                                      SEG_UNKNOWN,
1349                                      0,
1350                                      &zero_address_frag);
1351
1352                 tag_insert(S_GET_NAME(symbolP), symbolP);
1353                 symbol_table_insert(symbolP);
1354         } /* not found */
1355
1356         return(symbolP);
1357 } /* tag_find_or_make() */
1358
1359 static symbolS *tag_find(name)
1360 char *name;
1361 {
1362 #ifdef STRIP_UNDERSCORE
1363         if (*name == '_') name++;
1364 #endif /* STRIP_UNDERSCORE */
1365         return((symbolS*)hash_find(tag_hash, name));
1366 } /* tag_find() */
1367
1368 void obj_read_begin_hook() {
1369         /* These had better be the same.  Usually 18 bytes. */
1370 #ifndef BFD_HEADERS
1371         know(sizeof(SYMENT) == sizeof(AUXENT));
1372         know(SYMESZ == AUXESZ);
1373 #endif
1374         tag_init();
1375
1376         return;
1377 } /* obj_read_begin_hook() */
1378
1379 void obj_crawl_symbol_chain(headers)
1380 object_headers *headers;
1381 {
1382         int symbol_number = 0;
1383         lineno *lineP;
1384         symbolS *last_functionP = NULL;
1385         symbolS *last_tagP;
1386         symbolS *symbolP;
1387         symbolS *symbol_externP = NULL;
1388         symbolS *symbol_extern_lastP = NULL;
1389
1390         /* Initialize the stack used to keep track of the matching .bb .be */
1391         stack* block_stack = stack_init(512, sizeof(symbolS*));
1392
1393         /* JF deal with forward references first... */
1394         for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1395
1396                 if (symbolP->sy_forward) {
1397                         S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
1398                                               + S_GET_VALUE(symbolP->sy_forward)
1399                                               + symbolP->sy_forward->sy_frag->fr_address));
1400
1401                         if (
1402 #ifndef TE_I386AIX
1403                             SF_GET_GET_SEGMENT(symbolP)
1404 #else
1405                             SF_GET_GET_SEGMENT(symbolP)
1406                             && S_GET_SEGMENT(symbolP) == SEG_UNKNOWN
1407 #endif /* TE_I386AIX */
1408                             ) {
1409                                 S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
1410                         } /* forward segment also */
1411
1412                         symbolP->sy_forward=0;
1413                 } /* if it has a forward reference */
1414         } /* walk the symbol chain */
1415
1416         tc_crawl_symbol_chain(headers);
1417
1418         /* The symbol list should be ordered according to the following sequence
1419          * order :
1420          * . .file symbol
1421          * . debug entries for functions
1422          * . fake symbols for .text .data and .bss
1423          * . defined symbols
1424          * . undefined symbols
1425          * But this is not mandatory. The only important point is to put the
1426          * undefined symbols at the end of the list.
1427          */
1428
1429         if (symbol_rootP == NULL
1430             || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
1431                 know(!previous_file_symbol);
1432                 c_dot_file_symbol("fake");
1433         } /* Is there a .file symbol ? If not insert one at the beginning. */
1434
1435         /*
1436          * Build up static symbols for .text, .data and .bss
1437          */
1438         dot_text_symbol = (symbolS*)
1439             c_section_symbol(".text",
1440                              0,
1441                              H_GET_TEXT_SIZE(headers),
1442                              0/*text_relocation_number */,
1443                              0/*text_lineno_number */);
1444 #ifdef TE_I386AIX
1445         symbol_remove(dot_text_symbol, &symbol_rootP, &symbol_lastP);
1446         symbol_append(dot_text_symbol, previous_file_symbol,
1447                       &symbol_rootP, &symbol_lastP);
1448 #endif /* TE_I386AIX */
1449
1450         dot_data_symbol = (symbolS*)
1451             c_section_symbol(".data",
1452                              H_GET_TEXT_SIZE(headers),
1453                              H_GET_DATA_SIZE(headers),
1454                              0/*data_relocation_number */,
1455                              0); /* There are no data lineno entries */
1456 #ifdef TE_I386AIX
1457         symbol_remove(dot_data_symbol, &symbol_rootP, &symbol_lastP);
1458         symbol_append(dot_data_symbol, dot_text_symbol,
1459                       &symbol_rootP, &symbol_lastP);
1460 #endif /* TE_I386AIX */
1461
1462         dot_bss_symbol = (symbolS*)
1463             c_section_symbol(".bss",
1464                              H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers),
1465                              H_GET_BSS_SIZE(headers),
1466                              0, /* No relocation for a bss section. */
1467                              0); /* There are no bss lineno entries */
1468 #ifdef TE_I386AIX
1469         symbol_remove(dot_bss_symbol, &symbol_rootP, &symbol_lastP);
1470         symbol_append(dot_bss_symbol, dot_data_symbol,
1471                       &symbol_rootP, &symbol_lastP);
1472 #endif /* TE_I386AIX */
1473
1474 #if defined(DEBUG)
1475         verify_symbol_chain(symbol_rootP, symbol_lastP);
1476 #endif /* DEBUG */
1477
1478         /* Three traversals of symbol chains here.  The
1479            first traversal yanks externals into a temporary
1480            chain, removing the externals from the global
1481            chain, numbers symbols, and does some other guck.
1482            The second traversal is on the temporary chain of
1483            externals and just appends them to the global
1484            chain again, numbering them as we go.  The third
1485            traversal patches pointers to symbols (using sym
1486            indexes).  The last traversal was once done as
1487            part of the first pass, but that fails when a
1488            reference preceeds a definition as the definition
1489            has no number at the time we process the
1490            reference. */
1491
1492         /* Note that symbolP will be NULL at the end of a loop
1493            if an external was at the beginning of the list (it
1494            gets moved off the list).  Hence the weird check in
1495            the loop control.
1496            */
1497         for (symbolP = symbol_rootP;
1498              symbolP;
1499              symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
1500                 if (!SF_GET_DEBUG(symbolP)) {
1501                         /* Debug symbols do not need all this rubbish */
1502                         symbolS* real_symbolP;
1503
1504                         /* L* and C_EFCN symbols never merge. */
1505                         if (!SF_GET_LOCAL(symbolP)
1506                             && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
1507                             && real_symbolP != symbolP) {
1508                                 /* FIXME-SOON: where do dups come from?  Maybe tag references before definitions? xoxorich. */
1509                                 /* Move the debug data from the debug symbol to the
1510                                    real symbol. Do NOT do the oposite (i.e. move from
1511                                    real symbol to debug symbol and remove real symbol from the
1512                                    list.) Because some pointers refer to the real symbol
1513                                    whereas no pointers refer to the debug symbol. */
1514                                 c_symbol_merge(symbolP, real_symbolP);
1515                                 /* Replace the current symbol by the real one */
1516                                 /* The symbols will never be the last or the first
1517                                    because : 1st symbol is .file and 3 last symbols are
1518                                    .text, .data, .bss */
1519                                 symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
1520                                 symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
1521                                 symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1522                                 symbolP = real_symbolP;
1523                         } /* if not local but dup'd */
1524
1525                         if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_DATA)) {
1526                                 S_SET_SEGMENT(symbolP, SEG_TEXT);
1527                         } /* push data into text */
1528
1529                         S_SET_VALUE(symbolP, S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
1530
1531                         if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP)) {
1532                                 S_SET_EXTERNAL(symbolP);
1533                         } else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL) {
1534                                 if (S_GET_SEGMENT(symbolP) == SEG_TEXT){
1535                                         S_SET_STORAGE_CLASS(symbolP, C_LABEL);
1536                                 } else {
1537                                         S_SET_STORAGE_CLASS(symbolP, C_STAT);
1538                                 }
1539                         } /* no storage class yet */
1540
1541                         /* Mainly to speed up if not -g */
1542                         if (SF_GET_PROCESS(symbolP)) {
1543                                 /* Handle the nested blocks auxiliary info. */
1544                                 if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
1545                                         if (!strcmp(S_GET_NAME(symbolP), ".bb"))
1546                                             stack_push(block_stack, (char *) &symbolP);
1547                                         else { /* .eb */
1548                                                 register symbolS* begin_symbolP;
1549                                                 begin_symbolP = *(symbolS**)stack_pop(block_stack);
1550                                                 if (begin_symbolP == (symbolS*)0)
1551                                                     as_warn("mismatched .eb");
1552                                                 else
1553                                                     SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
1554                                         }
1555                                 }
1556                                 /* If we are able to identify the type of a function, and we
1557                                    are out of a function (last_functionP == 0) then, the
1558                                    function symbol will be associated with an auxiliary
1559                                    entry. */
1560                                 if (last_functionP == (symbolS*)0 &&
1561                                     SF_GET_FUNCTION(symbolP)) {
1562                                         last_functionP = symbolP;
1563
1564                                         if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
1565                                                 S_SET_NUMBER_AUXILIARY(symbolP, 1);
1566                                         } /* make it at least 1 */
1567
1568                                         /* Clobber possible stale .dim information. */
1569                                         memset(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
1570                                                '\0', sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
1571                                 }
1572                                 /* The C_FCN doesn't need any additional information.
1573                                    I don't even know if this is needed for sdb. But the
1574                                    standard assembler generates it, so...
1575                                    */
1576                                 if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
1577                                         if (last_functionP == (symbolS*)0)
1578                                             as_fatal("C_EFCN symbol out of scope");
1579                                         SA_SET_SYM_FSIZE(last_functionP,
1580                                                          (long)(S_GET_VALUE(symbolP) -
1581                                                                 S_GET_VALUE(last_functionP)));
1582                                         SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
1583                                         last_functionP = (symbolS*)0;
1584                                 }
1585                         }
1586                 } else if (SF_GET_TAG(symbolP)) {
1587                         /* First descriptor of a structure must point to
1588                            the first slot after the structure description. */
1589                         last_tagP = symbolP;
1590
1591                 } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
1592                         /* +2 take in account the current symbol */
1593                         SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
1594                 } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
1595                         if (S_GET_VALUE(symbolP)) {
1596                                 S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
1597                                 S_SET_VALUE(symbolP, 0);
1598                         } /* no one points at the first .file symbol */
1599                 } /* if debug or tag or eos or file */
1600
1601                 /* We must put the external symbols apart. The loader
1602                    does not bomb if we do not. But the references in
1603                    the endndx field for a .bb symbol are not corrected
1604                    if an external symbol is removed between .bb and .be.
1605                    I.e in the following case :
1606                    [20] .bb endndx = 22
1607                    [21] foo external
1608                    [22] .be
1609                    ld will move the symbol 21 to the end of the list but
1610                    endndx will still be 22 instead of 21. */
1611
1612
1613                 if (SF_GET_LOCAL(symbolP)) {
1614                         /* remove C_EFCN and LOCAL (L...) symbols */
1615                         /* next pointer remains valid */
1616                         symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1617
1618                 } else if (
1619 #ifdef TE_I386AIX
1620                            S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP)
1621 #else /* not TE_I386AIX */
1622                            !S_IS_DEFINED(symbolP) && !S_IS_DEBUG(symbolP) && !SF_GET_STATICS(symbolP)
1623 #endif /* not TE_I386AIX */
1624                            ) {
1625                         /* if external, Remove from the list */
1626                         symbolS *hold = symbol_previous(symbolP);
1627
1628                         symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
1629                         symbol_clear_list_pointers(symbolP);
1630                         symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
1631                         symbolP = hold;
1632                 } else {
1633                         if (SF_GET_STRING(symbolP)) {
1634                                 symbolP->sy_name_offset = string_byte_count;
1635                                 string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
1636                         } else {
1637                                 symbolP->sy_name_offset = 0;
1638                         } /* fix "long" names */
1639
1640                         symbolP->sy_number = symbol_number;
1641                         symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
1642                 } /* if local symbol */
1643         } /* traverse the symbol list */
1644
1645         for (symbolP = symbol_externP; symbol_externP;) {
1646                 symbolS *tmp = symbol_externP;
1647
1648                 /* append */
1649                 symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
1650                 symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
1651
1652                 /* and process */
1653                 if (SF_GET_STRING(tmp)) {
1654                         tmp->sy_name_offset = string_byte_count;
1655                         string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
1656                 } else {
1657                         tmp->sy_name_offset = 0;
1658                 } /* fix "long" names */
1659
1660                 tmp->sy_number = symbol_number;
1661                 symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
1662         } /* append the entire extern chain */
1663
1664         /* When a tag reference preceeds the tag definition,
1665            the definition will not have a number at the time
1666            we process the reference during the first
1667            traversal.  Thus, a second traversal. */
1668
1669         for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1670                 if (SF_GET_TAGGED(symbolP)) {
1671                         SA_SET_SYM_TAGNDX(symbolP, ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
1672                 } /* If the symbol has a tagndx entry, resolve it */
1673         } /* second traversal */
1674
1675         know(symbol_externP == NULL);
1676         know(symbol_extern_lastP == NULL);
1677
1678         /* FIXME-SOMEDAY I'm counting line no's here so we know what to put in the section
1679            headers, and I'm resolving the addresses since I'm not sure how to
1680            do it later. I am NOT resolving the linno's representing functions.
1681            Their symbols need a fileptr pointing to this linno when emitted.
1682            Thus, I resolve them on emit.  xoxorich. */
1683
1684         for (lineP = lineno_rootP; lineP; lineP = lineP->next) {
1685                 if (lineP->line.l_lnno > 0) {
1686                         lineP->line.l_addr.l_paddr += ((fragS*)lineP->frag)->fr_address;
1687                 } else {
1688                         ;
1689                 }
1690                 text_lineno_number++;
1691         } /* for each line number */
1692
1693         H_SET_SYMBOL_TABLE_SIZE(headers, symbol_number);
1694
1695         return;
1696 } /* obj_crawl_symbol_chain() */
1697
1698 /*
1699  * Find strings by crawling along symbol table chain.
1700  */
1701
1702 void obj_emit_strings(where)
1703 char **where;
1704 {
1705         symbolS *symbolP;
1706
1707 #ifdef CROSS_COMPILE
1708         /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
1709         md_number_to_chars(*where, string_byte_count, sizeof(string_byte_count));
1710         *where += sizeof(string_byte_count);
1711 #else /* CROSS_COMPILE */
1712         append(where, (char *) &string_byte_count, (unsigned long) sizeof(string_byte_count));
1713 #endif /* CROSS_COMPILE */
1714
1715         for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1716                 if (SF_GET_STRING(symbolP)) {
1717                         append(where, S_GET_NAME(symbolP), (unsigned long)(strlen(S_GET_NAME(symbolP)) + 1));
1718                 } /* if it has a string */
1719         } /* walk the symbol chain */
1720
1721         return;
1722 } /* obj_emit_strings() */
1723
1724 void obj_pre_write_hook(headers)
1725 object_headers *headers;
1726 {
1727         register int text_relocation_number = 0;
1728         register int data_relocation_number = 0;
1729         register fixS *fixP;
1730
1731         H_SET_MAGIC_NUMBER(headers, FILE_HEADER_MAGIC);
1732         H_SET_ENTRY_POINT(headers, 0);
1733
1734         /* FIXME-SOMEDAY this should be done at
1735            fixup_segment time but I'm going to wait until I
1736            do multiple segments.  xoxorich. */
1737         /* Count the number of relocation entries for text and data */
1738         for (fixP = text_fix_root; fixP; fixP = fixP->fx_next) {
1739                 if (fixP->fx_addsy) {
1740                         ++text_relocation_number;
1741 #ifdef TC_I960
1742                         /* two relocs per callj under coff. */
1743                         if (fixP->fx_callj) {
1744                                 ++text_relocation_number;
1745                         } /* if callj and not already fixed. */
1746 #endif /* TC_I960 */
1747 #ifdef TC_A29K
1748                         /* Count 2 for a constH */
1749                         if (fixP->fx_r_type == RELOC_CONSTH) {
1750                                 ++text_relocation_number;
1751                         }
1752 #endif
1753
1754                 } /* if not yet fixed */
1755         } /* for each fix */
1756
1757         SA_SET_SCN_NRELOC(dot_text_symbol, text_relocation_number);
1758         /* Assign the number of line number entries for the text section */
1759         SA_SET_SCN_NLINNO(dot_text_symbol, text_lineno_number);
1760         /* Assign the size of the section */
1761         SA_SET_SCN_SCNLEN(dot_text_symbol, H_GET_TEXT_SIZE(headers));
1762
1763         for (fixP = data_fix_root; fixP; fixP = fixP->fx_next) {
1764                 if (fixP->fx_addsy) {
1765                         ++data_relocation_number;
1766                 } /* if still relocatable */
1767 #ifdef TC_A29K
1768                 /* Count 2 for a constH */
1769                 if (fixP->fx_r_type == RELOC_CONSTH) {
1770                         ++data_relocation_number;
1771                 }
1772 #endif
1773
1774         } /* for each fix */
1775
1776
1777         SA_SET_SCN_NRELOC(dot_data_symbol, data_relocation_number);
1778         /* Assign the size of the section */
1779         SA_SET_SCN_SCNLEN(dot_data_symbol, H_GET_DATA_SIZE(headers));
1780
1781         /* Assign the size of the section */
1782         SA_SET_SCN_SCNLEN(dot_bss_symbol, H_GET_BSS_SIZE(headers));
1783
1784         /* pre write hook can add relocs (for 960 and 29k coff) so */
1785         headers->relocation_size = text_relocation_number * RELSZ +
1786             data_relocation_number *RELSZ;
1787
1788
1789
1790         /* Fill in extra coff fields */
1791
1792         /* Initialize general line number information. */
1793         H_SET_LINENO_SIZE(headers, text_lineno_number * LINESZ);
1794
1795         /* filehdr */
1796         H_SET_FILE_MAGIC_NUMBER(headers, FILE_HEADER_MAGIC);
1797         H_SET_NUMBER_OF_SECTIONS(headers, 3); /* text+data+bss */
1798 #ifndef OBJ_COFF_OMIT_TIMESTAMP
1799         H_SET_TIME_STAMP(headers, (long)time((long*)0));
1800 #else /* OBJ_COFF_OMIT_TIMESTAMP */
1801         H_SET_TIME_STAMP(headers, 0);
1802 #endif /* OBJ_COFF_OMIT_TIMESTAMP */
1803         H_SET_SYMBOL_TABLE_POINTER(headers, H_GET_SYMBOL_TABLE_FILE_OFFSET(headers));
1804 #if 0
1805         printf("FILHSZ %x\n", FILHSZ);
1806         printf("OBJ_COFF_AOUTHDRSZ %x\n", OBJ_COFF_AOUTHDRSZ);
1807         printf("section headers %x\n", H_GET_NUMBER_OF_SECTIONS(headers)  * SCNHSZ);
1808         printf("get text size %x\n", H_GET_TEXT_SIZE(headers));
1809         printf("get data size %x\n", H_GET_DATA_SIZE(headers));
1810         printf("get relocation size %x\n", H_GET_RELOCATION_SIZE(headers));
1811         printf("get lineno size %x\n", H_GET_LINENO_SIZE(headers));
1812 #endif
1813         /* symbol table size allready set */
1814         H_SET_SIZEOF_OPTIONAL_HEADER(headers, OBJ_COFF_AOUTHDRSZ);
1815
1816         /* do not added the F_RELFLG for the standard COFF.
1817          * The AIX linker complain on file with relocation info striped flag.
1818          */
1819 #ifdef KEEP_RELOC_INFO
1820         H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0)
1821                     | BYTE_ORDERING);
1822 #else
1823         H_SET_FLAGS(headers, (text_lineno_number == 0 ? F_LNNO : 0)
1824                     | ((text_relocation_number + data_relocation_number) ? 0 : F_RELFLG)
1825                     | BYTE_ORDERING);
1826 #endif
1827         /* aouthdr */
1828         /* magic number allready set */
1829         H_SET_VERSION_STAMP(headers, 0);
1830         /* Text, data, bss size; entry point; text_start and data_start are already set */
1831
1832         /* Build section headers */
1833
1834         c_section_header(&text_section_header,
1835                          ".text",
1836                          0,
1837                          H_GET_TEXT_SIZE(headers),
1838                          H_GET_TEXT_FILE_OFFSET(headers),
1839                          (SA_GET_SCN_NRELOC(dot_text_symbol)
1840                           ? H_GET_RELOCATION_FILE_OFFSET(headers)
1841                           : 0),
1842                          (text_lineno_number
1843                           ? H_GET_LINENO_FILE_OFFSET(headers)
1844                           : 0),
1845                          SA_GET_SCN_NRELOC(dot_text_symbol),
1846                          text_lineno_number,
1847                          section_alignment[(int) SEG_TEXT]);
1848
1849         c_section_header(&data_section_header,
1850                          ".data",
1851                          H_GET_TEXT_SIZE(headers),
1852                          H_GET_DATA_SIZE(headers),
1853                          (H_GET_DATA_SIZE(headers)
1854                           ? H_GET_DATA_FILE_OFFSET(headers)
1855                           : 0),
1856                          (SA_GET_SCN_NRELOC(dot_data_symbol)
1857                           ? (H_GET_RELOCATION_FILE_OFFSET(headers)
1858                              + text_section_header.s_nreloc * RELSZ)
1859                           : 0),
1860                          0, /* No line number information */
1861                          SA_GET_SCN_NRELOC(dot_data_symbol),
1862                          0,  /* No line number information */
1863                          section_alignment[(int) SEG_DATA]);
1864
1865         c_section_header(&bss_section_header,
1866                          ".bss",
1867                          H_GET_TEXT_SIZE(headers) + H_GET_DATA_SIZE(headers),
1868                          H_GET_BSS_SIZE(headers),
1869                          0, /* No file offset */
1870                          0, /* No relocation information */
1871                          0, /* No line number information */
1872                          0, /* No relocation information */
1873                          0, /* No line number information */
1874                          section_alignment[(int) SEG_BSS]);
1875
1876         return;
1877 } /* obj_pre_write_hook() */
1878
1879 /* This is a copy from aout.  All I do is neglect to actually build the symbol. */
1880
1881 static void obj_coff_stab(what)
1882 int what;
1883 {
1884         char *string;
1885         expressionS e;
1886         int goof = 0;   /* TRUE if we have aborted. */
1887         int length;
1888         int saved_type = 0;
1889         long longint;
1890         symbolS *symbolP = 0;
1891
1892         if (what == 's') {
1893                 string = demand_copy_C_string(&length);
1894                 SKIP_WHITESPACE();
1895
1896                 if (*input_line_pointer == ',') {
1897                         input_line_pointer++;
1898                 } else {
1899                         as_bad("I need a comma after symbol's name");
1900                         goof = 1;
1901                 } /* better be a comma */
1902         } /* skip the string */
1903
1904         /*
1905          * Input_line_pointer->after ','.  String->symbol name.
1906          */
1907         if (!goof) {
1908                 if (get_absolute_expression_and_terminator(&longint) != ',') {
1909                         as_bad("I want a comma after the n_type expression");
1910                         goof = 1;
1911                         input_line_pointer--; /* Backup over a non-',' char. */
1912                 } /* on error */
1913         } /* no error */
1914
1915         if (!goof) {
1916                 if (get_absolute_expression_and_terminator(&longint) != ',') {
1917                         as_bad("I want a comma after the n_other expression");
1918                         goof = 1;
1919                         input_line_pointer--; /* Backup over a non-',' char. */
1920                 } /* on error */
1921         } /* no error */
1922
1923         if (!goof) {
1924                 get_absolute_expression();
1925
1926                 if (what == 's' || what == 'n') {
1927                         if (*input_line_pointer != ',') {
1928                                 as_bad("I want a comma after the n_desc expression");
1929                                 goof = 1;
1930                         } else {
1931                                 input_line_pointer++;
1932                         } /* on goof */
1933                 } /* not stabd */
1934         } /* no error */
1935
1936         expression(&e);
1937
1938         if (goof) {
1939                 ignore_rest_of_line();
1940         } else {
1941                 demand_empty_rest_of_line();
1942         } /* on error */
1943 } /* obj_coff_stab() */
1944
1945 #ifdef DEBUG
1946 /* for debugging */
1947 char *s_get_name(s)
1948 symbolS *s;
1949 {
1950         return((s == NULL) ? "(NULL)" : S_GET_NAME(s));
1951 } /* s_get_name() */
1952
1953 void symbol_dump() {
1954         symbolS *symbolP;
1955
1956         for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
1957                 printf("%3ld: 0x%lx \"%s\" type = %ld, class = %d, segment = %d\n",
1958                        symbolP->sy_number,
1959                        (unsigned long) symbolP,
1960                        S_GET_NAME(symbolP),
1961                        (long) S_GET_DATA_TYPE(symbolP),
1962                        S_GET_STORAGE_CLASS(symbolP),
1963                        (int) S_GET_SEGMENT(symbolP));
1964         } /* traverse symbols */
1965
1966         return;
1967 } /* symbol_dump() */
1968 #endif /* DEBUG */
1969
1970
1971 /*
1972  * Local Variables:
1973  * comment-column: 0
1974  * fill-column: 131
1975  * End:
1976  */
1977
1978 /* end of obj-coff.c */