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