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