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