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