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