xref: /netbsd-src/external/gpl3/binutils/dist/gas/config/obj-coff.c (revision 9573673d78c64ea1eac42d7f2e9521be89932ae5)
1 /* coff object file format
2    Copyright (C) 1989-2015 Free Software Foundation, Inc.
3 
4    This file is part of GAS.
5 
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to the Free
18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20 
21 #define OBJ_HEADER "obj-coff.h"
22 
23 #include "as.h"
24 #include "safe-ctype.h"
25 #include "subsegs.h"
26 #include "struc-symbol.h"
27 
28 #ifdef TE_PE
29 #include "coff/pe.h"
30 #endif
31 
32 #ifdef OBJ_XCOFF
33 #include "coff/xcoff.h"
34 #endif
35 
36 #define streq(a,b)     (strcmp ((a), (b)) == 0)
37 #define strneq(a,b,n)  (strncmp ((a), (b), (n)) == 0)
38 
39 /* I think this is probably always correct.  */
40 #ifndef KEEP_RELOC_INFO
41 #define KEEP_RELOC_INFO
42 #endif
43 
44 /* obj_coff_section will use this macro to set a new section's
45    attributes when a directive has no valid flags or the "w" flag is
46    used.  This default should be appropriate for most.  */
47 #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
48 #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
49 #endif
50 
51 /* This is used to hold the symbol built by a sequence of pseudo-ops
52    from .def and .endef.  */
53 static symbolS *def_symbol_in_progress;
54 #ifdef TE_PE
55 /* PE weak alternate symbols begin with this string.  */
56 static const char weak_altprefix[] = ".weak.";
57 #endif /* TE_PE */
58 
59 #include "obj-coff-seh.c"
60 
61 typedef struct
62   {
63     unsigned long chunk_size;
64     unsigned long element_size;
65     unsigned long size;
66     char *data;
67     unsigned long pointer;
68   }
69 stack;
70 
71 
72 /* Stack stuff.  */
73 
74 static stack *
75 stack_init (unsigned long chunk_size,
76 	    unsigned long element_size)
77 {
78   stack *st;
79 
80   st = malloc (sizeof (* st));
81   if (!st)
82     return NULL;
83   st->data = malloc (chunk_size);
84   if (!st->data)
85     {
86       free (st);
87       return NULL;
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 static char *
97 stack_push (stack *st, char *element)
98 {
99   if (st->pointer + st->element_size >= st->size)
100     {
101       st->size += st->chunk_size;
102       if ((st->data = xrealloc (st->data, st->size)) == NULL)
103 	return NULL;
104     }
105   memcpy (st->data + st->pointer, element, st->element_size);
106   st->pointer += st->element_size;
107   return st->data + st->pointer;
108 }
109 
110 static char *
111 stack_pop (stack *st)
112 {
113   if (st->pointer < st->element_size)
114     {
115       st->pointer = 0;
116       return NULL;
117     }
118   st->pointer -= st->element_size;
119   return st->data + st->pointer;
120 }
121 
122 /* Maintain a list of the tagnames of the structures.  */
123 
124 static struct hash_control *tag_hash;
125 
126 static void
127 tag_init (void)
128 {
129   tag_hash = hash_new ();
130 }
131 
132 static void
133 tag_insert (const char *name, symbolS *symbolP)
134 {
135   const char *error_string;
136 
137   if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
138     as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
139 	      name, error_string);
140 }
141 
142 static symbolS *
143 tag_find (char *name)
144 {
145   return (symbolS *) hash_find (tag_hash, name);
146 }
147 
148 static symbolS *
149 tag_find_or_make (char *name)
150 {
151   symbolS *symbolP;
152 
153   if ((symbolP = tag_find (name)) == NULL)
154     {
155       symbolP = symbol_new (name, undefined_section,
156 			    0, &zero_address_frag);
157 
158       tag_insert (S_GET_NAME (symbolP), symbolP);
159       symbol_table_insert (symbolP);
160     }
161 
162   return symbolP;
163 }
164 
165 /* We accept the .bss directive to set the section for backward
166    compatibility with earlier versions of gas.  */
167 
168 static void
169 obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
170 {
171   if (*input_line_pointer == '\n')
172     subseg_new (".bss", get_absolute_expression ());
173   else
174     s_lcomm (0);
175 }
176 
177 #ifdef TE_PE
178 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
179    Parse a possible alignment value.  */
180 
181 static symbolS *
182 obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
183 {
184   addressT align = 0;
185 
186   if (*input_line_pointer == ',')
187     {
188       align = parse_align (0);
189       if (align == (addressT) -1)
190 	return NULL;
191     }
192 
193   S_SET_VALUE (symbolP, size);
194   S_SET_EXTERNAL (symbolP);
195   S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
196 
197   symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
198 
199   /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
200      Instead we must add a note to the .drectve section.  */
201   if (align)
202     {
203       segT current_seg = now_seg;
204       subsegT current_subseg = now_subseg;
205       flagword oldflags;
206       asection *sec;
207       size_t pfxlen, numlen;
208       char *frag;
209       char numbuff[20];
210 
211       sec = subseg_new (".drectve", 0);
212       oldflags = bfd_get_section_flags (stdoutput, sec);
213       if (oldflags == SEC_NO_FLAGS)
214 	{
215 	  if (!bfd_set_section_flags (stdoutput, sec,
216 		TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
217 	    as_warn (_("error setting flags for \"%s\": %s"),
218 		bfd_section_name (stdoutput, sec),
219 		bfd_errmsg (bfd_get_error ()));
220 	}
221 
222       /* Emit a string.  Note no NUL-termination.  */
223       pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1;
224       numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
225       frag = frag_more (pfxlen + numlen);
226       (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP));
227       memcpy (frag + pfxlen, numbuff, numlen);
228       /* Restore original subseg. */
229       subseg_set (current_seg, current_subseg);
230     }
231 
232   return symbolP;
233 }
234 
235 static void
236 obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
237 {
238   s_comm_internal (ignore, obj_coff_common_parse);
239 }
240 #endif /* TE_PE */
241 
242 #define GET_FILENAME_STRING(X) \
243   ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
244 
245 /* @@ Ick.  */
246 static segT
247 fetch_coff_debug_section (void)
248 {
249   static segT debug_section;
250 
251   if (!debug_section)
252     {
253       const asymbol *s;
254 
255       s = bfd_make_debug_symbol (stdoutput, NULL, 0);
256       gas_assert (s != 0);
257       debug_section = s->section;
258     }
259   return debug_section;
260 }
261 
262 void
263 SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
264 {
265   combined_entry_type *entry, *p;
266 
267   entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
268   p = coffsymbol (symbol_get_bfdsym (val))->native;
269   entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
270   entry->fix_end = 1;
271 }
272 
273 static void
274 SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
275 {
276   combined_entry_type *entry, *p;
277 
278   entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
279   p = coffsymbol (symbol_get_bfdsym (val))->native;
280   entry->u.auxent.x_sym.x_tagndx.p = p;
281   entry->fix_tag = 1;
282 }
283 
284 static int
285 S_GET_DATA_TYPE (symbolS *sym)
286 {
287   return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
288 }
289 
290 int
291 S_SET_DATA_TYPE (symbolS *sym, int val)
292 {
293   coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
294   return val;
295 }
296 
297 int
298 S_GET_STORAGE_CLASS (symbolS *sym)
299 {
300   return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
301 }
302 
303 int
304 S_SET_STORAGE_CLASS (symbolS *sym, int val)
305 {
306   coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
307   return val;
308 }
309 
310 /* Merge a debug symbol containing debug information into a normal symbol.  */
311 
312 static void
313 c_symbol_merge (symbolS *debug, symbolS *normal)
314 {
315   S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
316   S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
317 
318   if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
319     /* Take the most we have.  */
320     S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
321 
322   if (S_GET_NUMBER_AUXILIARY (debug) > 0)
323     /* Move all the auxiliary information.  */
324     memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
325 	    (S_GET_NUMBER_AUXILIARY (debug)
326 	     * sizeof (*SYM_AUXINFO (debug))));
327 
328   /* Move the debug flags.  */
329   SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
330 }
331 
332 void
333 c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED)
334 {
335   symbolS *symbolP;
336 
337   /* BFD converts filename to a .file symbol with an aux entry.  It
338      also handles chaining.  */
339   symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
340 
341   S_SET_STORAGE_CLASS (symbolP, C_FILE);
342   S_SET_NUMBER_AUXILIARY (symbolP, 1);
343 
344   symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
345 
346 #ifndef NO_LISTING
347   {
348     extern int listing;
349 
350     if (listing)
351       listing_source_file (filename);
352   }
353 #endif
354 
355   /* Make sure that the symbol is first on the symbol chain.  */
356   if (symbol_rootP != symbolP)
357     {
358       symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
359       symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
360     }
361 }
362 
363 /* Line number handling.  */
364 
365 struct line_no
366 {
367   struct line_no *next;
368   fragS *frag;
369   alent l;
370 };
371 
372 int coff_line_base;
373 
374 /* Symbol of last function, which we should hang line#s off of.  */
375 static symbolS *line_fsym;
376 
377 #define in_function()		(line_fsym != 0)
378 #define clear_function()	(line_fsym = 0)
379 #define set_function(F)		(line_fsym = (F), coff_add_linesym (F))
380 
381 
382 void
383 coff_obj_symbol_new_hook (symbolS *symbolP)
384 {
385   long   sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
386   char * s  = xmalloc (sz);
387 
388   memset (s, 0, sz);
389   coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s;
390   coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = TRUE;
391 
392   S_SET_DATA_TYPE (symbolP, T_NULL);
393   S_SET_STORAGE_CLASS (symbolP, 0);
394   S_SET_NUMBER_AUXILIARY (symbolP, 0);
395 
396   if (S_IS_STRING (symbolP))
397     SF_SET_STRING (symbolP);
398 
399   if (S_IS_LOCAL (symbolP))
400     SF_SET_LOCAL (symbolP);
401 }
402 
403 void
404 coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
405 {
406   long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
407   combined_entry_type * s = xmalloc (sz);
408 
409   memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
410   coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
411 
412   SF_SET (newsymP, SF_GET (orgsymP));
413 }
414 
415 
416 /* Handle .ln directives.  */
417 
418 static symbolS *current_lineno_sym;
419 static struct line_no *line_nos;
420 /* FIXME:  Blindly assume all .ln directives will be in the .text section.  */
421 int coff_n_line_nos;
422 
423 static void
424 add_lineno (fragS * frag, addressT offset, int num)
425 {
426   struct line_no * new_line = xmalloc (sizeof (* new_line));
427 
428   if (!current_lineno_sym)
429     abort ();
430 
431 #ifndef OBJ_XCOFF
432   /* The native aix assembler accepts negative line number.  */
433 
434   if (num <= 0)
435     {
436       /* Zero is used as an end marker in the file.  */
437       as_warn (_("Line numbers must be positive integers\n"));
438       num = 1;
439     }
440 #endif /* OBJ_XCOFF */
441   new_line->next = line_nos;
442   new_line->frag = frag;
443   new_line->l.line_number = num;
444   new_line->l.u.offset = offset;
445   line_nos = new_line;
446   coff_n_line_nos++;
447 }
448 
449 void
450 coff_add_linesym (symbolS *sym)
451 {
452   if (line_nos)
453     {
454       coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
455 	(alent *) line_nos;
456       coff_n_line_nos++;
457       line_nos = 0;
458     }
459   current_lineno_sym = sym;
460 }
461 
462 static void
463 obj_coff_ln (int appline)
464 {
465   int l;
466 
467   if (! appline && def_symbol_in_progress != NULL)
468     {
469       as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
470       demand_empty_rest_of_line ();
471       return;
472     }
473 
474   l = get_absolute_expression ();
475 
476   /* If there is no lineno symbol, treat a .ln
477      directive as if it were a .appline directive.  */
478   if (appline || current_lineno_sym == NULL)
479     new_logical_line ((char *) NULL, l - 1);
480   else
481     add_lineno (frag_now, frag_now_fix (), l);
482 
483 #ifndef NO_LISTING
484   {
485     extern int listing;
486 
487     if (listing)
488       {
489 	if (! appline)
490 	  l += coff_line_base - 1;
491 	listing_source_line (l);
492       }
493   }
494 #endif
495 
496   demand_empty_rest_of_line ();
497 }
498 
499 /* .loc is essentially the same as .ln; parse it for assembler
500    compatibility.  */
501 
502 static void
503 obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
504 {
505   int lineno;
506 
507   /* FIXME: Why do we need this check?  We need it for ECOFF, but why
508      do we need it for COFF?  */
509   if (now_seg != text_section)
510     {
511       as_warn (_(".loc outside of .text"));
512       demand_empty_rest_of_line ();
513       return;
514     }
515 
516   if (def_symbol_in_progress != NULL)
517     {
518       as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
519       demand_empty_rest_of_line ();
520       return;
521     }
522 
523   /* Skip the file number.  */
524   SKIP_WHITESPACE ();
525   get_absolute_expression ();
526   SKIP_WHITESPACE ();
527 
528   lineno = get_absolute_expression ();
529 
530 #ifndef NO_LISTING
531   {
532     extern int listing;
533 
534     if (listing)
535       {
536 	lineno += coff_line_base - 1;
537 	listing_source_line (lineno);
538       }
539   }
540 #endif
541 
542   demand_empty_rest_of_line ();
543 
544   add_lineno (frag_now, frag_now_fix (), lineno);
545 }
546 
547 /* Handle the .ident pseudo-op.  */
548 
549 static void
550 obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
551 {
552   segT current_seg = now_seg;
553   subsegT current_subseg = now_subseg;
554 
555 #ifdef TE_PE
556   {
557     segT sec;
558 
559     /* We could put it in .comment, but that creates an extra section
560        that shouldn't be loaded into memory, which requires linker
561        changes...  For now, until proven otherwise, use .rdata.  */
562     sec = subseg_new (".rdata$zzz", 0);
563     bfd_set_section_flags (stdoutput, sec,
564 			   ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
565 			    & bfd_applicable_section_flags (stdoutput)));
566   }
567 #else
568   subseg_new (".comment", 0);
569 #endif
570 
571   stringer (8 + 1);
572   subseg_set (current_seg, current_subseg);
573 }
574 
575 /* Handle .def directives.
576 
577    One might ask : why can't we symbol_new if the symbol does not
578    already exist and fill it with debug information.  Because of
579    the C_EFCN special symbol. It would clobber the value of the
580    function symbol before we have a chance to notice that it is
581    a C_EFCN. And a second reason is that the code is more clear this
582    way. (at least I think it is :-).  */
583 
584 #define SKIP_SEMI_COLON()	while (*input_line_pointer++ != ';')
585 #define SKIP_WHITESPACES()	while (*input_line_pointer == ' ' || \
586 				       *input_line_pointer == '\t')  \
587                                   input_line_pointer++;
588 
589 static void
590 obj_coff_def (int what ATTRIBUTE_UNUSED)
591 {
592   char name_end;		/* Char after the end of name.  */
593   char *symbol_name;		/* Name of the debug symbol.  */
594   char *symbol_name_copy;	/* Temporary copy of the name.  */
595   unsigned int symbol_name_length;
596 
597   if (def_symbol_in_progress != NULL)
598     {
599       as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
600       demand_empty_rest_of_line ();
601       return;
602     }
603 
604   SKIP_WHITESPACES ();
605 
606   name_end = get_symbol_name (&symbol_name);
607   symbol_name_length = strlen (symbol_name);
608   symbol_name_copy = xmalloc (symbol_name_length + 1);
609   strcpy (symbol_name_copy, symbol_name);
610 #ifdef tc_canonicalize_symbol_name
611   symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
612 #endif
613 
614   /* Initialize the new symbol.  */
615   def_symbol_in_progress = symbol_make (symbol_name_copy);
616   symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
617   S_SET_VALUE (def_symbol_in_progress, 0);
618 
619   if (S_IS_STRING (def_symbol_in_progress))
620     SF_SET_STRING (def_symbol_in_progress);
621 
622   (void) restore_line_pointer (name_end);
623 
624   demand_empty_rest_of_line ();
625 }
626 
627 static void
628 obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
629 {
630   symbolS *symbolP = NULL;
631 
632   if (def_symbol_in_progress == NULL)
633     {
634       as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
635       demand_empty_rest_of_line ();
636       return;
637     }
638 
639   /* Set the section number according to storage class.  */
640   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
641     {
642     case C_STRTAG:
643     case C_ENTAG:
644     case C_UNTAG:
645       SF_SET_TAG (def_symbol_in_progress);
646       /* Fall through.  */
647     case C_FILE:
648     case C_TPDEF:
649       SF_SET_DEBUG (def_symbol_in_progress);
650       S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
651       break;
652 
653     case C_EFCN:
654       SF_SET_LOCAL (def_symbol_in_progress);	/* Do not emit this symbol.  */
655       /* Fall through.  */
656     case C_BLOCK:
657       SF_SET_PROCESS (def_symbol_in_progress);	/* Will need processing before writing.  */
658       /* Fall through.  */
659     case C_FCN:
660       {
661 	const char *name;
662 
663 	S_SET_SEGMENT (def_symbol_in_progress, text_section);
664 
665 	name = S_GET_NAME (def_symbol_in_progress);
666 	if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
667 	  {
668 	    switch (name[1])
669 	      {
670 	      case 'b':
671 		/* .bf */
672 		if (! in_function ())
673 		  as_warn (_("`%s' symbol without preceding function"), name);
674 		/* Will need relocating.  */
675 		SF_SET_PROCESS (def_symbol_in_progress);
676 		clear_function ();
677 		break;
678 #ifdef TE_PE
679 	      case 'e':
680 		/* .ef */
681 		/* The MS compilers output the actual endline, not the
682 		   function-relative one... we want to match without
683 		   changing the assembler input.  */
684 		SA_SET_SYM_LNNO (def_symbol_in_progress,
685 				 (SA_GET_SYM_LNNO (def_symbol_in_progress)
686 				  + coff_line_base));
687 		break;
688 #endif
689 	      }
690 	  }
691       }
692       break;
693 
694 #ifdef C_AUTOARG
695     case C_AUTOARG:
696 #endif /* C_AUTOARG */
697     case C_AUTO:
698     case C_REG:
699     case C_ARG:
700     case C_REGPARM:
701     case C_FIELD:
702 
703     /* According to the COFF documentation:
704 
705        http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
706 
707        A special section number (-2) marks symbolic debugging symbols,
708        including structure/union/enumeration tag names, typedefs, and
709        the name of the file. A section number of -1 indicates that the
710        symbol has a value but is not relocatable. Examples of
711        absolute-valued symbols include automatic and register variables,
712        function arguments, and .eos symbols.
713 
714        But from Ian Lance Taylor:
715 
716        http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
717 
718        the actual tools all marked them as section -1. So the GNU COFF
719        assembler follows historical COFF assemblers.
720 
721        However, it causes problems for djgpp
722 
723        http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
724 
725        By defining STRICTCOFF, a COFF port can make the assembler to
726        follow the documented behavior.  */
727 #ifdef STRICTCOFF
728     case C_MOS:
729     case C_MOE:
730     case C_MOU:
731     case C_EOS:
732 #endif
733       SF_SET_DEBUG (def_symbol_in_progress);
734       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
735       break;
736 
737 #ifndef STRICTCOFF
738     case C_MOS:
739     case C_MOE:
740     case C_MOU:
741     case C_EOS:
742       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
743       break;
744 #endif
745 
746     case C_EXT:
747     case C_WEAKEXT:
748 #ifdef TE_PE
749     case C_NT_WEAK:
750 #endif
751     case C_STAT:
752     case C_LABEL:
753       /* Valid but set somewhere else (s_comm, s_lcomm, colon).  */
754       break;
755 
756     default:
757     case C_USTATIC:
758     case C_EXTDEF:
759     case C_ULABEL:
760       as_warn (_("unexpected storage class %d"),
761 	       S_GET_STORAGE_CLASS (def_symbol_in_progress));
762       break;
763     }
764 
765   /* Now that we have built a debug symbol, try to find if we should
766      merge with an existing symbol or not.  If a symbol is C_EFCN or
767      absolute_section or untagged SEG_DEBUG it never merges.  We also
768      don't merge labels, which are in a different namespace, nor
769      symbols which have not yet been defined since they are typically
770      unique, nor do we merge tags with non-tags.  */
771 
772   /* Two cases for functions.  Either debug followed by definition or
773      definition followed by debug.  For definition first, we will
774      merge the debug symbol into the definition.  For debug first, the
775      lineno entry MUST point to the definition function or else it
776      will point off into space when obj_crawl_symbol_chain() merges
777      the debug symbol into the real symbol.  Therefor, let's presume
778      the debug symbol is a real function reference.  */
779 
780   /* FIXME-SOON If for some reason the definition label/symbol is
781      never seen, this will probably leave an undefined symbol at link
782      time.  */
783 
784   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
785       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
786       || (streq (bfd_get_section_name (stdoutput,
787 				       S_GET_SEGMENT (def_symbol_in_progress)),
788 		 "*DEBUG*")
789 	  && !SF_GET_TAG (def_symbol_in_progress))
790       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
791       || ! symbol_constant_p (def_symbol_in_progress)
792       || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
793       || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
794     {
795       /* If it already is at the end of the symbol list, do nothing */
796       if (def_symbol_in_progress != symbol_lastP)
797 	{
798 	  symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
799 	  symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
800 			 &symbol_lastP);
801 	}
802     }
803   else
804     {
805       /* This symbol already exists, merge the newly created symbol
806 	 into the old one.  This is not mandatory. The linker can
807 	 handle duplicate symbols correctly. But I guess that it save
808 	 a *lot* of space if the assembly file defines a lot of
809 	 symbols. [loic]  */
810 
811       /* The debug entry (def_symbol_in_progress) is merged into the
812 	 previous definition.  */
813 
814       c_symbol_merge (def_symbol_in_progress, symbolP);
815       symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
816 
817       def_symbol_in_progress = symbolP;
818 
819       if (SF_GET_FUNCTION (def_symbol_in_progress)
820 	  || SF_GET_TAG (def_symbol_in_progress)
821 	  || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
822 	{
823 	  /* For functions, and tags, and static symbols, the symbol
824 	     *must* be where the debug symbol appears.  Move the
825 	     existing symbol to the current place.  */
826 	  /* If it already is at the end of the symbol list, do nothing.  */
827 	  if (def_symbol_in_progress != symbol_lastP)
828 	    {
829 	      symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
830 	      symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
831 	    }
832 	}
833     }
834 
835   if (SF_GET_TAG (def_symbol_in_progress))
836     {
837       symbolS *oldtag;
838 
839       oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
840       if (oldtag == NULL || ! SF_GET_TAG (oldtag))
841 	tag_insert (S_GET_NAME (def_symbol_in_progress),
842 		    def_symbol_in_progress);
843     }
844 
845   if (SF_GET_FUNCTION (def_symbol_in_progress))
846     {
847       set_function (def_symbol_in_progress);
848       SF_SET_PROCESS (def_symbol_in_progress);
849 
850       if (symbolP == NULL)
851 	/* That is, if this is the first time we've seen the
852 	   function.  */
853 	symbol_table_insert (def_symbol_in_progress);
854 
855     }
856 
857   def_symbol_in_progress = NULL;
858   demand_empty_rest_of_line ();
859 }
860 
861 static void
862 obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
863 {
864   int d_index;
865 
866   if (def_symbol_in_progress == NULL)
867     {
868       as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
869       demand_empty_rest_of_line ();
870       return;
871     }
872 
873   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
874 
875   for (d_index = 0; d_index < DIMNUM; d_index++)
876     {
877       SKIP_WHITESPACES ();
878       SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index,
879 			get_absolute_expression ());
880 
881       switch (*input_line_pointer)
882 	{
883 	case ',':
884 	  input_line_pointer++;
885 	  break;
886 
887 	default:
888 	  as_warn (_("badly formed .dim directive ignored"));
889 	  /* Fall through.  */
890 	case '\n':
891 	case ';':
892 	  d_index = DIMNUM;
893 	  break;
894 	}
895     }
896 
897   demand_empty_rest_of_line ();
898 }
899 
900 static void
901 obj_coff_line (int ignore ATTRIBUTE_UNUSED)
902 {
903   int this_base;
904 
905   if (def_symbol_in_progress == NULL)
906     {
907       /* Probably stabs-style line?  */
908       obj_coff_ln (0);
909       return;
910     }
911 
912   this_base = get_absolute_expression ();
913   if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
914     coff_line_base = this_base;
915 
916   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
917   SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
918 
919   demand_empty_rest_of_line ();
920 
921 #ifndef NO_LISTING
922   if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
923     {
924       extern int listing;
925 
926       if (listing)
927 	listing_source_line ((unsigned int) this_base);
928     }
929 #endif
930 }
931 
932 static void
933 obj_coff_size (int ignore ATTRIBUTE_UNUSED)
934 {
935   if (def_symbol_in_progress == NULL)
936     {
937       as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
938       demand_empty_rest_of_line ();
939       return;
940     }
941 
942   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
943   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
944   demand_empty_rest_of_line ();
945 }
946 
947 static void
948 obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
949 {
950   if (def_symbol_in_progress == NULL)
951     {
952       as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
953       demand_empty_rest_of_line ();
954       return;
955     }
956 
957   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
958   demand_empty_rest_of_line ();
959 }
960 
961 static void
962 obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
963 {
964   char *symbol_name;
965   char name_end;
966 
967   if (def_symbol_in_progress == NULL)
968     {
969       as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
970       demand_empty_rest_of_line ();
971       return;
972     }
973 
974   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
975   name_end = get_symbol_name (&symbol_name);
976 
977 #ifdef tc_canonicalize_symbol_name
978   symbol_name = tc_canonicalize_symbol_name (symbol_name);
979 #endif
980 
981   /* Assume that the symbol referred to by .tag is always defined.
982      This was a bad assumption.  I've added find_or_make. xoxorich.  */
983   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
984 		     tag_find_or_make (symbol_name));
985   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
986     as_warn (_("tag not found for .tag %s"), symbol_name);
987 
988   SF_SET_TAGGED (def_symbol_in_progress);
989 
990   (void) restore_line_pointer (name_end);
991   demand_empty_rest_of_line ();
992 }
993 
994 static void
995 obj_coff_type (int ignore ATTRIBUTE_UNUSED)
996 {
997   if (def_symbol_in_progress == NULL)
998     {
999       as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
1000       demand_empty_rest_of_line ();
1001       return;
1002     }
1003 
1004   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1005 
1006   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1007       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1008     SF_SET_FUNCTION (def_symbol_in_progress);
1009 
1010   demand_empty_rest_of_line ();
1011 }
1012 
1013 static void
1014 obj_coff_val (int ignore ATTRIBUTE_UNUSED)
1015 {
1016   if (def_symbol_in_progress == NULL)
1017     {
1018       as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1019       demand_empty_rest_of_line ();
1020       return;
1021     }
1022 
1023   if (is_name_beginner (*input_line_pointer))
1024     {
1025       char *symbol_name;
1026       char name_end = get_symbol_name (&symbol_name);
1027 
1028 #ifdef tc_canonicalize_symbol_name
1029       symbol_name = tc_canonicalize_symbol_name (symbol_name);
1030 #endif
1031       if (streq (symbol_name, "."))
1032 	{
1033 	  /* If the .val is != from the .def (e.g. statics).  */
1034 	  symbol_set_frag (def_symbol_in_progress, frag_now);
1035 	  S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1036 	}
1037       else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
1038 	{
1039 	  expressionS exp;
1040 
1041 	  exp.X_op = O_symbol;
1042 	  exp.X_add_symbol = symbol_find_or_make (symbol_name);
1043 	  exp.X_op_symbol = NULL;
1044 	  exp.X_add_number = 0;
1045 	  symbol_set_value_expression (def_symbol_in_progress, &exp);
1046 
1047 	  /* If the segment is undefined when the forward reference is
1048 	     resolved, then copy the segment id from the forward
1049 	     symbol.  */
1050 	  SF_SET_GET_SEGMENT (def_symbol_in_progress);
1051 
1052 	  /* FIXME: gcc can generate address expressions here in
1053 	     unusual cases (search for "obscure" in sdbout.c).  We
1054 	     just ignore the offset here, thus generating incorrect
1055 	     debugging information.  We ignore the rest of the line
1056 	     just below.  */
1057 	}
1058       /* Otherwise, it is the name of a non debug symbol and its value
1059          will be calculated later.  */
1060       (void) restore_line_pointer (name_end);
1061     }
1062   else
1063     {
1064       S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1065     }
1066 
1067   demand_empty_rest_of_line ();
1068 }
1069 
1070 #ifdef TE_PE
1071 
1072 /* Return nonzero if name begins with weak alternate symbol prefix.  */
1073 
1074 static int
1075 weak_is_altname (const char * name)
1076 {
1077   return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
1078 }
1079 
1080 /* Return the name of the alternate symbol
1081    name corresponding to a weak symbol's name.  */
1082 
1083 static const char *
1084 weak_name2altname (const char * name)
1085 {
1086   char *alt_name;
1087 
1088   alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
1089   strcpy (alt_name, weak_altprefix);
1090   return strcat (alt_name, name);
1091 }
1092 
1093 /* Return the name of the weak symbol corresponding to an
1094    alternate symbol.  */
1095 
1096 static const char *
1097 weak_altname2name (const char * name)
1098 {
1099   gas_assert (weak_is_altname (name));
1100   return xstrdup (name + 6);
1101 }
1102 
1103 /* Make a weak symbol name unique by
1104    appending the name of an external symbol.  */
1105 
1106 static const char *
1107 weak_uniquify (const char * name)
1108 {
1109   char *ret;
1110   const char * unique = "";
1111 
1112 #ifdef TE_PE
1113   if (an_external_name != NULL)
1114     unique = an_external_name;
1115 #endif
1116   gas_assert (weak_is_altname (name));
1117 
1118   ret = xmalloc (strlen (name) + strlen (unique) + 2);
1119   strcpy (ret, name);
1120   strcat (ret, ".");
1121   strcat (ret, unique);
1122   return ret;
1123 }
1124 
1125 void
1126 pecoff_obj_set_weak_hook (symbolS *symbolP)
1127 {
1128   symbolS *alternateP;
1129 
1130   /* See _Microsoft Portable Executable and Common Object
1131      File Format Specification_, section 5.5.3.
1132      Create a symbol representing the alternate value.
1133      coff_frob_symbol will set the value of this symbol from
1134      the value of the weak symbol itself.  */
1135   S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1136   S_SET_NUMBER_AUXILIARY (symbolP, 1);
1137   SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1138 
1139   alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1140   S_SET_EXTERNAL (alternateP);
1141   S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1142 
1143   SA_SET_SYM_TAGNDX (symbolP, alternateP);
1144 }
1145 
1146 void
1147 pecoff_obj_clear_weak_hook (symbolS *symbolP)
1148 {
1149   symbolS *alternateP;
1150 
1151   S_SET_STORAGE_CLASS (symbolP, 0);
1152   SA_SET_SYM_FSIZE (symbolP, 0);
1153 
1154   alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1155   S_CLEAR_EXTERNAL (alternateP);
1156 }
1157 
1158 #endif  /* TE_PE */
1159 
1160 /* Handle .weak.  This is a GNU extension in formats other than PE. */
1161 
1162 static void
1163 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1164 {
1165   char *name;
1166   int c;
1167   symbolS *symbolP;
1168 
1169   do
1170     {
1171       c = get_symbol_name (&name);
1172       if (*name == 0)
1173 	{
1174 	  as_warn (_("badly formed .weak directive ignored"));
1175 	  ignore_rest_of_line ();
1176 	  return;
1177 	}
1178       c = 0;
1179       symbolP = symbol_find_or_make (name);
1180       *input_line_pointer = c;
1181       SKIP_WHITESPACE_AFTER_NAME ();
1182       S_SET_WEAK (symbolP);
1183 
1184       if (c == ',')
1185 	{
1186 	  input_line_pointer++;
1187 	  SKIP_WHITESPACE ();
1188 	  if (*input_line_pointer == '\n')
1189 	    c = '\n';
1190 	}
1191 
1192     }
1193   while (c == ',');
1194 
1195   demand_empty_rest_of_line ();
1196 }
1197 
1198 void
1199 coff_obj_read_begin_hook (void)
1200 {
1201   /* These had better be the same.  Usually 18 bytes.  */
1202   know (sizeof (SYMENT) == sizeof (AUXENT));
1203   know (SYMESZ == AUXESZ);
1204   tag_init ();
1205 }
1206 
1207 symbolS *coff_last_function;
1208 #ifndef OBJ_XCOFF
1209 static symbolS *coff_last_bf;
1210 #endif
1211 
1212 void
1213 coff_frob_symbol (symbolS *symp, int *punt)
1214 {
1215   static symbolS *last_tagP;
1216   static stack *block_stack;
1217   static symbolS *set_end;
1218   symbolS *next_set_end = NULL;
1219 
1220   if (symp == &abs_symbol)
1221     {
1222       *punt = 1;
1223       return;
1224     }
1225 
1226   if (current_lineno_sym)
1227     coff_add_linesym (NULL);
1228 
1229   if (!block_stack)
1230     block_stack = stack_init (512, sizeof (symbolS*));
1231 
1232 #ifdef TE_PE
1233   if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1234       && ! S_IS_WEAK (symp)
1235       && weak_is_altname (S_GET_NAME (symp)))
1236     {
1237       /* This is a weak alternate symbol.  All processing of
1238 	 PECOFFweak symbols is done here, through the alternate.  */
1239       symbolS *weakp = symbol_find_noref (weak_altname2name
1240 					  (S_GET_NAME (symp)), 1);
1241 
1242       gas_assert (weakp);
1243       gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1244 
1245       if (! S_IS_WEAK (weakp))
1246 	{
1247 	  /* The symbol was turned from weak to strong.  Discard altname.  */
1248 	  *punt = 1;
1249 	  return;
1250 	}
1251       else if (symbol_equated_p (weakp))
1252 	{
1253 	  /* The weak symbol has an alternate specified; symp is unneeded.  */
1254 	  S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1255 	  SA_SET_SYM_TAGNDX (weakp,
1256 	    symbol_get_value_expression (weakp)->X_add_symbol);
1257 
1258 	  S_CLEAR_EXTERNAL (symp);
1259 	  *punt = 1;
1260 	  return;
1261 	}
1262       else
1263 	{
1264 	  /* The weak symbol has been assigned an alternate value.
1265              Copy this value to symp, and set symp as weakp's alternate.  */
1266 	  if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1267 	    {
1268 	      S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1269 	      S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1270 	    }
1271 
1272 	  if (S_IS_DEFINED (weakp))
1273 	    {
1274 	      /* This is a defined weak symbol.  Copy value information
1275 	         from the weak symbol itself to the alternate symbol.  */
1276 	      symbol_set_value_expression (symp,
1277 					   symbol_get_value_expression (weakp));
1278 	      symbol_set_frag (symp, symbol_get_frag (weakp));
1279 	      S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1280 	    }
1281 	  else
1282 	    {
1283 	      /* This is an undefined weak symbol.
1284 		 Define the alternate symbol to zero.  */
1285 	      S_SET_VALUE (symp, 0);
1286 	      S_SET_SEGMENT (symp, absolute_section);
1287 	    }
1288 
1289 	  S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1290 	  S_SET_STORAGE_CLASS (symp, C_EXT);
1291 
1292 	  S_SET_VALUE (weakp, 0);
1293 	  S_SET_SEGMENT (weakp, undefined_section);
1294 	}
1295     }
1296 #else /* TE_PE */
1297   if (S_IS_WEAK (symp))
1298     S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1299 #endif /* TE_PE */
1300 
1301   if (!S_IS_DEFINED (symp)
1302       && !S_IS_WEAK (symp)
1303       && S_GET_STORAGE_CLASS (symp) != C_STAT)
1304     S_SET_STORAGE_CLASS (symp, C_EXT);
1305 
1306   if (!SF_GET_DEBUG (symp))
1307     {
1308       symbolS * real;
1309 
1310       if (!SF_GET_LOCAL (symp)
1311 	  && !SF_GET_STATICS (symp)
1312 	  && S_GET_STORAGE_CLASS (symp) != C_LABEL
1313 	  && symbol_constant_p (symp)
1314 	  && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1315 	  && S_GET_STORAGE_CLASS (real) == C_NULL
1316 	  && real != symp)
1317 	{
1318 	  c_symbol_merge (symp, real);
1319 	  *punt = 1;
1320 	  return;
1321 	}
1322 
1323       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1324 	{
1325 	  gas_assert (S_GET_VALUE (symp) == 0);
1326 	  if (S_IS_WEAKREFD (symp))
1327 	    *punt = 1;
1328 	  else
1329 	    S_SET_EXTERNAL (symp);
1330 	}
1331       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1332 	{
1333 	  if (S_GET_SEGMENT (symp) == text_section
1334 	      && symp != seg_info (text_section)->sym)
1335 	    S_SET_STORAGE_CLASS (symp, C_LABEL);
1336 	  else
1337 	    S_SET_STORAGE_CLASS (symp, C_STAT);
1338 	}
1339 
1340       if (SF_GET_PROCESS (symp))
1341 	{
1342 	  if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1343 	    {
1344 	      if (streq (S_GET_NAME (symp), ".bb"))
1345 		stack_push (block_stack, (char *) &symp);
1346 	      else
1347 		{
1348 		  symbolS *begin;
1349 
1350 		  begin = *(symbolS **) stack_pop (block_stack);
1351 		  if (begin == 0)
1352 		    as_warn (_("mismatched .eb"));
1353 		  else
1354 		    next_set_end = begin;
1355 		}
1356 	    }
1357 
1358 	  if (coff_last_function == 0 && SF_GET_FUNCTION (symp)
1359 	      && S_IS_DEFINED (symp))
1360 	    {
1361 	      union internal_auxent *auxp;
1362 
1363 	      coff_last_function = symp;
1364 	      if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1365 		S_SET_NUMBER_AUXILIARY (symp, 1);
1366 	      auxp = SYM_AUXENT (symp);
1367 	      memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1368 		      sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1369 	    }
1370 
1371 	  if (S_GET_STORAGE_CLASS (symp) == C_EFCN
1372 	      && S_IS_DEFINED (symp))
1373 	    {
1374 	      if (coff_last_function == 0)
1375 		as_fatal (_("C_EFCN symbol for %s out of scope"),
1376 			  S_GET_NAME (symp));
1377 	      SA_SET_SYM_FSIZE (coff_last_function,
1378 				(long) (S_GET_VALUE (symp)
1379 					- S_GET_VALUE (coff_last_function)));
1380 	      next_set_end = coff_last_function;
1381 	      coff_last_function = 0;
1382 	    }
1383 	}
1384 
1385       if (S_IS_EXTERNAL (symp))
1386 	S_SET_STORAGE_CLASS (symp, C_EXT);
1387       else if (SF_GET_LOCAL (symp))
1388 	*punt = 1;
1389 
1390       if (SF_GET_FUNCTION (symp))
1391 	symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1392     }
1393 
1394   /* Double check weak symbols.  */
1395   if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1396     as_bad (_("Symbol `%s' can not be both weak and common"),
1397 	    S_GET_NAME (symp));
1398 
1399   if (SF_GET_TAG (symp))
1400     last_tagP = symp;
1401   else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1402     next_set_end = last_tagP;
1403 
1404 #ifdef OBJ_XCOFF
1405   /* This is pretty horrible, but we have to set *punt correctly in
1406      order to call SA_SET_SYM_ENDNDX correctly.  */
1407   if (! symbol_used_in_reloc_p (symp)
1408       && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1409 	  || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1410 	      && ! symbol_get_tc (symp)->output
1411 	      && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1412     *punt = 1;
1413 #endif
1414 
1415   if (set_end != (symbolS *) NULL
1416       && ! *punt
1417       && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1418 	  || (S_IS_DEFINED (symp)
1419 	      && ! S_IS_COMMON (symp)
1420 	      && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1421     {
1422       SA_SET_SYM_ENDNDX (set_end, symp);
1423       set_end = NULL;
1424     }
1425 
1426   if (next_set_end != NULL)
1427     {
1428       if (set_end != NULL)
1429 	as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1430 		 S_GET_NAME (set_end));
1431       set_end = next_set_end;
1432     }
1433 
1434 #ifndef OBJ_XCOFF
1435   if (! *punt
1436       && S_GET_STORAGE_CLASS (symp) == C_FCN
1437       && streq (S_GET_NAME (symp), ".bf"))
1438     {
1439       if (coff_last_bf != NULL)
1440 	SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1441       coff_last_bf = symp;
1442     }
1443 #endif
1444   if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1445     {
1446       int i;
1447       struct line_no *lptr;
1448       alent *l;
1449 
1450       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1451       for (i = 0; lptr; lptr = lptr->next)
1452 	i++;
1453       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1454 
1455       /* We need i entries for line numbers, plus 1 for the first
1456 	 entry which BFD will override, plus 1 for the last zero
1457 	 entry (a marker for BFD).  */
1458       l = xmalloc ((i + 2) * sizeof (* l));
1459       coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1460       l[i + 1].line_number = 0;
1461       l[i + 1].u.sym = NULL;
1462       for (; i > 0; i--)
1463 	{
1464 	  if (lptr->frag)
1465 	    lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1466 	  l[i] = lptr->l;
1467 	  lptr = lptr->next;
1468 	}
1469     }
1470 }
1471 
1472 void
1473 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1474 			  asection *sec,
1475 			  void * x ATTRIBUTE_UNUSED)
1476 {
1477   symbolS *secsym;
1478   segment_info_type *seginfo = seg_info (sec);
1479   int nlnno, nrelocs = 0;
1480 
1481   /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1482      tc-ppc.c.  Do not get confused by it.  */
1483   if (seginfo == NULL)
1484     return;
1485 
1486   if (streq (sec->name, ".text"))
1487     nlnno = coff_n_line_nos;
1488   else
1489     nlnno = 0;
1490   {
1491     /* @@ Hope that none of the fixups expand to more than one reloc
1492        entry...  */
1493     fixS *fixp = seginfo->fix_root;
1494     while (fixp)
1495       {
1496 	if (! fixp->fx_done)
1497 	  nrelocs++;
1498 	fixp = fixp->fx_next;
1499       }
1500   }
1501   if (bfd_get_section_size (sec) == 0
1502       && nrelocs == 0
1503       && nlnno == 0
1504       && sec != text_section
1505       && sec != data_section
1506       && sec != bss_section)
1507     return;
1508 
1509   secsym = section_symbol (sec);
1510   /* This is an estimate; we'll plug in the real value using
1511      SET_SECTION_RELOCS later */
1512   SA_SET_SCN_NRELOC (secsym, nrelocs);
1513   SA_SET_SCN_NLINNO (secsym, nlnno);
1514 }
1515 
1516 void
1517 coff_frob_file_after_relocs (void)
1518 {
1519   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1520 }
1521 
1522 /* Implement the .section pseudo op:
1523   	.section name {, "flags"}
1524                   ^         ^
1525                   |         +--- optional flags: 'b' for bss
1526                   |                              'i' for info
1527                   +-- section name               'l' for lib
1528                                                  'n' for noload
1529                                                  'o' for over
1530                                                  'w' for data
1531   						 'd' (apparently m88k for data)
1532 						 'e' for exclude
1533                                                  'x' for text
1534   						 'r' for read-only data
1535   						 's' for shared data (PE)
1536 						 'y' for noread
1537 					   '0' - '9' for power-of-two alignment (GNU extension).
1538    But if the argument is not a quoted string, treat it as a
1539    subsegment number.
1540 
1541    Note the 'a' flag is silently ignored.  This allows the same
1542    .section directive to be parsed in both ELF and COFF formats.  */
1543 
1544 void
1545 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1546 {
1547   /* Strip out the section name.  */
1548   char *section_name;
1549   char c;
1550   int alignment = -1;
1551   char *name;
1552   unsigned int exp;
1553   flagword flags, oldflags;
1554   asection *sec;
1555 
1556   if (flag_mri)
1557     {
1558       char type;
1559 
1560       s_mri_sect (&type);
1561       return;
1562     }
1563 
1564   c = get_symbol_name (&section_name);
1565   name = xmalloc (input_line_pointer - section_name + 1);
1566   strcpy (name, section_name);
1567   *input_line_pointer = c;
1568   SKIP_WHITESPACE_AFTER_NAME ();
1569 
1570   exp = 0;
1571   flags = SEC_NO_FLAGS;
1572 
1573   if (*input_line_pointer == ',')
1574     {
1575       ++input_line_pointer;
1576       SKIP_WHITESPACE ();
1577       if (*input_line_pointer != '"')
1578 	exp = get_absolute_expression ();
1579       else
1580 	{
1581 	  unsigned char attr;
1582 	  int readonly_removed = 0;
1583 	  int load_removed = 0;
1584 
1585 	  while (attr = *++input_line_pointer,
1586 		 attr != '"'
1587 		 && ! is_end_of_line[attr])
1588 	    {
1589 	      if (ISDIGIT (attr))
1590 		{
1591 		  alignment = attr - '0';
1592 		  continue;
1593 		}
1594 	      switch (attr)
1595 		{
1596 		case 'e':
1597 		  /* Exclude section from linking.  */
1598 		  flags |= SEC_EXCLUDE;
1599 		  break;
1600 
1601 		case 'b':
1602 		  /* Uninitialised data section.  */
1603 		  flags |= SEC_ALLOC;
1604 		  flags &=~ SEC_LOAD;
1605 		  break;
1606 
1607 		case 'n':
1608 		  /* Section not loaded.  */
1609 		  flags &=~ SEC_LOAD;
1610 		  flags |= SEC_NEVER_LOAD;
1611 		  load_removed = 1;
1612 		  break;
1613 
1614 		case 's':
1615 		  /* Shared section.  */
1616 		  flags |= SEC_COFF_SHARED;
1617 		  /* Fall through.  */
1618 		case 'd':
1619 		  /* Data section.  */
1620 		  flags |= SEC_DATA;
1621 		  if (! load_removed)
1622 		    flags |= SEC_LOAD;
1623 		  flags &=~ SEC_READONLY;
1624 		  break;
1625 
1626 		case 'w':
1627 		  /* Writable section.  */
1628 		  flags &=~ SEC_READONLY;
1629 		  readonly_removed = 1;
1630 		  break;
1631 
1632 		case 'a':
1633 		  /* Ignore.  Here for compatibility with ELF.  */
1634 		  break;
1635 
1636 		case 'r': /* Read-only section.  Implies a data section.  */
1637 		  readonly_removed = 0;
1638 		  /* Fall through.  */
1639 		case 'x': /* Executable section.  */
1640 		  /* If we are setting the 'x' attribute or if the 'r'
1641 		     attribute is being used to restore the readonly status
1642 		     of a code section (eg "wxr") then set the SEC_CODE flag,
1643 		     otherwise set the SEC_DATA flag.  */
1644 		  flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1645 		  if (! load_removed)
1646 		    flags |= SEC_LOAD;
1647 		  /* Note - the READONLY flag is set here, even for the 'x'
1648 		     attribute in order to be compatible with the MSVC
1649 		     linker.  */
1650 		  if (! readonly_removed)
1651 		    flags |= SEC_READONLY;
1652 		  break;
1653 
1654 		case 'y':
1655 		  flags |= SEC_COFF_NOREAD | SEC_READONLY;
1656 		  break;
1657 
1658 		case 'i': /* STYP_INFO */
1659 		case 'l': /* STYP_LIB */
1660 		case 'o': /* STYP_OVER */
1661 		  as_warn (_("unsupported section attribute '%c'"), attr);
1662 		  break;
1663 
1664 		default:
1665 		  as_warn (_("unknown section attribute '%c'"), attr);
1666 		  break;
1667 		}
1668 	    }
1669 	  if (attr == '"')
1670 	    ++input_line_pointer;
1671 	}
1672     }
1673 
1674   sec = subseg_new (name, (subsegT) exp);
1675 
1676   if (alignment >= 0)
1677     sec->alignment_power = alignment;
1678 
1679   oldflags = bfd_get_section_flags (stdoutput, sec);
1680   if (oldflags == SEC_NO_FLAGS)
1681     {
1682       /* Set section flags for a new section just created by subseg_new.
1683          Provide a default if no flags were parsed.  */
1684       if (flags == SEC_NO_FLAGS)
1685 	flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1686 
1687 #ifdef COFF_LONG_SECTION_NAMES
1688       /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1689          sections so adjust_reloc_syms in write.c will correctly handle
1690          relocs which refer to non-local symbols in these sections.  */
1691       if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1692 	flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1693 #endif
1694 
1695       if (! bfd_set_section_flags (stdoutput, sec, flags))
1696 	as_warn (_("error setting flags for \"%s\": %s"),
1697 		 bfd_section_name (stdoutput, sec),
1698 		 bfd_errmsg (bfd_get_error ()));
1699     }
1700   else if (flags != SEC_NO_FLAGS)
1701     {
1702       /* This section's attributes have already been set.  Warn if the
1703          attributes don't match.  */
1704       flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1705 			     | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1706 			     | SEC_COFF_NOREAD);
1707       if ((flags ^ oldflags) & matchflags)
1708 	as_warn (_("Ignoring changed section attributes for %s"), name);
1709     }
1710 
1711   demand_empty_rest_of_line ();
1712 }
1713 
1714 void
1715 coff_adjust_symtab (void)
1716 {
1717   if (symbol_rootP == NULL
1718       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1719     c_dot_file_symbol ("fake", 0);
1720 }
1721 
1722 void
1723 coff_frob_section (segT sec)
1724 {
1725   segT strsec;
1726   char *p;
1727   fragS *fragp;
1728   bfd_vma n_entries;
1729 
1730   /* The COFF back end in BFD requires that all section sizes be
1731      rounded up to multiples of the corresponding section alignments,
1732      supposedly because standard COFF has no other way of encoding alignment
1733      for sections.  If your COFF flavor has a different way of encoding
1734      section alignment, then skip this step, as TICOFF does.  */
1735   bfd_vma size = bfd_get_section_size (sec);
1736 #if !defined(TICOFF)
1737   bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
1738   bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
1739 
1740   if (size & mask)
1741     {
1742       bfd_vma new_size;
1743       fragS *last;
1744 
1745       new_size = (size + mask) & ~mask;
1746       bfd_set_section_size (stdoutput, sec, new_size);
1747 
1748       /* If the size had to be rounded up, add some padding in
1749          the last non-empty frag.  */
1750       fragp = seg_info (sec)->frchainP->frch_root;
1751       last = seg_info (sec)->frchainP->frch_last;
1752       while (fragp->fr_next != last)
1753 	fragp = fragp->fr_next;
1754       last->fr_address = size;
1755       fragp->fr_offset += new_size - size;
1756     }
1757 #endif
1758 
1759   /* If the section size is non-zero, the section symbol needs an aux
1760      entry associated with it, indicating the size.  We don't know
1761      all the values yet; coff_frob_symbol will fill them in later.  */
1762 #ifndef TICOFF
1763   if (size != 0
1764       || sec == text_section
1765       || sec == data_section
1766       || sec == bss_section)
1767 #endif
1768     {
1769       symbolS *secsym = section_symbol (sec);
1770       unsigned char sclass = C_STAT;
1771 
1772 #ifdef OBJ_XCOFF
1773       if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING)
1774         sclass = C_DWARF;
1775 #endif
1776       S_SET_STORAGE_CLASS (secsym, sclass);
1777       S_SET_NUMBER_AUXILIARY (secsym, 1);
1778       SF_SET_STATICS (secsym);
1779       SA_SET_SCN_SCNLEN (secsym, size);
1780     }
1781   /* FIXME: These should be in a "stabs.h" file, or maybe as.h.  */
1782 #ifndef STAB_SECTION_NAME
1783 #define STAB_SECTION_NAME ".stab"
1784 #endif
1785 #ifndef STAB_STRING_SECTION_NAME
1786 #define STAB_STRING_SECTION_NAME ".stabstr"
1787 #endif
1788   if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1789     return;
1790 
1791   strsec = sec;
1792   sec = subseg_get (STAB_SECTION_NAME, 0);
1793   /* size is already rounded up, since other section will be listed first */
1794   size = bfd_get_section_size (strsec);
1795 
1796   n_entries = bfd_get_section_size (sec) / 12 - 1;
1797 
1798   /* Find first non-empty frag.  It should be large enough.  */
1799   fragp = seg_info (sec)->frchainP->frch_root;
1800   while (fragp && fragp->fr_fix == 0)
1801     fragp = fragp->fr_next;
1802   gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1803 
1804   /* Store the values.  */
1805   p = fragp->fr_literal;
1806   bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1807   bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1808 }
1809 
1810 void
1811 obj_coff_init_stab_section (segT seg)
1812 {
1813   char *file;
1814   char *p;
1815   char *stabstr_name;
1816   unsigned int stroff;
1817 
1818   /* Make space for this first symbol.  */
1819   p = frag_more (12);
1820   /* Zero it out.  */
1821   memset (p, 0, 12);
1822   as_where (&file, (unsigned int *) NULL);
1823   stabstr_name = xmalloc (strlen (seg->name) + 4);
1824   strcpy (stabstr_name, seg->name);
1825   strcat (stabstr_name, "str");
1826   stroff = get_stab_string_offset (file, stabstr_name);
1827   know (stroff == 1);
1828   md_number_to_chars (p, stroff, 4);
1829 }
1830 
1831 #ifdef DEBUG
1832 const char * s_get_name (symbolS *);
1833 
1834 const char *
1835 s_get_name (symbolS *s)
1836 {
1837   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1838 }
1839 
1840 void symbol_dump (void);
1841 
1842 void
1843 symbol_dump (void)
1844 {
1845   symbolS *symbolP;
1846 
1847   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1848     printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1849 	    (unsigned long) symbolP,
1850 	    S_GET_NAME (symbolP),
1851 	    (long) S_GET_DATA_TYPE (symbolP),
1852 	    S_GET_STORAGE_CLASS (symbolP),
1853 	    (int) S_GET_SEGMENT (symbolP));
1854 }
1855 
1856 #endif /* DEBUG */
1857 
1858 const pseudo_typeS coff_pseudo_table[] =
1859 {
1860   {"ABORT", s_abort, 0},
1861   {"appline", obj_coff_ln, 1},
1862   /* We accept the .bss directive for backward compatibility with
1863      earlier versions of gas.  */
1864   {"bss", obj_coff_bss, 0},
1865 #ifdef TE_PE
1866   /* PE provides an enhanced version of .comm with alignment.  */
1867   {"comm", obj_coff_comm, 0},
1868 #endif /* TE_PE */
1869   {"def", obj_coff_def, 0},
1870   {"dim", obj_coff_dim, 0},
1871   {"endef", obj_coff_endef, 0},
1872   {"ident", obj_coff_ident, 0},
1873   {"line", obj_coff_line, 0},
1874   {"ln", obj_coff_ln, 0},
1875   {"scl", obj_coff_scl, 0},
1876   {"sect", obj_coff_section, 0},
1877   {"sect.s", obj_coff_section, 0},
1878   {"section", obj_coff_section, 0},
1879   {"section.s", obj_coff_section, 0},
1880   /* FIXME: We ignore the MRI short attribute.  */
1881   {"size", obj_coff_size, 0},
1882   {"tag", obj_coff_tag, 0},
1883   {"type", obj_coff_type, 0},
1884   {"val", obj_coff_val, 0},
1885   {"version", s_ignore, 0},
1886   {"loc", obj_coff_loc, 0},
1887   {"optim", s_ignore, 0},	/* For sun386i cc (?) */
1888   {"weak", obj_coff_weak, 0},
1889 #if defined TC_TIC4X
1890   /* The tic4x uses sdef instead of def.  */
1891   {"sdef", obj_coff_def, 0},
1892 #endif
1893 #if defined(SEH_CMDS)
1894   SEH_CMDS
1895 #endif
1896   {NULL, NULL, 0}
1897 };
1898 
1899 
1900 /* Support for a COFF emulation.  */
1901 
1902 static void
1903 coff_pop_insert (void)
1904 {
1905   pop_insert (coff_pseudo_table);
1906 }
1907 
1908 static int
1909 coff_separate_stab_sections (void)
1910 {
1911   return 1;
1912 }
1913 
1914 const struct format_ops coff_format_ops =
1915 {
1916   bfd_target_coff_flavour,
1917   0,	/* dfl_leading_underscore */
1918   1,	/* emit_section_symbols */
1919   0,    /* begin */
1920   c_dot_file_symbol,
1921   coff_frob_symbol,
1922   0,	/* frob_file */
1923   0,	/* frob_file_before_adjust */
1924   0,	/* frob_file_before_fix */
1925   coff_frob_file_after_relocs,
1926   0,	/* s_get_size */
1927   0,	/* s_set_size */
1928   0,	/* s_get_align */
1929   0,	/* s_set_align */
1930   0,	/* s_get_other */
1931   0,	/* s_set_other */
1932   0,	/* s_get_desc */
1933   0,	/* s_set_desc */
1934   0,	/* s_get_type */
1935   0,	/* s_set_type */
1936   0,	/* copy_symbol_attributes */
1937   0,	/* generate_asm_lineno */
1938   0,	/* process_stab */
1939   coff_separate_stab_sections,
1940   obj_coff_init_stab_section,
1941   0,	/* sec_sym_ok_for_reloc */
1942   coff_pop_insert,
1943   0,	/* ecoff_set_ext */
1944   coff_obj_read_begin_hook,
1945   coff_obj_symbol_new_hook,
1946   coff_obj_symbol_clone_hook,
1947   coff_adjust_symtab
1948 };
1949