s/boolean/bfd_boolean/ s/true/TRUE/ s/false/FALSE/. Simplify
[external/binutils.git] / gas / config / obj-coff.c
1 /* coff object file format
2    Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002
4    Free Software Foundation, Inc.
5
6    This file is part of GAS.
7
8    GAS is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    GAS is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to the Free
20    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 #define OBJ_HEADER "obj-coff.h"
24
25 #include "as.h"
26 #include "obstack.h"
27 #include "subsegs.h"
28
29 /* I think this is probably always correct.  */
30 #ifndef KEEP_RELOC_INFO
31 #define KEEP_RELOC_INFO
32 #endif
33
34 /* The BFD_ASSEMBLER version of obj_coff_section will use this macro to set
35    a new section's attributes when a directive has no valid flags or the
36    "w" flag is used. This default should be appropriate for most.  */
37 #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
38 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
39 #endif
40
41 /* This is used to hold the symbol built by a sequence of pseudo-ops
42    from .def and .endef.  */
43 static symbolS *def_symbol_in_progress;
44
45 typedef struct
46   {
47     unsigned long chunk_size;
48     unsigned long element_size;
49     unsigned long size;
50     char *data;
51     unsigned long pointer;
52   }
53 stack;
54
55 static stack *stack_init PARAMS ((unsigned long, unsigned long));
56 static char *stack_push PARAMS ((stack *, char *));
57 static char *stack_pop PARAMS ((stack *));
58 static void tag_init PARAMS ((void));
59 static void tag_insert PARAMS ((const char *, symbolS *));
60 static symbolS *tag_find PARAMS ((char *));
61 static symbolS *tag_find_or_make PARAMS ((char *));
62 static void obj_coff_bss PARAMS ((int));
63 static void obj_coff_weak PARAMS ((int));
64 const char *s_get_name PARAMS ((symbolS * s));
65 static void obj_coff_ln PARAMS ((int));
66 static void obj_coff_def PARAMS ((int));
67 static void obj_coff_endef PARAMS ((int));
68 static void obj_coff_dim PARAMS ((int));
69 static void obj_coff_line PARAMS ((int));
70 static void obj_coff_size PARAMS ((int));
71 static void obj_coff_scl PARAMS ((int));
72 static void obj_coff_tag PARAMS ((int));
73 static void obj_coff_val PARAMS ((int));
74 static void obj_coff_type PARAMS ((int));
75 static void obj_coff_ident PARAMS ((int));
76 #ifdef BFD_ASSEMBLER
77 static void obj_coff_loc PARAMS((int));
78 #endif
79 \f
80 /* stack stuff */
81
82 static stack *
83 stack_init (chunk_size, element_size)
84      unsigned long chunk_size;
85      unsigned long element_size;
86 {
87   stack *st;
88
89   st = (stack *) malloc (sizeof (stack));
90   if (!st)
91     return 0;
92   st->data = malloc (chunk_size);
93   if (!st->data)
94     {
95       free (st);
96       return 0;
97     }
98   st->pointer = 0;
99   st->size = chunk_size;
100   st->chunk_size = chunk_size;
101   st->element_size = element_size;
102   return st;
103 }
104
105 #if 0
106 /* Not currently used.  */
107 static void
108 stack_delete (st)
109      stack *st;
110 {
111   free (st->data);
112   free (st);
113 }
114 #endif
115
116 static char *
117 stack_push (st, element)
118      stack *st;
119      char *element;
120 {
121   if (st->pointer + st->element_size >= st->size)
122     {
123       st->size += st->chunk_size;
124       if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
125         return (char *) 0;
126     }
127   memcpy (st->data + st->pointer, element, st->element_size);
128   st->pointer += st->element_size;
129   return st->data + st->pointer;
130 }
131
132 static char *
133 stack_pop (st)
134      stack *st;
135 {
136   if (st->pointer < st->element_size)
137     {
138       st->pointer = 0;
139       return (char *) 0;
140     }
141   st->pointer -= st->element_size;
142   return st->data + st->pointer;
143 }
144 \f
145 /*
146  * Maintain a list of the tagnames of the structres.
147  */
148
149 static struct hash_control *tag_hash;
150
151 static void
152 tag_init ()
153 {
154   tag_hash = hash_new ();
155 }
156
157 static void
158 tag_insert (name, symbolP)
159      const char *name;
160      symbolS *symbolP;
161 {
162   const char *error_string;
163
164   if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
165     {
166       as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
167                 name, error_string);
168     }
169 }
170
171 static symbolS *
172 tag_find (name)
173      char *name;
174 {
175 #ifdef STRIP_UNDERSCORE
176   if (*name == '_')
177     name++;
178 #endif /* STRIP_UNDERSCORE */
179   return (symbolS *) hash_find (tag_hash, name);
180 }
181
182 static symbolS *
183 tag_find_or_make (name)
184      char *name;
185 {
186   symbolS *symbolP;
187
188   if ((symbolP = tag_find (name)) == NULL)
189     {
190       symbolP = symbol_new (name, undefined_section,
191                             0, &zero_address_frag);
192
193       tag_insert (S_GET_NAME (symbolP), symbolP);
194 #ifdef BFD_ASSEMBLER
195       symbol_table_insert (symbolP);
196 #endif
197     }                           /* not found */
198
199   return symbolP;
200 }
201
202 /* We accept the .bss directive to set the section for backward
203    compatibility with earlier versions of gas.  */
204
205 static void
206 obj_coff_bss (ignore)
207      int ignore ATTRIBUTE_UNUSED;
208 {
209   if (*input_line_pointer == '\n')
210     subseg_new (".bss", get_absolute_expression ());
211   else
212     s_lcomm (0);
213 }
214
215 /* Handle .weak.  This is a GNU extension.  */
216
217 static void
218 obj_coff_weak (ignore)
219      int ignore ATTRIBUTE_UNUSED;
220 {
221   char *name;
222   int c;
223   symbolS *symbolP;
224
225   do
226     {
227       name = input_line_pointer;
228       c = get_symbol_end ();
229       symbolP = symbol_find_or_make (name);
230       *input_line_pointer = c;
231       SKIP_WHITESPACE ();
232
233 #if defined BFD_ASSEMBLER || defined S_SET_WEAK
234       S_SET_WEAK (symbolP);
235 #endif
236
237 #ifdef TE_PE
238       S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
239 #else
240       S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
241 #endif
242
243       if (c == ',')
244         {
245           input_line_pointer++;
246           SKIP_WHITESPACE ();
247           if (*input_line_pointer == '\n')
248             c = '\n';
249         }
250     }
251   while (c == ',');
252
253   demand_empty_rest_of_line ();
254 }
255
256 #ifdef BFD_ASSEMBLER
257
258 static segT fetch_coff_debug_section PARAMS ((void));
259 static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
260 static int S_GET_DATA_TYPE PARAMS ((symbolS *));
261 void c_symbol_merge PARAMS ((symbolS *, symbolS *));
262 static void add_lineno PARAMS ((fragS *, addressT, int));
263
264 #define GET_FILENAME_STRING(X) \
265 ((char*) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
266
267 /* @@ Ick.  */
268 static segT
269 fetch_coff_debug_section ()
270 {
271   static segT debug_section;
272   if (!debug_section)
273     {
274       const asymbol *s;
275       s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0);
276       assert (s != 0);
277       debug_section = s->section;
278     }
279   return debug_section;
280 }
281
282 void
283 SA_SET_SYM_ENDNDX (sym, val)
284      symbolS *sym;
285      symbolS *val;
286 {
287   combined_entry_type *entry, *p;
288
289   entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
290   p = coffsymbol (symbol_get_bfdsym (val))->native;
291   entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
292   entry->fix_end = 1;
293 }
294
295 static void
296 SA_SET_SYM_TAGNDX (sym, val)
297      symbolS *sym;
298      symbolS *val;
299 {
300   combined_entry_type *entry, *p;
301
302   entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
303   p = coffsymbol (symbol_get_bfdsym (val))->native;
304   entry->u.auxent.x_sym.x_tagndx.p = p;
305   entry->fix_tag = 1;
306 }
307
308 static int
309 S_GET_DATA_TYPE (sym)
310      symbolS *sym;
311 {
312   return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
313 }
314
315 int
316 S_SET_DATA_TYPE (sym, val)
317      symbolS *sym;
318      int val;
319 {
320   coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
321   return val;
322 }
323
324 int
325 S_GET_STORAGE_CLASS (sym)
326      symbolS *sym;
327 {
328   return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
329 }
330
331 int
332 S_SET_STORAGE_CLASS (sym, val)
333      symbolS *sym;
334      int val;
335 {
336   coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
337   return val;
338 }
339
340 /* Merge a debug symbol containing debug information into a normal symbol.  */
341
342 void
343 c_symbol_merge (debug, normal)
344      symbolS *debug;
345      symbolS *normal;
346 {
347   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
348   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
349
350   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
351     {
352       /* take the most we have */
353       S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
354     }
355
356   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
357     {
358       /* Move all the auxiliary information.  */
359       memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
360               (S_GET_NUMBER_AUXILIARY (debug)
361                * sizeof (*SYM_AUXINFO (debug))));
362     }
363
364   /* Move the debug flags.  */
365   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
366 }
367
368 void
369 c_dot_file_symbol (filename)
370      const char *filename;
371 {
372   symbolS *symbolP;
373
374   /* BFD converts filename to a .file symbol with an aux entry.  It
375      also handles chaining.  */
376   symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
377
378   S_SET_STORAGE_CLASS (symbolP, C_FILE);
379   S_SET_NUMBER_AUXILIARY (symbolP, 1);
380
381   symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
382
383 #ifndef NO_LISTING
384   {
385     extern int listing;
386     if (listing)
387       {
388         listing_source_file (filename);
389       }
390   }
391 #endif
392
393   /* Make sure that the symbol is first on the symbol chain */
394   if (symbol_rootP != symbolP)
395     {
396       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
397       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
398     }                           /* if not first on the list */
399 }
400
401 /* Line number handling */
402
403 struct line_no {
404   struct line_no *next;
405   fragS *frag;
406   alent l;
407 };
408
409 int coff_line_base;
410
411 /* Symbol of last function, which we should hang line#s off of.  */
412 static symbolS *line_fsym;
413
414 #define in_function()           (line_fsym != 0)
415 #define clear_function()        (line_fsym = 0)
416 #define set_function(F)         (line_fsym = (F), coff_add_linesym (F))
417
418 \f
419 void
420 coff_obj_symbol_new_hook (symbolP)
421      symbolS *symbolP;
422 {
423   long   sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
424   char * s  = (char *) xmalloc (sz);
425
426   memset (s, 0, sz);
427   coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
428
429   S_SET_DATA_TYPE (symbolP, T_NULL);
430   S_SET_STORAGE_CLASS (symbolP, 0);
431   S_SET_NUMBER_AUXILIARY (symbolP, 0);
432
433   if (S_IS_STRING (symbolP))
434     SF_SET_STRING (symbolP);
435
436   if (S_IS_LOCAL (symbolP))
437     SF_SET_LOCAL (symbolP);
438 }
439
440 \f
441 /*
442  * Handle .ln directives.
443  */
444
445 static symbolS *current_lineno_sym;
446 static struct line_no *line_nos;
447 /* @@ Blindly assume all .ln directives will be in the .text section...  */
448 int coff_n_line_nos;
449
450 static void
451 add_lineno (frag, offset, num)
452      fragS *frag;
453      addressT offset;
454      int num;
455 {
456   struct line_no *new_line =
457     (struct line_no *) xmalloc (sizeof (struct line_no));
458   if (!current_lineno_sym)
459     {
460       abort ();
461     }
462
463 #ifndef OBJ_XCOFF
464   /* The native aix assembler accepts negative line number */
465
466   if (num <= 0)
467     {
468       /* Zero is used as an end marker in the file.  */
469       as_warn (_("Line numbers must be positive integers\n"));
470       num = 1;
471     }
472 #endif /* OBJ_XCOFF */
473   new_line->next = line_nos;
474   new_line->frag = frag;
475   new_line->l.line_number = num;
476   new_line->l.u.offset = offset;
477   line_nos = new_line;
478   coff_n_line_nos++;
479 }
480
481 void
482 coff_add_linesym (sym)
483      symbolS *sym;
484 {
485   if (line_nos)
486     {
487       coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
488         (alent *) line_nos;
489       coff_n_line_nos++;
490       line_nos = 0;
491     }
492   current_lineno_sym = sym;
493 }
494
495 static void
496 obj_coff_ln (appline)
497      int appline;
498 {
499   int l;
500
501   if (! appline && def_symbol_in_progress != NULL)
502     {
503       as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
504       demand_empty_rest_of_line ();
505       return;
506     }
507
508   l = get_absolute_expression ();
509
510   /* If there is no lineno symbol, treat a .ln
511      directive as if it were a .appline directive.  */
512   if (appline || current_lineno_sym == NULL)
513     new_logical_line ((char *) NULL, l - 1);
514   else
515     add_lineno (frag_now, frag_now_fix (), l);
516
517 #ifndef NO_LISTING
518   {
519     extern int listing;
520
521     if (listing)
522       {
523         if (! appline)
524           l += coff_line_base - 1;
525         listing_source_line (l);
526       }
527   }
528 #endif
529
530   demand_empty_rest_of_line ();
531 }
532
533 /* .loc is essentially the same as .ln; parse it for assembler
534    compatibility.  */
535
536 static void
537 obj_coff_loc (ignore)
538      int ignore ATTRIBUTE_UNUSED;
539 {
540   int lineno;
541
542   /* FIXME: Why do we need this check?  We need it for ECOFF, but why
543      do we need it for COFF?  */
544   if (now_seg != text_section)
545     {
546       as_warn (_(".loc outside of .text"));
547       demand_empty_rest_of_line ();
548       return;
549     }
550
551   if (def_symbol_in_progress != NULL)
552     {
553       as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
554       demand_empty_rest_of_line ();
555       return;
556     }
557
558   /* Skip the file number.  */
559   SKIP_WHITESPACE ();
560   get_absolute_expression ();
561   SKIP_WHITESPACE ();
562
563   lineno = get_absolute_expression ();
564
565 #ifndef NO_LISTING
566   {
567     extern int listing;
568
569     if (listing)
570       {
571         lineno += coff_line_base - 1;
572         listing_source_line (lineno);
573       }
574   }
575 #endif
576
577   demand_empty_rest_of_line ();
578
579   add_lineno (frag_now, frag_now_fix (), lineno);
580 }
581
582 /* Handle the .ident pseudo-op.  */
583
584 static void
585 obj_coff_ident (ignore)
586      int ignore ATTRIBUTE_UNUSED;
587 {
588   segT current_seg = now_seg;
589   subsegT current_subseg = now_subseg;
590
591 #ifdef TE_PE
592   {
593     segT sec;
594
595     /* We could put it in .comment, but that creates an extra section
596        that shouldn't be loaded into memory, which requires linker
597        changes...  For now, until proven otherwise, use .rdata.  */
598     sec = subseg_new (".rdata$zzz", 0);
599     bfd_set_section_flags (stdoutput, sec,
600                            ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
601                             & bfd_applicable_section_flags (stdoutput)));
602   }
603 #else
604   subseg_new (".comment", 0);
605 #endif
606
607   stringer (1);
608   subseg_set (current_seg, current_subseg);
609 }
610
611 /*
612  *                      def()
613  *
614  * Handle .def directives.
615  *
616  * One might ask : why can't we symbol_new if the symbol does not
617  * already exist and fill it with debug information.  Because of
618  * the C_EFCN special symbol. It would clobber the value of the
619  * function symbol before we have a chance to notice that it is
620  * a C_EFCN. And a second reason is that the code is more clear this
621  * way. (at least I think it is :-).
622  *
623  */
624
625 #define SKIP_SEMI_COLON()       while (*input_line_pointer++ != ';')
626 #define SKIP_WHITESPACES()      while (*input_line_pointer == ' ' || \
627                                        *input_line_pointer == '\t') \
628     input_line_pointer++;
629
630 static void
631 obj_coff_def (what)
632      int what ATTRIBUTE_UNUSED;
633 {
634   char name_end;                /* Char after the end of name */
635   char *symbol_name;            /* Name of the debug symbol */
636   char *symbol_name_copy;       /* Temporary copy of the name */
637   unsigned int symbol_name_length;
638
639   if (def_symbol_in_progress != NULL)
640     {
641       as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
642       demand_empty_rest_of_line ();
643       return;
644     }                           /* if not inside .def/.endef */
645
646   SKIP_WHITESPACES ();
647
648   symbol_name = input_line_pointer;
649 #ifdef STRIP_UNDERSCORE
650   if (symbol_name[0] == '_' && symbol_name[1] != 0)
651     symbol_name++;
652 #endif /* STRIP_UNDERSCORE */
653
654   name_end = get_symbol_end ();
655   symbol_name_length = strlen (symbol_name);
656   symbol_name_copy = xmalloc (symbol_name_length + 1);
657   strcpy (symbol_name_copy, symbol_name);
658 #ifdef tc_canonicalize_symbol_name
659   symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
660 #endif
661
662   /* Initialize the new symbol */
663   def_symbol_in_progress = symbol_make (symbol_name_copy);
664   symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
665   S_SET_VALUE (def_symbol_in_progress, 0);
666
667   if (S_IS_STRING (def_symbol_in_progress))
668     SF_SET_STRING (def_symbol_in_progress);
669
670   *input_line_pointer = name_end;
671
672   demand_empty_rest_of_line ();
673 }
674
675 unsigned int dim_index;
676
677 static void
678 obj_coff_endef (ignore)
679      int ignore ATTRIBUTE_UNUSED;
680 {
681   symbolS *symbolP = NULL;
682
683   /* DIM BUG FIX sac@cygnus.com */
684   dim_index = 0;
685   if (def_symbol_in_progress == NULL)
686     {
687       as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
688       demand_empty_rest_of_line ();
689       return;
690     }                           /* if not inside .def/.endef */
691
692   /* Set the section number according to storage class.  */
693   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
694     {
695     case C_STRTAG:
696     case C_ENTAG:
697     case C_UNTAG:
698       SF_SET_TAG (def_symbol_in_progress);
699       /* intentional fallthrough */
700     case C_FILE:
701     case C_TPDEF:
702       SF_SET_DEBUG (def_symbol_in_progress);
703       S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
704       break;
705
706     case C_EFCN:
707       SF_SET_LOCAL (def_symbol_in_progress);    /* Do not emit this symbol.  */
708       /* intentional fallthrough */
709     case C_BLOCK:
710       SF_SET_PROCESS (def_symbol_in_progress);  /* Will need processing before writing */
711       /* intentional fallthrough */
712     case C_FCN:
713       {
714         const char *name;
715         S_SET_SEGMENT (def_symbol_in_progress, text_section);
716
717         name = S_GET_NAME (def_symbol_in_progress);
718         if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
719           {
720             switch (name[1])
721               {
722               case 'b':
723                 /* .bf */
724                 if (! in_function ())
725                   as_warn (_("`%s' symbol without preceding function"), name);
726                 /* Will need relocating.  */
727                 SF_SET_PROCESS (def_symbol_in_progress);
728                 clear_function ();
729                 break;
730 #ifdef TE_PE
731               case 'e':
732                 /* .ef */
733                 /* The MS compilers output the actual endline, not the
734                    function-relative one... we want to match without
735                    changing the assembler input.  */
736                 SA_SET_SYM_LNNO (def_symbol_in_progress,
737                                  (SA_GET_SYM_LNNO (def_symbol_in_progress)
738                                   + coff_line_base));
739                 break;
740 #endif
741               }
742           }
743       }
744       break;
745
746 #ifdef C_AUTOARG
747     case C_AUTOARG:
748 #endif /* C_AUTOARG */
749     case C_AUTO:
750     case C_REG:
751     case C_ARG:
752     case C_REGPARM:
753     case C_FIELD:
754
755     /* According to the COFF documentation:
756
757        http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
758
759        A special section number (-2) marks symbolic debugging symbols,
760        including structure/union/enumeration tag names, typedefs, and
761        the name of the file. A section number of -1 indicates that the
762        symbol has a value but is not relocatable. Examples of
763        absolute-valued symbols include automatic and register variables,
764        function arguments, and .eos symbols.
765
766        But from Ian Lance Taylor:
767
768        http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
769
770        the actual tools all marked them as section -1. So the GNU COFF
771        assembler follows historical COFF assemblers.
772
773        However, it causes problems for djgpp
774
775        http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
776
777        By defining STRICTCOFF, a COFF port can make the assembler to
778        follow the documented behavior.  */
779 #ifdef STRICTCOFF
780     case C_MOS:
781     case C_MOE:
782     case C_MOU:
783     case C_EOS:
784 #endif
785       SF_SET_DEBUG (def_symbol_in_progress);
786       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
787       break;
788
789 #ifndef STRICTCOFF
790     case C_MOS:
791     case C_MOE:
792     case C_MOU:
793     case C_EOS:
794       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
795       break;
796 #endif
797
798     case C_EXT:
799     case C_WEAKEXT:
800 #ifdef TE_PE
801     case C_NT_WEAK:
802 #endif
803     case C_STAT:
804     case C_LABEL:
805       /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
806       break;
807
808     default:
809     case C_USTATIC:
810     case C_EXTDEF:
811     case C_ULABEL:
812       as_warn (_("unexpected storage class %d"),
813                S_GET_STORAGE_CLASS (def_symbol_in_progress));
814       break;
815     }                           /* switch on storage class */
816
817   /* Now that we have built a debug symbol, try to find if we should
818      merge with an existing symbol or not.  If a symbol is C_EFCN or
819      absolute_section or untagged SEG_DEBUG it never merges.  We also
820      don't merge labels, which are in a different namespace, nor
821      symbols which have not yet been defined since they are typically
822      unique, nor do we merge tags with non-tags.  */
823
824   /* Two cases for functions.  Either debug followed by definition or
825      definition followed by debug.  For definition first, we will
826      merge the debug symbol into the definition.  For debug first, the
827      lineno entry MUST point to the definition function or else it
828      will point off into space when obj_crawl_symbol_chain() merges
829      the debug symbol into the real symbol.  Therefor, let's presume
830      the debug symbol is a real function reference.  */
831
832   /* FIXME-SOON If for some reason the definition label/symbol is
833      never seen, this will probably leave an undefined symbol at link
834      time.  */
835
836   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
837       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
838       || (!strcmp (bfd_get_section_name (stdoutput,
839                                          S_GET_SEGMENT (def_symbol_in_progress)),
840                    "*DEBUG*")
841           && !SF_GET_TAG (def_symbol_in_progress))
842       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
843       || ! symbol_constant_p (def_symbol_in_progress)
844       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
845                                       DO_NOT_STRIP)) == NULL
846       || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
847     {
848       /* If it already is at the end of the symbol list, do nothing */
849       if (def_symbol_in_progress != symbol_lastP)
850         {
851           symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
852           symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
853                          &symbol_lastP);
854         }
855     }
856   else
857     {
858       /* This symbol already exists, merge the newly created symbol
859          into the old one.  This is not mandatory. The linker can
860          handle duplicate symbols correctly. But I guess that it save
861          a *lot* of space if the assembly file defines a lot of
862          symbols. [loic] */
863
864       /* The debug entry (def_symbol_in_progress) is merged into the
865          previous definition.  */
866
867       c_symbol_merge (def_symbol_in_progress, symbolP);
868       symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
869
870       def_symbol_in_progress = symbolP;
871
872       if (SF_GET_FUNCTION (def_symbol_in_progress)
873           || SF_GET_TAG (def_symbol_in_progress)
874           || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
875         {
876           /* For functions, and tags, and static symbols, the symbol
877              *must* be where the debug symbol appears.  Move the
878              existing symbol to the current place.  */
879           /* If it already is at the end of the symbol list, do nothing */
880           if (def_symbol_in_progress != symbol_lastP)
881             {
882               symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
883               symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
884             }
885         }
886     }
887
888   if (SF_GET_TAG (def_symbol_in_progress))
889     {
890       symbolS *oldtag;
891
892       oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
893                                  DO_NOT_STRIP);
894       if (oldtag == NULL || ! SF_GET_TAG (oldtag))
895         tag_insert (S_GET_NAME (def_symbol_in_progress),
896                     def_symbol_in_progress);
897     }
898
899   if (SF_GET_FUNCTION (def_symbol_in_progress))
900     {
901       know (sizeof (def_symbol_in_progress) <= sizeof (long));
902       set_function (def_symbol_in_progress);
903       SF_SET_PROCESS (def_symbol_in_progress);
904
905       if (symbolP == NULL)
906         {
907           /* That is, if this is the first time we've seen the
908              function...  */
909           symbol_table_insert (def_symbol_in_progress);
910         } /* definition follows debug */
911     } /* Create the line number entry pointing to the function being defined */
912
913   def_symbol_in_progress = NULL;
914   demand_empty_rest_of_line ();
915 }
916
917 static void
918 obj_coff_dim (ignore)
919      int ignore ATTRIBUTE_UNUSED;
920 {
921   int dim_index;
922
923   if (def_symbol_in_progress == NULL)
924     {
925       as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
926       demand_empty_rest_of_line ();
927       return;
928     }                           /* if not inside .def/.endef */
929
930   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
931
932   for (dim_index = 0; dim_index < DIMNUM; dim_index++)
933     {
934       SKIP_WHITESPACES ();
935       SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
936                         get_absolute_expression ());
937
938       switch (*input_line_pointer)
939         {
940         case ',':
941           input_line_pointer++;
942           break;
943
944         default:
945           as_warn (_("badly formed .dim directive ignored"));
946           /* intentional fallthrough */
947         case '\n':
948         case ';':
949           dim_index = DIMNUM;
950           break;
951         }
952     }
953
954   demand_empty_rest_of_line ();
955 }
956
957 static void
958 obj_coff_line (ignore)
959      int ignore ATTRIBUTE_UNUSED;
960 {
961   int this_base;
962
963   if (def_symbol_in_progress == NULL)
964     {
965       /* Probably stabs-style line?  */
966       obj_coff_ln (0);
967       return;
968     }
969
970   this_base = get_absolute_expression ();
971   if (!strcmp (".bf", S_GET_NAME (def_symbol_in_progress)))
972     coff_line_base = this_base;
973
974   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
975   SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
976
977   demand_empty_rest_of_line ();
978
979 #ifndef NO_LISTING
980   if (strcmp (".bf", S_GET_NAME (def_symbol_in_progress)) == 0)
981     {
982       extern int listing;
983
984       if (listing)
985         listing_source_line ((unsigned int) this_base);
986     }
987 #endif
988 }
989
990 static void
991 obj_coff_size (ignore)
992      int ignore ATTRIBUTE_UNUSED;
993 {
994   if (def_symbol_in_progress == NULL)
995     {
996       as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
997       demand_empty_rest_of_line ();
998       return;
999     }                           /* if not inside .def/.endef */
1000
1001   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1002   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
1003   demand_empty_rest_of_line ();
1004 }
1005
1006 static void
1007 obj_coff_scl (ignore)
1008      int ignore ATTRIBUTE_UNUSED;
1009 {
1010   if (def_symbol_in_progress == NULL)
1011     {
1012       as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
1013       demand_empty_rest_of_line ();
1014       return;
1015     }                           /* if not inside .def/.endef */
1016
1017   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
1018   demand_empty_rest_of_line ();
1019 }
1020
1021 static void
1022 obj_coff_tag (ignore)
1023      int ignore ATTRIBUTE_UNUSED;
1024 {
1025   char *symbol_name;
1026   char name_end;
1027
1028   if (def_symbol_in_progress == NULL)
1029     {
1030       as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
1031       demand_empty_rest_of_line ();
1032       return;
1033     }
1034
1035   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
1036   symbol_name = input_line_pointer;
1037   name_end = get_symbol_end ();
1038
1039 #ifdef tc_canonicalize_symbol_name
1040   symbol_name = tc_canonicalize_symbol_name (symbol_name);
1041 #endif
1042
1043   /* Assume that the symbol referred to by .tag is always defined.
1044      This was a bad assumption.  I've added find_or_make. xoxorich.  */
1045   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
1046                      tag_find_or_make (symbol_name));
1047   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
1048     {
1049       as_warn (_("tag not found for .tag %s"), symbol_name);
1050     }                           /* not defined */
1051
1052   SF_SET_TAGGED (def_symbol_in_progress);
1053   *input_line_pointer = name_end;
1054
1055   demand_empty_rest_of_line ();
1056 }
1057
1058 static void
1059 obj_coff_type (ignore)
1060      int ignore ATTRIBUTE_UNUSED;
1061 {
1062   if (def_symbol_in_progress == NULL)
1063     {
1064       as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
1065       demand_empty_rest_of_line ();
1066       return;
1067     }                           /* if not inside .def/.endef */
1068
1069   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1070
1071   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1072       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1073     {
1074       SF_SET_FUNCTION (def_symbol_in_progress);
1075     }                           /* is a function */
1076
1077   demand_empty_rest_of_line ();
1078 }
1079
1080 static void
1081 obj_coff_val (ignore)
1082      int ignore ATTRIBUTE_UNUSED;
1083 {
1084   if (def_symbol_in_progress == NULL)
1085     {
1086       as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1087       demand_empty_rest_of_line ();
1088       return;
1089     }                           /* if not inside .def/.endef */
1090
1091   if (is_name_beginner (*input_line_pointer))
1092     {
1093       char *symbol_name = input_line_pointer;
1094       char name_end = get_symbol_end ();
1095
1096 #ifdef tc_canonicalize_symbol_name
1097   symbol_name = tc_canonicalize_symbol_name (symbol_name);
1098 #endif
1099       if (!strcmp (symbol_name, "."))
1100         {
1101           symbol_set_frag (def_symbol_in_progress, frag_now);
1102           S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1103           /* If the .val is != from the .def (e.g. statics) */
1104         }
1105       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
1106         {
1107           expressionS exp;
1108
1109           exp.X_op = O_symbol;
1110           exp.X_add_symbol = symbol_find_or_make (symbol_name);
1111           exp.X_op_symbol = NULL;
1112           exp.X_add_number = 0;
1113           symbol_set_value_expression (def_symbol_in_progress, &exp);
1114
1115           /* If the segment is undefined when the forward reference is
1116              resolved, then copy the segment id from the forward
1117              symbol.  */
1118           SF_SET_GET_SEGMENT (def_symbol_in_progress);
1119
1120           /* FIXME: gcc can generate address expressions here in
1121              unusual cases (search for "obscure" in sdbout.c).  We
1122              just ignore the offset here, thus generating incorrect
1123              debugging information.  We ignore the rest of the line
1124              just below.  */
1125         }
1126       /* Otherwise, it is the name of a non debug symbol and its value
1127          will be calculated later.  */
1128       *input_line_pointer = name_end;
1129     }
1130   else
1131     {
1132       S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1133     }                           /* if symbol based */
1134
1135   demand_empty_rest_of_line ();
1136 }
1137
1138 void
1139 coff_obj_read_begin_hook ()
1140 {
1141   /* These had better be the same.  Usually 18 bytes.  */
1142 #ifndef BFD_HEADERS
1143   know (sizeof (SYMENT) == sizeof (AUXENT));
1144   know (SYMESZ == AUXESZ);
1145 #endif
1146   tag_init ();
1147 }
1148
1149 symbolS *coff_last_function;
1150 static symbolS *coff_last_bf;
1151
1152 void
1153 coff_frob_symbol (symp, punt)
1154      symbolS *symp;
1155      int *punt;
1156 {
1157   static symbolS *last_tagP;
1158   static stack *block_stack;
1159   static symbolS *set_end;
1160   symbolS *next_set_end = NULL;
1161
1162   if (symp == &abs_symbol)
1163     {
1164       *punt = 1;
1165       return;
1166     }
1167
1168   if (current_lineno_sym)
1169     coff_add_linesym ((symbolS *) 0);
1170
1171   if (!block_stack)
1172     block_stack = stack_init (512, sizeof (symbolS*));
1173
1174   if (S_IS_WEAK (symp))
1175     {
1176 #ifdef TE_PE
1177       S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
1178 #else
1179       S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1180 #endif
1181     }
1182
1183   if (!S_IS_DEFINED (symp)
1184       && !S_IS_WEAK (symp)
1185       && S_GET_STORAGE_CLASS (symp) != C_STAT)
1186     S_SET_STORAGE_CLASS (symp, C_EXT);
1187
1188   if (!SF_GET_DEBUG (symp))
1189     {
1190       symbolS * real;
1191
1192       if (!SF_GET_LOCAL (symp)
1193           && !SF_GET_STATICS (symp)
1194           && S_GET_STORAGE_CLASS (symp) != C_LABEL
1195           && symbol_constant_p(symp)
1196           && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
1197           && S_GET_STORAGE_CLASS (real) == C_NULL
1198           && real != symp)
1199         {
1200           c_symbol_merge (symp, real);
1201           *punt = 1;
1202           return;
1203         }
1204
1205       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1206         {
1207           assert (S_GET_VALUE (symp) == 0);
1208           S_SET_EXTERNAL (symp);
1209         }
1210       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1211         {
1212           if (S_GET_SEGMENT (symp) == text_section
1213               && symp != seg_info (text_section)->sym)
1214             S_SET_STORAGE_CLASS (symp, C_LABEL);
1215           else
1216             S_SET_STORAGE_CLASS (symp, C_STAT);
1217         }
1218
1219       if (SF_GET_PROCESS (symp))
1220         {
1221           if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1222             {
1223               if (!strcmp (S_GET_NAME (symp), ".bb"))
1224                 stack_push (block_stack, (char *) &symp);
1225               else
1226                 {
1227                   symbolS *begin;
1228
1229                   begin = *(symbolS **) stack_pop (block_stack);
1230                   if (begin == 0)
1231                     as_warn (_("mismatched .eb"));
1232                   else
1233                     next_set_end = begin;
1234                 }
1235             }
1236
1237           if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1238             {
1239               union internal_auxent *auxp;
1240
1241               coff_last_function = symp;
1242               if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1243                 S_SET_NUMBER_AUXILIARY (symp, 1);
1244               auxp = SYM_AUXENT (symp);
1245               memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1246                       sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1247             }
1248
1249           if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1250             {
1251               if (coff_last_function == 0)
1252                 as_fatal (_("C_EFCN symbol out of scope"));
1253               SA_SET_SYM_FSIZE (coff_last_function,
1254                                 (long) (S_GET_VALUE (symp)
1255                                         - S_GET_VALUE (coff_last_function)));
1256               next_set_end = coff_last_function;
1257               coff_last_function = 0;
1258             }
1259         }
1260
1261       if (S_IS_EXTERNAL (symp))
1262         S_SET_STORAGE_CLASS (symp, C_EXT);
1263       else if (SF_GET_LOCAL (symp))
1264         *punt = 1;
1265
1266       if (SF_GET_FUNCTION (symp))
1267         symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1268
1269       /* more ...  */
1270     }
1271
1272   /* Double check weak symbols.  */
1273   if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1274     as_bad (_("Symbol `%s' can not be both weak and common"),
1275             S_GET_NAME (symp));
1276
1277   if (SF_GET_TAG (symp))
1278     last_tagP = symp;
1279   else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1280     next_set_end = last_tagP;
1281
1282 #ifdef OBJ_XCOFF
1283   /* This is pretty horrible, but we have to set *punt correctly in
1284      order to call SA_SET_SYM_ENDNDX correctly.  */
1285   if (! symbol_used_in_reloc_p (symp)
1286       && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1287           || (! S_IS_EXTERNAL (symp)
1288               && ! symbol_get_tc (symp)->output
1289               && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1290     *punt = 1;
1291 #endif
1292
1293   if (set_end != (symbolS *) NULL
1294       && ! *punt
1295       && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1296           || (S_IS_DEFINED (symp)
1297               && ! S_IS_COMMON (symp)
1298               && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1299     {
1300       SA_SET_SYM_ENDNDX (set_end, symp);
1301       set_end = NULL;
1302     }
1303
1304   if (next_set_end != NULL)
1305     {
1306       if (set_end != NULL)
1307         as_warn ("Warning: internal error: forgetting to set endndx of %s",
1308                  S_GET_NAME (set_end));
1309       set_end = next_set_end;
1310     }
1311
1312 #ifndef OBJ_XCOFF
1313   if (! *punt
1314       && S_GET_STORAGE_CLASS (symp) == C_FCN
1315       && strcmp (S_GET_NAME (symp), ".bf") == 0)
1316     {
1317       if (coff_last_bf != NULL)
1318         SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1319       coff_last_bf = symp;
1320     }
1321 #endif
1322   if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1323     {
1324       int i;
1325       struct line_no *lptr;
1326       alent *l;
1327
1328       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1329       for (i = 0; lptr; lptr = lptr->next)
1330         i++;
1331       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1332
1333       /* We need i entries for line numbers, plus 1 for the first
1334          entry which BFD will override, plus 1 for the last zero
1335          entry (a marker for BFD).  */
1336       l = (alent *) xmalloc ((i + 2) * sizeof (alent));
1337       coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1338       l[i + 1].line_number = 0;
1339       l[i + 1].u.sym = NULL;
1340       for (; i > 0; i--)
1341         {
1342           if (lptr->frag)
1343             lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1344           l[i] = lptr->l;
1345           lptr = lptr->next;
1346         }
1347     }
1348 }
1349
1350 void
1351 coff_adjust_section_syms (abfd, sec, x)
1352      bfd *abfd ATTRIBUTE_UNUSED;
1353      asection *sec;
1354      PTR x ATTRIBUTE_UNUSED;
1355 {
1356   symbolS *secsym;
1357   segment_info_type *seginfo = seg_info (sec);
1358   int nlnno, nrelocs = 0;
1359
1360   /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1361      tc-ppc.c.  Do not get confused by it.  */
1362   if (seginfo == NULL)
1363     return;
1364
1365   if (!strcmp (sec->name, ".text"))
1366     nlnno = coff_n_line_nos;
1367   else
1368     nlnno = 0;
1369   {
1370     /* @@ Hope that none of the fixups expand to more than one reloc
1371        entry...  */
1372     fixS *fixp = seginfo->fix_root;
1373     while (fixp)
1374       {
1375         if (! fixp->fx_done)
1376           nrelocs++;
1377         fixp = fixp->fx_next;
1378       }
1379   }
1380   if (bfd_get_section_size_before_reloc (sec) == 0
1381       && nrelocs == 0
1382       && nlnno == 0
1383       && sec != text_section
1384       && sec != data_section
1385       && sec != bss_section)
1386     return;
1387   secsym = section_symbol (sec);
1388   /* This is an estimate; we'll plug in the real value using
1389      SET_SECTION_RELOCS later */
1390   SA_SET_SCN_NRELOC (secsym, nrelocs);
1391   SA_SET_SCN_NLINNO (secsym, nlnno);
1392 }
1393
1394 void
1395 coff_frob_file_after_relocs ()
1396 {
1397   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
1398 }
1399
1400 /* Implement the .section pseudo op:
1401         .section name {, "flags"}
1402                   ^         ^
1403                   |         +--- optional flags: 'b' for bss
1404                   |                              'i' for info
1405                   +-- section name               'l' for lib
1406                                                  'n' for noload
1407                                                  'o' for over
1408                                                  'w' for data
1409                                                  'd' (apparently m88k for data)
1410                                                  'x' for text
1411                                                  'r' for read-only data
1412                                                  's' for shared data (PE)
1413    But if the argument is not a quoted string, treat it as a
1414    subsegment number.
1415
1416    Note the 'a' flag is silently ignored.  This allows the same
1417    .section directive to be parsed in both ELF and COFF formats.  */
1418
1419 void
1420 obj_coff_section (ignore)
1421      int ignore ATTRIBUTE_UNUSED;
1422 {
1423   /* Strip out the section name */
1424   char *section_name;
1425   char c;
1426   char *name;
1427   unsigned int exp;
1428   flagword flags, oldflags;
1429   asection *sec;
1430
1431   if (flag_mri)
1432     {
1433       char type;
1434
1435       s_mri_sect (&type);
1436       return;
1437     }
1438
1439   section_name = input_line_pointer;
1440   c = get_symbol_end ();
1441
1442   name = xmalloc (input_line_pointer - section_name + 1);
1443   strcpy (name, section_name);
1444
1445   *input_line_pointer = c;
1446
1447   SKIP_WHITESPACE ();
1448
1449   exp = 0;
1450   flags = SEC_NO_FLAGS;
1451
1452   if (*input_line_pointer == ',')
1453     {
1454       ++input_line_pointer;
1455       SKIP_WHITESPACE ();
1456       if (*input_line_pointer != '"')
1457         exp = get_absolute_expression ();
1458       else
1459         {
1460           ++input_line_pointer;
1461           while (*input_line_pointer != '"'
1462                  && ! is_end_of_line[(unsigned char) *input_line_pointer])
1463             {
1464               switch (*input_line_pointer)
1465                 {
1466                 case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
1467                 case 'n': flags &=~ SEC_LOAD; flags |= SEC_NEVER_LOAD; break;
1468
1469                 case 's': flags |= SEC_SHARED; /* fall through */
1470                 case 'd': flags |= SEC_DATA | SEC_LOAD; /* fall through */
1471                 case 'w': flags &=~ SEC_READONLY; break;
1472
1473                 case 'a': break; /* For compatability with ELF.  */
1474                 case 'x': flags |= SEC_CODE | SEC_LOAD; break;
1475                 case 'r': flags |= SEC_READONLY; break;
1476
1477                 case 'i': /* STYP_INFO */
1478                 case 'l': /* STYP_LIB */
1479                 case 'o': /* STYP_OVER */
1480                   as_warn (_("unsupported section attribute '%c'"),
1481                            *input_line_pointer);
1482                   break;
1483
1484                 default:
1485                   as_warn(_("unknown section attribute '%c'"),
1486                           *input_line_pointer);
1487                   break;
1488                 }
1489               ++input_line_pointer;
1490             }
1491           if (*input_line_pointer == '"')
1492             ++input_line_pointer;
1493         }
1494     }
1495
1496   sec = subseg_new (name, (subsegT) exp);
1497
1498   oldflags = bfd_get_section_flags (stdoutput, sec);
1499   if (oldflags == SEC_NO_FLAGS)
1500     {
1501       /* Set section flags for a new section just created by subseg_new.
1502          Provide a default if no flags were parsed.  */
1503       if (flags == SEC_NO_FLAGS)
1504         flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1505
1506 #ifdef COFF_LONG_SECTION_NAMES
1507       /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1508          sections so adjust_reloc_syms in write.c will correctly handle
1509          relocs which refer to non-local symbols in these sections.  */
1510       if (strncmp (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1) == 0)
1511         flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1512 #endif
1513
1514       if (! bfd_set_section_flags (stdoutput, sec, flags))
1515         as_warn (_("error setting flags for \"%s\": %s"),
1516                  bfd_section_name (stdoutput, sec),
1517                  bfd_errmsg (bfd_get_error ()));
1518     }
1519   else if (flags != SEC_NO_FLAGS)
1520     {
1521       /* This section's attributes have already been set. Warn if the
1522          attributes don't match.  */
1523       flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1524                              | SEC_DATA | SEC_SHARED | SEC_NEVER_LOAD);
1525       if ((flags ^ oldflags) & matchflags)
1526         as_warn (_("Ignoring changed section attributes for %s"), name);
1527     }
1528
1529   demand_empty_rest_of_line ();
1530 }
1531
1532 void
1533 coff_adjust_symtab ()
1534 {
1535   if (symbol_rootP == NULL
1536       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1537     c_dot_file_symbol ("fake");
1538 }
1539
1540 void
1541 coff_frob_section (sec)
1542      segT sec;
1543 {
1544   segT strsec;
1545   char *p;
1546   fragS *fragp;
1547   bfd_vma size, n_entries, mask;
1548   bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1549
1550   /* The COFF back end in BFD requires that all section sizes be
1551      rounded up to multiples of the corresponding section alignments,
1552      supposedly because standard COFF has no other way of encoding alignment
1553      for sections.  If your COFF flavor has a different way of encoding
1554      section alignment, then skip this step, as TICOFF does.  */
1555   size = bfd_get_section_size_before_reloc (sec);
1556   mask = ((bfd_vma) 1 << align_power) - 1;
1557 #if !defined(TICOFF)
1558   if (size & mask)
1559     {
1560       bfd_vma new_size;
1561       fragS *last;
1562
1563       new_size = (size + mask) & ~mask;
1564       bfd_set_section_size (stdoutput, sec, new_size);
1565
1566       /* If the size had to be rounded up, add some padding in
1567          the last non-empty frag.  */
1568       fragp = seg_info (sec)->frchainP->frch_root;
1569       last = seg_info (sec)->frchainP->frch_last;
1570       while (fragp->fr_next != last)
1571         fragp = fragp->fr_next;
1572       last->fr_address = size;
1573       fragp->fr_offset += new_size - size;
1574     }
1575 #endif
1576
1577   /* If the section size is non-zero, the section symbol needs an aux
1578      entry associated with it, indicating the size.  We don't know
1579      all the values yet; coff_frob_symbol will fill them in later.  */
1580 #ifndef TICOFF
1581   if (size != 0
1582       || sec == text_section
1583       || sec == data_section
1584       || sec == bss_section)
1585 #endif
1586     {
1587       symbolS *secsym = section_symbol (sec);
1588
1589       S_SET_STORAGE_CLASS (secsym, C_STAT);
1590       S_SET_NUMBER_AUXILIARY (secsym, 1);
1591       SF_SET_STATICS (secsym);
1592       SA_SET_SCN_SCNLEN (secsym, size);
1593     }
1594
1595   /* @@ these should be in a "stabs.h" file, or maybe as.h */
1596 #ifndef STAB_SECTION_NAME
1597 #define STAB_SECTION_NAME ".stab"
1598 #endif
1599 #ifndef STAB_STRING_SECTION_NAME
1600 #define STAB_STRING_SECTION_NAME ".stabstr"
1601 #endif
1602   if (strcmp (STAB_STRING_SECTION_NAME, sec->name))
1603     return;
1604
1605   strsec = sec;
1606   sec = subseg_get (STAB_SECTION_NAME, 0);
1607   /* size is already rounded up, since other section will be listed first */
1608   size = bfd_get_section_size_before_reloc (strsec);
1609
1610   n_entries = bfd_get_section_size_before_reloc (sec) / 12 - 1;
1611
1612   /* Find first non-empty frag.  It should be large enough.  */
1613   fragp = seg_info (sec)->frchainP->frch_root;
1614   while (fragp && fragp->fr_fix == 0)
1615     fragp = fragp->fr_next;
1616   assert (fragp != 0 && fragp->fr_fix >= 12);
1617
1618   /* Store the values.  */
1619   p = fragp->fr_literal;
1620   bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1621   bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1622 }
1623
1624 void
1625 obj_coff_init_stab_section (seg)
1626      segT seg;
1627 {
1628   char *file;
1629   char *p;
1630   char *stabstr_name;
1631   unsigned int stroff;
1632
1633   /* Make space for this first symbol.  */
1634   p = frag_more (12);
1635   /* Zero it out.  */
1636   memset (p, 0, 12);
1637   as_where (&file, (unsigned int *) NULL);
1638   stabstr_name = (char *) xmalloc (strlen (seg->name) + 4);
1639   strcpy (stabstr_name, seg->name);
1640   strcat (stabstr_name, "str");
1641   stroff = get_stab_string_offset (file, stabstr_name);
1642   know (stroff == 1);
1643   md_number_to_chars (p, stroff, 4);
1644 }
1645
1646 #ifdef DEBUG
1647 /* for debugging */
1648 const char *
1649 s_get_name (s)
1650      symbolS *s;
1651 {
1652   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1653 }
1654
1655 void
1656 symbol_dump ()
1657 {
1658   symbolS *symbolP;
1659
1660   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1661     {
1662       printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1663              (unsigned long) symbolP,
1664              S_GET_NAME(symbolP),
1665              (long) S_GET_DATA_TYPE(symbolP),
1666              S_GET_STORAGE_CLASS(symbolP),
1667              (int) S_GET_SEGMENT(symbolP));
1668     }
1669 }
1670
1671 #endif /* DEBUG */
1672
1673 #else /* not BFD_ASSEMBLER */
1674
1675 #include "frags.h"
1676 /* This is needed because we include internal bfd things.  */
1677 #include <time.h>
1678
1679 #include "libbfd.h"
1680 #include "libcoff.h"
1681
1682 #ifdef TE_PE
1683 #include "coff/pe.h"
1684 #endif
1685
1686 /* The NOP_OPCODE is for the alignment fill value.  Fill with nop so
1687    that we can stick sections together without causing trouble.  */
1688 #ifndef NOP_OPCODE
1689 #define NOP_OPCODE 0x00
1690 #endif
1691
1692 /* The zeroes if symbol name is longer than 8 chars */
1693 #define S_SET_ZEROES(s,v)               ((s)->sy_symbol.ost_entry.n_zeroes = (v))
1694
1695 #define MIN(a,b) ((a) < (b)? (a) : (b))
1696
1697 /* This vector is used to turn a gas internal segment number into a
1698    section number suitable for insertion into a coff symbol table.
1699    This must correspond to seg_info_off_by_4.  */
1700
1701 const short seg_N_TYPE[] =
1702 {                               /* in: segT   out: N_TYPE bits */
1703   C_ABS_SECTION,
1704   1,    2,  3,   4,    5,   6,   7,   8,   9,  10,
1705   11,  12,  13,  14,  15,  16,  17,  18,  19,  20,
1706   21,  22,  23,  24,  25,  26,  27,  28,  29,  30,
1707   31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
1708   C_UNDEF_SECTION,              /* SEG_UNKNOWN */
1709   C_UNDEF_SECTION,              /* SEG_GOOF */
1710   C_UNDEF_SECTION,              /* SEG_EXPR */
1711   C_DEBUG_SECTION,              /* SEG_DEBUG */
1712   C_NTV_SECTION,                /* SEG_NTV */
1713   C_PTV_SECTION,                /* SEG_PTV */
1714   C_REGISTER_SECTION,           /* SEG_REGISTER */
1715 };
1716
1717 int function_lineoff = -1;      /* Offset in line#s where the last function
1718                                    started (the odd entry for line #0) */
1719
1720 /* Structure used to keep the filenames which
1721    are too long around so that we can stick them
1722    into the string table.  */
1723 struct filename_list
1724 {
1725   char *filename;
1726   struct filename_list *next;
1727 };
1728
1729 static struct filename_list *filename_list_head;
1730 static struct filename_list *filename_list_tail;
1731
1732 static symbolS *last_line_symbol;
1733
1734 /* Add 4 to the real value to get the index and compensate the
1735    negatives. This vector is used by S_GET_SEGMENT to turn a coff
1736    section number into a segment number.  */
1737
1738 bfd *abfd;
1739 static symbolS *previous_file_symbol;
1740 static int line_base;
1741
1742 void c_symbol_merge PARAMS ((symbolS *, symbolS *));
1743 symbolS *c_section_symbol PARAMS ((char *, int));
1744 void obj_coff_section PARAMS ((int));
1745 void do_relocs_for PARAMS ((bfd *, object_headers *, unsigned long *));
1746 char * symbol_to_chars PARAMS ((bfd *, char *, symbolS *));
1747 void w_strings PARAMS ((char *));
1748
1749 static void fixup_segment PARAMS ((segment_info_type *, segT));
1750 static void fixup_mdeps PARAMS ((fragS *, object_headers *, segT));
1751 static void fill_section PARAMS ((bfd *,  object_headers *, unsigned long *));
1752 static int c_line_new PARAMS ((symbolS *, long, int, fragS *));
1753 static void w_symbols PARAMS ((bfd *, char *, symbolS *));
1754 static void adjust_stab_section PARAMS ((bfd *, segT));
1755 static void obj_coff_lcomm PARAMS ((int));
1756 static void obj_coff_text PARAMS ((int));
1757 static void obj_coff_data PARAMS ((int));
1758 static unsigned int count_entries_in_chain PARAMS ((unsigned int));
1759 static void coff_header_append PARAMS ((bfd *, object_headers *));
1760 static unsigned int yank_symbols PARAMS ((void));
1761 static unsigned int glue_symbols PARAMS ((symbolS **, symbolS **));
1762 static unsigned int tie_tags PARAMS ((void));
1763 static void crawl_symbols PARAMS ((object_headers *, bfd *));
1764 static void do_linenos_for PARAMS ((bfd *, object_headers *, unsigned long *));
1765 static void remove_subsegs PARAMS ((void));
1766
1767
1768
1769 /* When not using BFD_ASSEMBLER, we permit up to 40 sections.
1770
1771    This array maps a COFF section number into a gas section number.
1772    Because COFF uses negative section numbers, you must add 4 to the
1773    COFF section number when indexing into this array; this is done via
1774    the SEG_INFO_FROM_SECTION_NUMBER macro.  This must correspond to
1775    seg_N_TYPE.  */
1776
1777 static const segT seg_info_off_by_4[] =
1778 {
1779  SEG_PTV,
1780  SEG_NTV,
1781  SEG_DEBUG,
1782  SEG_ABSOLUTE,
1783  SEG_UNKNOWN,
1784  SEG_E0,  SEG_E1,  SEG_E2,  SEG_E3,  SEG_E4,
1785  SEG_E5,  SEG_E6,  SEG_E7,  SEG_E8,  SEG_E9,
1786  SEG_E10, SEG_E11, SEG_E12, SEG_E13, SEG_E14,
1787  SEG_E15, SEG_E16, SEG_E17, SEG_E18, SEG_E19,
1788  SEG_E20, SEG_E21, SEG_E22, SEG_E23, SEG_E24,
1789  SEG_E25, SEG_E26, SEG_E27, SEG_E28, SEG_E29,
1790  SEG_E30, SEG_E31, SEG_E32, SEG_E33, SEG_E34,
1791  SEG_E35, SEG_E36, SEG_E37, SEG_E38, SEG_E39,
1792  (segT) 40,
1793  (segT) 41,
1794  (segT) 42,
1795  (segT) 43,
1796  (segT) 44,
1797  (segT) 45,
1798  (segT) 0,
1799  (segT) 0,
1800  (segT) 0,
1801  SEG_REGISTER
1802 };
1803
1804 #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
1805
1806 static relax_addressT relax_align PARAMS ((relax_addressT, long));
1807
1808 static relax_addressT
1809 relax_align (address, alignment)
1810      relax_addressT address;
1811      long alignment;
1812 {
1813   relax_addressT mask;
1814   relax_addressT new_address;
1815
1816   mask = ~((~0) << alignment);
1817   new_address = (address + mask) & (~mask);
1818   return (new_address - address);
1819 }
1820
1821 segT
1822 s_get_segment (x)
1823      symbolS * x;
1824 {
1825   return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum);
1826 }
1827
1828 static unsigned int size_section PARAMS ((bfd *, unsigned int));
1829
1830 /* Calculate the size of the frag chain and fill in the section header
1831    to contain all of it, also fill in the addr of the sections.  */
1832
1833 static unsigned int
1834 size_section (abfd, idx)
1835      bfd *abfd ATTRIBUTE_UNUSED;
1836      unsigned int idx;
1837 {
1838
1839   unsigned int size = 0;
1840   fragS *frag = segment_info[idx].frchainP->frch_root;
1841
1842   while (frag)
1843     {
1844       size = frag->fr_address;
1845       if (frag->fr_address != size)
1846         {
1847           fprintf (stderr, _("Out of step\n"));
1848           size = frag->fr_address;
1849         }
1850
1851       switch (frag->fr_type)
1852         {
1853 #ifdef TC_COFF_SIZEMACHDEP
1854         case rs_machine_dependent:
1855           size += TC_COFF_SIZEMACHDEP (frag);
1856           break;
1857 #endif
1858         case rs_space:
1859         case rs_fill:
1860         case rs_org:
1861           size += frag->fr_fix;
1862           size += frag->fr_offset * frag->fr_var;
1863           break;
1864         case rs_align:
1865         case rs_align_code:
1866         case rs_align_test:
1867           {
1868             addressT off;
1869
1870             size += frag->fr_fix;
1871             off = relax_align (size, frag->fr_offset);
1872             if (frag->fr_subtype != 0 && off > frag->fr_subtype)
1873               off = 0;
1874             size += off;
1875           }
1876           break;
1877         default:
1878           BAD_CASE (frag->fr_type);
1879           break;
1880         }
1881       frag = frag->fr_next;
1882     }
1883   segment_info[idx].scnhdr.s_size = size;
1884   return size;
1885 }
1886
1887 static unsigned int
1888 count_entries_in_chain (idx)
1889      unsigned int idx;
1890 {
1891   unsigned int nrelocs;
1892   fixS *fixup_ptr;
1893
1894   /* Count the relocations.  */
1895   fixup_ptr = segment_info[idx].fix_root;
1896   nrelocs = 0;
1897   while (fixup_ptr != (fixS *) NULL)
1898     {
1899       if (fixup_ptr->fx_done == 0 && TC_COUNT_RELOC (fixup_ptr))
1900         {
1901 #if defined(TC_A29K) || defined(TC_OR32)
1902           if (fixup_ptr->fx_r_type == RELOC_CONSTH)
1903             nrelocs += 2;
1904           else
1905             nrelocs++;
1906 #else
1907           nrelocs++;
1908 #endif
1909         }
1910
1911       fixup_ptr = fixup_ptr->fx_next;
1912     }
1913   return nrelocs;
1914 }
1915
1916 #ifdef TE_AUX
1917
1918 static int compare_external_relocs PARAMS ((const PTR, const PTR));
1919
1920 /* AUX's ld expects relocations to be sorted.  */
1921
1922 static int
1923 compare_external_relocs (x, y)
1924      const PTR x;
1925      const PTR y;
1926 {
1927   struct external_reloc *a = (struct external_reloc *) x;
1928   struct external_reloc *b = (struct external_reloc *) y;
1929   bfd_vma aadr = bfd_getb32 (a->r_vaddr);
1930   bfd_vma badr = bfd_getb32 (b->r_vaddr);
1931   return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
1932 }
1933
1934 #endif
1935
1936 /* Output all the relocations for a section.  */
1937
1938 void
1939 do_relocs_for (abfd, h, file_cursor)
1940      bfd * abfd;
1941      object_headers * h;
1942      unsigned long *file_cursor;
1943 {
1944   unsigned int nrelocs;
1945   unsigned int idx;
1946   unsigned long reloc_start = *file_cursor;
1947
1948   for (idx = SEG_E0; idx < SEG_LAST; idx++)
1949     {
1950       if (segment_info[idx].scnhdr.s_name[0])
1951         {
1952           struct external_reloc *ext_ptr;
1953           struct external_reloc *external_reloc_vec;
1954           unsigned int external_reloc_size;
1955           unsigned int base = segment_info[idx].scnhdr.s_paddr;
1956           fixS *fix_ptr = segment_info[idx].fix_root;
1957           nrelocs = count_entries_in_chain (idx);
1958
1959           if (nrelocs)
1960             /* Bypass this stuff if no relocs.  This also incidentally
1961                avoids a SCO bug, where free(malloc(0)) tends to crash.  */
1962             {
1963               external_reloc_size = nrelocs * RELSZ;
1964               external_reloc_vec =
1965                 (struct external_reloc *) malloc (external_reloc_size);
1966
1967               ext_ptr = external_reloc_vec;
1968
1969               /* Fill in the internal coff style reloc struct from the
1970                  internal fix list.  */
1971               while (fix_ptr)
1972                 {
1973                   struct internal_reloc intr;
1974
1975                   /* Only output some of the relocations.  */
1976                   if (fix_ptr->fx_done == 0 && TC_COUNT_RELOC (fix_ptr))
1977                     {
1978 #ifdef TC_RELOC_MANGLE
1979                       TC_RELOC_MANGLE (&segment_info[idx], fix_ptr, &intr,
1980                                        base);
1981 #else
1982                       symbolS *dot;
1983                       symbolS *symbol_ptr = fix_ptr->fx_addsy;
1984
1985                       intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
1986                       intr.r_vaddr =
1987                         base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
1988
1989 #ifdef TC_KEEP_FX_OFFSET
1990                       intr.r_offset = fix_ptr->fx_offset;
1991 #else
1992                       intr.r_offset = 0;
1993 #endif
1994
1995                       while (symbol_ptr->sy_value.X_op == O_symbol
1996                              && (! S_IS_DEFINED (symbol_ptr)
1997                                  || S_IS_COMMON (symbol_ptr)))
1998                         {
1999                           symbolS *n;
2000
2001                           /* We must avoid looping, as that can occur
2002                              with a badly written program.  */
2003                           n = symbol_ptr->sy_value.X_add_symbol;
2004                           if (n == symbol_ptr)
2005                             break;
2006                           symbol_ptr = n;
2007                         }
2008
2009                       /* Turn the segment of the symbol into an offset.  */
2010                       if (symbol_ptr)
2011                         {
2012                           resolve_symbol_value (symbol_ptr);
2013                           if (! symbol_ptr->sy_resolved)
2014                             {
2015                               char *file;
2016                               unsigned int line;
2017
2018                               if (expr_symbol_where (symbol_ptr, &file, &line))
2019                                 as_bad_where (file, line,
2020                                               _("unresolved relocation"));
2021                               else
2022                                 as_bad (_("bad relocation: symbol `%s' not in symbol table"),
2023                                         S_GET_NAME (symbol_ptr));
2024                             }
2025
2026                           dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
2027                           if (dot)
2028                             intr.r_symndx = dot->sy_number;
2029                           else
2030                             intr.r_symndx = symbol_ptr->sy_number;
2031                         }
2032                       else
2033                         intr.r_symndx = -1;
2034 #endif
2035                       (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
2036                       ext_ptr++;
2037 #if defined(TC_A29K)
2038                       /* The 29k has a special kludge for the high 16 bit
2039                          reloc.  Two relocations are emited, R_IHIHALF,
2040                          and R_IHCONST. The second one doesn't contain a
2041                          symbol, but uses the value for offset.  */
2042                       if (intr.r_type == R_IHIHALF)
2043                         {
2044                           /* Now emit the second bit.  */
2045                           intr.r_type = R_IHCONST;
2046                           intr.r_symndx = fix_ptr->fx_addnumber;
2047                           (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
2048                           ext_ptr++;
2049                         }
2050 #endif
2051 #if defined(TC_OR32)
2052                       /* The or32 has a special kludge for the high 16 bit
2053                          reloc.  Two relocations are emited, R_IHIHALF,
2054                          and R_IHCONST. The second one doesn't contain a
2055                          symbol, but uses the value for offset.  */
2056                       if (intr.r_type == R_IHIHALF)
2057                         {
2058                           /* Now emit the second bit.  */
2059                           intr.r_type = R_IHCONST;
2060                           intr.r_symndx = fix_ptr->fx_addnumber;
2061                           (void) bfd_coff_swap_reloc_out (abfd, & intr, ext_ptr);
2062                           ext_ptr ++;
2063                         }
2064 #endif
2065                     }
2066
2067                   fix_ptr = fix_ptr->fx_next;
2068                 }
2069 #ifdef TE_AUX
2070               /* Sort the reloc table.  */
2071               qsort ((PTR) external_reloc_vec, nrelocs,
2072                      sizeof (struct external_reloc), compare_external_relocs);
2073 #endif
2074               /* Write out the reloc table.  */
2075               bfd_bwrite ((PTR) external_reloc_vec,
2076                           (bfd_size_type) external_reloc_size, abfd);
2077               free (external_reloc_vec);
2078
2079               /* Fill in section header info.  */
2080               segment_info[idx].scnhdr.s_relptr = *file_cursor;
2081               *file_cursor += external_reloc_size;
2082               segment_info[idx].scnhdr.s_nreloc = nrelocs;
2083             }
2084           else
2085             {
2086               /* No relocs.  */
2087               segment_info[idx].scnhdr.s_relptr = 0;
2088             }
2089         }
2090     }
2091
2092   /* Set relocation_size field in file headers.  */
2093   H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
2094 }
2095
2096 /* Run through a frag chain and write out the data to go with it, fill
2097    in the scnhdrs with the info on the file postions.  */
2098
2099 static void
2100 fill_section (abfd, h, file_cursor)
2101      bfd * abfd;
2102      object_headers *h ATTRIBUTE_UNUSED;
2103      unsigned long *file_cursor;
2104 {
2105   unsigned int i;
2106   unsigned int paddr = 0;
2107
2108   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
2109     {
2110       unsigned int offset = 0;
2111       struct internal_scnhdr *s = &(segment_info[i].scnhdr);
2112
2113       PROGRESS (1);
2114
2115       if (s->s_name[0])
2116         {
2117           fragS *frag = segment_info[i].frchainP->frch_root;
2118           char *buffer = NULL;
2119
2120           if (s->s_size == 0)
2121             s->s_scnptr = 0;
2122           else
2123             {
2124               buffer = xmalloc (s->s_size);
2125               s->s_scnptr = *file_cursor;
2126             }
2127           know (s->s_paddr == paddr);
2128
2129           if (strcmp (s->s_name, ".text") == 0)
2130             s->s_flags |= STYP_TEXT;
2131           else if (strcmp (s->s_name, ".data") == 0)
2132             s->s_flags |= STYP_DATA;
2133           else if (strcmp (s->s_name, ".bss") == 0)
2134             {
2135               s->s_scnptr = 0;
2136               s->s_flags |= STYP_BSS;
2137
2138               /* @@ Should make the i386 and a29k coff targets define
2139                  COFF_NOLOAD_PROBLEM, and have only one test here.  */
2140 #ifndef TC_I386
2141 #ifndef TC_A29K
2142 #ifndef TC_OR32
2143 #ifndef COFF_NOLOAD_PROBLEM
2144               /* Apparently the SVR3 linker (and exec syscall) and UDI
2145                  mondfe progrem are confused by noload sections.  */
2146               s->s_flags |= STYP_NOLOAD;
2147 #endif
2148 #endif
2149 #endif
2150 #endif
2151             }
2152           else if (strcmp (s->s_name, ".lit") == 0)
2153             s->s_flags = STYP_LIT | STYP_TEXT;
2154           else if (strcmp (s->s_name, ".init") == 0)
2155             s->s_flags |= STYP_TEXT;
2156           else if (strcmp (s->s_name, ".fini") == 0)
2157             s->s_flags |= STYP_TEXT;
2158           else if (strncmp (s->s_name, ".comment", 8) == 0)
2159             s->s_flags |= STYP_INFO;
2160
2161           while (frag)
2162             {
2163               unsigned int fill_size;
2164               switch (frag->fr_type)
2165                 {
2166                 case rs_machine_dependent:
2167                   if (frag->fr_fix)
2168                     {
2169                       memcpy (buffer + frag->fr_address,
2170                               frag->fr_literal,
2171                               (unsigned int) frag->fr_fix);
2172                       offset += frag->fr_fix;
2173                     }
2174
2175                   break;
2176                 case rs_space:
2177                 case rs_fill:
2178                 case rs_align:
2179                 case rs_align_code:
2180                 case rs_align_test:
2181                 case rs_org:
2182                   if (frag->fr_fix)
2183                     {
2184                       memcpy (buffer + frag->fr_address,
2185                               frag->fr_literal,
2186                               (unsigned int) frag->fr_fix);
2187                       offset += frag->fr_fix;
2188                     }
2189
2190                   fill_size = frag->fr_var;
2191                   if (fill_size && frag->fr_offset > 0)
2192                     {
2193                       unsigned int count;
2194                       unsigned int off = frag->fr_fix;
2195                       for (count = frag->fr_offset; count; count--)
2196                         {
2197                           if (fill_size + frag->fr_address + off <= s->s_size)
2198                             {
2199                               memcpy (buffer + frag->fr_address + off,
2200                                       frag->fr_literal + frag->fr_fix,
2201                                       fill_size);
2202                               off += fill_size;
2203                               offset += fill_size;
2204                             }
2205                         }
2206                     }
2207                   break;
2208                 case rs_broken_word:
2209                   break;
2210                 default:
2211                   abort ();
2212                 }
2213               frag = frag->fr_next;
2214             }
2215
2216           if (s->s_size != 0)
2217             {
2218               if (s->s_scnptr != 0)
2219                 {
2220                   bfd_bwrite (buffer, s->s_size, abfd);
2221                   *file_cursor += s->s_size;
2222                 }
2223               free (buffer);
2224             }
2225           paddr += s->s_size;
2226         }
2227     }
2228 }
2229
2230 /* Coff file generation & utilities.  */
2231
2232 static void
2233 coff_header_append (abfd, h)
2234      bfd * abfd;
2235      object_headers * h;
2236 {
2237   unsigned int i;
2238   char buffer[1000];
2239   char buffero[1000];
2240 #ifdef COFF_LONG_SECTION_NAMES
2241   unsigned long string_size = 4;
2242 #endif
2243
2244   bfd_seek (abfd, (file_ptr) 0, 0);
2245
2246 #ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
2247   H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
2248   H_SET_VERSION_STAMP (h, 0);
2249   H_SET_ENTRY_POINT (h, 0);
2250   H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
2251   H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
2252   H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
2253                                                              buffero));
2254 #else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2255   H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
2256 #endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
2257
2258   i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
2259
2260   bfd_bwrite (buffer, (bfd_size_type) i, abfd);
2261   bfd_bwrite (buffero, (bfd_size_type) H_GET_SIZEOF_OPTIONAL_HEADER (h), abfd);
2262
2263   for (i = SEG_E0; i < SEG_LAST; i++)
2264     {
2265       if (segment_info[i].scnhdr.s_name[0])
2266         {
2267           unsigned int size;
2268
2269 #ifdef COFF_LONG_SECTION_NAMES
2270           /* Support long section names as found in PE.  This code
2271              must coordinate with that in write_object_file and
2272              w_strings.  */
2273           if (strlen (segment_info[i].name) > SCNNMLEN)
2274             {
2275               memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
2276               sprintf (segment_info[i].scnhdr.s_name, "/%lu", string_size);
2277               string_size += strlen (segment_info[i].name) + 1;
2278             }
2279 #endif
2280           size = bfd_coff_swap_scnhdr_out (abfd,
2281                                            &(segment_info[i].scnhdr),
2282                                            buffer);
2283           if (size == 0)
2284             as_bad (_("bfd_coff_swap_scnhdr_out failed"));
2285           bfd_bwrite (buffer, (bfd_size_type) size, abfd);
2286         }
2287     }
2288 }
2289
2290 char *
2291 symbol_to_chars (abfd, where, symbolP)
2292      bfd * abfd;
2293      char *where;
2294      symbolS * symbolP;
2295 {
2296   unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
2297   unsigned int i;
2298   valueT val;
2299
2300   /* Turn any symbols with register attributes into abs symbols.  */
2301   if (S_GET_SEGMENT (symbolP) == reg_section)
2302     S_SET_SEGMENT (symbolP, absolute_section);
2303
2304   /* At the same time, relocate all symbols to their output value.  */
2305 #ifndef TE_PE
2306   val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
2307          + S_GET_VALUE (symbolP));
2308 #else
2309   val = S_GET_VALUE (symbolP);
2310 #endif
2311
2312   S_SET_VALUE (symbolP, val);
2313
2314   symbolP->sy_symbol.ost_entry.n_value = val;
2315
2316   where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
2317                                   where);
2318
2319   for (i = 0; i < numaux; i++)
2320     {
2321       where += bfd_coff_swap_aux_out (abfd,
2322                                       &symbolP->sy_symbol.ost_auxent[i],
2323                                       S_GET_DATA_TYPE (symbolP),
2324                                       S_GET_STORAGE_CLASS (symbolP),
2325                                       i, numaux, where);
2326     }
2327
2328   return where;
2329 }
2330
2331 void
2332 coff_obj_symbol_new_hook (symbolP)
2333      symbolS *symbolP;
2334 {
2335   char underscore = 0;          /* Symbol has leading _  */
2336
2337   /* Effective symbol.  */
2338   /* Store the pointer in the offset.  */
2339   S_SET_ZEROES (symbolP, 0L);
2340   S_SET_DATA_TYPE (symbolP, T_NULL);
2341   S_SET_STORAGE_CLASS (symbolP, 0);
2342   S_SET_NUMBER_AUXILIARY (symbolP, 0);
2343   /* Additional information.  */
2344   symbolP->sy_symbol.ost_flags = 0;
2345   /* Auxiliary entries.  */
2346   memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);
2347
2348   if (S_IS_STRING (symbolP))
2349     SF_SET_STRING (symbolP);
2350   if (!underscore && S_IS_LOCAL (symbolP))
2351     SF_SET_LOCAL (symbolP);
2352 }
2353
2354 /* Handle .ln directives.  */
2355
2356 static void
2357 obj_coff_ln (appline)
2358      int appline;
2359 {
2360   int l;
2361
2362   if (! appline && def_symbol_in_progress != NULL)
2363     {
2364       /* Wrong context.  */
2365       as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
2366       demand_empty_rest_of_line ();
2367       return;
2368     }
2369
2370   l = get_absolute_expression ();
2371   c_line_new (0, frag_now_fix (), l, frag_now);
2372
2373   if (appline)
2374     new_logical_line ((char *) NULL, l - 1);
2375
2376 #ifndef NO_LISTING
2377   {
2378     extern int listing;
2379
2380     if (listing)
2381       {
2382         if (! appline)
2383           l += line_base - 1;
2384         listing_source_line ((unsigned int) l);
2385       }
2386
2387   }
2388 #endif
2389   demand_empty_rest_of_line ();
2390 }
2391
2392 /* Handle .def directives.
2393  
2394   One might ask : why can't we symbol_new if the symbol does not
2395   already exist and fill it with debug information.  Because of
2396   the C_EFCN special symbol. It would clobber the value of the
2397   function symbol before we have a chance to notice that it is
2398   a C_EFCN. And a second reason is that the code is more clear this
2399   way. (at least I think it is :-).  */
2400
2401 #define SKIP_SEMI_COLON()       while (*input_line_pointer++ != ';')
2402 #define SKIP_WHITESPACES()      while (*input_line_pointer == ' ' || \
2403                                       *input_line_pointer == '\t') \
2404                                          input_line_pointer++;
2405
2406 static void
2407 obj_coff_def (what)
2408      int what ATTRIBUTE_UNUSED;
2409 {
2410   char name_end;                /* Char after the end of name.  */
2411   char *symbol_name;            /* Name of the debug symbol.  */
2412   char *symbol_name_copy;       /* Temporary copy of the name.  */
2413   unsigned int symbol_name_length;
2414
2415   if (def_symbol_in_progress != NULL)
2416     {
2417       as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
2418       demand_empty_rest_of_line ();
2419       return;
2420     }
2421
2422   SKIP_WHITESPACES ();
2423
2424   def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
2425   memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));
2426
2427   symbol_name = input_line_pointer;
2428   name_end = get_symbol_end ();
2429   symbol_name_length = strlen (symbol_name);
2430   symbol_name_copy = xmalloc (symbol_name_length + 1);
2431   strcpy (symbol_name_copy, symbol_name);
2432 #ifdef tc_canonicalize_symbol_name
2433   symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
2434 #endif
2435
2436   /* Initialize the new symbol.  */
2437 #ifdef STRIP_UNDERSCORE
2438   S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
2439                                        ? symbol_name_copy + 1
2440                                        : symbol_name_copy));
2441 #else /* STRIP_UNDERSCORE */
2442   S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
2443 #endif /* STRIP_UNDERSCORE */
2444   /* free(symbol_name_copy); */
2445   def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;
2446   def_symbol_in_progress->sy_number = ~0;
2447   def_symbol_in_progress->sy_frag = &zero_address_frag;
2448   S_SET_VALUE (def_symbol_in_progress, 0);
2449
2450   if (S_IS_STRING (def_symbol_in_progress))
2451     SF_SET_STRING (def_symbol_in_progress);
2452
2453   *input_line_pointer = name_end;
2454
2455   demand_empty_rest_of_line ();
2456 }
2457
2458 unsigned int dim_index;
2459
2460 static void
2461 obj_coff_endef (ignore)
2462      int ignore ATTRIBUTE_UNUSED;
2463 {
2464   symbolS *symbolP = 0;
2465   /* DIM BUG FIX sac@cygnus.com */
2466   dim_index = 0;
2467   if (def_symbol_in_progress == NULL)
2468     {
2469       as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
2470       demand_empty_rest_of_line ();
2471       return;
2472     }
2473
2474   /* Set the section number according to storage class.  */
2475   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
2476     {
2477     case C_STRTAG:
2478     case C_ENTAG:
2479     case C_UNTAG:
2480       SF_SET_TAG (def_symbol_in_progress);
2481       /* Intentional fallthrough.  */
2482
2483     case C_FILE:
2484     case C_TPDEF:
2485       SF_SET_DEBUG (def_symbol_in_progress);
2486       S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
2487       break;
2488
2489     case C_EFCN:
2490       /* Do not emit this symbol.  */
2491       SF_SET_LOCAL (def_symbol_in_progress);
2492       /* Intentional fallthrough. */
2493       
2494     case C_BLOCK:
2495       /* Will need processing before writing.  */
2496       SF_SET_PROCESS (def_symbol_in_progress);
2497       /* Intentional fallthrough.  */
2498
2499     case C_FCN:
2500       S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
2501
2502       if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)
2503         {                       /* .bf */
2504           if (function_lineoff < 0)
2505             fprintf (stderr, _("`.bf' symbol without preceding function\n"));
2506
2507           SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
2508
2509           SF_SET_PROCESS (last_line_symbol);
2510           SF_SET_ADJ_LNNOPTR (last_line_symbol);
2511           SF_SET_PROCESS (def_symbol_in_progress);
2512           function_lineoff = -1;
2513         }
2514
2515       /* Value is always set to .  */
2516       def_symbol_in_progress->sy_frag = frag_now;
2517       S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2518       break;
2519
2520 #ifdef C_AUTOARG
2521     case C_AUTOARG:
2522 #endif /* C_AUTOARG */
2523     case C_AUTO:
2524     case C_REG:
2525     case C_MOS:
2526     case C_MOE:
2527     case C_MOU:
2528     case C_ARG:
2529     case C_REGPARM:
2530     case C_FIELD:
2531     case C_EOS:
2532       SF_SET_DEBUG (def_symbol_in_progress);
2533       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
2534       break;
2535
2536     case C_EXT:
2537     case C_WEAKEXT:
2538 #ifdef TE_PE
2539     case C_NT_WEAK:
2540 #endif
2541     case C_STAT:
2542     case C_LABEL:
2543       /* Valid but set somewhere else (s_comm, s_lcomm, colon).  */
2544       break;
2545
2546     case C_USTATIC:
2547     case C_EXTDEF:
2548     case C_ULABEL:
2549       as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
2550       break;
2551     }
2552
2553   /* Now that we have built a debug symbol, try to find if we should
2554      merge with an existing symbol or not.  If a symbol is C_EFCN or
2555      absolute_section or untagged SEG_DEBUG it never merges.  We also
2556      don't merge labels, which are in a different namespace, nor
2557      symbols which have not yet been defined since they are typically
2558      unique, nor do we merge tags with non-tags.  */
2559
2560   /* Two cases for functions.  Either debug followed by definition or
2561      definition followed by debug.  For definition first, we will
2562      merge the debug symbol into the definition.  For debug first, the
2563      lineno entry MUST point to the definition function or else it
2564      will point off into space when crawl_symbols() merges the debug
2565      symbol into the real symbol.  Therefor, let's presume the debug
2566      symbol is a real function reference.  */
2567
2568   /* FIXME-SOON If for some reason the definition label/symbol is
2569      never seen, this will probably leave an undefined symbol at link
2570      time.  */
2571
2572   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
2573       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
2574       || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
2575           && !SF_GET_TAG (def_symbol_in_progress))
2576       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
2577       || def_symbol_in_progress->sy_value.X_op != O_constant
2578       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
2579       || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
2580     {
2581       symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
2582                      &symbol_lastP);
2583     }
2584   else
2585     {
2586       /* This symbol already exists, merge the newly created symbol
2587          into the old one.  This is not mandatory. The linker can
2588          handle duplicate symbols correctly. But I guess that it save
2589          a *lot* of space if the assembly file defines a lot of
2590          symbols. [loic] */
2591
2592       /* The debug entry (def_symbol_in_progress) is merged into the
2593          previous definition.  */
2594
2595       c_symbol_merge (def_symbol_in_progress, symbolP);
2596       /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich.  */
2597       def_symbol_in_progress = symbolP;
2598
2599       if (SF_GET_FUNCTION (def_symbol_in_progress)
2600           || SF_GET_TAG (def_symbol_in_progress)
2601           || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
2602         {
2603           /* For functions, and tags, and static symbols, the symbol
2604              *must* be where the debug symbol appears.  Move the
2605              existing symbol to the current place.  */
2606           /* If it already is at the end of the symbol list, do nothing.  */
2607           if (def_symbol_in_progress != symbol_lastP)
2608             {
2609               symbol_remove (def_symbol_in_progress, &symbol_rootP,
2610                              &symbol_lastP);
2611               symbol_append (def_symbol_in_progress, symbol_lastP,
2612                              &symbol_rootP, &symbol_lastP);
2613             }
2614         }
2615     }
2616
2617   if (SF_GET_TAG (def_symbol_in_progress))
2618     {
2619       symbolS *oldtag;
2620
2621       oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
2622                                  DO_NOT_STRIP);
2623       if (oldtag == NULL || ! SF_GET_TAG (oldtag))
2624         tag_insert (S_GET_NAME (def_symbol_in_progress),
2625                     def_symbol_in_progress);
2626     }
2627
2628   if (SF_GET_FUNCTION (def_symbol_in_progress))
2629     {
2630       know (sizeof (def_symbol_in_progress) <= sizeof (long));
2631       function_lineoff
2632         = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
2633
2634       SF_SET_PROCESS (def_symbol_in_progress);
2635
2636       if (symbolP == NULL)
2637         {
2638           /* That is, if this is the first time we've seen the
2639              function...  */
2640           symbol_table_insert (def_symbol_in_progress);
2641         }
2642     }
2643
2644   def_symbol_in_progress = NULL;
2645   demand_empty_rest_of_line ();
2646 }
2647
2648 static void
2649 obj_coff_dim (ignore)
2650      int ignore ATTRIBUTE_UNUSED;
2651 {
2652   int dim_index;
2653
2654   if (def_symbol_in_progress == NULL)
2655     {
2656       as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
2657       demand_empty_rest_of_line ();
2658       return;
2659     }
2660
2661   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2662
2663   for (dim_index = 0; dim_index < DIMNUM; dim_index++)
2664     {
2665       SKIP_WHITESPACES ();
2666       SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
2667                         get_absolute_expression ());
2668
2669       switch (*input_line_pointer)
2670         {
2671         case ',':
2672           input_line_pointer++;
2673           break;
2674
2675         default:
2676           as_warn (_("badly formed .dim directive ignored"));
2677           /* Intentional fallthrough.  */
2678
2679         case '\n':
2680         case ';':
2681           dim_index = DIMNUM;
2682           break;
2683         }
2684     }
2685
2686   demand_empty_rest_of_line ();
2687 }
2688
2689 static void
2690 obj_coff_line (ignore)
2691      int ignore ATTRIBUTE_UNUSED;
2692 {
2693   int this_base;
2694   const char *name;
2695
2696   if (def_symbol_in_progress == NULL)
2697     {
2698       obj_coff_ln (0);
2699       return;
2700     }
2701
2702   name = S_GET_NAME (def_symbol_in_progress);
2703   this_base = get_absolute_expression ();
2704
2705   /* Only .bf symbols indicate the use of a new base line number; the
2706      line numbers associated with .ef, .bb, .eb are relative to the
2707      start of the containing function.  */
2708   if (!strcmp (".bf", name))
2709     {
2710 #if 0 /* XXX Can we ever have line numbers going backwards?  */
2711       if (this_base > line_base)
2712 #endif
2713         line_base = this_base;
2714
2715 #ifndef NO_LISTING
2716       {
2717         extern int listing;
2718         if (listing)
2719           listing_source_line ((unsigned int) line_base);
2720       }
2721 #endif
2722     }
2723
2724   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2725   SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
2726
2727   demand_empty_rest_of_line ();
2728 }
2729
2730 static void
2731 obj_coff_size (ignore)
2732      int ignore ATTRIBUTE_UNUSED;
2733 {
2734   if (def_symbol_in_progress == NULL)
2735     {
2736       as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
2737       demand_empty_rest_of_line ();
2738       return;
2739     }
2740
2741   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2742   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
2743   demand_empty_rest_of_line ();
2744 }
2745
2746 static void
2747 obj_coff_scl (ignore)
2748      int ignore ATTRIBUTE_UNUSED;
2749 {
2750   if (def_symbol_in_progress == NULL)
2751     {
2752       as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
2753       demand_empty_rest_of_line ();
2754       return;
2755     }
2756
2757   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
2758   demand_empty_rest_of_line ();
2759 }
2760
2761 static void
2762 obj_coff_tag (ignore)
2763      int ignore ATTRIBUTE_UNUSED;
2764 {
2765   char *symbol_name;
2766   char name_end;
2767
2768   if (def_symbol_in_progress == NULL)
2769     {
2770       as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
2771       demand_empty_rest_of_line ();
2772       return;
2773     }
2774
2775   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
2776   symbol_name = input_line_pointer;
2777   name_end = get_symbol_end ();
2778 #ifdef tc_canonicalize_symbol_name
2779   symbol_name = tc_canonicalize_symbol_name (symbol_name);
2780 #endif
2781
2782   /* Assume that the symbol referred to by .tag is always defined.
2783      This was a bad assumption.  I've added find_or_make. xoxorich.  */
2784   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
2785                      (long) tag_find_or_make (symbol_name));
2786   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
2787     as_warn (_("tag not found for .tag %s"), symbol_name);
2788
2789   SF_SET_TAGGED (def_symbol_in_progress);
2790   *input_line_pointer = name_end;
2791
2792   demand_empty_rest_of_line ();
2793 }
2794
2795 static void
2796 obj_coff_type (ignore)
2797      int ignore ATTRIBUTE_UNUSED;
2798 {
2799   if (def_symbol_in_progress == NULL)
2800     {
2801       as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
2802       demand_empty_rest_of_line ();
2803       return;
2804     }
2805
2806   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
2807
2808   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
2809       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
2810     SF_SET_FUNCTION (def_symbol_in_progress);
2811
2812   demand_empty_rest_of_line ();
2813 }
2814
2815 static void
2816 obj_coff_val (ignore)
2817      int ignore ATTRIBUTE_UNUSED;
2818 {
2819   if (def_symbol_in_progress == NULL)
2820     {
2821       as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
2822       demand_empty_rest_of_line ();
2823       return;
2824     }
2825
2826   if (is_name_beginner (*input_line_pointer))
2827     {
2828       char *symbol_name = input_line_pointer;
2829       char name_end = get_symbol_end ();
2830
2831 #ifdef tc_canonicalize_symbol_name
2832   symbol_name = tc_canonicalize_symbol_name (symbol_name);
2833 #endif
2834
2835       if (!strcmp (symbol_name, "."))
2836         {
2837           def_symbol_in_progress->sy_frag = frag_now;
2838           S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
2839           /* If the .val is != from the .def (e.g. statics).  */
2840         }
2841       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
2842         {
2843           def_symbol_in_progress->sy_value.X_op = O_symbol;
2844           def_symbol_in_progress->sy_value.X_add_symbol =
2845             symbol_find_or_make (symbol_name);
2846           def_symbol_in_progress->sy_value.X_op_symbol = NULL;
2847           def_symbol_in_progress->sy_value.X_add_number = 0;
2848
2849           /* If the segment is undefined when the forward reference is
2850              resolved, then copy the segment id from the forward
2851              symbol.  */
2852           SF_SET_GET_SEGMENT (def_symbol_in_progress);
2853
2854           /* FIXME: gcc can generate address expressions here in
2855              unusual cases (search for "obscure" in sdbout.c).  We
2856              just ignore the offset here, thus generating incorrect
2857              debugging information.  We ignore the rest of the line
2858              just below.  */
2859         }
2860       /* Otherwise, it is the name of a non debug symbol and
2861          its value will be calculated later.  */
2862       *input_line_pointer = name_end;
2863
2864       /* FIXME: this is to avoid an error message in the
2865          FIXME case mentioned just above.  */
2866       while (! is_end_of_line[(unsigned char) *input_line_pointer])
2867         ++input_line_pointer;
2868     }
2869   else
2870     {
2871       S_SET_VALUE (def_symbol_in_progress,
2872                    (valueT) get_absolute_expression ());
2873     }                           /* if symbol based */
2874
2875   demand_empty_rest_of_line ();
2876 }
2877
2878 #ifdef TE_PE
2879
2880 /* Handle the .linkonce pseudo-op.  This is parsed by s_linkonce in
2881    read.c, which then calls this object file format specific routine.  */
2882
2883 void
2884 obj_coff_pe_handle_link_once (type)
2885      enum linkonce_type type;
2886 {
2887   seg_info (now_seg)->scnhdr.s_flags |= IMAGE_SCN_LNK_COMDAT;
2888
2889   /* We store the type in the seg_info structure, and use it to set up
2890      the auxiliary entry for the section symbol in c_section_symbol.  */
2891   seg_info (now_seg)->linkonce = type;
2892 }
2893
2894 #endif /* TE_PE */
2895
2896 void
2897 coff_obj_read_begin_hook ()
2898 {
2899   /* These had better be the same.  Usually 18 bytes.  */
2900 #ifndef BFD_HEADERS
2901   know (sizeof (SYMENT) == sizeof (AUXENT));
2902   know (SYMESZ == AUXESZ);
2903 #endif
2904   tag_init ();
2905 }
2906
2907 /* This function runs through the symbol table and puts all the
2908    externals onto another chain.  */
2909
2910 /* The chain of globals.  */
2911 symbolS *symbol_globalP;
2912 symbolS *symbol_global_lastP;
2913
2914 /* The chain of externals.  */
2915 symbolS *symbol_externP;
2916 symbolS *symbol_extern_lastP;
2917
2918 stack *block_stack;
2919 symbolS *last_functionP;
2920 static symbolS *last_bfP;
2921 symbolS *last_tagP;
2922
2923 static unsigned int
2924 yank_symbols ()
2925 {
2926   symbolS *symbolP;
2927   unsigned int symbol_number = 0;
2928   unsigned int last_file_symno = 0;
2929
2930   struct filename_list *filename_list_scan = filename_list_head;
2931
2932   for (symbolP = symbol_rootP;
2933        symbolP;
2934        symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
2935     {
2936       if (symbolP->sy_mri_common)
2937         {
2938           if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
2939 #ifdef TE_PE
2940               || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
2941 #endif
2942               || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
2943             as_bad (_("%s: global symbols not supported in common sections"),
2944                     S_GET_NAME (symbolP));
2945           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2946           continue;
2947         }
2948
2949       if (!SF_GET_DEBUG (symbolP))
2950         {
2951           /* Debug symbols do not need all this rubbish.  */
2952           symbolS *real_symbolP;
2953
2954           /* L* and C_EFCN symbols never merge.  */
2955           if (!SF_GET_LOCAL (symbolP)
2956               && !SF_GET_STATICS (symbolP)
2957               && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
2958               && symbolP->sy_value.X_op == O_constant
2959               && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
2960               && real_symbolP != symbolP)
2961             {
2962               /* FIXME-SOON: where do dups come from?
2963                  Maybe tag references before definitions? xoxorich.  */
2964               /* Move the debug data from the debug symbol to the
2965                  real symbol. Do NOT do the oposite (i.e. move from
2966                  real symbol to debug symbol and remove real symbol from the
2967                  list.) Because some pointers refer to the real symbol
2968                  whereas no pointers refer to the debug symbol.  */
2969               c_symbol_merge (symbolP, real_symbolP);
2970               /* Replace the current symbol by the real one.  */
2971               /* The symbols will never be the last or the first
2972                  because : 1st symbol is .file and 3 last symbols are
2973                  .text, .data, .bss.  */
2974               symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
2975               symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
2976               symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
2977               symbolP = real_symbolP;
2978             }
2979
2980           if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
2981             S_SET_SEGMENT (symbolP, SEG_E0);
2982
2983           resolve_symbol_value (symbolP);
2984
2985           if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
2986             {
2987               if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
2988                 {
2989                   S_SET_EXTERNAL (symbolP);
2990                 }
2991
2992               else if (S_GET_SEGMENT (symbolP) == SEG_E0)
2993                 S_SET_STORAGE_CLASS (symbolP, C_LABEL);
2994
2995               else
2996                 S_SET_STORAGE_CLASS (symbolP, C_STAT);
2997             }
2998
2999           /* Mainly to speed up if not -g.  */
3000           if (SF_GET_PROCESS (symbolP))
3001             {
3002               /* Handle the nested blocks auxiliary info.  */
3003               if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
3004                 {
3005                   if (!strcmp (S_GET_NAME (symbolP), ".bb"))
3006                     stack_push (block_stack, (char *) &symbolP);
3007                   else
3008                     {
3009                       /* .eb */
3010                       symbolS *begin_symbolP;
3011
3012                       begin_symbolP = *(symbolS **) stack_pop (block_stack);
3013                       if (begin_symbolP == (symbolS *) 0)
3014                         as_warn (_("mismatched .eb"));
3015                       else
3016                         SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
3017                     }
3018                 }
3019               /* If we are able to identify the type of a function, and we
3020                are out of a function (last_functionP == 0) then, the
3021                function symbol will be associated with an auxiliary
3022                entry.  */
3023               if (last_functionP == (symbolS *) 0 &&
3024                   SF_GET_FUNCTION (symbolP))
3025                 {
3026                   last_functionP = symbolP;
3027
3028                   if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
3029                     S_SET_NUMBER_AUXILIARY (symbolP, 1);
3030
3031                   /* Clobber possible stale .dim information.  */
3032 #if 0
3033                   /* Iffed out by steve - this fries the lnnoptr info too.  */
3034                   bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
3035                          sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
3036 #endif
3037                 }
3038               if (S_GET_STORAGE_CLASS (symbolP) == C_FCN)
3039                 {
3040                   if (strcmp (S_GET_NAME (symbolP), ".bf") == 0)
3041                     {
3042                       if (last_bfP != NULL)
3043                         SA_SET_SYM_ENDNDX (last_bfP, symbol_number);
3044                       last_bfP = symbolP;
3045                     }
3046                 }
3047               else if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
3048                 {
3049                   /* I don't even know if this is needed for sdb. But
3050                      the standard assembler generates it, so...  */
3051                   if (last_functionP == (symbolS *) 0)
3052                     as_fatal (_("C_EFCN symbol out of scope"));
3053                   SA_SET_SYM_FSIZE (last_functionP,
3054                                     (long) (S_GET_VALUE (symbolP) -
3055                                             S_GET_VALUE (last_functionP)));
3056                   SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
3057                  last_functionP = (symbolS *) 0;
3058                 }
3059             }
3060         }
3061       else if (SF_GET_TAG (symbolP))
3062         {
3063           /* First descriptor of a structure must point to
3064              the first slot after the structure description.  */
3065           last_tagP = symbolP;
3066
3067         }
3068       else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
3069         {
3070           /* +2 take in account the current symbol.  */
3071           SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
3072         }
3073       else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
3074         {
3075           /* If the filename was too long to fit in the
3076              auxent, put it in the string table.  */
3077           if (SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
3078               && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
3079             {
3080               SA_SET_FILE_FNAME_OFFSET (symbolP, string_byte_count);
3081               string_byte_count += strlen (filename_list_scan->filename) + 1;
3082               filename_list_scan = filename_list_scan->next;
3083             }
3084           if (S_GET_VALUE (symbolP))
3085             {
3086               S_SET_VALUE (symbolP, last_file_symno);
3087               last_file_symno = symbol_number;
3088             }
3089         }
3090
3091 #ifdef tc_frob_coff_symbol
3092       tc_frob_coff_symbol (symbolP);
3093 #endif
3094
3095       /* We must put the external symbols apart. The loader
3096          does not bomb if we do not. But the references in
3097          the endndx field for a .bb symbol are not corrected
3098          if an external symbol is removed between .bb and .be.
3099          I.e in the following case :
3100          [20] .bb endndx = 22
3101          [21] foo external
3102          [22] .be
3103          ld will move the symbol 21 to the end of the list but
3104          endndx will still be 22 instead of 21.  */
3105
3106       if (SF_GET_LOCAL (symbolP))
3107         {
3108           /* Remove C_EFCN and LOCAL (L...) symbols.  */
3109           /* Next pointer remains valid.  */
3110           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3111
3112         }
3113       else if (symbolP->sy_value.X_op == O_symbol
3114                && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
3115         {
3116           /* Skip symbols which were equated to undefined or common
3117              symbols.  */
3118           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3119         }
3120       else if (!S_IS_DEFINED (symbolP)
3121                && !S_IS_DEBUG (symbolP)
3122                && !SF_GET_STATICS (symbolP)
3123                && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3124 #ifdef TE_PE
3125                    || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3126 #endif
3127                    || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
3128         {
3129           /* If external, Remove from the list.  */
3130           symbolS *hold = symbol_previous (symbolP);
3131
3132           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3133           symbol_clear_list_pointers (symbolP);
3134           symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
3135           symbolP = hold;
3136         }
3137       else if (! S_IS_DEBUG (symbolP)
3138                && ! SF_GET_STATICS (symbolP)
3139                && ! SF_GET_FUNCTION (symbolP)
3140                && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
3141 #ifdef TE_PE
3142                    || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
3143 #endif
3144                    || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
3145         {
3146           symbolS *hold = symbol_previous (symbolP);
3147
3148           /* The O'Reilly COFF book says that defined global symbols
3149              come at the end of the symbol table, just before
3150              undefined global symbols.  */
3151           symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3152           symbol_clear_list_pointers (symbolP);
3153           symbol_append (symbolP, symbol_global_lastP, &symbol_globalP,
3154                          &symbol_global_lastP);
3155           symbolP = hold;
3156         }
3157       else
3158         {
3159           if (SF_GET_STRING (symbolP))
3160             {
3161               symbolP->sy_name_offset = string_byte_count;
3162               string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
3163             }
3164           else
3165             {
3166               symbolP->sy_name_offset = 0;
3167             }
3168
3169           symbolP->sy_number = symbol_number;
3170           symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3171         }
3172     }
3173
3174   return symbol_number;
3175 }
3176
3177 static unsigned int
3178 glue_symbols (head, tail)
3179      symbolS **head;
3180      symbolS **tail;
3181 {
3182   unsigned int symbol_number = 0;
3183
3184   while (*head != NULL)
3185     {
3186       symbolS *tmp = *head;
3187
3188       /* Append.  */
3189       symbol_remove (tmp, head, tail);
3190       symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
3191
3192       /* Process.  */
3193       if (SF_GET_STRING (tmp))
3194         {
3195           tmp->sy_name_offset = string_byte_count;
3196           string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
3197         }
3198       else
3199         {
3200           /* Fix "long" names.  */
3201           tmp->sy_name_offset = 0;
3202         }
3203
3204       tmp->sy_number = symbol_number;
3205       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
3206     }
3207
3208   return symbol_number;
3209 }
3210
3211 static unsigned int
3212 tie_tags ()
3213 {
3214   unsigned int symbol_number = 0;
3215   symbolS *symbolP;
3216
3217   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
3218     {
3219       symbolP->sy_number = symbol_number;
3220
3221       if (SF_GET_TAGGED (symbolP))
3222         {
3223           SA_SET_SYM_TAGNDX
3224             (symbolP,
3225              ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
3226         }
3227
3228       symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
3229     }
3230
3231   return symbol_number;
3232 }
3233
3234
3235 static void
3236 crawl_symbols (h, abfd)
3237      object_headers *h;
3238      bfd *abfd ATTRIBUTE_UNUSED;
3239 {
3240   unsigned int i;
3241
3242   /* Initialize the stack used to keep track of the matching .bb .be.  */
3243
3244   block_stack = stack_init (512, sizeof (symbolS *));
3245
3246   /* The symbol list should be ordered according to the following sequence
3247      order :
3248      . .file symbol
3249      . debug entries for functions
3250      . fake symbols for the sections, including .text .data and .bss
3251      . defined symbols
3252      . undefined symbols
3253      But this is not mandatory. The only important point is to put the
3254      undefined symbols at the end of the list.  */
3255
3256   /* Is there a .file symbol ? If not insert one at the beginning.  */
3257   if (symbol_rootP == NULL
3258       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
3259     c_dot_file_symbol ("fake");
3260
3261   /* Build up static symbols for the sections, they are filled in later.  */
3262
3263   for (i = SEG_E0; i < SEG_LAST; i++)
3264     if (segment_info[i].scnhdr.s_name[0])
3265       segment_info[i].dot = c_section_symbol ((char *) segment_info[i].name,
3266                                               i - SEG_E0 + 1);
3267
3268   /* Take all the externals out and put them into another chain.  */
3269   H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
3270   /* Take the externals and glue them onto the end.  */
3271   H_SET_SYMBOL_TABLE_SIZE (h,
3272                            (H_GET_SYMBOL_COUNT (h)
3273                             + glue_symbols (&symbol_globalP,
3274                                             &symbol_global_lastP)
3275                             + glue_symbols (&symbol_externP,
3276                                             &symbol_extern_lastP)));
3277
3278   H_SET_SYMBOL_TABLE_SIZE (h, tie_tags ());
3279   know (symbol_globalP == NULL);
3280   know (symbol_global_lastP == NULL);
3281   know (symbol_externP == NULL);
3282   know (symbol_extern_lastP == NULL);
3283 }
3284
3285 /* Find strings by crawling along symbol table chain.  */
3286
3287 void
3288 w_strings (where)
3289      char *where;
3290 {
3291   symbolS *symbolP;
3292   struct filename_list *filename_list_scan = filename_list_head;
3293
3294   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK.  */
3295   md_number_to_chars (where, (valueT) string_byte_count, 4);
3296   where += 4;
3297
3298 #ifdef COFF_LONG_SECTION_NAMES
3299   /* Support long section names as found in PE.  This code must
3300      coordinate with that in coff_header_append and write_object_file.  */
3301   {
3302     unsigned int i;
3303
3304     for (i = SEG_E0; i < SEG_LAST; i++)
3305       {
3306         if (segment_info[i].scnhdr.s_name[0]
3307             && strlen (segment_info[i].name) > SCNNMLEN)
3308           {
3309             unsigned int size;
3310
3311             size = strlen (segment_info[i].name) + 1;
3312             memcpy (where, segment_info[i].name, size);
3313             where += size;
3314           }
3315       }
3316   }
3317 #endif /* COFF_LONG_SECTION_NAMES */
3318
3319   for (symbolP = symbol_rootP;
3320        symbolP;
3321        symbolP = symbol_next (symbolP))
3322     {
3323       unsigned int size;
3324
3325       if (SF_GET_STRING (symbolP))
3326         {
3327           size = strlen (S_GET_NAME (symbolP)) + 1;
3328           memcpy (where, S_GET_NAME (symbolP), size);
3329           where += size;
3330         }
3331       if (S_GET_STORAGE_CLASS (symbolP) == C_FILE
3332           && SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
3333           && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
3334         {
3335           size = strlen (filename_list_scan->filename) + 1;
3336           memcpy (where, filename_list_scan->filename, size);
3337           filename_list_scan = filename_list_scan ->next;
3338           where += size;
3339         }
3340     }
3341 }
3342
3343 static void
3344 do_linenos_for (abfd, h, file_cursor)
3345      bfd * abfd;
3346      object_headers * h;
3347      unsigned long *file_cursor;
3348 {
3349   unsigned int idx;
3350   unsigned long start = *file_cursor;
3351
3352   for (idx = SEG_E0; idx < SEG_LAST; idx++)
3353     {
3354       segment_info_type *s = segment_info + idx;
3355
3356       if (s->scnhdr.s_nlnno != 0)
3357         {
3358           struct lineno_list *line_ptr;
3359
3360           struct external_lineno *buffer =
3361           (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
3362
3363           struct external_lineno *dst = buffer;
3364
3365           /* Run through the table we've built and turn it into its external
3366              form, take this chance to remove duplicates.  */
3367
3368           for (line_ptr = s->lineno_list_head;
3369                line_ptr != (struct lineno_list *) NULL;
3370                line_ptr = line_ptr->next)
3371             {
3372               if (line_ptr->line.l_lnno == 0)
3373                 {
3374                   /* Turn a pointer to a symbol into the symbols' index,
3375                      provided that it has been initialised.  */
3376                   if (line_ptr->line.l_addr.l_symndx)
3377                     line_ptr->line.l_addr.l_symndx =
3378                       ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
3379                 }
3380               else
3381                 line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
3382
3383               (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
3384               dst++;
3385             }
3386
3387           s->scnhdr.s_lnnoptr = *file_cursor;
3388
3389           bfd_bwrite (buffer, (bfd_size_type) s->scnhdr.s_nlnno * LINESZ, abfd);
3390           free (buffer);
3391
3392           *file_cursor += s->scnhdr.s_nlnno * LINESZ;
3393         }
3394     }
3395
3396   H_SET_LINENO_SIZE (h, *file_cursor - start);
3397 }
3398
3399 /* Now we run through the list of frag chains in a segment and
3400    make all the subsegment frags appear at the end of the
3401    list, as if the seg 0 was extra long.  */
3402
3403 static void
3404 remove_subsegs ()
3405 {
3406   unsigned int i;
3407
3408   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3409     {
3410       frchainS *head = segment_info[i].frchainP;
3411       fragS dummy;
3412       fragS *prev_frag = &dummy;
3413
3414       while (head && head->frch_seg == i)
3415         {
3416           prev_frag->fr_next = head->frch_root;
3417           prev_frag = head->frch_last;
3418           head = head->frch_next;
3419         }
3420       prev_frag->fr_next = 0;
3421     }
3422 }
3423
3424 unsigned long machine;
3425 int coff_flags;
3426
3427 #ifndef SUB_SEGMENT_ALIGN
3428 #ifdef HANDLE_ALIGN
3429 /* The last subsegment gets an aligment corresponding to the alignment
3430    of the section.  This allows proper nop-filling at the end of
3431    code-bearing sections.  */
3432 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN)                                 \
3433   (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG)     \
3434    ? get_recorded_alignment (SEG) : 0)
3435 #else
3436 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 1
3437 #endif
3438 #endif
3439
3440 extern void
3441 write_object_file ()
3442 {
3443   int i;
3444   const char *name;
3445   struct frchain *frchain_ptr;
3446
3447   object_headers headers;
3448   unsigned long file_cursor;
3449   bfd *abfd;
3450   unsigned int addr;
3451   abfd = bfd_openw (out_file_name, TARGET_FORMAT);
3452
3453   if (abfd == 0)
3454     {
3455       as_perror (_("FATAL: Can't create %s"), out_file_name);
3456       exit (EXIT_FAILURE);
3457     }
3458   bfd_set_format (abfd, bfd_object);
3459   bfd_set_arch_mach (abfd, BFD_ARCH, machine);
3460
3461   string_byte_count = 4;
3462
3463   /* Run through all the sub-segments and align them up.  Also
3464      close any open frags.  We tack a .fill onto the end of the
3465      frag chain so that any .align's size can be worked by looking
3466      at the next frag.  */
3467   for (frchain_ptr = frchain_root;
3468        frchain_ptr != (struct frchain *) NULL;
3469        frchain_ptr = frchain_ptr->frch_next)
3470     {
3471       int alignment;
3472
3473       subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
3474
3475       alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr);
3476
3477 #ifdef md_do_align
3478       md_do_align (alignment, (char *) NULL, 0, 0, alignment_done);
3479 #endif
3480       if (subseg_text_p (now_seg))
3481         frag_align_code (alignment, 0);
3482       else
3483         frag_align (alignment, 0, 0);
3484
3485 #ifdef md_do_align
3486     alignment_done:
3487 #endif
3488
3489       frag_wane (frag_now);
3490       frag_now->fr_fix = 0;
3491       know (frag_now->fr_next == NULL);
3492     }
3493
3494   remove_subsegs ();
3495
3496   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3497     relax_segment (segment_info[i].frchainP->frch_root, i);
3498
3499   /* Relaxation has completed.  Freeze all syms.  */
3500   finalize_syms = 1;
3501
3502   H_SET_NUMBER_OF_SECTIONS (&headers, 0);
3503
3504   /* Find out how big the sections are, and set the addresses.  */
3505   addr = 0;
3506   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3507     {
3508       long size;
3509
3510       segment_info[i].scnhdr.s_paddr = addr;
3511       segment_info[i].scnhdr.s_vaddr = addr;
3512
3513       if (segment_info[i].scnhdr.s_name[0])
3514         {
3515           H_SET_NUMBER_OF_SECTIONS (&headers,
3516                                     H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
3517
3518 #ifdef COFF_LONG_SECTION_NAMES
3519           /* Support long section names as found in PE.  This code
3520              must coordinate with that in coff_header_append and
3521              w_strings.  */
3522           {
3523             unsigned int len;
3524
3525             len = strlen (segment_info[i].name);
3526             if (len > SCNNMLEN)
3527               string_byte_count += len + 1;
3528           }
3529 #endif /* COFF_LONG_SECTION_NAMES */
3530         }
3531
3532       size = size_section (abfd, (unsigned int) i);
3533       addr += size;
3534
3535       /* I think the section alignment is only used on the i960; the
3536          i960 needs it, and it should do no harm on other targets.  */
3537 #ifdef ALIGNMENT_IN_S_FLAGS
3538       segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
3539 #else
3540       segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
3541 #endif
3542
3543       if (i == SEG_E0)
3544         H_SET_TEXT_SIZE (&headers, size);
3545       else if (i == SEG_E1)
3546         H_SET_DATA_SIZE (&headers, size);
3547       else if (i == SEG_E2)
3548         H_SET_BSS_SIZE (&headers, size);
3549     }
3550
3551   /* Turn the gas native symbol table shape into a coff symbol table.  */
3552   crawl_symbols (&headers, abfd);
3553
3554   if (string_byte_count == 4)
3555     string_byte_count = 0;
3556
3557   H_SET_STRING_SIZE (&headers, string_byte_count);
3558
3559 #ifdef tc_frob_file
3560   tc_frob_file ();
3561 #endif
3562
3563   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3564     {
3565       fixup_mdeps (segment_info[i].frchainP->frch_root, &headers, i);
3566       fixup_segment (&segment_info[i], i);
3567     }
3568
3569   /* Look for ".stab" segments and fill in their initial symbols
3570      correctly.  */
3571   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
3572     {
3573       name = segment_info[i].name;
3574
3575       if (name != NULL
3576           && strncmp (".stab", name, 5) == 0
3577           && strncmp (".stabstr", name, 8) != 0)
3578         adjust_stab_section (abfd, i);
3579     }
3580
3581   file_cursor = H_GET_TEXT_FILE_OFFSET (&headers);
3582
3583   bfd_seek (abfd, (file_ptr) file_cursor, 0);
3584
3585   /* Plant the data.  */
3586   fill_section (abfd, &headers, &file_cursor);
3587
3588   do_relocs_for (abfd, &headers, &file_cursor);
3589
3590   do_linenos_for (abfd, &headers, &file_cursor);
3591
3592   H_SET_FILE_MAGIC_NUMBER (&headers, COFF_MAGIC);
3593 #ifndef OBJ_COFF_OMIT_TIMESTAMP
3594   H_SET_TIME_STAMP (&headers, (long)time((time_t *)0));
3595 #else
3596   H_SET_TIME_STAMP (&headers, 0);
3597 #endif
3598 #ifdef TC_COFF_SET_MACHINE
3599   TC_COFF_SET_MACHINE (&headers);
3600 #endif
3601
3602 #ifndef COFF_FLAGS
3603 #define COFF_FLAGS 0
3604 #endif
3605
3606 #ifdef KEEP_RELOC_INFO
3607   H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
3608                           COFF_FLAGS | coff_flags));
3609 #else
3610   H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers)     ? 0 : F_LNNO)   |
3611                           (H_GET_RELOCATION_SIZE(&headers) ? 0 : F_RELFLG) |
3612                           COFF_FLAGS | coff_flags));
3613 #endif
3614
3615   {
3616     unsigned int symtable_size = H_GET_SYMBOL_TABLE_SIZE (&headers);
3617     char *buffer1 = xmalloc (symtable_size + string_byte_count + 1);
3618
3619     H_SET_SYMBOL_TABLE_POINTER (&headers, bfd_tell (abfd));
3620     w_symbols (abfd, buffer1, symbol_rootP);
3621     if (string_byte_count > 0)
3622       w_strings (buffer1 + symtable_size);
3623     bfd_bwrite (buffer1, (bfd_size_type) symtable_size + string_byte_count,
3624                 abfd);
3625     free (buffer1);
3626   }
3627
3628   coff_header_append (abfd, &headers);
3629 #if 0
3630   /* Recent changes to write need this, but where it should
3631      go is up to Ken..  */
3632   if (!bfd_close_all_done (abfd))
3633     as_fatal (_("Can't close %s: %s"), out_file_name,
3634               bfd_errmsg (bfd_get_error ()));
3635 #else
3636   {
3637     extern bfd *stdoutput;
3638     stdoutput = abfd;
3639   }
3640 #endif
3641
3642 }
3643
3644 /* Add a new segment.  This is called from subseg_new via the
3645    obj_new_segment macro.  */
3646
3647 segT
3648 obj_coff_add_segment (name)
3649      const char *name;
3650 {
3651   unsigned int i;
3652
3653 #ifndef COFF_LONG_SECTION_NAMES
3654   char buf[SCNNMLEN + 1];
3655
3656   strncpy (buf, name, SCNNMLEN);
3657   buf[SCNNMLEN] = '\0';
3658   name = buf;
3659 #endif
3660
3661   for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
3662     if (strcmp (name, segment_info[i].name) == 0)
3663       return (segT) i;
3664
3665   if (i == SEG_LAST)
3666     {
3667       as_bad (_("Too many new sections; can't add \"%s\""), name);
3668       return now_seg;
3669     }
3670
3671   /* Add a new section.  */
3672   strncpy (segment_info[i].scnhdr.s_name, name,
3673            sizeof (segment_info[i].scnhdr.s_name));
3674   segment_info[i].scnhdr.s_flags = STYP_REG;
3675   segment_info[i].name = xstrdup (name);
3676
3677   return (segT) i;
3678 }
3679
3680 /* Implement the .section pseudo op:
3681         .section name {, "flags"}
3682                   ^         ^
3683                   |         +--- optional flags: 'b' for bss
3684                   |                              'i' for info
3685                   +-- section name               'l' for lib
3686                                                  'n' for noload
3687                                                  'o' for over
3688                                                  'w' for data
3689                                                  'd' (apparently m88k for data)
3690                                                  'x' for text
3691                                                  'r' for read-only data
3692    But if the argument is not a quoted string, treat it as a
3693    subsegment number.  */
3694
3695 void
3696 obj_coff_section (ignore)
3697      int ignore ATTRIBUTE_UNUSED;
3698 {
3699   /* Strip out the section name.  */
3700   char *section_name, *name;
3701   char c;
3702   unsigned int exp;
3703   long flags;
3704
3705   if (flag_mri)
3706     {
3707       char type;
3708
3709       s_mri_sect (&type);
3710       flags = 0;
3711       if (type == 'C')
3712         flags = STYP_TEXT;
3713       else if (type == 'D')
3714         flags = STYP_DATA;
3715       segment_info[now_seg].scnhdr.s_flags |= flags;
3716
3717       return;
3718     }
3719
3720   section_name = input_line_pointer;
3721   c = get_symbol_end ();
3722
3723   name = xmalloc (input_line_pointer - section_name + 1);
3724   strcpy (name, section_name);
3725
3726   *input_line_pointer = c;
3727
3728   exp = 0;
3729   flags = 0;
3730
3731   SKIP_WHITESPACE ();
3732   if (*input_line_pointer == ',')
3733     {
3734       ++input_line_pointer;
3735       SKIP_WHITESPACE ();
3736
3737       if (*input_line_pointer != '"')
3738         exp = get_absolute_expression ();
3739       else
3740         {
3741           ++input_line_pointer;
3742           while (*input_line_pointer != '"'
3743                  && ! is_end_of_line[(unsigned char) *input_line_pointer])
3744             {
3745               switch (*input_line_pointer)
3746                 {
3747                 case 'b': flags |= STYP_BSS;    break;
3748                 case 'i': flags |= STYP_INFO;   break;
3749                 case 'l': flags |= STYP_LIB;    break;
3750                 case 'n': flags |= STYP_NOLOAD; break;
3751                 case 'o': flags |= STYP_OVER;   break;
3752                 case 'd':
3753                 case 'w': flags |= STYP_DATA;   break;
3754                 case 'x': flags |= STYP_TEXT;   break;
3755                 case 'r': flags |= STYP_LIT;    break;
3756                 default:
3757                   as_warn(_("unknown section attribute '%c'"),
3758                           *input_line_pointer);
3759                   break;
3760                 }
3761               ++input_line_pointer;
3762             }
3763           if (*input_line_pointer == '"')
3764             ++input_line_pointer;
3765         }
3766     }
3767
3768   subseg_new (name, (subsegT) exp);
3769
3770   segment_info[now_seg].scnhdr.s_flags |= flags;
3771
3772   demand_empty_rest_of_line ();
3773 }
3774
3775 static void
3776 obj_coff_text (ignore)
3777      int ignore ATTRIBUTE_UNUSED;
3778 {
3779   subseg_new (".text", get_absolute_expression ());
3780 }
3781
3782 static void
3783 obj_coff_data (ignore)
3784      int ignore ATTRIBUTE_UNUSED;
3785 {
3786   if (flag_readonly_data_in_text)
3787     subseg_new (".text", get_absolute_expression () + 1000);
3788   else
3789     subseg_new (".data", get_absolute_expression ());
3790 }
3791
3792 static void
3793 obj_coff_ident (ignore)
3794      int ignore ATTRIBUTE_UNUSED;
3795 {
3796   segT current_seg = now_seg;           /* Save current seg.  */
3797   subsegT current_subseg = now_subseg;
3798
3799   subseg_new (".comment", 0);           /* .comment seg.  */
3800   stringer (1);                         /* Read string.  */
3801   subseg_set (current_seg, current_subseg);     /* Restore current seg.  */
3802 }
3803
3804 void
3805 c_symbol_merge (debug, normal)
3806      symbolS *debug;
3807      symbolS *normal;
3808 {
3809   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
3810   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
3811
3812   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
3813     S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
3814
3815   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
3816     memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
3817             (char *) &debug->sy_symbol.ost_auxent[0],
3818             (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ));
3819
3820   /* Move the debug flags.  */
3821   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
3822 }
3823
3824 static int
3825 c_line_new (symbol, paddr, line_number, frag)
3826      symbolS * symbol;
3827      long paddr;
3828      int line_number;
3829      fragS * frag;
3830 {
3831   struct lineno_list *new_line =
3832   (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
3833
3834   segment_info_type *s = segment_info + now_seg;
3835   new_line->line.l_lnno = line_number;
3836
3837   if (line_number == 0)
3838     {
3839       last_line_symbol = symbol;
3840       new_line->line.l_addr.l_symndx = (long) symbol;
3841     }
3842   else
3843     {
3844       new_line->line.l_addr.l_paddr = paddr;
3845     }
3846
3847   new_line->frag = (char *) frag;
3848   new_line->next = (struct lineno_list *) NULL;
3849
3850   if (s->lineno_list_head == (struct lineno_list *) NULL)
3851     s->lineno_list_head = new_line;
3852   else
3853     s->lineno_list_tail->next = new_line;
3854
3855   s->lineno_list_tail = new_line;
3856   return LINESZ * s->scnhdr.s_nlnno++;
3857 }
3858
3859 void
3860 c_dot_file_symbol (filename)
3861      char *filename;
3862 {
3863   symbolS *symbolP;
3864
3865   symbolP = symbol_new (".file",
3866                         SEG_DEBUG,
3867                         0,
3868                         &zero_address_frag);
3869
3870   S_SET_STORAGE_CLASS (symbolP, C_FILE);
3871   S_SET_NUMBER_AUXILIARY (symbolP, 1);
3872
3873   if (strlen (filename) > FILNMLEN)
3874     {
3875       /* Filename is too long to fit into an auxent,
3876          we stick it into the string table instead.  We keep
3877          a linked list of the filenames we find so we can emit
3878          them later.  */
3879       struct filename_list *f = ((struct filename_list *)
3880                                  xmalloc (sizeof (struct filename_list)));
3881
3882       f->filename = filename;
3883       f->next = 0;
3884
3885       SA_SET_FILE_FNAME_ZEROS (symbolP, 0);
3886       SA_SET_FILE_FNAME_OFFSET (symbolP, 1);
3887
3888       if (filename_list_tail)
3889         filename_list_tail->next = f;
3890       else
3891         filename_list_head = f;
3892       filename_list_tail = f;
3893     }
3894   else
3895     {
3896       SA_SET_FILE_FNAME (symbolP, filename);
3897     }
3898 #ifndef NO_LISTING
3899   {
3900     extern int listing;
3901     if (listing)
3902       listing_source_file (filename);
3903   }
3904 #endif
3905   SF_SET_DEBUG (symbolP);
3906   S_SET_VALUE (symbolP, (valueT) previous_file_symbol);
3907
3908   previous_file_symbol = symbolP;
3909
3910   /* Make sure that the symbol is first on the symbol chain.  */
3911   if (symbol_rootP != symbolP)
3912     {
3913       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
3914       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
3915     }
3916 }
3917
3918 /* Build a 'section static' symbol.  */
3919
3920 symbolS *
3921 c_section_symbol (name, idx)
3922      char *name;
3923      int idx;
3924 {
3925   symbolS *symbolP;
3926
3927   symbolP = symbol_find_base (name, DO_NOT_STRIP);
3928   if (symbolP == NULL)
3929     symbolP = symbol_new (name, idx, 0, &zero_address_frag);
3930   else
3931     {
3932       /* Mmmm.  I just love violating interfaces.  Makes me feel...dirty.  */
3933       S_SET_SEGMENT (symbolP, idx);
3934       symbolP->sy_frag = &zero_address_frag;
3935     }
3936
3937   S_SET_STORAGE_CLASS (symbolP, C_STAT);
3938   S_SET_NUMBER_AUXILIARY (symbolP, 1);
3939
3940   SF_SET_STATICS (symbolP);
3941
3942 #ifdef TE_DELTA
3943   /* manfred@s-direktnet.de: section symbols *must* have the LOCAL bit cleared,
3944      which is set by the new definition of LOCAL_LABEL in tc-m68k.h.  */
3945   SF_CLEAR_LOCAL (symbolP);
3946 #endif
3947 #ifdef TE_PE
3948   /* If the .linkonce pseudo-op was used for this section, we must
3949      store the information in the auxiliary entry for the section
3950      symbol.  */
3951   if (segment_info[idx].linkonce != LINKONCE_UNSET)
3952     {
3953       int type;
3954
3955       switch (segment_info[idx].linkonce)
3956         {
3957         default:
3958           abort ();
3959         case LINKONCE_DISCARD:
3960           type = IMAGE_COMDAT_SELECT_ANY;
3961           break;
3962         case LINKONCE_ONE_ONLY:
3963           type = IMAGE_COMDAT_SELECT_NODUPLICATES;
3964           break;
3965         case LINKONCE_SAME_SIZE:
3966           type = IMAGE_COMDAT_SELECT_SAME_SIZE;
3967           break;
3968         case LINKONCE_SAME_CONTENTS:
3969           type = IMAGE_COMDAT_SELECT_EXACT_MATCH;
3970           break;
3971         }
3972
3973       SYM_AUXENT (symbolP)->x_scn.x_comdat = type;
3974     }
3975 #endif /* TE_PE */
3976
3977   return symbolP;
3978 }
3979
3980 static void
3981 w_symbols (abfd, where, symbol_rootP)
3982      bfd * abfd;
3983      char *where;
3984      symbolS * symbol_rootP;
3985 {
3986   symbolS *symbolP;
3987   unsigned int i;
3988
3989   /* First fill in those values we have only just worked out.  */
3990   for (i = SEG_E0; i < SEG_LAST; i++)
3991     {
3992       symbolP = segment_info[i].dot;
3993       if (symbolP)
3994         {
3995           SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
3996           SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
3997           SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
3998         }
3999     }
4000
4001   /* Emit all symbols left in the symbol chain.  */
4002   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
4003     {
4004       /* Used to save the offset of the name. It is used to point
4005          to the string in memory but must be a file offset.  */
4006       char *temp;
4007
4008       /* We can't fix the lnnoptr field in yank_symbols with the other
4009          adjustments, because we have to wait until we know where they
4010          go in the file.  */
4011       if (SF_GET_ADJ_LNNOPTR (symbolP))
4012         SA_GET_SYM_LNNOPTR (symbolP) +=
4013           segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr;
4014
4015       tc_coff_symbol_emit_hook (symbolP);
4016
4017       temp = S_GET_NAME (symbolP);
4018       if (SF_GET_STRING (symbolP))
4019         {
4020           S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
4021           S_SET_ZEROES (symbolP, 0);
4022         }
4023       else
4024         {
4025           memset (symbolP->sy_symbol.ost_entry.n_name, 0, SYMNMLEN);
4026           strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
4027         }
4028       where = symbol_to_chars (abfd, where, symbolP);
4029       S_SET_NAME (symbolP, temp);
4030     }
4031 }
4032
4033 static void
4034 obj_coff_lcomm (ignore)
4035      int ignore ATTRIBUTE_UNUSED;
4036 {
4037   s_lcomm(0);
4038   return;
4039 #if 0
4040   char *name;
4041   char c;
4042   int temp;
4043   char *p;
4044
4045   symbolS *symbolP;
4046
4047   name = input_line_pointer;
4048
4049   c = get_symbol_end ();
4050   p = input_line_pointer;
4051   *p = c;
4052   SKIP_WHITESPACE ();
4053   if (*input_line_pointer != ',')
4054     {
4055       as_bad (_("Expected comma after name"));
4056       ignore_rest_of_line ();
4057       return;
4058     }
4059   if (*input_line_pointer == '\n')
4060     {
4061       as_bad (_("Missing size expression"));
4062       return;
4063     }
4064   input_line_pointer++;
4065   if ((temp = get_absolute_expression ()) < 0)
4066     {
4067       as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
4068       ignore_rest_of_line ();
4069       return;
4070     }
4071   *p = 0;
4072
4073   symbolP = symbol_find_or_make (name);
4074
4075   if (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN &&
4076       S_GET_VALUE (symbolP) == 0)
4077     {
4078       if (! need_pass_2)
4079         {
4080           char *p;
4081           segT current_seg = now_seg;   /* Save current seg.  */
4082           subsegT current_subseg = now_subseg;
4083
4084           subseg_set (SEG_E2, 1);
4085           symbolP->sy_frag = frag_now;
4086           p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
4087                        (offsetT) temp, (char *) 0);
4088           *p = 0;
4089           subseg_set (current_seg, current_subseg); /* Restore current seg.  */
4090           S_SET_SEGMENT (symbolP, SEG_E2);
4091           S_SET_STORAGE_CLASS (symbolP, C_STAT);
4092         }
4093     }
4094   else
4095     as_bad (_("Symbol %s already defined"), name);
4096
4097   demand_empty_rest_of_line ();
4098 #endif
4099 }
4100
4101 static void
4102 fixup_mdeps (frags, h, this_segment)
4103      fragS * frags;
4104      object_headers * h;
4105      segT this_segment;
4106 {
4107   subseg_change (this_segment, 0);
4108
4109   while (frags)
4110     {
4111       switch (frags->fr_type)
4112         {
4113         case rs_align:
4114         case rs_align_code:
4115         case rs_align_test:
4116         case rs_org:
4117 #ifdef HANDLE_ALIGN
4118           HANDLE_ALIGN (frags);
4119 #endif
4120           frags->fr_type = rs_fill;
4121           frags->fr_offset =
4122             ((frags->fr_next->fr_address - frags->fr_address - frags->fr_fix)
4123              / frags->fr_var);
4124           break;
4125         case rs_machine_dependent:
4126           md_convert_frag (h, this_segment, frags);
4127           frag_wane (frags);
4128           break;
4129         default:
4130           ;
4131         }
4132       frags = frags->fr_next;
4133     }
4134 }
4135
4136 #if 1
4137
4138 #ifndef TC_FORCE_RELOCATION
4139 #define TC_FORCE_RELOCATION(fix) 0
4140 #endif
4141
4142 static void
4143 fixup_segment (segP, this_segment_type)
4144      segment_info_type * segP;
4145      segT this_segment_type;
4146 {
4147   fixS * fixP;
4148   symbolS *add_symbolP;
4149   symbolS *sub_symbolP;
4150   long add_number;
4151   int size;
4152   char *place;
4153   long where;
4154   char pcrel;
4155   fragS *fragP;
4156   segT add_symbol_segment = absolute_section;
4157
4158   for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
4159     {
4160       fragP = fixP->fx_frag;
4161       know (fragP);
4162       where = fixP->fx_where;
4163       place = fragP->fr_literal + where;
4164       size = fixP->fx_size;
4165       add_symbolP = fixP->fx_addsy;
4166       sub_symbolP = fixP->fx_subsy;
4167       add_number = fixP->fx_offset;
4168       pcrel = fixP->fx_pcrel;
4169
4170       /* We want function-relative stabs to work on systems which
4171          may use a relaxing linker; thus we must handle the sym1-sym2
4172          fixups function-relative stabs generates.
4173
4174          Of course, if you actually enable relaxing in the linker, the
4175          line and block scoping information is going to be incorrect
4176          in some cases.  The only way to really fix this is to support
4177          a reloc involving the difference of two symbols.  */
4178       if (linkrelax
4179           && (!sub_symbolP || pcrel))
4180         continue;
4181
4182 #ifdef TC_I960
4183       if (fixP->fx_tcbit && SF_GET_CALLNAME (add_symbolP))
4184         {
4185           /* Relocation should be done via the associated 'bal' entry
4186              point symbol.  */
4187
4188           if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
4189             {
4190               as_bad_where (fixP->fx_file, fixP->fx_line,
4191                             _("No 'bal' entry point for leafproc %s"),
4192                             S_GET_NAME (add_symbolP));
4193               continue;
4194             }
4195           fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
4196         }
4197 #endif
4198
4199       /* Make sure the symbols have been resolved; this may not have
4200          happened if these are expression symbols.  */
4201       if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
4202         resolve_symbol_value (add_symbolP);
4203
4204       if (add_symbolP != NULL)
4205         {
4206           /* If this fixup is against a symbol which has been equated
4207              to another symbol, convert it to the other symbol.  */
4208           if (add_symbolP->sy_value.X_op == O_symbol
4209               && (! S_IS_DEFINED (add_symbolP)
4210                   || S_IS_COMMON (add_symbolP)))
4211             {
4212               while (add_symbolP->sy_value.X_op == O_symbol
4213                      && (! S_IS_DEFINED (add_symbolP)
4214                          || S_IS_COMMON (add_symbolP)))
4215                 {
4216                   symbolS *n;
4217
4218                   /* We must avoid looping, as that can occur with a
4219                      badly written program.  */
4220                   n = add_symbolP->sy_value.X_add_symbol;
4221                   if (n == add_symbolP)
4222                     break;
4223                   add_number += add_symbolP->sy_value.X_add_number;
4224                   add_symbolP = n;
4225                 }
4226               fixP->fx_addsy = add_symbolP;
4227               fixP->fx_offset = add_number;
4228             }
4229         }
4230
4231       if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
4232         resolve_symbol_value (sub_symbolP);
4233
4234       if (add_symbolP != NULL
4235           && add_symbolP->sy_mri_common)
4236         {
4237           know (add_symbolP->sy_value.X_op == O_symbol);
4238           add_number += S_GET_VALUE (add_symbolP);
4239           fixP->fx_offset = add_number;
4240           add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
4241         }
4242
4243       if (add_symbolP)
4244         add_symbol_segment = S_GET_SEGMENT (add_symbolP);
4245
4246       if (sub_symbolP)
4247         {
4248           if (add_symbolP == NULL || add_symbol_segment == absolute_section)
4249             {
4250               if (add_symbolP != NULL)
4251                 {
4252                   add_number += S_GET_VALUE (add_symbolP);
4253                   add_symbolP = NULL;
4254                   fixP->fx_addsy = NULL;
4255                 }
4256
4257               /* It's just -sym.  */
4258               if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
4259                 {
4260                   add_number -= S_GET_VALUE (sub_symbolP);
4261                   fixP->fx_subsy = 0;
4262                   fixP->fx_done = 1;
4263                 }
4264               else
4265                 {
4266 #ifndef TC_M68K
4267                   as_bad_where (fixP->fx_file, fixP->fx_line,
4268                                 _("Negative of non-absolute symbol %s"),
4269                                 S_GET_NAME (sub_symbolP));
4270 #endif
4271                   add_number -= S_GET_VALUE (sub_symbolP);
4272                 }               /* not absolute */
4273
4274               /* if sub_symbol is in the same segment that add_symbol
4275                  and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE.  */
4276             }
4277           else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
4278                    && SEG_NORMAL (add_symbol_segment))
4279             {
4280               /* Difference of 2 symbols from same segment.  Can't
4281                  make difference of 2 undefineds: 'value' means
4282                  something different for N_UNDF.  */
4283 #ifdef TC_I960
4284               /* Makes no sense to use the difference of 2 arbitrary symbols
4285                  as the target of a call instruction.  */
4286               if (fixP->fx_tcbit)
4287                 as_bad_where (fixP->fx_file, fixP->fx_line,
4288                               _("callj to difference of 2 symbols"));
4289 #endif /* TC_I960 */
4290               add_number += S_GET_VALUE (add_symbolP) -
4291                 S_GET_VALUE (sub_symbolP);
4292               add_symbolP = NULL;
4293
4294               if (!TC_FORCE_RELOCATION (fixP))
4295                 {
4296                   fixP->fx_addsy = NULL;
4297                   fixP->fx_subsy = NULL;
4298                   fixP->fx_done = 1;
4299 #ifdef TC_M68K /* is this right? */
4300                   pcrel = 0;
4301                   fixP->fx_pcrel = 0;
4302 #endif
4303                 }
4304             }
4305           else
4306             {
4307               /* Different segments in subtraction.  */
4308               know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
4309
4310               if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
4311                 add_number -= S_GET_VALUE (sub_symbolP);
4312
4313 #ifdef DIFF_EXPR_OK
4314               else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
4315 #if 0 /* Okay for 68k, at least...  */
4316                        && !pcrel
4317 #endif
4318                        )
4319                 {
4320                   /* Make it pc-relative.  */
4321                   add_number += (md_pcrel_from (fixP)
4322                                  - S_GET_VALUE (sub_symbolP));
4323                   pcrel = 1;
4324                   fixP->fx_pcrel = 1;
4325                   sub_symbolP = 0;
4326                   fixP->fx_subsy = 0;
4327                 }
4328 #endif
4329               else
4330                 {
4331                   as_bad_where (fixP->fx_file, fixP->fx_line,
4332                                 _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
4333                                 segment_name (S_GET_SEGMENT (sub_symbolP)),
4334                                 S_GET_NAME (sub_symbolP),
4335                                 (long) (fragP->fr_address + where));
4336                 }
4337             }
4338         }
4339
4340       if (add_symbolP)
4341         {
4342           if (add_symbol_segment == this_segment_type && pcrel)
4343             {
4344               /* This fixup was made when the symbol's segment was
4345                  SEG_UNKNOWN, but it is now in the local segment.
4346                  So we know how to do the address without relocation.  */
4347 #ifdef TC_I960
4348               /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
4349                  in which cases it modifies *fixP as appropriate.  In the case
4350                  of a 'calls', no further work is required, and *fixP has been
4351                  set up to make the rest of the code below a no-op.  */
4352               reloc_callj (fixP);
4353 #endif /* TC_I960 */
4354
4355               add_number += S_GET_VALUE (add_symbolP);
4356               add_number -= md_pcrel_from (fixP);
4357
4358               /* We used to do
4359                    add_number -= segP->scnhdr.s_vaddr;
4360                  if defined (TC_I386) || defined (TE_LYNX).  I now
4361                  think that was an error propagated from the case when
4362                  we are going to emit the relocation.  If we are not
4363                  going to emit the relocation, then we just want to
4364                  set add_number to the difference between the symbols.
4365                  This is a case that would only arise when there is a
4366                  PC relative reference from a section other than .text
4367                  to a symbol defined in the same section, and the
4368                  reference is not relaxed.  Since jump instructions on
4369                  the i386 are relaxed, this could only arise with a
4370                  call instruction.  */
4371
4372               pcrel = 0;        /* Lie. Don't want further pcrel processing.  */
4373               if (!TC_FORCE_RELOCATION (fixP))
4374                 {
4375                   fixP->fx_addsy = NULL;
4376                   fixP->fx_done = 1;
4377                 }
4378             }
4379           else
4380             {
4381               switch (add_symbol_segment)
4382                 {
4383                 case absolute_section:
4384 #ifdef TC_I960
4385                   /* See comment about reloc_callj() above.  */
4386                   reloc_callj (fixP);
4387 #endif /* TC_I960 */
4388                   add_number += S_GET_VALUE (add_symbolP);
4389                   add_symbolP = NULL;
4390
4391                   if (!TC_FORCE_RELOCATION (fixP))
4392                     {
4393                       fixP->fx_addsy = NULL;
4394                       fixP->fx_done = 1;
4395                     }
4396                   break;
4397                 default:
4398
4399 #if defined(TC_A29K) || (defined(TE_PE) && defined(TC_I386)) || defined(TC_M88K) || defined(TC_OR32)
4400                   /* This really should be handled in the linker, but
4401                      backward compatibility forbids.  */
4402                   add_number += S_GET_VALUE (add_symbolP);
4403 #else
4404                   add_number += S_GET_VALUE (add_symbolP) +
4405                     segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
4406 #endif
4407                   break;
4408
4409                 case SEG_UNKNOWN:
4410 #ifdef TC_I960
4411                   if ((int) fixP->fx_bit_fixP == 13)
4412                     {
4413                       /* This is a COBR instruction.  They have only a
4414                          13-bit displacement and are only to be used
4415                          for local branches: flag as error, don't generate
4416                          relocation.  */
4417                       as_bad_where (fixP->fx_file, fixP->fx_line,
4418                                     _("can't use COBR format with external label"));
4419                       fixP->fx_addsy = NULL;
4420                       fixP->fx_done = 1;
4421                       continue;
4422                     }
4423 #endif /* TC_I960 */
4424 #if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND)
4425                   /* 386 COFF uses a peculiar format in which the
4426                      value of a common symbol is stored in the .text
4427                      segment (I've checked this on SVR3.2 and SCO
4428                      3.2.2) Ian Taylor <ian@cygnus.com>.  */
4429                   /* This is also true for 68k COFF on sysv machines
4430                      (Checked on Motorola sysv68 R3V6 and R3V7.1, and also on
4431                      UNIX System V/M68000, Release 1.0 from ATT/Bell Labs)
4432                      Philippe De Muyter <phdm@info.ucl.ac.be>.  */
4433                   if (S_IS_COMMON (add_symbolP))
4434                     add_number += S_GET_VALUE (add_symbolP);
4435 #endif
4436                   break;
4437
4438                 }
4439             }
4440         }
4441
4442       if (pcrel)
4443         {
4444 #if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K) && !defined(TC_OR32)
4445           /* This adjustment is not correct on the m88k, for which the
4446              linker does all the computation.  */
4447           add_number -= md_pcrel_from (fixP);
4448 #endif
4449           if (add_symbolP == 0)
4450             fixP->fx_addsy = &abs_symbol;
4451 #if defined (TC_I386) || defined (TE_LYNX) || defined (TC_I960) || defined (TC_M68K)
4452           /* On the 386 we must adjust by the segment vaddr as well.
4453              Ian Taylor.
4454
4455              I changed the i960 to work this way as well.  This is
4456              compatible with the current GNU linker behaviour.  I do
4457              not know what other i960 COFF assemblers do.  This is not
4458              a common case: normally, only assembler code will contain
4459              a PC relative reloc, and only branches which do not
4460              originate in the .text section will have a non-zero
4461              address.
4462
4463              I changed the m68k to work this way as well.  This will
4464              break existing PC relative relocs from sections which do
4465              not start at address 0, but it will make ld -r work.
4466              Ian Taylor, 4 Oct 96.  */
4467
4468           add_number -= segP->scnhdr.s_vaddr;
4469 #endif
4470         }
4471
4472       md_apply_fix3 (fixP, (valueT *) & add_number, this_segment_type);
4473
4474       if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
4475         {
4476 #ifndef TC_M88K
4477           /* The m88k uses the offset field of the reloc to get around
4478              this problem.  */
4479           if ((size == 1
4480                && ((add_number & ~0xFF)
4481                    || (fixP->fx_signed && (add_number & 0x80)))
4482                && ((add_number & ~0xFF) != (-1 & ~0xFF)
4483                    || (add_number & 0x80) == 0))
4484               || (size == 2
4485                   && ((add_number & ~0xFFFF)
4486                       || (fixP->fx_signed && (add_number & 0x8000)))
4487                   && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)
4488                       || (add_number & 0x8000) == 0)))
4489             {
4490               as_bad_where (fixP->fx_file, fixP->fx_line,
4491                             _("Value of %ld too large for field of %d bytes at 0x%lx"),
4492                             (long) add_number, size,
4493                             (unsigned long) (fragP->fr_address + where));
4494             }
4495 #endif
4496 #ifdef WARN_SIGNED_OVERFLOW_WORD
4497           /* Warn if a .word value is too large when treated as a
4498              signed number.  We already know it is not too negative.
4499              This is to catch over-large switches generated by gcc on
4500              the 68k.  */
4501           if (!flag_signed_overflow_ok
4502               && size == 2
4503               && add_number > 0x7fff)
4504             as_bad_where (fixP->fx_file, fixP->fx_line,
4505                           _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
4506                           (long) add_number,
4507                           (unsigned long) (fragP->fr_address + where));
4508 #endif
4509         }
4510     }
4511 }
4512
4513 #endif
4514
4515 /* The first entry in a .stab section is special.  */
4516
4517 void
4518 obj_coff_init_stab_section (seg)
4519      segT seg;
4520 {
4521   char *file;
4522   char *p;
4523   char *stabstr_name;
4524   unsigned int stroff;
4525
4526   /* Make space for this first symbol.  */
4527   p = frag_more (12);
4528   /* Zero it out.  */
4529   memset (p, 0, 12);
4530   as_where (&file, (unsigned int *) NULL);
4531   stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
4532   strcpy (stabstr_name, segment_info[seg].name);
4533   strcat (stabstr_name, "str");
4534   stroff = get_stab_string_offset (file, stabstr_name);
4535   know (stroff == 1);
4536   md_number_to_chars (p, stroff, 4);
4537 }
4538
4539 /* Fill in the counts in the first entry in a .stab section.  */
4540
4541 static void
4542 adjust_stab_section(abfd, seg)
4543      bfd *abfd;
4544      segT seg;
4545 {
4546   segT stabstrseg = SEG_UNKNOWN;
4547   const char *secname, *name2;
4548   char *name;
4549   char *p = NULL;
4550   int i, strsz = 0, nsyms;
4551   fragS *frag = segment_info[seg].frchainP->frch_root;
4552
4553   /* Look for the associated string table section.  */
4554
4555   secname = segment_info[seg].name;
4556   name = (char *) alloca (strlen (secname) + 4);
4557   strcpy (name, secname);
4558   strcat (name, "str");
4559
4560   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
4561     {
4562       name2 = segment_info[i].name;
4563       if (name2 != NULL && strncmp(name2, name, 8) == 0)
4564         {
4565           stabstrseg = i;
4566           break;
4567         }
4568     }
4569
4570   /* If we found the section, get its size.  */
4571   if (stabstrseg != SEG_UNKNOWN)
4572     strsz = size_section (abfd, stabstrseg);
4573
4574   nsyms = size_section (abfd, seg) / 12 - 1;
4575
4576   /* Look for the first frag of sufficient size for the initial stab
4577      symbol, and collect a pointer to it.  */
4578   while (frag && frag->fr_fix < 12)
4579     frag = frag->fr_next;
4580   assert (frag != 0);
4581   p = frag->fr_literal;
4582   assert (p != 0);
4583
4584   /* Write in the number of stab symbols and the size of the string
4585      table.  */
4586   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
4587   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
4588 }
4589
4590 #endif /* not BFD_ASSEMBLER */
4591
4592 const pseudo_typeS coff_pseudo_table[] =
4593 {
4594   {"def", obj_coff_def, 0},
4595   {"dim", obj_coff_dim, 0},
4596   {"endef", obj_coff_endef, 0},
4597   {"line", obj_coff_line, 0},
4598   {"ln", obj_coff_ln, 0},
4599 #ifdef BFD_ASSEMBLER
4600   {"loc", obj_coff_loc, 0},
4601 #endif
4602   {"appline", obj_coff_ln, 1},
4603   {"scl", obj_coff_scl, 0},
4604   {"size", obj_coff_size, 0},
4605   {"tag", obj_coff_tag, 0},
4606   {"type", obj_coff_type, 0},
4607   {"val", obj_coff_val, 0},
4608   {"section", obj_coff_section, 0},
4609   {"sect", obj_coff_section, 0},
4610   /* FIXME: We ignore the MRI short attribute.  */
4611   {"section.s", obj_coff_section, 0},
4612   {"sect.s", obj_coff_section, 0},
4613   /* We accept the .bss directive for backward compatibility with
4614      earlier versions of gas.  */
4615   {"bss", obj_coff_bss, 0},
4616   {"weak", obj_coff_weak, 0},
4617   {"ident", obj_coff_ident, 0},
4618 #ifndef BFD_ASSEMBLER
4619   {"use", obj_coff_section, 0},
4620   {"text", obj_coff_text, 0},
4621   {"data", obj_coff_data, 0},
4622   {"lcomm", obj_coff_lcomm, 0},
4623 #else
4624   {"optim", s_ignore, 0},       /* For sun386i cc (?) */
4625 #endif
4626   {"version", s_ignore, 0},
4627   {"ABORT", s_abort, 0},
4628 #if defined( TC_M88K ) || defined ( TC_TIC4X )
4629   /* The m88k and tic4x uses sdef instead of def.  */
4630   {"sdef", obj_coff_def, 0},
4631 #endif
4632   {NULL, NULL, 0}               /* end sentinel */
4633 };                              /* coff_pseudo_table */
4634 \f
4635 #ifdef BFD_ASSEMBLER
4636
4637 /* Support for a COFF emulation.  */
4638
4639 static void coff_pop_insert PARAMS ((void));
4640 static int coff_separate_stab_sections PARAMS ((void));
4641
4642 static void
4643 coff_pop_insert ()
4644 {
4645   pop_insert (coff_pseudo_table);
4646 }
4647
4648 static int
4649 coff_separate_stab_sections ()
4650 {
4651   return 1;
4652 }
4653
4654 const struct format_ops coff_format_ops =
4655 {
4656   bfd_target_coff_flavour,
4657   0,    /* dfl_leading_underscore */
4658   1,    /* emit_section_symbols */
4659   0,    /* begin */
4660   c_dot_file_symbol,
4661   coff_frob_symbol,
4662   0,    /* frob_file */
4663   0,    /* frob_file_before_adjust */
4664   0,    /* frob_file_before_fix */
4665   coff_frob_file_after_relocs,
4666   0,    /* s_get_size */
4667   0,    /* s_set_size */
4668   0,    /* s_get_align */
4669   0,    /* s_set_align */
4670   0,    /* s_get_other */
4671   0,    /* s_set_other */
4672   0,    /* s_get_desc */
4673   0,    /* s_set_desc */
4674   0,    /* s_get_type */
4675   0,    /* s_set_type */
4676   0,    /* copy_symbol_attributes */
4677   0,    /* generate_asm_lineno */
4678   0,    /* process_stab */
4679   coff_separate_stab_sections,
4680   obj_coff_init_stab_section,
4681   0,    /* sec_sym_ok_for_reloc */
4682   coff_pop_insert,
4683   0,    /* ecoff_set_ext */
4684   coff_obj_read_begin_hook,
4685   coff_obj_symbol_new_hook
4686 };
4687
4688 #endif