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