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