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