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