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