Prepare gas for 64-bit obstacks
[external/binutils.git] / gas / config / obj-coff.c
1 /* coff object file format
2    Copyright (C) 1989-2014 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
391   S_SET_DATA_TYPE (symbolP, T_NULL);
392   S_SET_STORAGE_CLASS (symbolP, 0);
393   S_SET_NUMBER_AUXILIARY (symbolP, 0);
394
395   if (S_IS_STRING (symbolP))
396     SF_SET_STRING (symbolP);
397
398   if (S_IS_LOCAL (symbolP))
399     SF_SET_LOCAL (symbolP);
400 }
401
402 void
403 coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
404 {
405   long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
406   combined_entry_type * s = xmalloc (sz);
407
408   memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
409   coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
410
411   SF_SET (newsymP, SF_GET (orgsymP));
412 }
413
414 \f
415 /* Handle .ln directives.  */
416
417 static symbolS *current_lineno_sym;
418 static struct line_no *line_nos;
419 /* FIXME:  Blindly assume all .ln directives will be in the .text section.  */
420 int coff_n_line_nos;
421
422 static void
423 add_lineno (fragS * frag, addressT offset, int num)
424 {
425   struct line_no * new_line = xmalloc (sizeof (* new_line));
426
427   if (!current_lineno_sym)
428     abort ();
429
430 #ifndef OBJ_XCOFF
431   /* The native aix assembler accepts negative line number.  */
432
433   if (num <= 0)
434     {
435       /* Zero is used as an end marker in the file.  */
436       as_warn (_("Line numbers must be positive integers\n"));
437       num = 1;
438     }
439 #endif /* OBJ_XCOFF */
440   new_line->next = line_nos;
441   new_line->frag = frag;
442   new_line->l.line_number = num;
443   new_line->l.u.offset = offset;
444   line_nos = new_line;
445   coff_n_line_nos++;
446 }
447
448 void
449 coff_add_linesym (symbolS *sym)
450 {
451   if (line_nos)
452     {
453       coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
454         (alent *) line_nos;
455       coff_n_line_nos++;
456       line_nos = 0;
457     }
458   current_lineno_sym = sym;
459 }
460
461 static void
462 obj_coff_ln (int appline)
463 {
464   int l;
465
466   if (! appline && def_symbol_in_progress != NULL)
467     {
468       as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
469       demand_empty_rest_of_line ();
470       return;
471     }
472
473   l = get_absolute_expression ();
474
475   /* If there is no lineno symbol, treat a .ln
476      directive as if it were a .appline directive.  */
477   if (appline || current_lineno_sym == NULL)
478     new_logical_line ((char *) NULL, l - 1);
479   else
480     add_lineno (frag_now, frag_now_fix (), l);
481
482 #ifndef NO_LISTING
483   {
484     extern int listing;
485
486     if (listing)
487       {
488         if (! appline)
489           l += coff_line_base - 1;
490         listing_source_line (l);
491       }
492   }
493 #endif
494
495   demand_empty_rest_of_line ();
496 }
497
498 /* .loc is essentially the same as .ln; parse it for assembler
499    compatibility.  */
500
501 static void
502 obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
503 {
504   int lineno;
505
506   /* FIXME: Why do we need this check?  We need it for ECOFF, but why
507      do we need it for COFF?  */
508   if (now_seg != text_section)
509     {
510       as_warn (_(".loc outside of .text"));
511       demand_empty_rest_of_line ();
512       return;
513     }
514
515   if (def_symbol_in_progress != NULL)
516     {
517       as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
518       demand_empty_rest_of_line ();
519       return;
520     }
521
522   /* Skip the file number.  */
523   SKIP_WHITESPACE ();
524   get_absolute_expression ();
525   SKIP_WHITESPACE ();
526
527   lineno = get_absolute_expression ();
528
529 #ifndef NO_LISTING
530   {
531     extern int listing;
532
533     if (listing)
534       {
535         lineno += coff_line_base - 1;
536         listing_source_line (lineno);
537       }
538   }
539 #endif
540
541   demand_empty_rest_of_line ();
542
543   add_lineno (frag_now, frag_now_fix (), lineno);
544 }
545
546 /* Handle the .ident pseudo-op.  */
547
548 static void
549 obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
550 {
551   segT current_seg = now_seg;
552   subsegT current_subseg = now_subseg;
553
554 #ifdef TE_PE
555   {
556     segT sec;
557
558     /* We could put it in .comment, but that creates an extra section
559        that shouldn't be loaded into memory, which requires linker
560        changes...  For now, until proven otherwise, use .rdata.  */
561     sec = subseg_new (".rdata$zzz", 0);
562     bfd_set_section_flags (stdoutput, sec,
563                            ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
564                             & bfd_applicable_section_flags (stdoutput)));
565   }
566 #else
567   subseg_new (".comment", 0);
568 #endif
569
570   stringer (8 + 1);
571   subseg_set (current_seg, current_subseg);
572 }
573
574 /* Handle .def directives.
575
576    One might ask : why can't we symbol_new if the symbol does not
577    already exist and fill it with debug information.  Because of
578    the C_EFCN special symbol. It would clobber the value of the
579    function symbol before we have a chance to notice that it is
580    a C_EFCN. And a second reason is that the code is more clear this
581    way. (at least I think it is :-).  */
582
583 #define SKIP_SEMI_COLON()       while (*input_line_pointer++ != ';')
584 #define SKIP_WHITESPACES()      while (*input_line_pointer == ' ' || \
585                                        *input_line_pointer == '\t')  \
586                                   input_line_pointer++;
587
588 static void
589 obj_coff_def (int what ATTRIBUTE_UNUSED)
590 {
591   char name_end;                /* Char after the end of name.  */
592   char *symbol_name;            /* Name of the debug symbol.  */
593   char *symbol_name_copy;       /* Temporary copy of the name.  */
594   unsigned int symbol_name_length;
595
596   if (def_symbol_in_progress != NULL)
597     {
598       as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
599       demand_empty_rest_of_line ();
600       return;
601     }
602
603   SKIP_WHITESPACES ();
604
605   symbol_name = input_line_pointer;
606   name_end = get_symbol_end ();
607   symbol_name_length = strlen (symbol_name);
608   symbol_name_copy = xmalloc (symbol_name_length + 1);
609   strcpy (symbol_name_copy, symbol_name);
610 #ifdef tc_canonicalize_symbol_name
611   symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
612 #endif
613
614   /* Initialize the new symbol.  */
615   def_symbol_in_progress = symbol_make (symbol_name_copy);
616   symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
617   S_SET_VALUE (def_symbol_in_progress, 0);
618
619   if (S_IS_STRING (def_symbol_in_progress))
620     SF_SET_STRING (def_symbol_in_progress);
621
622   *input_line_pointer = name_end;
623
624   demand_empty_rest_of_line ();
625 }
626
627 static void
628 obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
629 {
630   symbolS *symbolP = NULL;
631
632   if (def_symbol_in_progress == NULL)
633     {
634       as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
635       demand_empty_rest_of_line ();
636       return;
637     }
638
639   /* Set the section number according to storage class.  */
640   switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
641     {
642     case C_STRTAG:
643     case C_ENTAG:
644     case C_UNTAG:
645       SF_SET_TAG (def_symbol_in_progress);
646       /* Fall through.  */
647     case C_FILE:
648     case C_TPDEF:
649       SF_SET_DEBUG (def_symbol_in_progress);
650       S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
651       break;
652
653     case C_EFCN:
654       SF_SET_LOCAL (def_symbol_in_progress);    /* Do not emit this symbol.  */
655       /* Fall through.  */
656     case C_BLOCK:
657       SF_SET_PROCESS (def_symbol_in_progress);  /* Will need processing before writing.  */
658       /* Fall through.  */
659     case C_FCN:
660       {
661         const char *name;
662
663         S_SET_SEGMENT (def_symbol_in_progress, text_section);
664
665         name = S_GET_NAME (def_symbol_in_progress);
666         if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
667           {
668             switch (name[1])
669               {
670               case 'b':
671                 /* .bf */
672                 if (! in_function ())
673                   as_warn (_("`%s' symbol without preceding function"), name);
674                 /* Will need relocating.  */
675                 SF_SET_PROCESS (def_symbol_in_progress);
676                 clear_function ();
677                 break;
678 #ifdef TE_PE
679               case 'e':
680                 /* .ef */
681                 /* The MS compilers output the actual endline, not the
682                    function-relative one... we want to match without
683                    changing the assembler input.  */
684                 SA_SET_SYM_LNNO (def_symbol_in_progress,
685                                  (SA_GET_SYM_LNNO (def_symbol_in_progress)
686                                   + coff_line_base));
687                 break;
688 #endif
689               }
690           }
691       }
692       break;
693
694 #ifdef C_AUTOARG
695     case C_AUTOARG:
696 #endif /* C_AUTOARG */
697     case C_AUTO:
698     case C_REG:
699     case C_ARG:
700     case C_REGPARM:
701     case C_FIELD:
702
703     /* According to the COFF documentation:
704
705        http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
706
707        A special section number (-2) marks symbolic debugging symbols,
708        including structure/union/enumeration tag names, typedefs, and
709        the name of the file. A section number of -1 indicates that the
710        symbol has a value but is not relocatable. Examples of
711        absolute-valued symbols include automatic and register variables,
712        function arguments, and .eos symbols.
713
714        But from Ian Lance Taylor:
715
716        http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
717
718        the actual tools all marked them as section -1. So the GNU COFF
719        assembler follows historical COFF assemblers.
720
721        However, it causes problems for djgpp
722
723        http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
724
725        By defining STRICTCOFF, a COFF port can make the assembler to
726        follow the documented behavior.  */
727 #ifdef STRICTCOFF
728     case C_MOS:
729     case C_MOE:
730     case C_MOU:
731     case C_EOS:
732 #endif
733       SF_SET_DEBUG (def_symbol_in_progress);
734       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
735       break;
736
737 #ifndef STRICTCOFF
738     case C_MOS:
739     case C_MOE:
740     case C_MOU:
741     case C_EOS:
742       S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
743       break;
744 #endif
745
746     case C_EXT:
747     case C_WEAKEXT:
748 #ifdef TE_PE
749     case C_NT_WEAK:
750 #endif
751     case C_STAT:
752     case C_LABEL:
753       /* Valid but set somewhere else (s_comm, s_lcomm, colon).  */
754       break;
755
756     default:
757     case C_USTATIC:
758     case C_EXTDEF:
759     case C_ULABEL:
760       as_warn (_("unexpected storage class %d"),
761                S_GET_STORAGE_CLASS (def_symbol_in_progress));
762       break;
763     }
764
765   /* Now that we have built a debug symbol, try to find if we should
766      merge with an existing symbol or not.  If a symbol is C_EFCN or
767      absolute_section or untagged SEG_DEBUG it never merges.  We also
768      don't merge labels, which are in a different namespace, nor
769      symbols which have not yet been defined since they are typically
770      unique, nor do we merge tags with non-tags.  */
771
772   /* Two cases for functions.  Either debug followed by definition or
773      definition followed by debug.  For definition first, we will
774      merge the debug symbol into the definition.  For debug first, the
775      lineno entry MUST point to the definition function or else it
776      will point off into space when obj_crawl_symbol_chain() merges
777      the debug symbol into the real symbol.  Therefor, let's presume
778      the debug symbol is a real function reference.  */
779
780   /* FIXME-SOON If for some reason the definition label/symbol is
781      never seen, this will probably leave an undefined symbol at link
782      time.  */
783
784   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
785       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
786       || (streq (bfd_get_section_name (stdoutput,
787                                        S_GET_SEGMENT (def_symbol_in_progress)),
788                  "*DEBUG*")
789           && !SF_GET_TAG (def_symbol_in_progress))
790       || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
791       || ! symbol_constant_p (def_symbol_in_progress)
792       || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
793       || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
794     {
795       /* If it already is at the end of the symbol list, do nothing */
796       if (def_symbol_in_progress != symbol_lastP)
797         {
798           symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
799           symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
800                          &symbol_lastP);
801         }
802     }
803   else
804     {
805       /* This symbol already exists, merge the newly created symbol
806          into the old one.  This is not mandatory. The linker can
807          handle duplicate symbols correctly. But I guess that it save
808          a *lot* of space if the assembly file defines a lot of
809          symbols. [loic]  */
810
811       /* The debug entry (def_symbol_in_progress) is merged into the
812          previous definition.  */
813
814       c_symbol_merge (def_symbol_in_progress, symbolP);
815       symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
816
817       def_symbol_in_progress = symbolP;
818
819       if (SF_GET_FUNCTION (def_symbol_in_progress)
820           || SF_GET_TAG (def_symbol_in_progress)
821           || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
822         {
823           /* For functions, and tags, and static symbols, the symbol
824              *must* be where the debug symbol appears.  Move the
825              existing symbol to the current place.  */
826           /* If it already is at the end of the symbol list, do nothing.  */
827           if (def_symbol_in_progress != symbol_lastP)
828             {
829               symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
830               symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
831             }
832         }
833     }
834
835   if (SF_GET_TAG (def_symbol_in_progress))
836     {
837       symbolS *oldtag;
838
839       oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
840       if (oldtag == NULL || ! SF_GET_TAG (oldtag))
841         tag_insert (S_GET_NAME (def_symbol_in_progress),
842                     def_symbol_in_progress);
843     }
844
845   if (SF_GET_FUNCTION (def_symbol_in_progress))
846     {
847       set_function (def_symbol_in_progress);
848       SF_SET_PROCESS (def_symbol_in_progress);
849
850       if (symbolP == NULL)
851         /* That is, if this is the first time we've seen the
852            function.  */
853         symbol_table_insert (def_symbol_in_progress);
854
855     }
856
857   def_symbol_in_progress = NULL;
858   demand_empty_rest_of_line ();
859 }
860
861 static void
862 obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
863 {
864   int d_index;
865
866   if (def_symbol_in_progress == NULL)
867     {
868       as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
869       demand_empty_rest_of_line ();
870       return;
871     }
872
873   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
874
875   for (d_index = 0; d_index < DIMNUM; d_index++)
876     {
877       SKIP_WHITESPACES ();
878       SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index,
879                         get_absolute_expression ());
880
881       switch (*input_line_pointer)
882         {
883         case ',':
884           input_line_pointer++;
885           break;
886
887         default:
888           as_warn (_("badly formed .dim directive ignored"));
889           /* Fall through.  */
890         case '\n':
891         case ';':
892           d_index = DIMNUM;
893           break;
894         }
895     }
896
897   demand_empty_rest_of_line ();
898 }
899
900 static void
901 obj_coff_line (int ignore ATTRIBUTE_UNUSED)
902 {
903   int this_base;
904
905   if (def_symbol_in_progress == NULL)
906     {
907       /* Probably stabs-style line?  */
908       obj_coff_ln (0);
909       return;
910     }
911
912   this_base = get_absolute_expression ();
913   if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
914     coff_line_base = this_base;
915
916   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
917   SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
918
919   demand_empty_rest_of_line ();
920
921 #ifndef NO_LISTING
922   if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
923     {
924       extern int listing;
925
926       if (listing)
927         listing_source_line ((unsigned int) this_base);
928     }
929 #endif
930 }
931
932 static void
933 obj_coff_size (int ignore ATTRIBUTE_UNUSED)
934 {
935   if (def_symbol_in_progress == NULL)
936     {
937       as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
938       demand_empty_rest_of_line ();
939       return;
940     }
941
942   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
943   SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
944   demand_empty_rest_of_line ();
945 }
946
947 static void
948 obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
949 {
950   if (def_symbol_in_progress == NULL)
951     {
952       as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
953       demand_empty_rest_of_line ();
954       return;
955     }
956
957   S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
958   demand_empty_rest_of_line ();
959 }
960
961 static void
962 obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
963 {
964   char *symbol_name;
965   char name_end;
966
967   if (def_symbol_in_progress == NULL)
968     {
969       as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
970       demand_empty_rest_of_line ();
971       return;
972     }
973
974   S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
975   symbol_name = input_line_pointer;
976   name_end = get_symbol_end ();
977
978 #ifdef tc_canonicalize_symbol_name
979   symbol_name = tc_canonicalize_symbol_name (symbol_name);
980 #endif
981
982   /* Assume that the symbol referred to by .tag is always defined.
983      This was a bad assumption.  I've added find_or_make. xoxorich.  */
984   SA_SET_SYM_TAGNDX (def_symbol_in_progress,
985                      tag_find_or_make (symbol_name));
986   if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
987     as_warn (_("tag not found for .tag %s"), symbol_name);
988
989   SF_SET_TAGGED (def_symbol_in_progress);
990   *input_line_pointer = name_end;
991
992   demand_empty_rest_of_line ();
993 }
994
995 static void
996 obj_coff_type (int ignore ATTRIBUTE_UNUSED)
997 {
998   if (def_symbol_in_progress == NULL)
999     {
1000       as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
1001       demand_empty_rest_of_line ();
1002       return;
1003     }
1004
1005   S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
1006
1007   if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
1008       S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
1009     SF_SET_FUNCTION (def_symbol_in_progress);
1010
1011   demand_empty_rest_of_line ();
1012 }
1013
1014 static void
1015 obj_coff_val (int ignore ATTRIBUTE_UNUSED)
1016 {
1017   if (def_symbol_in_progress == NULL)
1018     {
1019       as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
1020       demand_empty_rest_of_line ();
1021       return;
1022     }
1023
1024   if (is_name_beginner (*input_line_pointer))
1025     {
1026       char *symbol_name = input_line_pointer;
1027       char name_end = get_symbol_end ();
1028
1029 #ifdef tc_canonicalize_symbol_name
1030   symbol_name = tc_canonicalize_symbol_name (symbol_name);
1031 #endif
1032       if (streq (symbol_name, "."))
1033         {
1034           /* If the .val is != from the .def (e.g. statics).  */
1035           symbol_set_frag (def_symbol_in_progress, frag_now);
1036           S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
1037         }
1038       else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
1039         {
1040           expressionS exp;
1041
1042           exp.X_op = O_symbol;
1043           exp.X_add_symbol = symbol_find_or_make (symbol_name);
1044           exp.X_op_symbol = NULL;
1045           exp.X_add_number = 0;
1046           symbol_set_value_expression (def_symbol_in_progress, &exp);
1047
1048           /* If the segment is undefined when the forward reference is
1049              resolved, then copy the segment id from the forward
1050              symbol.  */
1051           SF_SET_GET_SEGMENT (def_symbol_in_progress);
1052
1053           /* FIXME: gcc can generate address expressions here in
1054              unusual cases (search for "obscure" in sdbout.c).  We
1055              just ignore the offset here, thus generating incorrect
1056              debugging information.  We ignore the rest of the line
1057              just below.  */
1058         }
1059       /* Otherwise, it is the name of a non debug symbol and its value
1060          will be calculated later.  */
1061       *input_line_pointer = name_end;
1062     }
1063   else
1064     {
1065       S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1066     }
1067
1068   demand_empty_rest_of_line ();
1069 }
1070
1071 #ifdef TE_PE
1072
1073 /* Return nonzero if name begins with weak alternate symbol prefix.  */
1074
1075 static int
1076 weak_is_altname (const char * name)
1077 {
1078   return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1);
1079 }
1080
1081 /* Return the name of the alternate symbol
1082    name corresponding to a weak symbol's name.  */
1083
1084 static const char *
1085 weak_name2altname (const char * name)
1086 {
1087   char *alt_name;
1088
1089   alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name));
1090   strcpy (alt_name, weak_altprefix);
1091   return strcat (alt_name, name);
1092 }
1093
1094 /* Return the name of the weak symbol corresponding to an
1095    alternate symbol.  */
1096
1097 static const char *
1098 weak_altname2name (const char * name)
1099 {
1100   gas_assert (weak_is_altname (name));
1101   return xstrdup (name + 6);
1102 }
1103
1104 /* Make a weak symbol name unique by
1105    appending the name of an external symbol.  */
1106
1107 static const char *
1108 weak_uniquify (const char * name)
1109 {
1110   char *ret;
1111   const char * unique = "";
1112
1113 #ifdef TE_PE
1114   if (an_external_name != NULL)
1115     unique = an_external_name;
1116 #endif
1117   gas_assert (weak_is_altname (name));
1118
1119   ret = xmalloc (strlen (name) + strlen (unique) + 2);
1120   strcpy (ret, name);
1121   strcat (ret, ".");
1122   strcat (ret, unique);
1123   return ret;
1124 }
1125
1126 void
1127 pecoff_obj_set_weak_hook (symbolS *symbolP)
1128 {
1129   symbolS *alternateP;
1130
1131   /* See _Microsoft Portable Executable and Common Object
1132      File Format Specification_, section 5.5.3.
1133      Create a symbol representing the alternate value.
1134      coff_frob_symbol will set the value of this symbol from
1135      the value of the weak symbol itself.  */
1136   S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1137   S_SET_NUMBER_AUXILIARY (symbolP, 1);
1138   SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1139
1140   alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
1141   S_SET_EXTERNAL (alternateP);
1142   S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1143
1144   SA_SET_SYM_TAGNDX (symbolP, alternateP);
1145 }
1146
1147 void
1148 pecoff_obj_clear_weak_hook (symbolS *symbolP)
1149 {
1150   symbolS *alternateP;
1151
1152   S_SET_STORAGE_CLASS (symbolP, 0);
1153   SA_SET_SYM_FSIZE (symbolP, 0);
1154
1155   alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
1156   S_CLEAR_EXTERNAL (alternateP);
1157 }
1158
1159 #endif  /* TE_PE */
1160
1161 /* Handle .weak.  This is a GNU extension in formats other than PE. */
1162
1163 static void
1164 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1165 {
1166   char *name;
1167   int c;
1168   symbolS *symbolP;
1169
1170   do
1171     {
1172       name = input_line_pointer;
1173       c = get_symbol_end ();
1174       if (*name == 0)
1175         {
1176           as_warn (_("badly formed .weak directive ignored"));
1177           ignore_rest_of_line ();
1178           return;
1179         }
1180       c = 0;
1181       symbolP = symbol_find_or_make (name);
1182       *input_line_pointer = c;
1183       SKIP_WHITESPACE ();
1184       S_SET_WEAK (symbolP);
1185
1186       if (c == ',')
1187         {
1188           input_line_pointer++;
1189           SKIP_WHITESPACE ();
1190           if (*input_line_pointer == '\n')
1191             c = '\n';
1192         }
1193
1194     }
1195   while (c == ',');
1196
1197   demand_empty_rest_of_line ();
1198 }
1199
1200 void
1201 coff_obj_read_begin_hook (void)
1202 {
1203   /* These had better be the same.  Usually 18 bytes.  */
1204   know (sizeof (SYMENT) == sizeof (AUXENT));
1205   know (SYMESZ == AUXESZ);
1206   tag_init ();
1207 }
1208
1209 symbolS *coff_last_function;
1210 #ifndef OBJ_XCOFF
1211 static symbolS *coff_last_bf;
1212 #endif
1213
1214 void
1215 coff_frob_symbol (symbolS *symp, int *punt)
1216 {
1217   static symbolS *last_tagP;
1218   static stack *block_stack;
1219   static symbolS *set_end;
1220   symbolS *next_set_end = NULL;
1221
1222   if (symp == &abs_symbol)
1223     {
1224       *punt = 1;
1225       return;
1226     }
1227
1228   if (current_lineno_sym)
1229     coff_add_linesym (NULL);
1230
1231   if (!block_stack)
1232     block_stack = stack_init (512, sizeof (symbolS*));
1233
1234 #ifdef TE_PE
1235   if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1236       && ! S_IS_WEAK (symp)
1237       && weak_is_altname (S_GET_NAME (symp)))
1238     {
1239       /* This is a weak alternate symbol.  All processing of
1240          PECOFFweak symbols is done here, through the alternate.  */
1241       symbolS *weakp = symbol_find_noref (weak_altname2name
1242                                           (S_GET_NAME (symp)), 1);
1243
1244       gas_assert (weakp);
1245       gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1246
1247       if (! S_IS_WEAK (weakp))
1248         {
1249           /* The symbol was turned from weak to strong.  Discard altname.  */
1250           *punt = 1;
1251           return;
1252         }
1253       else if (symbol_equated_p (weakp))
1254         {
1255           /* The weak symbol has an alternate specified; symp is unneeded.  */
1256           S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1257           SA_SET_SYM_TAGNDX (weakp,
1258             symbol_get_value_expression (weakp)->X_add_symbol);
1259
1260           S_CLEAR_EXTERNAL (symp);
1261           *punt = 1;
1262           return;
1263         }
1264       else
1265         {
1266           /* The weak symbol has been assigned an alternate value.
1267              Copy this value to symp, and set symp as weakp's alternate.  */
1268           if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1269             {
1270               S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1271               S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1272             }
1273
1274           if (S_IS_DEFINED (weakp))
1275             {
1276               /* This is a defined weak symbol.  Copy value information
1277                  from the weak symbol itself to the alternate symbol.  */
1278               symbol_set_value_expression (symp,
1279                                            symbol_get_value_expression (weakp));
1280               symbol_set_frag (symp, symbol_get_frag (weakp));
1281               S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1282             }
1283           else
1284             {
1285               /* This is an undefined weak symbol.
1286                  Define the alternate symbol to zero.  */
1287               S_SET_VALUE (symp, 0);
1288               S_SET_SEGMENT (symp, absolute_section);
1289             }
1290
1291           S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1292           S_SET_STORAGE_CLASS (symp, C_EXT);
1293
1294           S_SET_VALUE (weakp, 0);
1295           S_SET_SEGMENT (weakp, undefined_section);
1296         }
1297     }
1298 #else /* TE_PE */
1299   if (S_IS_WEAK (symp))
1300     S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1301 #endif /* TE_PE */
1302
1303   if (!S_IS_DEFINED (symp)
1304       && !S_IS_WEAK (symp)
1305       && S_GET_STORAGE_CLASS (symp) != C_STAT)
1306     S_SET_STORAGE_CLASS (symp, C_EXT);
1307
1308   if (!SF_GET_DEBUG (symp))
1309     {
1310       symbolS * real;
1311
1312       if (!SF_GET_LOCAL (symp)
1313           && !SF_GET_STATICS (symp)
1314           && S_GET_STORAGE_CLASS (symp) != C_LABEL
1315           && symbol_constant_p (symp)
1316           && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1317           && S_GET_STORAGE_CLASS (real) == C_NULL
1318           && real != symp)
1319         {
1320           c_symbol_merge (symp, real);
1321           *punt = 1;
1322           return;
1323         }
1324
1325       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1326         {
1327           gas_assert (S_GET_VALUE (symp) == 0);
1328           if (S_IS_WEAKREFD (symp))
1329             *punt = 1;
1330           else
1331             S_SET_EXTERNAL (symp);
1332         }
1333       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1334         {
1335           if (S_GET_SEGMENT (symp) == text_section
1336               && symp != seg_info (text_section)->sym)
1337             S_SET_STORAGE_CLASS (symp, C_LABEL);
1338           else
1339             S_SET_STORAGE_CLASS (symp, C_STAT);
1340         }
1341
1342       if (SF_GET_PROCESS (symp))
1343         {
1344           if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1345             {
1346               if (streq (S_GET_NAME (symp), ".bb"))
1347                 stack_push (block_stack, (char *) &symp);
1348               else
1349                 {
1350                   symbolS *begin;
1351
1352                   begin = *(symbolS **) stack_pop (block_stack);
1353                   if (begin == 0)
1354                     as_warn (_("mismatched .eb"));
1355                   else
1356                     next_set_end = begin;
1357                 }
1358             }
1359
1360           if (coff_last_function == 0 && SF_GET_FUNCTION (symp)
1361               && S_IS_DEFINED (symp))
1362             {
1363               union internal_auxent *auxp;
1364
1365               coff_last_function = symp;
1366               if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1367                 S_SET_NUMBER_AUXILIARY (symp, 1);
1368               auxp = SYM_AUXENT (symp);
1369               memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1370                       sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1371             }
1372
1373           if (S_GET_STORAGE_CLASS (symp) == C_EFCN
1374               && S_IS_DEFINED (symp))
1375             {
1376               if (coff_last_function == 0)
1377                 as_fatal (_("C_EFCN symbol for %s out of scope"),
1378                           S_GET_NAME (symp));
1379               SA_SET_SYM_FSIZE (coff_last_function,
1380                                 (long) (S_GET_VALUE (symp)
1381                                         - S_GET_VALUE (coff_last_function)));
1382               next_set_end = coff_last_function;
1383               coff_last_function = 0;
1384             }
1385         }
1386
1387       if (S_IS_EXTERNAL (symp))
1388         S_SET_STORAGE_CLASS (symp, C_EXT);
1389       else if (SF_GET_LOCAL (symp))
1390         *punt = 1;
1391
1392       if (SF_GET_FUNCTION (symp))
1393         symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1394     }
1395
1396   /* Double check weak symbols.  */
1397   if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1398     as_bad (_("Symbol `%s' can not be both weak and common"),
1399             S_GET_NAME (symp));
1400
1401   if (SF_GET_TAG (symp))
1402     last_tagP = symp;
1403   else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1404     next_set_end = last_tagP;
1405
1406 #ifdef OBJ_XCOFF
1407   /* This is pretty horrible, but we have to set *punt correctly in
1408      order to call SA_SET_SYM_ENDNDX correctly.  */
1409   if (! symbol_used_in_reloc_p (symp)
1410       && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1411           || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1412               && ! symbol_get_tc (symp)->output
1413               && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1414     *punt = 1;
1415 #endif
1416
1417   if (set_end != (symbolS *) NULL
1418       && ! *punt
1419       && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1420           || (S_IS_DEFINED (symp)
1421               && ! S_IS_COMMON (symp)
1422               && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1423     {
1424       SA_SET_SYM_ENDNDX (set_end, symp);
1425       set_end = NULL;
1426     }
1427
1428   if (next_set_end != NULL)
1429     {
1430       if (set_end != NULL)
1431         as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1432                  S_GET_NAME (set_end));
1433       set_end = next_set_end;
1434     }
1435
1436 #ifndef OBJ_XCOFF
1437   if (! *punt
1438       && S_GET_STORAGE_CLASS (symp) == C_FCN
1439       && streq (S_GET_NAME (symp), ".bf"))
1440     {
1441       if (coff_last_bf != NULL)
1442         SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1443       coff_last_bf = symp;
1444     }
1445 #endif
1446   if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1447     {
1448       int i;
1449       struct line_no *lptr;
1450       alent *l;
1451
1452       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1453       for (i = 0; lptr; lptr = lptr->next)
1454         i++;
1455       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1456
1457       /* We need i entries for line numbers, plus 1 for the first
1458          entry which BFD will override, plus 1 for the last zero
1459          entry (a marker for BFD).  */
1460       l = xmalloc ((i + 2) * sizeof (* l));
1461       coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1462       l[i + 1].line_number = 0;
1463       l[i + 1].u.sym = NULL;
1464       for (; i > 0; i--)
1465         {
1466           if (lptr->frag)
1467             lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1468           l[i] = lptr->l;
1469           lptr = lptr->next;
1470         }
1471     }
1472 }
1473
1474 void
1475 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1476                           asection *sec,
1477                           void * x ATTRIBUTE_UNUSED)
1478 {
1479   symbolS *secsym;
1480   segment_info_type *seginfo = seg_info (sec);
1481   int nlnno, nrelocs = 0;
1482
1483   /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1484      tc-ppc.c.  Do not get confused by it.  */
1485   if (seginfo == NULL)
1486     return;
1487
1488   if (streq (sec->name, ".text"))
1489     nlnno = coff_n_line_nos;
1490   else
1491     nlnno = 0;
1492   {
1493     /* @@ Hope that none of the fixups expand to more than one reloc
1494        entry...  */
1495     fixS *fixp = seginfo->fix_root;
1496     while (fixp)
1497       {
1498         if (! fixp->fx_done)
1499           nrelocs++;
1500         fixp = fixp->fx_next;
1501       }
1502   }
1503   if (bfd_get_section_size (sec) == 0
1504       && nrelocs == 0
1505       && nlnno == 0
1506       && sec != text_section
1507       && sec != data_section
1508       && sec != bss_section)
1509     return;
1510
1511   secsym = section_symbol (sec);
1512   /* This is an estimate; we'll plug in the real value using
1513      SET_SECTION_RELOCS later */
1514   SA_SET_SCN_NRELOC (secsym, nrelocs);
1515   SA_SET_SCN_NLINNO (secsym, nlnno);
1516 }
1517
1518 void
1519 coff_frob_file_after_relocs (void)
1520 {
1521   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1522 }
1523
1524 /* Implement the .section pseudo op:
1525         .section name {, "flags"}
1526                   ^         ^
1527                   |         +--- optional flags: 'b' for bss
1528                   |                              'i' for info
1529                   +-- section name               'l' for lib
1530                                                  'n' for noload
1531                                                  'o' for over
1532                                                  'w' for data
1533                                                  'd' (apparently m88k for data)
1534                                                  'e' for exclude
1535                                                  'x' for text
1536                                                  'r' for read-only data
1537                                                  's' for shared data (PE)
1538                                                  'y' for noread
1539                                            '0' - '9' for power-of-two alignment (GNU extension).
1540    But if the argument is not a quoted string, treat it as a
1541    subsegment number.
1542
1543    Note the 'a' flag is silently ignored.  This allows the same
1544    .section directive to be parsed in both ELF and COFF formats.  */
1545
1546 void
1547 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1548 {
1549   /* Strip out the section name.  */
1550   char *section_name;
1551   char c;
1552   int alignment = -1;
1553   char *name;
1554   unsigned int exp;
1555   flagword flags, oldflags;
1556   asection *sec;
1557
1558   if (flag_mri)
1559     {
1560       char type;
1561
1562       s_mri_sect (&type);
1563       return;
1564     }
1565
1566   section_name = input_line_pointer;
1567   c = get_symbol_end ();
1568
1569   name = xmalloc (input_line_pointer - section_name + 1);
1570   strcpy (name, section_name);
1571
1572   *input_line_pointer = c;
1573
1574   SKIP_WHITESPACE ();
1575
1576   exp = 0;
1577   flags = SEC_NO_FLAGS;
1578
1579   if (*input_line_pointer == ',')
1580     {
1581       ++input_line_pointer;
1582       SKIP_WHITESPACE ();
1583       if (*input_line_pointer != '"')
1584         exp = get_absolute_expression ();
1585       else
1586         {
1587           unsigned char attr;
1588           int readonly_removed = 0;
1589           int load_removed = 0;
1590
1591           while (attr = *++input_line_pointer,
1592                  attr != '"'
1593                  && ! is_end_of_line[attr])
1594             {
1595               if (ISDIGIT (attr))
1596                 {
1597                   alignment = attr - '0';
1598                   continue;
1599                 }
1600               switch (attr)
1601                 {
1602                 case 'e':
1603                   /* Exclude section from linking.  */
1604                   flags |= SEC_EXCLUDE;
1605                   break;
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
1682   if (alignment >= 0)
1683     sec->alignment_power = alignment;
1684
1685   oldflags = bfd_get_section_flags (stdoutput, sec);
1686   if (oldflags == SEC_NO_FLAGS)
1687     {
1688       /* Set section flags for a new section just created by subseg_new.
1689          Provide a default if no flags were parsed.  */
1690       if (flags == SEC_NO_FLAGS)
1691         flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1692
1693 #ifdef COFF_LONG_SECTION_NAMES
1694       /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1695          sections so adjust_reloc_syms in write.c will correctly handle
1696          relocs which refer to non-local symbols in these sections.  */
1697       if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1698         flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1699 #endif
1700
1701       if (! bfd_set_section_flags (stdoutput, sec, flags))
1702         as_warn (_("error setting flags for \"%s\": %s"),
1703                  bfd_section_name (stdoutput, sec),
1704                  bfd_errmsg (bfd_get_error ()));
1705     }
1706   else if (flags != SEC_NO_FLAGS)
1707     {
1708       /* This section's attributes have already been set.  Warn if the
1709          attributes don't match.  */
1710       flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1711                              | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1712                              | SEC_COFF_NOREAD);
1713       if ((flags ^ oldflags) & matchflags)
1714         as_warn (_("Ignoring changed section attributes for %s"), name);
1715     }
1716
1717   demand_empty_rest_of_line ();
1718 }
1719
1720 void
1721 coff_adjust_symtab (void)
1722 {
1723   if (symbol_rootP == NULL
1724       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1725     c_dot_file_symbol ("fake", 0);
1726 }
1727
1728 void
1729 coff_frob_section (segT sec)
1730 {
1731   segT strsec;
1732   char *p;
1733   fragS *fragp;
1734   bfd_vma n_entries;
1735
1736   /* The COFF back end in BFD requires that all section sizes be
1737      rounded up to multiples of the corresponding section alignments,
1738      supposedly because standard COFF has no other way of encoding alignment
1739      for sections.  If your COFF flavor has a different way of encoding
1740      section alignment, then skip this step, as TICOFF does.  */
1741   bfd_vma size = bfd_get_section_size (sec);
1742 #if !defined(TICOFF)
1743   bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
1744   bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
1745
1746   if (size & mask)
1747     {
1748       bfd_vma new_size;
1749       fragS *last;
1750
1751       new_size = (size + mask) & ~mask;
1752       bfd_set_section_size (stdoutput, sec, new_size);
1753
1754       /* If the size had to be rounded up, add some padding in
1755          the last non-empty frag.  */
1756       fragp = seg_info (sec)->frchainP->frch_root;
1757       last = seg_info (sec)->frchainP->frch_last;
1758       while (fragp->fr_next != last)
1759         fragp = fragp->fr_next;
1760       last->fr_address = size;
1761       fragp->fr_offset += new_size - size;
1762     }
1763 #endif
1764
1765   /* If the section size is non-zero, the section symbol needs an aux
1766      entry associated with it, indicating the size.  We don't know
1767      all the values yet; coff_frob_symbol will fill them in later.  */
1768 #ifndef TICOFF
1769   if (size != 0
1770       || sec == text_section
1771       || sec == data_section
1772       || sec == bss_section)
1773 #endif
1774     {
1775       symbolS *secsym = section_symbol (sec);
1776       unsigned char sclass = C_STAT;
1777
1778 #ifdef OBJ_XCOFF
1779       if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING)
1780         sclass = C_DWARF;
1781 #endif
1782       S_SET_STORAGE_CLASS (secsym, sclass);
1783       S_SET_NUMBER_AUXILIARY (secsym, 1);
1784       SF_SET_STATICS (secsym);
1785       SA_SET_SCN_SCNLEN (secsym, size);
1786     }
1787   /* FIXME: These should be in a "stabs.h" file, or maybe as.h.  */
1788 #ifndef STAB_SECTION_NAME
1789 #define STAB_SECTION_NAME ".stab"
1790 #endif
1791 #ifndef STAB_STRING_SECTION_NAME
1792 #define STAB_STRING_SECTION_NAME ".stabstr"
1793 #endif
1794   if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1795     return;
1796
1797   strsec = sec;
1798   sec = subseg_get (STAB_SECTION_NAME, 0);
1799   /* size is already rounded up, since other section will be listed first */
1800   size = bfd_get_section_size (strsec);
1801
1802   n_entries = bfd_get_section_size (sec) / 12 - 1;
1803
1804   /* Find first non-empty frag.  It should be large enough.  */
1805   fragp = seg_info (sec)->frchainP->frch_root;
1806   while (fragp && fragp->fr_fix == 0)
1807     fragp = fragp->fr_next;
1808   gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1809
1810   /* Store the values.  */
1811   p = fragp->fr_literal;
1812   bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1813   bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1814 }
1815
1816 void
1817 obj_coff_init_stab_section (segT seg)
1818 {
1819   char *file;
1820   char *p;
1821   char *stabstr_name;
1822   unsigned int stroff;
1823
1824   /* Make space for this first symbol.  */
1825   p = frag_more (12);
1826   /* Zero it out.  */
1827   memset (p, 0, 12);
1828   as_where (&file, (unsigned int *) NULL);
1829   stabstr_name = xmalloc (strlen (seg->name) + 4);
1830   strcpy (stabstr_name, seg->name);
1831   strcat (stabstr_name, "str");
1832   stroff = get_stab_string_offset (file, stabstr_name);
1833   know (stroff == 1);
1834   md_number_to_chars (p, stroff, 4);
1835 }
1836
1837 #ifdef DEBUG
1838 const char * s_get_name (symbolS *);
1839
1840 const char *
1841 s_get_name (symbolS *s)
1842 {
1843   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1844 }
1845
1846 void symbol_dump (void);
1847
1848 void
1849 symbol_dump (void)
1850 {
1851   symbolS *symbolP;
1852
1853   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1854     printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1855             (unsigned long) symbolP,
1856             S_GET_NAME (symbolP),
1857             (long) S_GET_DATA_TYPE (symbolP),
1858             S_GET_STORAGE_CLASS (symbolP),
1859             (int) S_GET_SEGMENT (symbolP));
1860 }
1861
1862 #endif /* DEBUG */
1863
1864 const pseudo_typeS coff_pseudo_table[] =
1865 {
1866   {"ABORT", s_abort, 0},
1867   {"appline", obj_coff_ln, 1},
1868   /* We accept the .bss directive for backward compatibility with
1869      earlier versions of gas.  */
1870   {"bss", obj_coff_bss, 0},
1871 #ifdef TE_PE
1872   /* PE provides an enhanced version of .comm with alignment.  */
1873   {"comm", obj_coff_comm, 0},
1874 #endif /* TE_PE */
1875   {"def", obj_coff_def, 0},
1876   {"dim", obj_coff_dim, 0},
1877   {"endef", obj_coff_endef, 0},
1878   {"ident", obj_coff_ident, 0},
1879   {"line", obj_coff_line, 0},
1880   {"ln", obj_coff_ln, 0},
1881   {"scl", obj_coff_scl, 0},
1882   {"sect", obj_coff_section, 0},
1883   {"sect.s", obj_coff_section, 0},
1884   {"section", obj_coff_section, 0},
1885   {"section.s", obj_coff_section, 0},
1886   /* FIXME: We ignore the MRI short attribute.  */
1887   {"size", obj_coff_size, 0},
1888   {"tag", obj_coff_tag, 0},
1889   {"type", obj_coff_type, 0},
1890   {"val", obj_coff_val, 0},
1891   {"version", s_ignore, 0},
1892   {"loc", obj_coff_loc, 0},
1893   {"optim", s_ignore, 0},       /* For sun386i cc (?) */
1894   {"weak", obj_coff_weak, 0},
1895 #if defined TC_TIC4X
1896   /* The tic4x uses sdef instead of def.  */
1897   {"sdef", obj_coff_def, 0},
1898 #endif
1899 #if defined(SEH_CMDS)
1900   SEH_CMDS
1901 #endif
1902   {NULL, NULL, 0}
1903 };
1904 \f
1905
1906 /* Support for a COFF emulation.  */
1907
1908 static void
1909 coff_pop_insert (void)
1910 {
1911   pop_insert (coff_pseudo_table);
1912 }
1913
1914 static int
1915 coff_separate_stab_sections (void)
1916 {
1917   return 1;
1918 }
1919
1920 const struct format_ops coff_format_ops =
1921 {
1922   bfd_target_coff_flavour,
1923   0,    /* dfl_leading_underscore */
1924   1,    /* emit_section_symbols */
1925   0,    /* begin */
1926   c_dot_file_symbol,
1927   coff_frob_symbol,
1928   0,    /* frob_file */
1929   0,    /* frob_file_before_adjust */
1930   0,    /* frob_file_before_fix */
1931   coff_frob_file_after_relocs,
1932   0,    /* s_get_size */
1933   0,    /* s_set_size */
1934   0,    /* s_get_align */
1935   0,    /* s_set_align */
1936   0,    /* s_get_other */
1937   0,    /* s_set_other */
1938   0,    /* s_get_desc */
1939   0,    /* s_set_desc */
1940   0,    /* s_get_type */
1941   0,    /* s_set_type */
1942   0,    /* copy_symbol_attributes */
1943   0,    /* generate_asm_lineno */
1944   0,    /* process_stab */
1945   coff_separate_stab_sections,
1946   obj_coff_init_stab_section,
1947   0,    /* sec_sym_ok_for_reloc */
1948   coff_pop_insert,
1949   0,    /* ecoff_set_ext */
1950   coff_obj_read_begin_hook,
1951   coff_obj_symbol_new_hook,
1952   coff_obj_symbol_clone_hook,
1953   coff_adjust_symtab
1954 };