OSDN Git Service

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