OSDN Git Service

* README-vms: Delete.
[pf3gnuchains/pf3gnuchains3x.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 #endif  /* TE_PE */
1059
1060 /* Handle .weak.  This is a GNU extension in formats other than PE. */
1061
1062 static void
1063 obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1064 {
1065   char *name;
1066   int c;
1067   symbolS *symbolP;
1068 #ifdef TE_PE
1069   symbolS *alternateP;
1070 #endif
1071
1072   do
1073     {
1074       name = input_line_pointer;
1075       c = get_symbol_end ();
1076       if (*name == 0)
1077         {
1078           as_warn (_("badly formed .weak directive ignored"));
1079           ignore_rest_of_line ();
1080           return;
1081         }
1082       c = 0;
1083       symbolP = symbol_find_or_make (name);
1084       *input_line_pointer = c;
1085       SKIP_WHITESPACE ();
1086       S_SET_WEAK (symbolP);
1087
1088 #ifdef TE_PE
1089       /* See _Microsoft Portable Executable and Common Object
1090          File Format Specification_, section 5.5.3.
1091          Create a symbol representing the alternate value.
1092          coff_frob_symbol will set the value of this symbol from
1093          the value of the weak symbol itself.  */
1094       S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1095       S_SET_NUMBER_AUXILIARY (symbolP, 1);
1096       SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
1097
1098       alternateP = symbol_find_or_make (weak_name2altname (name));
1099       S_SET_EXTERNAL (alternateP);
1100       S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1101
1102       SA_SET_SYM_TAGNDX (symbolP, alternateP);
1103 #endif
1104
1105       if (c == ',')
1106         {
1107           input_line_pointer++;
1108           SKIP_WHITESPACE ();
1109           if (*input_line_pointer == '\n')
1110             c = '\n';
1111         }
1112
1113     }
1114   while (c == ',');
1115
1116   demand_empty_rest_of_line ();
1117 }
1118
1119 void
1120 coff_obj_read_begin_hook (void)
1121 {
1122   /* These had better be the same.  Usually 18 bytes.  */
1123   know (sizeof (SYMENT) == sizeof (AUXENT));
1124   know (SYMESZ == AUXESZ);
1125   tag_init ();
1126 }
1127
1128 symbolS *coff_last_function;
1129 #ifndef OBJ_XCOFF
1130 static symbolS *coff_last_bf;
1131 #endif
1132
1133 void
1134 coff_frob_symbol (symbolS *symp, int *punt)
1135 {
1136   static symbolS *last_tagP;
1137   static stack *block_stack;
1138   static symbolS *set_end;
1139   symbolS *next_set_end = NULL;
1140
1141   if (symp == &abs_symbol)
1142     {
1143       *punt = 1;
1144       return;
1145     }
1146
1147   if (current_lineno_sym)
1148     coff_add_linesym (NULL);
1149
1150   if (!block_stack)
1151     block_stack = stack_init (512, sizeof (symbolS*));
1152
1153 #ifdef TE_PE
1154   if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1155       && ! S_IS_WEAK (symp)
1156       && weak_is_altname (S_GET_NAME (symp)))
1157     {
1158       /* This is a weak alternate symbol.  All processing of
1159          PECOFFweak symbols is done here, through the alternate.  */
1160       symbolS *weakp = symbol_find (weak_altname2name (S_GET_NAME (symp)));
1161
1162       assert (weakp);
1163       assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1164
1165       if (symbol_equated_p (weakp))
1166         {
1167           /* The weak symbol has an alternate specified; symp is unneeded.  */
1168           S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1169           SA_SET_SYM_TAGNDX (weakp,
1170             symbol_get_value_expression (weakp)->X_add_symbol);
1171
1172           S_CLEAR_EXTERNAL (symp);
1173           *punt = 1;
1174           return;
1175         }
1176       else
1177         {
1178           /* The weak symbol has been assigned an alternate value.
1179              Copy this value to symp, and set symp as weakp's alternate.  */
1180           if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1181             {
1182               S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1183               S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1184             }
1185
1186           if (S_IS_DEFINED (weakp))
1187             {
1188               /* This is a defined weak symbol.  Copy value information
1189                  from the weak symbol itself to the alternate symbol.  */
1190               symbol_set_value_expression (symp,
1191                                            symbol_get_value_expression (weakp));
1192               symbol_set_frag (symp, symbol_get_frag (weakp));
1193               S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1194             }
1195           else
1196             {
1197               /* This is an undefined weak symbol.
1198                  Define the alternate symbol to zero.  */
1199               S_SET_VALUE (symp, 0);
1200               S_SET_SEGMENT (symp, absolute_section);
1201             }
1202
1203           S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1204           S_SET_STORAGE_CLASS (symp, C_EXT);
1205
1206           S_SET_VALUE (weakp, 0);
1207           S_SET_SEGMENT (weakp, undefined_section);
1208         }
1209     }
1210 #else /* TE_PE */
1211   if (S_IS_WEAK (symp))
1212     S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1213 #endif /* TE_PE */
1214
1215   if (!S_IS_DEFINED (symp)
1216       && !S_IS_WEAK (symp)
1217       && S_GET_STORAGE_CLASS (symp) != C_STAT)
1218     S_SET_STORAGE_CLASS (symp, C_EXT);
1219
1220   if (!SF_GET_DEBUG (symp))
1221     {
1222       symbolS * real;
1223
1224       if (!SF_GET_LOCAL (symp)
1225           && !SF_GET_STATICS (symp)
1226           && S_GET_STORAGE_CLASS (symp) != C_LABEL
1227           && symbol_constant_p (symp)
1228           && (real = symbol_find (S_GET_NAME (symp)))
1229           && S_GET_STORAGE_CLASS (real) == C_NULL
1230           && real != symp)
1231         {
1232           c_symbol_merge (symp, real);
1233           *punt = 1;
1234           return;
1235         }
1236
1237       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1238         {
1239           assert (S_GET_VALUE (symp) == 0);
1240           S_SET_EXTERNAL (symp);
1241         }
1242       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1243         {
1244           if (S_GET_SEGMENT (symp) == text_section
1245               && symp != seg_info (text_section)->sym)
1246             S_SET_STORAGE_CLASS (symp, C_LABEL);
1247           else
1248             S_SET_STORAGE_CLASS (symp, C_STAT);
1249         }
1250
1251       if (SF_GET_PROCESS (symp))
1252         {
1253           if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1254             {
1255               if (streq (S_GET_NAME (symp), ".bb"))
1256                 stack_push (block_stack, (char *) &symp);
1257               else
1258                 {
1259                   symbolS *begin;
1260
1261                   begin = *(symbolS **) stack_pop (block_stack);
1262                   if (begin == 0)
1263                     as_warn (_("mismatched .eb"));
1264                   else
1265                     next_set_end = begin;
1266                 }
1267             }
1268
1269           if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
1270             {
1271               union internal_auxent *auxp;
1272
1273               coff_last_function = symp;
1274               if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1275                 S_SET_NUMBER_AUXILIARY (symp, 1);
1276               auxp = SYM_AUXENT (symp);
1277               memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
1278                       sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
1279             }
1280
1281           if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
1282             {
1283               if (coff_last_function == 0)
1284                 as_fatal (_("C_EFCN symbol for %s out of scope"),
1285                           S_GET_NAME (symp));
1286               SA_SET_SYM_FSIZE (coff_last_function,
1287                                 (long) (S_GET_VALUE (symp)
1288                                         - S_GET_VALUE (coff_last_function)));
1289               next_set_end = coff_last_function;
1290               coff_last_function = 0;
1291             }
1292         }
1293
1294       if (S_IS_EXTERNAL (symp))
1295         S_SET_STORAGE_CLASS (symp, C_EXT);
1296       else if (SF_GET_LOCAL (symp))
1297         *punt = 1;
1298
1299       if (SF_GET_FUNCTION (symp))
1300         symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1301     }
1302
1303   /* Double check weak symbols.  */
1304   if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1305     as_bad (_("Symbol `%s' can not be both weak and common"),
1306             S_GET_NAME (symp));
1307
1308   if (SF_GET_TAG (symp))
1309     last_tagP = symp;
1310   else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1311     next_set_end = last_tagP;
1312
1313 #ifdef OBJ_XCOFF
1314   /* This is pretty horrible, but we have to set *punt correctly in
1315      order to call SA_SET_SYM_ENDNDX correctly.  */
1316   if (! symbol_used_in_reloc_p (symp)
1317       && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1318           || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1319               && ! symbol_get_tc (symp)->output
1320               && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1321     *punt = 1;
1322 #endif
1323
1324   if (set_end != (symbolS *) NULL
1325       && ! *punt
1326       && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1327           || (S_IS_DEFINED (symp)
1328               && ! S_IS_COMMON (symp)
1329               && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1330     {
1331       SA_SET_SYM_ENDNDX (set_end, symp);
1332       set_end = NULL;
1333     }
1334
1335   if (next_set_end != NULL)
1336     {
1337       if (set_end != NULL)
1338         as_warn ("Warning: internal error: forgetting to set endndx of %s",
1339                  S_GET_NAME (set_end));
1340       set_end = next_set_end;
1341     }
1342
1343 #ifndef OBJ_XCOFF
1344   if (! *punt
1345       && S_GET_STORAGE_CLASS (symp) == C_FCN
1346       && streq (S_GET_NAME (symp), ".bf"))
1347     {
1348       if (coff_last_bf != NULL)
1349         SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1350       coff_last_bf = symp;
1351     }
1352 #endif
1353   if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1354     {
1355       int i;
1356       struct line_no *lptr;
1357       alent *l;
1358
1359       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1360       for (i = 0; lptr; lptr = lptr->next)
1361         i++;
1362       lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1363
1364       /* We need i entries for line numbers, plus 1 for the first
1365          entry which BFD will override, plus 1 for the last zero
1366          entry (a marker for BFD).  */
1367       l = xmalloc ((i + 2) * sizeof (* l));
1368       coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1369       l[i + 1].line_number = 0;
1370       l[i + 1].u.sym = NULL;
1371       for (; i > 0; i--)
1372         {
1373           if (lptr->frag)
1374             lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1375           l[i] = lptr->l;
1376           lptr = lptr->next;
1377         }
1378     }
1379 }
1380
1381 void
1382 coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1383                           asection *sec,
1384                           void * x ATTRIBUTE_UNUSED)
1385 {
1386   symbolS *secsym;
1387   segment_info_type *seginfo = seg_info (sec);
1388   int nlnno, nrelocs = 0;
1389
1390   /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1391      tc-ppc.c.  Do not get confused by it.  */
1392   if (seginfo == NULL)
1393     return;
1394
1395   if (streq (sec->name, ".text"))
1396     nlnno = coff_n_line_nos;
1397   else
1398     nlnno = 0;
1399   {
1400     /* @@ Hope that none of the fixups expand to more than one reloc
1401        entry...  */
1402     fixS *fixp = seginfo->fix_root;
1403     while (fixp)
1404       {
1405         if (! fixp->fx_done)
1406           nrelocs++;
1407         fixp = fixp->fx_next;
1408       }
1409   }
1410   if (bfd_get_section_size (sec) == 0
1411       && nrelocs == 0
1412       && nlnno == 0
1413       && sec != text_section
1414       && sec != data_section
1415       && sec != bss_section)
1416     return;
1417
1418   secsym = section_symbol (sec);
1419   /* This is an estimate; we'll plug in the real value using
1420      SET_SECTION_RELOCS later */
1421   SA_SET_SCN_NRELOC (secsym, nrelocs);
1422   SA_SET_SCN_NLINNO (secsym, nlnno);
1423 }
1424
1425 void
1426 coff_frob_file_after_relocs (void)
1427 {
1428   bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1429 }
1430
1431 /* Implement the .section pseudo op:
1432         .section name {, "flags"}
1433                   ^         ^
1434                   |         +--- optional flags: 'b' for bss
1435                   |                              'i' for info
1436                   +-- section name               'l' for lib
1437                                                  'n' for noload
1438                                                  'o' for over
1439                                                  'w' for data
1440                                                  'd' (apparently m88k for data)
1441                                                  'x' for text
1442                                                  'r' for read-only data
1443                                                  's' for shared data (PE)
1444    But if the argument is not a quoted string, treat it as a
1445    subsegment number.
1446
1447    Note the 'a' flag is silently ignored.  This allows the same
1448    .section directive to be parsed in both ELF and COFF formats.  */
1449
1450 void
1451 obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1452 {
1453   /* Strip out the section name.  */
1454   char *section_name;
1455   char c;
1456   char *name;
1457   unsigned int exp;
1458   flagword flags, oldflags;
1459   asection *sec;
1460
1461   if (flag_mri)
1462     {
1463       char type;
1464
1465       s_mri_sect (&type);
1466       return;
1467     }
1468
1469   section_name = input_line_pointer;
1470   c = get_symbol_end ();
1471
1472   name = xmalloc (input_line_pointer - section_name + 1);
1473   strcpy (name, section_name);
1474
1475   *input_line_pointer = c;
1476
1477   SKIP_WHITESPACE ();
1478
1479   exp = 0;
1480   flags = SEC_NO_FLAGS;
1481
1482   if (*input_line_pointer == ',')
1483     {
1484       ++input_line_pointer;
1485       SKIP_WHITESPACE ();
1486       if (*input_line_pointer != '"')
1487         exp = get_absolute_expression ();
1488       else
1489         {
1490           ++input_line_pointer;
1491           while (*input_line_pointer != '"'
1492                  && ! is_end_of_line[(unsigned char) *input_line_pointer])
1493             {
1494               switch (*input_line_pointer)
1495                 {
1496                 case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
1497                 case 'n': flags &=~ SEC_LOAD; flags |= SEC_NEVER_LOAD; break;
1498
1499                 case 's': flags |= SEC_COFF_SHARED; /* Fall through.  */
1500                 case 'd': flags |= SEC_DATA | SEC_LOAD; /* Fall through.  */
1501                 case 'w': flags &=~ SEC_READONLY; break;
1502
1503                 case 'a': break; /* For compatibility with ELF.  */
1504                 case 'x': flags |= SEC_CODE | SEC_LOAD; break;
1505                 case 'r': flags |= SEC_DATA | SEC_LOAD | SEC_READONLY; break;
1506
1507                 case 'i': /* STYP_INFO */
1508                 case 'l': /* STYP_LIB */
1509                 case 'o': /* STYP_OVER */
1510                   as_warn (_("unsupported section attribute '%c'"),
1511                            *input_line_pointer);
1512                   break;
1513
1514                 default:
1515                   as_warn (_("unknown section attribute '%c'"),
1516                            *input_line_pointer);
1517                   break;
1518                 }
1519               ++input_line_pointer;
1520             }
1521           if (*input_line_pointer == '"')
1522             ++input_line_pointer;
1523         }
1524     }
1525
1526   sec = subseg_new (name, (subsegT) exp);
1527
1528   oldflags = bfd_get_section_flags (stdoutput, sec);
1529   if (oldflags == SEC_NO_FLAGS)
1530     {
1531       /* Set section flags for a new section just created by subseg_new.
1532          Provide a default if no flags were parsed.  */
1533       if (flags == SEC_NO_FLAGS)
1534         flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1535
1536 #ifdef COFF_LONG_SECTION_NAMES
1537       /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1538          sections so adjust_reloc_syms in write.c will correctly handle
1539          relocs which refer to non-local symbols in these sections.  */
1540       if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1))
1541         flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1542 #endif
1543
1544       if (! bfd_set_section_flags (stdoutput, sec, flags))
1545         as_warn (_("error setting flags for \"%s\": %s"),
1546                  bfd_section_name (stdoutput, sec),
1547                  bfd_errmsg (bfd_get_error ()));
1548     }
1549   else if (flags != SEC_NO_FLAGS)
1550     {
1551       /* This section's attributes have already been set.  Warn if the
1552          attributes don't match.  */
1553       flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1554                              | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD);
1555       if ((flags ^ oldflags) & matchflags)
1556         as_warn (_("Ignoring changed section attributes for %s"), name);
1557     }
1558
1559   demand_empty_rest_of_line ();
1560 }
1561
1562 void
1563 coff_adjust_symtab (void)
1564 {
1565   if (symbol_rootP == NULL
1566       || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1567     c_dot_file_symbol ("fake", 0);
1568 }
1569
1570 void
1571 coff_frob_section (segT sec)
1572 {
1573   segT strsec;
1574   char *p;
1575   fragS *fragp;
1576   bfd_vma size, n_entries, mask;
1577   bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER;
1578
1579   /* The COFF back end in BFD requires that all section sizes be
1580      rounded up to multiples of the corresponding section alignments,
1581      supposedly because standard COFF has no other way of encoding alignment
1582      for sections.  If your COFF flavor has a different way of encoding
1583      section alignment, then skip this step, as TICOFF does.  */
1584   size = bfd_get_section_size (sec);
1585   mask = ((bfd_vma) 1 << align_power) - 1;
1586 #if !defined(TICOFF)
1587   if (size & mask)
1588     {
1589       bfd_vma new_size;
1590       fragS *last;
1591
1592       new_size = (size + mask) & ~mask;
1593       bfd_set_section_size (stdoutput, sec, new_size);
1594
1595       /* If the size had to be rounded up, add some padding in
1596          the last non-empty frag.  */
1597       fragp = seg_info (sec)->frchainP->frch_root;
1598       last = seg_info (sec)->frchainP->frch_last;
1599       while (fragp->fr_next != last)
1600         fragp = fragp->fr_next;
1601       last->fr_address = size;
1602       fragp->fr_offset += new_size - size;
1603     }
1604 #endif
1605
1606   /* If the section size is non-zero, the section symbol needs an aux
1607      entry associated with it, indicating the size.  We don't know
1608      all the values yet; coff_frob_symbol will fill them in later.  */
1609 #ifndef TICOFF
1610   if (size != 0
1611       || sec == text_section
1612       || sec == data_section
1613       || sec == bss_section)
1614 #endif
1615     {
1616       symbolS *secsym = section_symbol (sec);
1617
1618       S_SET_STORAGE_CLASS (secsym, C_STAT);
1619       S_SET_NUMBER_AUXILIARY (secsym, 1);
1620       SF_SET_STATICS (secsym);
1621       SA_SET_SCN_SCNLEN (secsym, size);
1622     }
1623
1624   /* FIXME: These should be in a "stabs.h" file, or maybe as.h.  */
1625 #ifndef STAB_SECTION_NAME
1626 #define STAB_SECTION_NAME ".stab"
1627 #endif
1628 #ifndef STAB_STRING_SECTION_NAME
1629 #define STAB_STRING_SECTION_NAME ".stabstr"
1630 #endif
1631   if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1632     return;
1633
1634   strsec = sec;
1635   sec = subseg_get (STAB_SECTION_NAME, 0);
1636   /* size is already rounded up, since other section will be listed first */
1637   size = bfd_get_section_size (strsec);
1638
1639   n_entries = bfd_get_section_size (sec) / 12 - 1;
1640
1641   /* Find first non-empty frag.  It should be large enough.  */
1642   fragp = seg_info (sec)->frchainP->frch_root;
1643   while (fragp && fragp->fr_fix == 0)
1644     fragp = fragp->fr_next;
1645   assert (fragp != 0 && fragp->fr_fix >= 12);
1646
1647   /* Store the values.  */
1648   p = fragp->fr_literal;
1649   bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
1650   bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
1651 }
1652
1653 void
1654 obj_coff_init_stab_section (segT seg)
1655 {
1656   char *file;
1657   char *p;
1658   char *stabstr_name;
1659   unsigned int stroff;
1660
1661   /* Make space for this first symbol.  */
1662   p = frag_more (12);
1663   /* Zero it out.  */
1664   memset (p, 0, 12);
1665   as_where (&file, (unsigned int *) NULL);
1666   stabstr_name = xmalloc (strlen (seg->name) + 4);
1667   strcpy (stabstr_name, seg->name);
1668   strcat (stabstr_name, "str");
1669   stroff = get_stab_string_offset (file, stabstr_name);
1670   know (stroff == 1);
1671   md_number_to_chars (p, stroff, 4);
1672 }
1673
1674 #ifdef DEBUG
1675 const char *
1676 s_get_name (symbolS *s)
1677 {
1678   return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
1679 }
1680
1681 void
1682 symbol_dump (void)
1683 {
1684   symbolS *symbolP;
1685
1686   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1687     printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1688             (unsigned long) symbolP,
1689             S_GET_NAME (symbolP),
1690             (long) S_GET_DATA_TYPE (symbolP),
1691             S_GET_STORAGE_CLASS (symbolP),
1692             (int) S_GET_SEGMENT (symbolP));
1693 }
1694
1695 #endif /* DEBUG */
1696
1697 const pseudo_typeS coff_pseudo_table[] =
1698 {
1699   {"ABORT", s_abort, 0},
1700   {"appline", obj_coff_ln, 1},
1701   /* We accept the .bss directive for backward compatibility with
1702      earlier versions of gas.  */
1703   {"bss", obj_coff_bss, 0},
1704   {"def", obj_coff_def, 0},
1705   {"dim", obj_coff_dim, 0},
1706   {"endef", obj_coff_endef, 0},
1707   {"ident", obj_coff_ident, 0},
1708   {"line", obj_coff_line, 0},
1709   {"ln", obj_coff_ln, 0},
1710   {"scl", obj_coff_scl, 0},
1711   {"sect", obj_coff_section, 0},
1712   {"sect.s", obj_coff_section, 0},
1713   {"section", obj_coff_section, 0},
1714   {"section.s", obj_coff_section, 0},
1715   /* FIXME: We ignore the MRI short attribute.  */
1716   {"size", obj_coff_size, 0},
1717   {"tag", obj_coff_tag, 0},
1718   {"type", obj_coff_type, 0},
1719   {"val", obj_coff_val, 0},
1720   {"version", s_ignore, 0},
1721   {"loc", obj_coff_loc, 0},
1722   {"optim", s_ignore, 0},       /* For sun386i cc (?) */
1723   {"weak", obj_coff_weak, 0},
1724 #if defined TC_TIC4X
1725   /* The tic4x uses sdef instead of def.  */
1726   {"sdef", obj_coff_def, 0},
1727 #endif
1728   {NULL, NULL, 0}
1729 };
1730 \f
1731
1732 /* Support for a COFF emulation.  */
1733
1734 static void
1735 coff_pop_insert (void)
1736 {
1737   pop_insert (coff_pseudo_table);
1738 }
1739
1740 static int
1741 coff_separate_stab_sections (void)
1742 {
1743   return 1;
1744 }
1745
1746 const struct format_ops coff_format_ops =
1747 {
1748   bfd_target_coff_flavour,
1749   0,    /* dfl_leading_underscore */
1750   1,    /* emit_section_symbols */
1751   0,    /* begin */
1752   c_dot_file_symbol,
1753   coff_frob_symbol,
1754   0,    /* frob_file */
1755   0,    /* frob_file_before_adjust */
1756   0,    /* frob_file_before_fix */
1757   coff_frob_file_after_relocs,
1758   0,    /* s_get_size */
1759   0,    /* s_set_size */
1760   0,    /* s_get_align */
1761   0,    /* s_set_align */
1762   0,    /* s_get_other */
1763   0,    /* s_set_other */
1764   0,    /* s_get_desc */
1765   0,    /* s_set_desc */
1766   0,    /* s_get_type */
1767   0,    /* s_set_type */
1768   0,    /* copy_symbol_attributes */
1769   0,    /* generate_asm_lineno */
1770   0,    /* process_stab */
1771   coff_separate_stab_sections,
1772   obj_coff_init_stab_section,
1773   0,    /* sec_sym_ok_for_reloc */
1774   coff_pop_insert,
1775   0,    /* ecoff_set_ext */
1776   coff_obj_read_begin_hook,
1777   coff_obj_symbol_new_hook
1778 };