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