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