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