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