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