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