* obj.h (struct format_ops): Add adjust_symtab.
[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, 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 \f
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 \f
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 \f
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 \f
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   char * weak_name;
1099   char * dot;
1100
1101   gas_assert (weak_is_altname (name));
1102
1103   weak_name = xstrdup (name + 6);
1104   if ((dot = strchr (weak_name, '.')))
1105     *dot = 0;
1106   return weak_name;
1107 }
1108
1109 /* Make a weak symbol name unique by
1110    appending the name of an external symbol.  */
1111
1112 static const char *
1113 weak_uniquify (const char * name)
1114 {
1115   char *ret;
1116   const char * unique = "";
1117
1118 #ifdef TE_PE
1119   if (an_external_name != NULL)
1120     unique = an_external_name;
1121 #endif
1122   gas_assert (weak_is_altname (name));
1123
1124   if (strchr (name + sizeof (weak_altprefix), '.'))
1125     return name;
1126
1127   ret = xmalloc (strlen (name) + strlen (unique) + 2);
1128   strcpy (ret, name);
1129   strcat (ret, ".");
1130   strcat (ret, unique);
1131   return ret;
1132 }
1133
1134 void
1135 pecoff_obj_set_weak_hook (symbolS *symbolP)
1136 {
1137   symbolS *alternateP;
1138
1139   /* See _Microsoft Portable Executable and Common Object
1140      File Format Specification_, section 5.5.3.
1141      Create a symbol representing the alternate value.
1142      coff_frob_symbol will set the value of this symbol from
1143      the value of the weak symbol itself.  */
1144   S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1145   S_SET_NUMBER_AUXILIARY (symbolP, 1);
1146   SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1147
1148   alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1149   S_SET_EXTERNAL (alternateP);
1150   S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1151
1152   SA_SET_SYM_TAGNDX (symbolP, alternateP);
1153 }
1154
1155 void
1156 pecoff_obj_clear_weak_hook (symbolS *symbolP)
1157 {
1158   symbolS *alternateP;
1159
1160   S_SET_STORAGE_CLASS (symbolP, 0);
1161   SA_SET_SYM_FSIZE (symbolP, 0);
1162
1163   alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1164   S_CLEAR_EXTERNAL (alternateP);
1165 }
1166
1167 #endif  /* TE_PE */
1168
1169 /* Handle .weak.  This is a GNU extension in formats other than PE. */
1170
1171 static void
1172 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1173 {
1174   char *name;
1175   int c;
1176   symbolS *symbolP;
1177
1178   do
1179     {
1180       name = input_line_pointer;
1181       c = get_symbol_end ();
1182       if (*name == 0)
1183         {
1184           as_warn (_("badly formed .weak directive ignored"));
1185           ignore_rest_of_line ();
1186           return;
1187         }
1188       c = 0;
1189       symbolP = symbol_find_or_make (name);
1190       *input_line_pointer = c;
1191       SKIP_WHITESPACE ();
1192       S_SET_WEAK (symbolP);
1193
1194       if (c == ',')
1195         {
1196           input_line_pointer++;
1197           SKIP_WHITESPACE ();
1198           if (*input_line_pointer == '\n')
1199             c = '\n';
1200         }
1201
1202     }
1203   while (c == ',');
1204
1205   demand_empty_rest_of_line ();
1206 }
1207
1208 void
1209 coff_obj_read_begin_hook (void)
1210 {
1211   /* These had better be the same.  Usually 18 bytes.  */
1212   know (sizeof (SYMENT) == sizeof (AUXENT));
1213   know (SYMESZ == AUXESZ);
1214   tag_init ();
1215 }
1216
1217 symbolS *coff_last_function;
1218 #ifndef OBJ_XCOFF
1219 static symbolS *coff_last_bf;
1220 #endif
1221
1222 void
1223 coff_frob_symbol (symbolS *symp, int *punt)
1224 {
1225   static symbolS *last_tagP;
1226   static stack *block_stack;
1227   static symbolS *set_end;
1228   symbolS *next_set_end = NULL;
1229
1230   if (symp == &abs_symbol)
1231     {
1232       *punt = 1;
1233       return;
1234     }
1235
1236   if (current_lineno_sym)
1237     coff_add_linesym (NULL);
1238
1239   if (!block_stack)
1240     block_stack = stack_init (512, sizeof (symbolS*));
1241
1242 #ifdef TE_PE
1243   if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1244       && ! S_IS_WEAK (symp)
1245       && weak_is_altname (S_GET_NAME (symp)))
1246     {
1247       /* This is a weak alternate symbol.  All processing of
1248          PECOFFweak symbols is done here, through the alternate.  */
1249       symbolS *weakp = symbol_find_noref (weak_altname2name
1250                                           (S_GET_NAME (symp)), 1);
1251
1252       gas_assert (weakp);
1253       gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1254
1255       if (! S_IS_WEAK (weakp))
1256         {
1257           /* The symbol was turned from weak to strong.  Discard altname.  */
1258           *punt = 1;
1259           return;
1260         }
1261       else if (symbol_equated_p (weakp))
1262         {
1263           /* The weak symbol has an alternate specified; symp is unneeded.  */
1264           S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1265           SA_SET_SYM_TAGNDX (weakp,
1266             symbol_get_value_expression (weakp)->X_add_symbol);
1267
1268           S_CLEAR_EXTERNAL (symp);
1269           *punt = 1;
1270           return;
1271         }
1272       else
1273         {
1274           /* The weak symbol has been assigned an alternate value.
1275              Copy this value to symp, and set symp as weakp's alternate.  */
1276           if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1277             {
1278               S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1279               S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1280             }
1281
1282           if (S_IS_DEFINED (weakp))
1283             {
1284               /* This is a defined weak symbol.  Copy value information
1285                  from the weak symbol itself to the alternate symbol.  */
1286               symbol_set_value_expression (symp,
1287                                            symbol_get_value_expression (weakp));
1288               symbol_set_frag (symp, symbol_get_frag (weakp));
1289               S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1290             }
1291           else
1292             {
1293               /* This is an undefined weak symbol.
1294                  Define the alternate symbol to zero.  */
1295               S_SET_VALUE (symp, 0);
1296               S_SET_SEGMENT (symp, absolute_section);
1297             }
1298
1299           S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1300           S_SET_STORAGE_CLASS (symp, C_EXT);
1301
1302           S_SET_VALUE (weakp, 0);
1303           S_SET_SEGMENT (weakp, undefined_section);
1304         }
1305     }
1306 #else /* TE_PE */
1307   if (S_IS_WEAK (symp))
1308     S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1309 #endif /* TE_PE */
1310
1311   if (!S_IS_DEFINED (symp)
1312       && !S_IS_WEAK (symp)
1313       && S_GET_STORAGE_CLASS (symp) != C_STAT)
1314     S_SET_STORAGE_CLASS (symp, C_EXT);
1315
1316   if (!SF_GET_DEBUG (symp))
1317     {
1318       symbolS * real;
1319
1320       if (!SF_GET_LOCAL (symp)
1321           && !SF_GET_STATICS (symp)
1322           && S_GET_STORAGE_CLASS (symp) != C_LABEL
1323           && symbol_constant_p (symp)
1324           && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1325           && S_GET_STORAGE_CLASS (real) == C_NULL
1326           && real != symp)
1327         {
1328           c_symbol_merge (symp, real);
1329           *punt = 1;
1330           return;
1331         }
1332
1333       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1334         {
1335           gas_assert (S_GET_VALUE (symp) == 0);
1336           if (S_IS_WEAKREFD (symp))
1337             *punt = 1;
1338           else
1339             S_SET_EXTERNAL (symp);
1340         }
1341       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1342         {
1343           if (S_GET_SEGMENT (symp) == text_section
1344               && symp != seg_info (text_section)->sym)
1345             S_SET_STORAGE_CLASS (symp, C_LABEL);
1346           else
1347             S_SET_STORAGE_CLASS (symp, C_STAT);
1348         }
1349
1350       if (SF_GET_PROCESS (symp))
1351         {
1352           if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1353             {
1354               if (streq (S_GET_NAME (symp), ".bb"))
1355                 stack_push (block_stack, (char *) &symp);
1356               else
1357                 {
1358                   symbolS *begin;
1359
1360                   begin = *(symbolS **) stack_pop (block_stack);
1361                   if (begin == 0)
1362                     as_warn (_("mismatched .eb"));
1363                   else
1364                     next_set_end = begin;
1365                 }
1366             }
1367
1368           if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1369             {
1370               union internal_auxent *auxp;
1371
1372               coff_last_function = symp;
1373               if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1374                 S_SET_NUMBER_AUXILIARY (symp, 1);
1375               auxp = SYM_AUXENT (symp);
1376               memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1377                       sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1378             }
1379
1380           if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1381             {
1382               if (coff_last_function == 0)
1383                 as_fatal (_("C_EFCN symbol for %s out of scope"),
1384                           S_GET_NAME (symp));
1385               SA_SET_SYM_FSIZE (coff_last_function,
1386                                 (long) (S_GET_VALUE (symp)
1387                                         - S_GET_VALUE (coff_last_function)));
1388               next_set_end = coff_last_function;
1389               coff_last_function = 0;
1390             }
1391         }
1392
1393       if (S_IS_EXTERNAL (symp))
1394         S_SET_STORAGE_CLASS (symp, C_EXT);
1395       else if (SF_GET_LOCAL (symp))
1396         *punt = 1;
1397
1398       if (SF_GET_FUNCTION (symp))
1399         symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1400     }
1401
1402   /* Double check weak symbols.  */
1403   if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1404     as_bad (_("Symbol `%s' can not be both weak and common"),
1405             S_GET_NAME (symp));
1406
1407   if (SF_GET_TAG (symp))
1408     last_tagP = symp;
1409   else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1410     next_set_end = last_tagP;
1411
1412 #ifdef OBJ_XCOFF
1413   /* This is pretty horrible, but we have to set *punt correctly in
1414      order to call SA_SET_SYM_ENDNDX correctly.  */
1415   if (! symbol_used_in_reloc_p (symp)
1416       && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1417           || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1418               && ! symbol_get_tc (symp)->output
1419               && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1420     *punt = 1;
1421 #endif
1422
1423   if (set_end != (symbolS *) NULL
1424       && ! *punt
1425       && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1426           || (S_IS_DEFINED (symp)
1427               && ! S_IS_COMMON (symp)
1428               && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1429     {
1430       SA_SET_SYM_ENDNDX (set_end, symp);
1431       set_end = NULL;
1432     }
1433
1434   if (next_set_end != NULL)
1435     {
1436       if (set_end != NULL)
1437         as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1438                  S_GET_NAME (set_end));
1439       set_end = next_set_end;
1440     }
1441
1442 #ifndef OBJ_XCOFF
1443   if (! *punt
1444       && S_GET_STORAGE_CLASS (symp) == C_FCN
1445       && streq (S_GET_NAME (symp), ".bf"))
1446     {
1447       if (coff_last_bf != NULL)
1448         SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1449       coff_last_bf = symp;
1450     }
1451 #endif
1452   if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1453     {
1454       int i;
1455       struct line_no *lptr;
1456       alent *l;
1457
1458       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1459       for (i = 0; lptr; lptr = lptr->next)
1460         i++;
1461       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1462
1463       /* We need i entries for line numbers, plus 1 for the first
1464          entry which BFD will override, plus 1 for the last zero
1465          entry (a marker for BFD).  */
1466       l = xmalloc ((i + 2) * sizeof (* l));
1467       coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1468       l[i + 1].line_number = 0;
1469       l[i + 1].u.sym = NULL;
1470       for (; i > 0; i--)
1471         {
1472           if (lptr->frag)
1473             lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1474           l[i] = lptr->l;
1475           lptr = lptr->next;
1476         }
1477     }
1478 }
1479
1480 void
1481 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1482                           asection *sec,
1483                           void * x ATTRIBUTE_UNUSED)
1484 {
1485   symbolS *secsym;
1486   segment_info_type *seginfo = seg_info (sec);
1487   int nlnno, nrelocs = 0;
1488
1489   /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1490      tc-ppc.c.  Do not get confused by it.  */
1491   if (seginfo == NULL)
1492     return;
1493
1494   if (streq (sec->name, ".text"))
1495     nlnno = coff_n_line_nos;
1496   else
1497     nlnno = 0;
1498   {
1499     /* @@ Hope that none of the fixups expand to more than one reloc
1500        entry...  */
1501     fixS *fixp = seginfo->fix_root;
1502     while (fixp)
1503       {
1504         if (! fixp->fx_done)
1505           nrelocs++;
1506         fixp = fixp->fx_next;
1507       }
1508   }
1509   if (bfd_get_section_size (sec) == 0
1510       && nrelocs == 0
1511       && nlnno == 0
1512       && sec != text_section
1513       && sec != data_section
1514       && sec != bss_section)
1515     return;
1516
1517   secsym = section_symbol (sec);
1518   /* This is an estimate; we'll plug in the real value using
1519      SET_SECTION_RELOCS later */
1520   SA_SET_SCN_NRELOC (secsym, nrelocs);
1521   SA_SET_SCN_NLINNO (secsym, nlnno);
1522 }
1523
1524 void
1525 coff_frob_file_after_relocs (void)
1526 {
1527   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1528 }
1529
1530 /* Implement the .section pseudo op:
1531         .section name {, "flags"}
1532                   ^         ^
1533                   |         +--- optional flags: 'b' for bss
1534                   |                              'i' for info
1535                   +-- section name               'l' for lib
1536                                                  'n' for noload
1537                                                  'o' for over
1538                                                  'w' for data
1539                                                  'd' (apparently m88k for data)
1540                                                  'x' for text
1541                                                  'r' for read-only data
1542                                                  's' for shared data (PE)
1543                                                  'y' for noread
1544                                            '0' - '9' for power-of-two alignment (GNU extension).
1545    But if the argument is not a quoted string, treat it as a
1546    subsegment number.
1547
1548    Note the 'a' flag is silently ignored.  This allows the same
1549    .section directive to be parsed in both ELF and COFF formats.  */
1550
1551 void
1552 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1553 {
1554   /* Strip out the section name.  */
1555   char *section_name;
1556   char c;
1557   int alignment = -1;
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               if (ISDIGIT (attr))
1601                 {
1602                   alignment = attr - '0';
1603                   continue;
1604                 }
1605               switch (attr)
1606                 {
1607                 case 'b':
1608                   /* Uninitialised data section.  */
1609                   flags |= SEC_ALLOC;
1610                   flags &=~ SEC_LOAD;
1611                   break;
1612
1613                 case 'n':
1614                   /* Section not loaded.  */
1615                   flags &=~ SEC_LOAD;
1616                   flags |= SEC_NEVER_LOAD;
1617                   load_removed = 1;
1618                   break;
1619
1620                 case 's':
1621                   /* Shared section.  */
1622                   flags |= SEC_COFF_SHARED;
1623                   /* Fall through.  */
1624                 case 'd':
1625                   /* Data section.  */
1626                   flags |= SEC_DATA;
1627                   if (! load_removed)
1628                     flags |= SEC_LOAD;
1629                   flags &=~ SEC_READONLY;
1630                   break;
1631
1632                 case 'w':
1633                   /* Writable section.  */
1634                   flags &=~ SEC_READONLY;
1635                   readonly_removed = 1;
1636                   break;
1637
1638                 case 'a':
1639                   /* Ignore.  Here for compatibility with ELF.  */
1640                   break;
1641
1642                 case 'r': /* Read-only section.  Implies a data section.  */
1643                   readonly_removed = 0;
1644                   /* Fall through.  */
1645                 case 'x': /* Executable section.  */
1646                   /* If we are setting the 'x' attribute or if the 'r'
1647                      attribute is being used to restore the readonly status
1648                      of a code section (eg "wxr") then set the SEC_CODE flag,
1649                      otherwise set the SEC_DATA flag.  */
1650                   flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1651                   if (! load_removed)
1652                     flags |= SEC_LOAD;
1653                   /* Note - the READONLY flag is set here, even for the 'x'
1654                      attribute in order to be compatible with the MSVC
1655                      linker.  */
1656                   if (! readonly_removed)
1657                     flags |= SEC_READONLY;
1658                   break;
1659
1660                 case 'y':
1661                   flags |= SEC_COFF_NOREAD | SEC_READONLY;
1662                   break;
1663
1664                 case 'i': /* STYP_INFO */
1665                 case 'l': /* STYP_LIB */
1666                 case 'o': /* STYP_OVER */
1667                   as_warn (_("unsupported section attribute '%c'"), attr);
1668                   break;
1669
1670                 default:
1671                   as_warn (_("unknown section attribute '%c'"), attr);
1672                   break;
1673                 }
1674             }
1675           if (attr == '"')
1676             ++input_line_pointer;
1677         }
1678     }
1679
1680   sec = subseg_new (name, (subsegT) exp);
1681   if (alignment >= 0)
1682     sec->alignment_power = alignment;
1683
1684   oldflags = bfd_get_section_flags (stdoutput, sec);
1685   if (oldflags == SEC_NO_FLAGS)
1686     {
1687       /* Set section flags for a new section just created by subseg_new.
1688          Provide a default if no flags were parsed.  */
1689       if (flags == SEC_NO_FLAGS)
1690         flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1691
1692 #ifdef COFF_LONG_SECTION_NAMES
1693       /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1694          sections so adjust_reloc_syms in write.c will correctly handle
1695          relocs which refer to non-local symbols in these sections.  */
1696       if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1697         flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1698 #endif
1699
1700       if (! bfd_set_section_flags (stdoutput, sec, flags))
1701         as_warn (_("error setting flags for \"%s\": %s"),
1702                  bfd_section_name (stdoutput, sec),
1703                  bfd_errmsg (bfd_get_error ()));
1704     }
1705   else if (flags != SEC_NO_FLAGS)
1706     {
1707       /* This section's attributes have already been set.  Warn if the
1708          attributes don't match.  */
1709       flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1710                              | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1711                              | SEC_COFF_NOREAD);
1712       if ((flags ^ oldflags) & matchflags)
1713         as_warn (_("Ignoring changed section attributes for %s"), name);
1714     }
1715
1716   demand_empty_rest_of_line ();
1717 }
1718
1719 void
1720 coff_adjust_symtab (void)
1721 {
1722   if (symbol_rootP == NULL
1723       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1724     c_dot_file_symbol ("fake", 0);
1725 }
1726
1727 void
1728 coff_frob_section (segT sec)
1729 {
1730   segT strsec;
1731   char *p;
1732   fragS *fragp;
1733   bfd_vma n_entries;
1734
1735   /* The COFF back end in BFD requires that all section sizes be
1736      rounded up to multiples of the corresponding section alignments,
1737      supposedly because standard COFF has no other way of encoding alignment
1738      for sections.  If your COFF flavor has a different way of encoding
1739      section alignment, then skip this step, as TICOFF does.  */
1740   bfd_vma size = bfd_get_section_size (sec);
1741 #if !defined(TICOFF)
1742   bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
1743   bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
1744
1745   if (size & mask)
1746     {
1747       bfd_vma new_size;
1748       fragS *last;
1749
1750       new_size = (size + mask) & ~mask;
1751       bfd_set_section_size (stdoutput, sec, new_size);
1752
1753       /* If the size had to be rounded up, add some padding in
1754          the last non-empty frag.  */
1755       fragp = seg_info (sec)->frchainP->frch_root;
1756       last = seg_info (sec)->frchainP->frch_last;
1757       while (fragp->fr_next != last)
1758         fragp = fragp->fr_next;
1759       last->fr_address = size;
1760       fragp->fr_offset += new_size - size;
1761     }
1762 #endif
1763
1764   /* If the section size is non-zero, the section symbol needs an aux
1765      entry associated with it, indicating the size.  We don't know
1766      all the values yet; coff_frob_symbol will fill them in later.  */
1767 #ifndef TICOFF
1768   if (size != 0
1769       || sec == text_section
1770       || sec == data_section
1771       || sec == bss_section)
1772 #endif
1773     {
1774       symbolS *secsym = section_symbol (sec);
1775
1776       S_SET_STORAGE_CLASS (secsym, C_STAT);
1777       S_SET_NUMBER_AUXILIARY (secsym, 1);
1778       SF_SET_STATICS (secsym);
1779       SA_SET_SCN_SCNLEN (secsym, size);
1780     }
1781   /* FIXME: These should be in a "stabs.h" file, or maybe as.h.  */
1782 #ifndef STAB_SECTION_NAME
1783 #define STAB_SECTION_NAME ".stab"
1784 #endif
1785 #ifndef STAB_STRING_SECTION_NAME
1786 #define STAB_STRING_SECTION_NAME ".stabstr"
1787 #endif
1788   if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1789     return;
1790
1791   strsec = sec;
1792   sec = subseg_get (STAB_SECTION_NAME, 0);
1793   /* size is already rounded up, since other section will be listed first */
1794   size = bfd_get_section_size (strsec);
1795
1796   n_entries = bfd_get_section_size (sec) / 12 - 1;
1797
1798   /* Find first non-empty frag.  It should be large enough.  */
1799   fragp = seg_info (sec)->frchainP->frch_root;
1800   while (fragp && fragp->fr_fix == 0)
1801     fragp = fragp->fr_next;
1802   gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1803
1804   /* Store the values.  */
1805   p = fragp->fr_literal;
1806   bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1807   bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1808 }
1809
1810 void
1811 obj_coff_init_stab_section (segT seg)
1812 {
1813   char *file;
1814   char *p;
1815   char *stabstr_name;
1816   unsigned int stroff;
1817
1818   /* Make space for this first symbol.  */
1819   p = frag_more (12);
1820   /* Zero it out.  */
1821   memset (p, 0, 12);
1822   as_where (&file, (unsigned int *) NULL);
1823   stabstr_name = xmalloc (strlen (seg->name) + 4);
1824   strcpy (stabstr_name, seg->name);
1825   strcat (stabstr_name, "str");
1826   stroff = get_stab_string_offset (file, stabstr_name);
1827   know (stroff == 1);
1828   md_number_to_chars (p, stroff, 4);
1829 }
1830
1831 #ifdef DEBUG
1832 const char * s_get_name (symbolS *);
1833
1834 const char *
1835 s_get_name (symbolS *s)
1836 {
1837   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1838 }
1839
1840 void symbol_dump (void);
1841
1842 void
1843 symbol_dump (void)
1844 {
1845   symbolS *symbolP;
1846
1847   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1848     printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1849             (unsigned long) symbolP,
1850             S_GET_NAME (symbolP),
1851             (long) S_GET_DATA_TYPE (symbolP),
1852             S_GET_STORAGE_CLASS (symbolP),
1853             (int) S_GET_SEGMENT (symbolP));
1854 }
1855
1856 #endif /* DEBUG */
1857
1858 const pseudo_typeS coff_pseudo_table[] =
1859 {
1860   {"ABORT", s_abort, 0},
1861   {"appline", obj_coff_ln, 1},
1862   /* We accept the .bss directive for backward compatibility with
1863      earlier versions of gas.  */
1864   {"bss", obj_coff_bss, 0},
1865 #ifdef TE_PE
1866   /* PE provides an enhanced version of .comm with alignment.  */
1867   {"comm", obj_coff_comm, 0},
1868 #endif /* TE_PE */
1869   {"def", obj_coff_def, 0},
1870   {"dim", obj_coff_dim, 0},
1871   {"endef", obj_coff_endef, 0},
1872   {"ident", obj_coff_ident, 0},
1873   {"line", obj_coff_line, 0},
1874   {"ln", obj_coff_ln, 0},
1875   {"scl", obj_coff_scl, 0},
1876   {"sect", obj_coff_section, 0},
1877   {"sect.s", obj_coff_section, 0},
1878   {"section", obj_coff_section, 0},
1879   {"section.s", obj_coff_section, 0},
1880   /* FIXME: We ignore the MRI short attribute.  */
1881   {"size", obj_coff_size, 0},
1882   {"tag", obj_coff_tag, 0},
1883   {"type", obj_coff_type, 0},
1884   {"val", obj_coff_val, 0},
1885   {"version", s_ignore, 0},
1886   {"loc", obj_coff_loc, 0},
1887   {"optim", s_ignore, 0},       /* For sun386i cc (?) */
1888   {"weak", obj_coff_weak, 0},
1889 #if defined TC_TIC4X
1890   /* The tic4x uses sdef instead of def.  */
1891   {"sdef", obj_coff_def, 0},
1892 #endif
1893 #if defined(SEH_CMDS)
1894   SEH_CMDS
1895 #endif
1896   {NULL, NULL, 0}
1897 };
1898 \f
1899
1900 /* Support for a COFF emulation.  */
1901
1902 static void
1903 coff_pop_insert (void)
1904 {
1905   pop_insert (coff_pseudo_table);
1906 }
1907
1908 static int
1909 coff_separate_stab_sections (void)
1910 {
1911   return 1;
1912 }
1913
1914 const struct format_ops coff_format_ops =
1915 {
1916   bfd_target_coff_flavour,
1917   0,    /* dfl_leading_underscore */
1918   1,    /* emit_section_symbols */
1919   0,    /* begin */
1920   c_dot_file_symbol,
1921   coff_frob_symbol,
1922   0,    /* frob_file */
1923   0,    /* frob_file_before_adjust */
1924   0,    /* frob_file_before_fix */
1925   coff_frob_file_after_relocs,
1926   0,    /* s_get_size */
1927   0,    /* s_set_size */
1928   0,    /* s_get_align */
1929   0,    /* s_set_align */
1930   0,    /* s_get_other */
1931   0,    /* s_set_other */
1932   0,    /* s_get_desc */
1933   0,    /* s_set_desc */
1934   0,    /* s_get_type */
1935   0,    /* s_set_type */
1936   0,    /* copy_symbol_attributes */
1937   0,    /* generate_asm_lineno */
1938   0,    /* process_stab */
1939   coff_separate_stab_sections,
1940   obj_coff_init_stab_section,
1941   0,    /* sec_sym_ok_for_reloc */
1942   coff_pop_insert,
1943   0,    /* ecoff_set_ext */
1944   coff_obj_read_begin_hook,
1945   coff_obj_symbol_new_hook,
1946   coff_obj_symbol_clone_hook,
1947   coff_obj_adjust_symtab
1948 };