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