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