Home | History | Annotate | Line # | Download | only in config
obj-elf.c revision 1.7
      1 /* ELF object file format
      2    Copyright (C) 1992-2020 Free Software Foundation, Inc.
      3 
      4    This file is part of GAS, the GNU Assembler.
      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
      8    published by the Free Software Foundation; either version 3,
      9    or (at your option) any later version.
     10 
     11    GAS is distributed in the hope that it will be useful, but
     12    WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     14    the 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-elf.h"
     22 #include "as.h"
     23 #include "safe-ctype.h"
     24 #include "subsegs.h"
     25 #include "obstack.h"
     26 #include "dwarf2dbg.h"
     27 
     28 #ifndef ECOFF_DEBUGGING
     29 #define ECOFF_DEBUGGING 0
     30 #else
     31 #define NEED_ECOFF_DEBUG
     32 #endif
     33 
     34 #ifdef NEED_ECOFF_DEBUG
     35 #include "ecoff.h"
     36 #include "bfd/ecoff-bfd.h"
     37 #endif
     38 
     39 #ifdef TC_ALPHA
     40 #include "elf/alpha.h"
     41 #endif
     42 
     43 #ifdef TC_MIPS
     44 #include "elf/mips.h"
     45 #endif
     46 
     47 #ifdef TC_PPC
     48 #include "elf/ppc.h"
     49 #endif
     50 
     51 #ifdef TC_I386
     52 #include "elf/x86-64.h"
     53 #endif
     54 
     55 #ifdef TC_MEP
     56 #include "elf/mep.h"
     57 #endif
     58 
     59 #ifdef TC_NIOS2
     60 #include "elf/nios2.h"
     61 #endif
     62 
     63 #ifdef TC_PRU
     64 #include "elf/pru.h"
     65 #endif
     66 
     67 static void obj_elf_line (int);
     68 static void obj_elf_size (int);
     69 static void obj_elf_type (int);
     70 static void obj_elf_ident (int);
     71 static void obj_elf_weak (int);
     72 static void obj_elf_local (int);
     73 static void obj_elf_visibility (int);
     74 static void obj_elf_symver (int);
     75 static void obj_elf_subsection (int);
     76 static void obj_elf_popsection (int);
     77 static void obj_elf_gnu_attribute (int);
     78 static void obj_elf_tls_common (int);
     79 static void obj_elf_lcomm (int);
     80 static void obj_elf_struct (int);
     81 
     82 static const pseudo_typeS elf_pseudo_table[] =
     83 {
     84   {"comm", obj_elf_common, 0},
     85   {"common", obj_elf_common, 1},
     86   {"ident", obj_elf_ident, 0},
     87   {"lcomm", obj_elf_lcomm, 0},
     88   {"local", obj_elf_local, 0},
     89   {"previous", obj_elf_previous, 0},
     90   {"section", obj_elf_section, 0},
     91   {"section.s", obj_elf_section, 0},
     92   {"sect", obj_elf_section, 0},
     93   {"sect.s", obj_elf_section, 0},
     94   {"pushsection", obj_elf_section, 1},
     95   {"popsection", obj_elf_popsection, 0},
     96   {"size", obj_elf_size, 0},
     97   {"type", obj_elf_type, 0},
     98   {"version", obj_elf_version, 0},
     99   {"weak", obj_elf_weak, 0},
    100 
    101   /* These define symbol visibility.  */
    102   {"internal", obj_elf_visibility, STV_INTERNAL},
    103   {"hidden", obj_elf_visibility, STV_HIDDEN},
    104   {"protected", obj_elf_visibility, STV_PROTECTED},
    105 
    106   /* These are used for stabs-in-elf configurations.  */
    107   {"line", obj_elf_line, 0},
    108 
    109   /* This is a GNU extension to handle symbol versions.  */
    110   {"symver", obj_elf_symver, 0},
    111 
    112   /* A GNU extension to change subsection only.  */
    113   {"subsection", obj_elf_subsection, 0},
    114 
    115   /* These are GNU extensions to aid in garbage collecting C++ vtables.  */
    116   {"vtable_inherit", obj_elf_vtable_inherit, 0},
    117   {"vtable_entry", obj_elf_vtable_entry, 0},
    118 
    119   /* A GNU extension for object attributes.  */
    120   {"gnu_attribute", obj_elf_gnu_attribute, 0},
    121 
    122   /* These are used for dwarf.  */
    123   {"2byte", cons, 2},
    124   {"4byte", cons, 4},
    125   {"8byte", cons, 8},
    126   /* These are used for dwarf2.  */
    127   { "file", dwarf2_directive_file, 0 },
    128   { "loc",  dwarf2_directive_loc,  0 },
    129   { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
    130 
    131   /* We need to trap the section changing calls to handle .previous.  */
    132   {"data", obj_elf_data, 0},
    133   {"offset", obj_elf_struct, 0},
    134   {"struct", obj_elf_struct, 0},
    135   {"text", obj_elf_text, 0},
    136 
    137   {"tls_common", obj_elf_tls_common, 0},
    138 
    139   /* End sentinel.  */
    140   {NULL, NULL, 0},
    141 };
    142 
    143 static const pseudo_typeS ecoff_debug_pseudo_table[] =
    144 {
    145 #ifdef NEED_ECOFF_DEBUG
    146   /* COFF style debugging information for ECOFF. .ln is not used; .loc
    147      is used instead.  */
    148   { "def",	ecoff_directive_def,	0 },
    149   { "dim",	ecoff_directive_dim,	0 },
    150   { "endef",	ecoff_directive_endef,	0 },
    151   { "file",	ecoff_directive_file,	0 },
    152   { "scl",	ecoff_directive_scl,	0 },
    153   { "tag",	ecoff_directive_tag,	0 },
    154   { "val",	ecoff_directive_val,	0 },
    155 
    156   /* COFF debugging requires pseudo-ops .size and .type, but ELF
    157      already has meanings for those.  We use .esize and .etype
    158      instead.  These are only generated by gcc anyhow.  */
    159   { "esize",	ecoff_directive_size,	0 },
    160   { "etype",	ecoff_directive_type,	0 },
    161 
    162   /* ECOFF specific debugging information.  */
    163   { "aent",	ecoff_directive_ent,	1 },
    164   { "begin",	ecoff_directive_begin,	0 },
    165   { "bend",	ecoff_directive_bend,	0 },
    166   { "end",	ecoff_directive_end,	0 },
    167   { "ent",	ecoff_directive_ent,	0 },
    168   { "fmask",	ecoff_directive_fmask,	0 },
    169   { "frame",	ecoff_directive_frame,	0 },
    170   { "loc",	ecoff_directive_loc,	0 },
    171   { "mask",	ecoff_directive_mask,	0 },
    172 
    173   /* Other ECOFF directives.  */
    174   { "extern",	ecoff_directive_extern,	0 },
    175 
    176   /* These are used on Irix.  I don't know how to implement them.  */
    177   { "alias",	s_ignore,		0 },
    178   { "bgnb",	s_ignore,		0 },
    179   { "endb",	s_ignore,		0 },
    180   { "lab",	s_ignore,		0 },
    181   { "noalias",	s_ignore,		0 },
    182   { "verstamp",	s_ignore,		0 },
    183   { "vreg",	s_ignore,		0 },
    184 #endif
    185 
    186   {NULL, NULL, 0}			/* end sentinel */
    187 };
    188 
    189 #undef NO_RELOC
    190 #include "aout/aout64.h"
    191 
    192 /* This is called when the assembler starts.  */
    193 
    194 asection *elf_com_section_ptr;
    195 
    196 void
    197 elf_begin (void)
    198 {
    199   asection *s;
    200 
    201   /* Add symbols for the known sections to the symbol table.  */
    202   s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
    203   symbol_table_insert (section_symbol (s));
    204   s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
    205   symbol_table_insert (section_symbol (s));
    206   s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
    207   symbol_table_insert (section_symbol (s));
    208   elf_com_section_ptr = bfd_com_section_ptr;
    209 }
    210 
    211 void
    212 elf_pop_insert (void)
    213 {
    214   pop_insert (elf_pseudo_table);
    215   if (ECOFF_DEBUGGING)
    216     pop_insert (ecoff_debug_pseudo_table);
    217 }
    218 
    219 static bfd_vma
    220 elf_s_get_size (symbolS *sym)
    221 {
    222   return S_GET_SIZE (sym);
    223 }
    224 
    225 static void
    226 elf_s_set_size (symbolS *sym, bfd_vma sz)
    227 {
    228   S_SET_SIZE (sym, sz);
    229 }
    230 
    231 static bfd_vma
    232 elf_s_get_align (symbolS *sym)
    233 {
    234   return S_GET_ALIGN (sym);
    235 }
    236 
    237 static void
    238 elf_s_set_align (symbolS *sym, bfd_vma align)
    239 {
    240   S_SET_ALIGN (sym, align);
    241 }
    242 
    243 int
    244 elf_s_get_other (symbolS *sym)
    245 {
    246   return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
    247 }
    248 
    249 static void
    250 elf_s_set_other (symbolS *sym, int other)
    251 {
    252   S_SET_OTHER (sym, other);
    253 }
    254 
    255 static int
    256 elf_sec_sym_ok_for_reloc (asection *sec)
    257 {
    258   return obj_sec_sym_ok_for_reloc (sec);
    259 }
    260 
    261 void
    262 elf_file_symbol (const char *s, int appfile)
    263 {
    264   asymbol *bsym;
    265 
    266   if (!appfile
    267       || symbol_rootP == NULL
    268       || (bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
    269       || (bsym->flags & BSF_FILE) == 0)
    270     {
    271       symbolS *sym;
    272       size_t name_length;
    273 
    274       sym = symbol_new (s, absolute_section, 0, NULL);
    275       symbol_set_frag (sym, &zero_address_frag);
    276 
    277       name_length = strlen (s);
    278       if (name_length > strlen (S_GET_NAME (sym)))
    279 	{
    280 	  obstack_grow (&notes, s, name_length + 1);
    281 	  S_SET_NAME (sym, (const char *) obstack_finish (&notes));
    282 	}
    283       else
    284 	strcpy ((char *) S_GET_NAME (sym), s);
    285 
    286       symbol_get_bfdsym (sym)->flags |= BSF_FILE;
    287 
    288       if (symbol_rootP != sym
    289 	  && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
    290 	      || (bsym->flags & BSF_FILE) == 0))
    291 	{
    292 	  symbol_remove (sym, &symbol_rootP, &symbol_lastP);
    293 	  symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
    294 	}
    295 
    296 #ifdef DEBUG
    297       verify_symbol_chain (symbol_rootP, symbol_lastP);
    298 #endif
    299     }
    300 
    301 #ifdef NEED_ECOFF_DEBUG
    302   ecoff_new_file (s, appfile);
    303 #endif
    304 }
    305 
    306 /* Called from read.c:s_comm after we've parsed .comm symbol, size.
    307    Parse a possible alignment value.  */
    308 
    309 symbolS *
    310 elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
    311 {
    312   addressT align = 0;
    313   int is_local = symbol_get_obj (symbolP)->local;
    314 
    315   if (*input_line_pointer == ',')
    316     {
    317       char *save = input_line_pointer;
    318 
    319       input_line_pointer++;
    320       SKIP_WHITESPACE ();
    321 
    322       if (*input_line_pointer == '"')
    323 	{
    324 	  /* For sparc.  Accept .common symbol, length, "bss"  */
    325 	  input_line_pointer++;
    326 	  /* Some use the dot, some don't.  */
    327 	  if (*input_line_pointer == '.')
    328 	    input_line_pointer++;
    329 	  /* Some say data, some say bss.  */
    330 	  if (strncmp (input_line_pointer, "bss\"", 4) == 0)
    331 	    input_line_pointer += 4;
    332 	  else if (strncmp (input_line_pointer, "data\"", 5) == 0)
    333 	    input_line_pointer += 5;
    334 	  else
    335 	    {
    336 	      char *p = input_line_pointer;
    337 	      char c;
    338 
    339 	      while (*--p != '"')
    340 		;
    341 	      while (!is_end_of_line[(unsigned char) *input_line_pointer])
    342 		if (*input_line_pointer++ == '"')
    343 		  break;
    344 	      c = *input_line_pointer;
    345 	      *input_line_pointer = '\0';
    346 	      as_bad (_("bad .common segment %s"), p);
    347 	      *input_line_pointer = c;
    348 	      ignore_rest_of_line ();
    349 	      return NULL;
    350 	    }
    351 	  /* ??? Don't ask me why these are always global.  */
    352 	  is_local = 0;
    353 	}
    354       else
    355 	{
    356 	  input_line_pointer = save;
    357 	  align = parse_align (is_local);
    358 	  if (align == (addressT) -1)
    359 	    return NULL;
    360 	}
    361     }
    362 
    363   if (is_local)
    364     {
    365       bss_alloc (symbolP, size, align);
    366       S_CLEAR_EXTERNAL (symbolP);
    367     }
    368   else
    369     {
    370       S_SET_VALUE (symbolP, size);
    371       S_SET_ALIGN (symbolP, align);
    372       S_SET_EXTERNAL (symbolP);
    373       S_SET_SEGMENT (symbolP, elf_com_section_ptr);
    374     }
    375 
    376   symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
    377 
    378   return symbolP;
    379 }
    380 
    381 void
    382 obj_elf_common (int is_common)
    383 {
    384   if (flag_mri && is_common)
    385     s_mri_common (0);
    386   else
    387     s_comm_internal (0, elf_common_parse);
    388 }
    389 
    390 static void
    391 obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
    392 {
    393   symbolS *symbolP = s_comm_internal (0, elf_common_parse);
    394 
    395   if (symbolP)
    396     symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
    397 }
    398 
    399 static void
    400 obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
    401 {
    402   symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
    403 
    404   if (symbolP)
    405     symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
    406 }
    407 
    408 static symbolS *
    409 get_sym_from_input_line_and_check (void)
    410 {
    411   char *name;
    412   char c;
    413   symbolS *sym;
    414 
    415   c = get_symbol_name (& name);
    416   sym = symbol_find_or_make (name);
    417   *input_line_pointer = c;
    418   SKIP_WHITESPACE_AFTER_NAME ();
    419 
    420   /* There is no symbol name if input_line_pointer has not moved.  */
    421   if (name == input_line_pointer)
    422     as_bad (_("Missing symbol name in directive"));
    423   return sym;
    424 }
    425 
    426 static void
    427 obj_elf_local (int ignore ATTRIBUTE_UNUSED)
    428 {
    429   int c;
    430   symbolS *symbolP;
    431 
    432   do
    433     {
    434       symbolP = get_sym_from_input_line_and_check ();
    435       c = *input_line_pointer;
    436       S_CLEAR_EXTERNAL (symbolP);
    437       symbol_get_obj (symbolP)->local = 1;
    438       if (c == ',')
    439 	{
    440 	  input_line_pointer++;
    441 	  SKIP_WHITESPACE ();
    442 	  if (*input_line_pointer == '\n')
    443 	    c = '\n';
    444 	}
    445     }
    446   while (c == ',');
    447   demand_empty_rest_of_line ();
    448 }
    449 
    450 static void
    451 obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
    452 {
    453   int c;
    454   symbolS *symbolP;
    455 
    456   do
    457     {
    458       symbolP = get_sym_from_input_line_and_check ();
    459       c = *input_line_pointer;
    460       S_SET_WEAK (symbolP);
    461       if (c == ',')
    462 	{
    463 	  input_line_pointer++;
    464 	  SKIP_WHITESPACE ();
    465 	  if (*input_line_pointer == '\n')
    466 	    c = '\n';
    467 	}
    468     }
    469   while (c == ',');
    470   demand_empty_rest_of_line ();
    471 }
    472 
    473 static void
    474 obj_elf_visibility (int visibility)
    475 {
    476   int c;
    477   symbolS *symbolP;
    478   asymbol *bfdsym;
    479   elf_symbol_type *elfsym;
    480 
    481   do
    482     {
    483       symbolP = get_sym_from_input_line_and_check ();
    484 
    485       bfdsym = symbol_get_bfdsym (symbolP);
    486       elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
    487 
    488       gas_assert (elfsym);
    489 
    490       elfsym->internal_elf_sym.st_other &= ~3;
    491       elfsym->internal_elf_sym.st_other |= visibility;
    492 
    493       c = *input_line_pointer;
    494       if (c == ',')
    495 	{
    496 	  input_line_pointer ++;
    497 
    498 	  SKIP_WHITESPACE ();
    499 
    500 	  if (*input_line_pointer == '\n')
    501 	    c = '\n';
    502 	}
    503     }
    504   while (c == ',');
    505 
    506   demand_empty_rest_of_line ();
    507 }
    508 
    509 static segT previous_section;
    510 static int previous_subsection;
    511 
    512 struct section_stack
    513 {
    514   struct section_stack *next;
    515   segT seg, prev_seg;
    516   int subseg, prev_subseg;
    517 };
    518 
    519 static struct section_stack *section_stack;
    520 
    521 /* Match both section group name and the sh_info field.  */
    522 struct section_match
    523 {
    524   const char *group_name;
    525   unsigned int info;
    526 };
    527 
    528 static bfd_boolean
    529 get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
    530 {
    531   struct section_match *match = (struct section_match *) inf;
    532   const char *gname = match->group_name;
    533   const char *group_name = elf_group_name (sec);
    534   unsigned int info = elf_section_data (sec)->this_hdr.sh_info;
    535 
    536   return (info == match->info
    537 	  && (group_name == gname
    538 	      || (group_name != NULL
    539 		  && gname != NULL
    540 		  && strcmp (group_name, gname) == 0)));
    541 }
    542 
    543 /* Handle the .section pseudo-op.  This code supports two different
    544    syntaxes.
    545 
    546    The first is found on Solaris, and looks like
    547        .section ".sec1",#alloc,#execinstr,#write
    548    Here the names after '#' are the SHF_* flags to turn on for the
    549    section.  I'm not sure how it determines the SHT_* type (BFD
    550    doesn't really give us control over the type, anyhow).
    551 
    552    The second format is found on UnixWare, and probably most SVR4
    553    machines, and looks like
    554        .section .sec1,"a",@progbits
    555    The quoted string may contain any combination of a, w, x, and
    556    represents the SHF_* flags to turn on for the section.  The string
    557    beginning with '@' can be progbits or nobits.  There should be
    558    other possibilities, but I don't know what they are.  In any case,
    559    BFD doesn't really let us set the section type.  */
    560 
    561 void
    562 obj_elf_change_section (const char *name,
    563 			unsigned int type,
    564 			unsigned int info,
    565 			bfd_vma attr,
    566 			int entsize,
    567 			const char *group_name,
    568 			int linkonce,
    569 			int push)
    570 {
    571   asection *old_sec;
    572   segT sec;
    573   flagword flags;
    574   const struct elf_backend_data *bed;
    575   const struct bfd_elf_special_section *ssect;
    576   struct section_match match;
    577 
    578 #ifdef md_flush_pending_output
    579   md_flush_pending_output ();
    580 #endif
    581 
    582   /* Switch to the section, creating it if necessary.  */
    583   if (push)
    584     {
    585       struct section_stack *elt;
    586       elt = XNEW (struct section_stack);
    587       elt->next = section_stack;
    588       elt->seg = now_seg;
    589       elt->prev_seg = previous_section;
    590       elt->subseg = now_subseg;
    591       elt->prev_subseg = previous_subsection;
    592       section_stack = elt;
    593     }
    594   previous_section = now_seg;
    595   previous_subsection = now_subseg;
    596 
    597   match.group_name = group_name;
    598   match.info = info;
    599   old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
    600 					(void *) &match);
    601   if (old_sec)
    602     {
    603       sec = old_sec;
    604       subseg_set (sec, 0);
    605     }
    606   else
    607     sec = subseg_force_new (name, 0);
    608 
    609   bed = get_elf_backend_data (stdoutput);
    610   ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
    611 
    612   if (ssect != NULL)
    613     {
    614       bfd_boolean override = FALSE;
    615 
    616       if (type == SHT_NULL)
    617 	type = ssect->type;
    618       else if (type != ssect->type)
    619 	{
    620 	  if (old_sec == NULL
    621 	      /* Some older versions of gcc will emit
    622 
    623 		 .section .init_array,"aw",@progbits
    624 
    625 		 for __attribute__ ((section (".init_array"))).
    626 		 "@progbits" is incorrect.  Also for x86-64 large bss
    627 		 sections, some older versions of gcc will emit
    628 
    629 		 .section .lbss,"aw",@progbits
    630 
    631 		 "@progbits" is incorrect.  */
    632 #ifdef TC_I386
    633 	      && (bed->s->arch_size != 64
    634 		  || !(ssect->attr & SHF_X86_64_LARGE))
    635 #endif
    636 	      && ssect->type != SHT_INIT_ARRAY
    637 	      && ssect->type != SHT_FINI_ARRAY
    638 	      && ssect->type != SHT_PREINIT_ARRAY)
    639 	    {
    640 	      /* We allow to specify any type for a .note section.  */
    641 	      if (ssect->type != SHT_NOTE
    642 		  /* Processor and application defined types are allowed too.  */
    643 		  && type < SHT_LOPROC)
    644 		as_warn (_("setting incorrect section type for %s"),
    645 			 name);
    646 	    }
    647 	  else
    648 	    {
    649 	      as_warn (_("ignoring incorrect section type for %s"),
    650 		       name);
    651 	      type = ssect->type;
    652 	    }
    653 	}
    654 
    655       if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC))
    656 			      & ~ssect->attr) != 0)
    657 	{
    658 	  /* As a GNU extension, we permit a .note section to be
    659 	     allocatable.  If the linker sees an allocatable .note
    660 	     section, it will create a PT_NOTE segment in the output
    661 	     file.  We also allow "x" for .note.GNU-stack.  */
    662 	  if (ssect->type == SHT_NOTE
    663 	      && (attr == SHF_ALLOC || attr == SHF_EXECINSTR))
    664 	    ;
    665 	  /* Allow different SHF_MERGE and SHF_STRINGS if we have
    666 	     something like .rodata.str.  */
    667 	  else if (ssect->suffix_length == -2
    668 		   && name[ssect->prefix_length] == '.'
    669 		   && (attr
    670 		       & ~ssect->attr
    671 		       & ~SHF_MERGE
    672 		       & ~SHF_STRINGS) == 0)
    673 	    ;
    674 	  /* .interp, .strtab and .symtab can have SHF_ALLOC.  */
    675 	  else if (attr == SHF_ALLOC
    676 		   && (strcmp (name, ".interp") == 0
    677 		       || strcmp (name, ".strtab") == 0
    678 		       || strcmp (name, ".symtab") == 0))
    679 	    override = TRUE;
    680 	  /* .note.GNU-stack can have SHF_EXECINSTR.  */
    681 	  else if (attr == SHF_EXECINSTR
    682 		   && strcmp (name, ".note.GNU-stack") == 0)
    683 	    override = TRUE;
    684 #ifdef TC_ALPHA
    685 	  /* A section on Alpha may have SHF_ALPHA_GPREL.  */
    686 	  else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
    687 	    override = TRUE;
    688 #endif
    689 #ifdef TC_RX
    690 	  else if (attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
    691 		   && (ssect->type == SHT_INIT_ARRAY
    692 		       || ssect->type == SHT_FINI_ARRAY
    693 		       || ssect->type == SHT_PREINIT_ARRAY))
    694 	    /* RX init/fini arrays can and should have the "awx" attributes set.  */
    695 	    ;
    696 #endif
    697 	  else
    698 	    {
    699 	      if (group_name == NULL)
    700 		as_warn (_("setting incorrect section attributes for %s"),
    701 			 name);
    702 	      override = TRUE;
    703 	    }
    704 	}
    705 
    706       if (!override && old_sec == NULL)
    707 	attr |= ssect->attr;
    708     }
    709 
    710   /* Convert ELF type and flags to BFD flags.  */
    711   flags = (SEC_RELOC
    712 	   | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
    713 	   | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
    714 	   | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
    715 	   | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
    716 	   | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
    717 	   | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
    718 	   | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
    719 	   | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
    720 #ifdef md_elf_section_flags
    721   flags = md_elf_section_flags (flags, attr, type);
    722 #endif
    723 
    724   if (linkonce)
    725     flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
    726 
    727   if (old_sec == NULL)
    728     {
    729       symbolS *secsym;
    730 
    731       if (type == SHT_NULL)
    732 	type = bfd_elf_get_default_section_type (flags);
    733       elf_section_type (sec) = type;
    734       elf_section_flags (sec) = attr;
    735       elf_section_data (sec)->this_hdr.sh_info = info;
    736 
    737       /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
    738       if (type == SHT_NOBITS)
    739 	seg_info (sec)->bss = 1;
    740 
    741       bfd_set_section_flags (sec, flags);
    742       if (flags & SEC_MERGE)
    743 	sec->entsize = entsize;
    744       elf_group_name (sec) = group_name;
    745 
    746       /* Add a symbol for this section to the symbol table.  */
    747       secsym = symbol_find (name);
    748       if (secsym != NULL)
    749 	symbol_set_bfdsym (secsym, sec->symbol);
    750       else
    751 	symbol_table_insert (section_symbol (sec));
    752     }
    753   else
    754     {
    755       if (type != SHT_NULL
    756 	  && (unsigned) type != elf_section_type (old_sec))
    757 	as_warn (_("ignoring changed section type for %s"), name);
    758 
    759       if (attr != 0)
    760 	{
    761 	  /* If section attributes are specified the second time we see a
    762 	     particular section, then check that they are the same as we
    763 	     saw the first time.  */
    764 	  if (((old_sec->flags ^ flags)
    765 	       & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
    766 		  | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
    767 		  | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
    768 		  | SEC_THREAD_LOCAL)))
    769 	    as_warn (_("ignoring changed section attributes for %s"), name);
    770 	  else
    771 	    /* FIXME: Maybe we should consider removing a previously set
    772 	       processor or application specific attribute as suspicious ?  */
    773 	    elf_section_flags (sec) = attr;
    774 
    775 	  if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
    776 	    as_warn (_("ignoring changed section entity size for %s"), name);
    777 	}
    778     }
    779 
    780 #ifdef md_elf_section_change_hook
    781   md_elf_section_change_hook ();
    782 #endif
    783 }
    784 
    785 static bfd_vma
    786 obj_elf_parse_section_letters (char *str, size_t len,
    787 			       bfd_boolean *is_clone, bfd_vma *gnu_attr)
    788 {
    789   bfd_vma attr = 0;
    790   *is_clone = FALSE;
    791 
    792   while (len > 0)
    793     {
    794       switch (*str)
    795 	{
    796 	case 'a':
    797 	  attr |= SHF_ALLOC;
    798 	  break;
    799 	case 'e':
    800 	  attr |= SHF_EXCLUDE;
    801 	  break;
    802 	case 'w':
    803 	  attr |= SHF_WRITE;
    804 	  break;
    805 	case 'x':
    806 	  attr |= SHF_EXECINSTR;
    807 	  break;
    808 	case 'M':
    809 	  attr |= SHF_MERGE;
    810 	  break;
    811 	case 'S':
    812 	  attr |= SHF_STRINGS;
    813 	  break;
    814 	case 'G':
    815 	  attr |= SHF_GROUP;
    816 	  break;
    817 	case 'T':
    818 	  attr |= SHF_TLS;
    819 	  break;
    820 	case 'd':
    821 	  *gnu_attr |= SHF_GNU_MBIND;
    822 	  break;
    823 	case '?':
    824 	  *is_clone = TRUE;
    825 	  break;
    826 	/* Compatibility.  */
    827 	case 'm':
    828 	  if (*(str - 1) == 'a')
    829 	    {
    830 	      attr |= SHF_MERGE;
    831 	      if (len > 1 && str[1] == 's')
    832 		{
    833 		  attr |= SHF_STRINGS;
    834 		  str++, len--;
    835 		}
    836 	      break;
    837 	    }
    838 	  /* Fall through.  */
    839 	default:
    840 	  {
    841 	    const char *bad_msg = _("unrecognized .section attribute:"
    842 				    " want a,e,w,x,M,S,G,T or number");
    843 #ifdef md_elf_section_letter
    844 	    bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
    845 	    if (md_attr != (bfd_vma) -1)
    846 	      attr |= md_attr;
    847 	    else
    848 #endif
    849 	      if (ISDIGIT (*str))
    850 		{
    851 		  char * end;
    852 
    853 		  attr |= strtoul (str, & end, 0);
    854 		  /* Update str and len, allowing for the fact that
    855 		     we will execute str++ and len-- below.  */
    856 		  end --;
    857 		  len -= (end - str);
    858 		  str = end;
    859 		}
    860 	      else
    861 		as_fatal ("%s", bad_msg);
    862 	  }
    863 	  break;
    864 	}
    865       str++, len--;
    866     }
    867 
    868   return attr;
    869 }
    870 
    871 static int
    872 obj_elf_section_type (char *str, size_t len, bfd_boolean warn)
    873 {
    874   if (len == 8 && strncmp (str, "progbits", 8) == 0)
    875     return SHT_PROGBITS;
    876   if (len == 6 && strncmp (str, "nobits", 6) == 0)
    877     return SHT_NOBITS;
    878   if (len == 4 && strncmp (str, "note", 4) == 0)
    879     return SHT_NOTE;
    880   if (len == 10 && strncmp (str, "init_array", 10) == 0)
    881     return SHT_INIT_ARRAY;
    882   if (len == 10 && strncmp (str, "fini_array", 10) == 0)
    883     return SHT_FINI_ARRAY;
    884   if (len == 13 && strncmp (str, "preinit_array", 13) == 0)
    885     return SHT_PREINIT_ARRAY;
    886 
    887 #ifdef md_elf_section_type
    888   {
    889     int md_type = md_elf_section_type (str, len);
    890     if (md_type >= 0)
    891       return md_type;
    892   }
    893 #endif
    894 
    895   if (ISDIGIT (*str))
    896     {
    897       char * end;
    898       int type = strtoul (str, & end, 0);
    899 
    900       if (warn && (size_t) (end - str) != len)
    901 	as_warn (_("extraneous characters at end of numeric section type"));
    902 
    903       return type;
    904     }
    905 
    906   if (warn)
    907     as_warn (_("unrecognized section type"));
    908   return 0;
    909 }
    910 
    911 static bfd_vma
    912 obj_elf_section_word (char *str, size_t len, int *type)
    913 {
    914   int ret;
    915 
    916   if (len == 5 && strncmp (str, "write", 5) == 0)
    917     return SHF_WRITE;
    918   if (len == 5 && strncmp (str, "alloc", 5) == 0)
    919     return SHF_ALLOC;
    920   if (len == 9 && strncmp (str, "execinstr", 9) == 0)
    921     return SHF_EXECINSTR;
    922   if (len == 7 && strncmp (str, "exclude", 7) == 0)
    923     return SHF_EXCLUDE;
    924   if (len == 3 && strncmp (str, "tls", 3) == 0)
    925     return SHF_TLS;
    926 
    927 #ifdef md_elf_section_word
    928   {
    929     bfd_vma md_attr = md_elf_section_word (str, len);
    930     if (md_attr > 0)
    931       return md_attr;
    932   }
    933 #endif
    934 
    935   ret = obj_elf_section_type (str, len, FALSE);
    936   if (ret != 0)
    937     *type = ret;
    938   else
    939     as_warn (_("unrecognized section attribute"));
    940 
    941   return 0;
    942 }
    943 
    944 /* Get name of section.  */
    945 const char *
    946 obj_elf_section_name (void)
    947 {
    948   char *name;
    949 
    950   SKIP_WHITESPACE ();
    951   if (*input_line_pointer == '"')
    952     {
    953       int dummy;
    954 
    955       name = demand_copy_C_string (&dummy);
    956       if (name == NULL)
    957 	{
    958 	  ignore_rest_of_line ();
    959 	  return NULL;
    960 	}
    961     }
    962   else
    963     {
    964       char *end = input_line_pointer;
    965 
    966       while (0 == strchr ("\n\t,; ", *end))
    967 	end++;
    968       if (end == input_line_pointer)
    969 	{
    970 	  as_bad (_("missing name"));
    971 	  ignore_rest_of_line ();
    972 	  return NULL;
    973 	}
    974 
    975       name = xmemdup0 (input_line_pointer, end - input_line_pointer);
    976 
    977       while (flag_sectname_subst)
    978         {
    979 	  char *subst = strchr (name, '%');
    980 	  if (subst && subst[1] == 'S')
    981 	    {
    982 	      int oldlen = strlen (name);
    983 	      int substlen = strlen (now_seg->name);
    984 	      int newlen = oldlen - 2 + substlen;
    985 	      char *newname = XNEWVEC (char, newlen + 1);
    986 	      int headlen = subst - name;
    987 	      memcpy (newname, name, headlen);
    988 	      strcpy (newname + headlen, now_seg->name);
    989 	      strcat (newname + headlen, subst + 2);
    990 	      xfree (name);
    991 	      name = newname;
    992 	    }
    993 	  else
    994 	    break;
    995 	}
    996 
    997 #ifdef tc_canonicalize_section_name
    998       name = tc_canonicalize_section_name (name);
    999 #endif
   1000       input_line_pointer = end;
   1001     }
   1002   SKIP_WHITESPACE ();
   1003   return name;
   1004 }
   1005 
   1006 void
   1007 obj_elf_section (int push)
   1008 {
   1009   const char *name, *group_name;
   1010   char *beg;
   1011   int type, dummy;
   1012   bfd_vma attr;
   1013   bfd_vma gnu_attr;
   1014   int entsize;
   1015   int linkonce;
   1016   subsegT new_subsection = -1;
   1017   unsigned int info = 0;
   1018 
   1019   if (flag_mri)
   1020     {
   1021       char mri_type;
   1022 
   1023 #ifdef md_flush_pending_output
   1024       md_flush_pending_output ();
   1025 #endif
   1026 
   1027       previous_section = now_seg;
   1028       previous_subsection = now_subseg;
   1029 
   1030       s_mri_sect (&mri_type);
   1031 
   1032 #ifdef md_elf_section_change_hook
   1033       md_elf_section_change_hook ();
   1034 #endif
   1035 
   1036       return;
   1037     }
   1038 
   1039   name = obj_elf_section_name ();
   1040   if (name == NULL)
   1041     return;
   1042 
   1043   symbolS * sym;
   1044   if ((sym = symbol_find (name)) != NULL
   1045       && ! symbol_section_p (sym)
   1046       && S_IS_DEFINED (sym)
   1047       && ! S_IS_VOLATILE (sym)
   1048       && ! S_CAN_BE_REDEFINED (sym))
   1049     {
   1050       as_bad (_("section name '%s' already defined as another symbol"), name);
   1051       ignore_rest_of_line ();
   1052       return;
   1053     }
   1054   type = SHT_NULL;
   1055   attr = 0;
   1056   gnu_attr = 0;
   1057   group_name = NULL;
   1058   entsize = 0;
   1059   linkonce = 0;
   1060 
   1061   if (*input_line_pointer == ',')
   1062     {
   1063       /* Skip the comma.  */
   1064       ++input_line_pointer;
   1065       SKIP_WHITESPACE ();
   1066 
   1067       if (push && ISDIGIT (*input_line_pointer))
   1068 	{
   1069 	  /* .pushsection has an optional subsection.  */
   1070 	  new_subsection = (subsegT) get_absolute_expression ();
   1071 
   1072 	  SKIP_WHITESPACE ();
   1073 
   1074 	  /* Stop if we don't see a comma.  */
   1075 	  if (*input_line_pointer != ',')
   1076 	    goto done;
   1077 
   1078 	  /* Skip the comma.  */
   1079 	  ++input_line_pointer;
   1080 	  SKIP_WHITESPACE ();
   1081 	}
   1082 
   1083       if (*input_line_pointer == '"')
   1084 	{
   1085 	  bfd_boolean is_clone;
   1086 
   1087 	  beg = demand_copy_C_string (&dummy);
   1088 	  if (beg == NULL)
   1089 	    {
   1090 	      ignore_rest_of_line ();
   1091 	      return;
   1092 	    }
   1093 	  attr |= obj_elf_parse_section_letters (beg, strlen (beg),
   1094 						 &is_clone, &gnu_attr);
   1095 
   1096 	  SKIP_WHITESPACE ();
   1097 	  if (*input_line_pointer == ',')
   1098 	    {
   1099 	      char c;
   1100 	      char *save = input_line_pointer;
   1101 
   1102 	      ++input_line_pointer;
   1103 	      SKIP_WHITESPACE ();
   1104 	      c = *input_line_pointer;
   1105 	      if (c == '"')
   1106 		{
   1107 		  beg = demand_copy_C_string (&dummy);
   1108 		  if (beg == NULL)
   1109 		    {
   1110 		      ignore_rest_of_line ();
   1111 		      return;
   1112 		    }
   1113 		  type = obj_elf_section_type (beg, strlen (beg), TRUE);
   1114 		}
   1115 	      else if (c == '@' || c == '%')
   1116 		{
   1117 		  ++input_line_pointer;
   1118 
   1119 		  if (ISDIGIT (* input_line_pointer))
   1120 		    type = strtoul (input_line_pointer, &input_line_pointer, 0);
   1121 		  else
   1122 		    {
   1123 		      c = get_symbol_name (& beg);
   1124 		      (void) restore_line_pointer (c);
   1125 		      type = obj_elf_section_type (beg,
   1126 						   input_line_pointer - beg,
   1127 						   TRUE);
   1128 		    }
   1129 		}
   1130 	      else
   1131 		input_line_pointer = save;
   1132 	    }
   1133 
   1134 	  SKIP_WHITESPACE ();
   1135 	  if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
   1136 	    {
   1137 	      ++input_line_pointer;
   1138 	      SKIP_WHITESPACE ();
   1139 	      entsize = get_absolute_expression ();
   1140 	      SKIP_WHITESPACE ();
   1141 	      if (entsize < 0)
   1142 		{
   1143 		  as_warn (_("invalid merge entity size"));
   1144 		  attr &= ~SHF_MERGE;
   1145 		  entsize = 0;
   1146 		}
   1147 	    }
   1148 	  else if ((attr & SHF_MERGE) != 0)
   1149 	    {
   1150 	      as_warn (_("entity size for SHF_MERGE not specified"));
   1151 	      attr &= ~SHF_MERGE;
   1152 	    }
   1153 
   1154 	  if ((attr & SHF_GROUP) != 0 && is_clone)
   1155 	    {
   1156 	      as_warn (_("? section flag ignored with G present"));
   1157 	      is_clone = FALSE;
   1158 	    }
   1159 	  if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
   1160 	    {
   1161 	      ++input_line_pointer;
   1162 	      group_name = obj_elf_section_name ();
   1163 	      if (group_name == NULL)
   1164 		attr &= ~SHF_GROUP;
   1165 	      else if (*input_line_pointer == ',')
   1166 		{
   1167 		  ++input_line_pointer;
   1168 		  SKIP_WHITESPACE ();
   1169 		  if (strncmp (input_line_pointer, "comdat", 6) == 0)
   1170 		    {
   1171 		      input_line_pointer += 6;
   1172 		      linkonce = 1;
   1173 		    }
   1174 		}
   1175 	      else if (strncmp (name, ".gnu.linkonce", 13) == 0)
   1176 		linkonce = 1;
   1177 	    }
   1178 	  else if ((attr & SHF_GROUP) != 0)
   1179 	    {
   1180 	      as_warn (_("group name for SHF_GROUP not specified"));
   1181 	      attr &= ~SHF_GROUP;
   1182 	    }
   1183 
   1184 	  if (is_clone)
   1185 	    {
   1186 	      const char *now_group = elf_group_name (now_seg);
   1187 	      if (now_group != NULL)
   1188 		{
   1189 		  group_name = xstrdup (now_group);
   1190 		  linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
   1191 		}
   1192 	    }
   1193 
   1194 	  if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
   1195 	    {
   1196 	      ++input_line_pointer;
   1197 	      SKIP_WHITESPACE ();
   1198 	      if (ISDIGIT (* input_line_pointer))
   1199 		{
   1200 		  char *t = input_line_pointer;
   1201 		  info = strtoul (input_line_pointer,
   1202 				  &input_line_pointer, 0);
   1203 		  if (info == (unsigned int) -1)
   1204 		    {
   1205 		      as_warn (_("unsupported mbind section info: %s"), t);
   1206 		      info = 0;
   1207 		    }
   1208 		}
   1209 	    }
   1210 	}
   1211       else
   1212 	{
   1213 	  do
   1214 	    {
   1215 	      char c;
   1216 
   1217 	      SKIP_WHITESPACE ();
   1218 	      if (*input_line_pointer != '#')
   1219 		{
   1220 		  as_bad (_("character following name is not '#'"));
   1221 		  ignore_rest_of_line ();
   1222 		  return;
   1223 		}
   1224 	      ++input_line_pointer;
   1225 	      c = get_symbol_name (& beg);
   1226 	      (void) restore_line_pointer (c);
   1227 
   1228 	      attr |= obj_elf_section_word (beg, input_line_pointer - beg,
   1229 					    &type);
   1230 
   1231 	      SKIP_WHITESPACE ();
   1232 	    }
   1233 	  while (*input_line_pointer++ == ',');
   1234 	  --input_line_pointer;
   1235 	}
   1236     }
   1237 
   1238 done:
   1239   demand_empty_rest_of_line ();
   1240 
   1241   obj_elf_change_section (name, type, info, attr, entsize, group_name,
   1242 			  linkonce, push);
   1243 
   1244   if ((gnu_attr & SHF_GNU_MBIND) != 0)
   1245     {
   1246       struct elf_backend_data *bed;
   1247 
   1248       if ((attr & SHF_ALLOC) == 0)
   1249 	as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
   1250 
   1251       bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
   1252       if (bed->elf_osabi == ELFOSABI_NONE)
   1253 	bed->elf_osabi = ELFOSABI_GNU;
   1254       else if (bed->elf_osabi != ELFOSABI_GNU
   1255 	       && bed->elf_osabi != ELFOSABI_FREEBSD)
   1256 	as_bad (_("GNU_MBIND section is supported only by GNU "
   1257 		  "and FreeBSD targets"));
   1258       elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
   1259     }
   1260   elf_section_flags (now_seg) |= gnu_attr;
   1261 
   1262   if (push && new_subsection != -1)
   1263     subseg_set (now_seg, new_subsection);
   1264 }
   1265 
   1266 /* Change to the .data section.  */
   1267 
   1268 void
   1269 obj_elf_data (int i)
   1270 {
   1271 #ifdef md_flush_pending_output
   1272   md_flush_pending_output ();
   1273 #endif
   1274 
   1275   previous_section = now_seg;
   1276   previous_subsection = now_subseg;
   1277   s_data (i);
   1278 
   1279 #ifdef md_elf_section_change_hook
   1280   md_elf_section_change_hook ();
   1281 #endif
   1282 }
   1283 
   1284 /* Change to the .text section.  */
   1285 
   1286 void
   1287 obj_elf_text (int i)
   1288 {
   1289 #ifdef md_flush_pending_output
   1290   md_flush_pending_output ();
   1291 #endif
   1292 
   1293   previous_section = now_seg;
   1294   previous_subsection = now_subseg;
   1295   s_text (i);
   1296 
   1297 #ifdef md_elf_section_change_hook
   1298   md_elf_section_change_hook ();
   1299 #endif
   1300 }
   1301 
   1302 /* Change to the *ABS* section.  */
   1303 
   1304 void
   1305 obj_elf_struct (int i)
   1306 {
   1307 #ifdef md_flush_pending_output
   1308   md_flush_pending_output ();
   1309 #endif
   1310 
   1311   previous_section = now_seg;
   1312   previous_subsection = now_subseg;
   1313   s_struct (i);
   1314 
   1315 #ifdef md_elf_section_change_hook
   1316   md_elf_section_change_hook ();
   1317 #endif
   1318 }
   1319 
   1320 static void
   1321 obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
   1322 {
   1323   int temp;
   1324 
   1325 #ifdef md_flush_pending_output
   1326   md_flush_pending_output ();
   1327 #endif
   1328 
   1329   previous_section = now_seg;
   1330   previous_subsection = now_subseg;
   1331 
   1332   temp = get_absolute_expression ();
   1333   subseg_set (now_seg, (subsegT) temp);
   1334   demand_empty_rest_of_line ();
   1335 
   1336 #ifdef md_elf_section_change_hook
   1337   md_elf_section_change_hook ();
   1338 #endif
   1339 }
   1340 
   1341 /* This can be called from the processor backends if they change
   1342    sections.  */
   1343 
   1344 void
   1345 obj_elf_section_change_hook (void)
   1346 {
   1347   previous_section = now_seg;
   1348   previous_subsection = now_subseg;
   1349 }
   1350 
   1351 void
   1352 obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
   1353 {
   1354   segT new_section;
   1355   int new_subsection;
   1356 
   1357   if (previous_section == 0)
   1358     {
   1359       as_warn (_(".previous without corresponding .section; ignored"));
   1360       return;
   1361     }
   1362 
   1363 #ifdef md_flush_pending_output
   1364   md_flush_pending_output ();
   1365 #endif
   1366 
   1367   new_section = previous_section;
   1368   new_subsection = previous_subsection;
   1369   previous_section = now_seg;
   1370   previous_subsection = now_subseg;
   1371   subseg_set (new_section, new_subsection);
   1372 
   1373 #ifdef md_elf_section_change_hook
   1374   md_elf_section_change_hook ();
   1375 #endif
   1376 }
   1377 
   1378 static void
   1379 obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
   1380 {
   1381   struct section_stack *top = section_stack;
   1382 
   1383   if (top == NULL)
   1384     {
   1385       as_warn (_(".popsection without corresponding .pushsection; ignored"));
   1386       return;
   1387     }
   1388 
   1389 #ifdef md_flush_pending_output
   1390   md_flush_pending_output ();
   1391 #endif
   1392 
   1393   section_stack = top->next;
   1394   previous_section = top->prev_seg;
   1395   previous_subsection = top->prev_subseg;
   1396   subseg_set (top->seg, top->subseg);
   1397   free (top);
   1398 
   1399 #ifdef md_elf_section_change_hook
   1400   md_elf_section_change_hook ();
   1401 #endif
   1402 }
   1403 
   1404 static void
   1405 obj_elf_line (int ignore ATTRIBUTE_UNUSED)
   1406 {
   1407   /* Assume delimiter is part of expression.  BSD4.2 as fails with
   1408      delightful bug, so we are not being incompatible here.  */
   1409   new_logical_line (NULL, get_absolute_expression ());
   1410   demand_empty_rest_of_line ();
   1411 }
   1412 
   1413 /* This handles the .symver pseudo-op, which is used to specify a
   1414    symbol version.  The syntax is ``.symver NAME,SYMVERNAME''.
   1415    SYMVERNAME may contain ELF_VER_CHR ('@') characters.  This
   1416    pseudo-op causes the assembler to emit a symbol named SYMVERNAME
   1417    with the same value as the symbol NAME.  */
   1418 
   1419 static void
   1420 obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
   1421 {
   1422   char *name;
   1423   char c;
   1424   char old_lexat;
   1425   symbolS *sym;
   1426 
   1427   sym = get_sym_from_input_line_and_check ();
   1428 
   1429   if (*input_line_pointer != ',')
   1430     {
   1431       as_bad (_("expected comma after name in .symver"));
   1432       ignore_rest_of_line ();
   1433       return;
   1434     }
   1435 
   1436   ++input_line_pointer;
   1437   SKIP_WHITESPACE ();
   1438 
   1439   /* Temporarily include '@' in symbol names.  */
   1440   old_lexat = lex_type[(unsigned char) '@'];
   1441   lex_type[(unsigned char) '@'] |= LEX_NAME;
   1442   c = get_symbol_name (& name);
   1443   lex_type[(unsigned char) '@'] = old_lexat;
   1444 
   1445   if (S_IS_COMMON (sym))
   1446     {
   1447       as_bad (_("`%s' can't be versioned to common symbol '%s'"),
   1448 	      name, S_GET_NAME (sym));
   1449       ignore_rest_of_line ();
   1450       return;
   1451     }
   1452 
   1453   if (symbol_get_obj (sym)->versioned_name == NULL)
   1454     {
   1455       symbol_get_obj (sym)->versioned_name = xstrdup (name);
   1456 
   1457       (void) restore_line_pointer (c);
   1458 
   1459       if (strchr (symbol_get_obj (sym)->versioned_name,
   1460 		  ELF_VER_CHR) == NULL)
   1461 	{
   1462 	  as_bad (_("missing version name in `%s' for symbol `%s'"),
   1463 		  symbol_get_obj (sym)->versioned_name,
   1464 		  S_GET_NAME (sym));
   1465 	  ignore_rest_of_line ();
   1466 	  return;
   1467 	}
   1468     }
   1469   else
   1470     {
   1471       if (strcmp (symbol_get_obj (sym)->versioned_name, name))
   1472 	{
   1473 	  as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"),
   1474 		  name, symbol_get_obj (sym)->versioned_name,
   1475 		  S_GET_NAME (sym));
   1476 	  ignore_rest_of_line ();
   1477 	  return;
   1478 	}
   1479 
   1480       (void) restore_line_pointer (c);
   1481     }
   1482 
   1483   demand_empty_rest_of_line ();
   1484 }
   1485 
   1486 /* This handles the .vtable_inherit pseudo-op, which is used to indicate
   1487    to the linker the hierarchy in which a particular table resides.  The
   1488    syntax is ".vtable_inherit CHILDNAME, PARENTNAME".  */
   1489 
   1490 struct fix *
   1491 obj_elf_get_vtable_inherit (void)
   1492 {
   1493   char *cname, *pname;
   1494   symbolS *csym, *psym;
   1495   char c, bad = 0;
   1496 
   1497   if (*input_line_pointer == '#')
   1498     ++input_line_pointer;
   1499 
   1500   c = get_symbol_name (& cname);
   1501   csym = symbol_find (cname);
   1502 
   1503   /* GCFIXME: should check that we don't have two .vtable_inherits for
   1504      the same child symbol.  Also, we can currently only do this if the
   1505      child symbol is already exists and is placed in a fragment.  */
   1506 
   1507   if (csym == NULL || symbol_get_frag (csym) == NULL)
   1508     {
   1509       as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
   1510 	      cname);
   1511       bad = 1;
   1512     }
   1513 
   1514   *input_line_pointer = c;
   1515 
   1516   SKIP_WHITESPACE_AFTER_NAME ();
   1517   if (*input_line_pointer != ',')
   1518     {
   1519       as_bad (_("expected comma after name in .vtable_inherit"));
   1520       ignore_rest_of_line ();
   1521       return NULL;
   1522     }
   1523 
   1524   ++input_line_pointer;
   1525   SKIP_WHITESPACE ();
   1526 
   1527   if (*input_line_pointer == '#')
   1528     ++input_line_pointer;
   1529 
   1530   if (input_line_pointer[0] == '0'
   1531       && (input_line_pointer[1] == '\0'
   1532 	  || ISSPACE (input_line_pointer[1])))
   1533     {
   1534       psym = section_symbol (absolute_section);
   1535       ++input_line_pointer;
   1536     }
   1537   else
   1538     {
   1539       c = get_symbol_name (& pname);
   1540       psym = symbol_find_or_make (pname);
   1541       restore_line_pointer (c);
   1542     }
   1543 
   1544   demand_empty_rest_of_line ();
   1545 
   1546   if (bad)
   1547     return NULL;
   1548 
   1549   gas_assert (symbol_get_value_expression (csym)->X_op == O_constant);
   1550   return fix_new (symbol_get_frag (csym),
   1551 		  symbol_get_value_expression (csym)->X_add_number,
   1552 		  0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
   1553 }
   1554 
   1555 /* This is a version of obj_elf_get_vtable_inherit() that is
   1556    suitable for use in struct _pseudo_type tables.  */
   1557 
   1558 void
   1559 obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
   1560 {
   1561   (void) obj_elf_get_vtable_inherit ();
   1562 }
   1563 
   1564 /* This handles the .vtable_entry pseudo-op, which is used to indicate
   1565    to the linker that a vtable slot was used.  The syntax is
   1566    ".vtable_entry tablename, offset".  */
   1567 
   1568 struct fix *
   1569 obj_elf_get_vtable_entry (void)
   1570 {
   1571   symbolS *sym;
   1572   offsetT offset;
   1573 
   1574   if (*input_line_pointer == '#')
   1575     ++input_line_pointer;
   1576 
   1577   sym = get_sym_from_input_line_and_check ();
   1578   if (*input_line_pointer != ',')
   1579     {
   1580       as_bad (_("expected comma after name in .vtable_entry"));
   1581       ignore_rest_of_line ();
   1582       return NULL;
   1583     }
   1584 
   1585   ++input_line_pointer;
   1586   if (*input_line_pointer == '#')
   1587     ++input_line_pointer;
   1588 
   1589   offset = get_absolute_expression ();
   1590 
   1591   demand_empty_rest_of_line ();
   1592 
   1593   return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
   1594 		  BFD_RELOC_VTABLE_ENTRY);
   1595 }
   1596 
   1597 /* This is a version of obj_elf_get_vtable_entry() that is
   1598    suitable for use in struct _pseudo_type tables.  */
   1599 
   1600 void
   1601 obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
   1602 {
   1603   (void) obj_elf_get_vtable_entry ();
   1604 }
   1605 
   1606 #define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
   1607 
   1608 static inline int
   1609 skip_past_char (char ** str, char c)
   1610 {
   1611   if (**str == c)
   1612     {
   1613       (*str)++;
   1614       return 0;
   1615     }
   1616   else
   1617     return -1;
   1618 }
   1619 #define skip_past_comma(str) skip_past_char (str, ',')
   1620 
   1621 /* A list of attributes that have been explicitly set by the assembly code.
   1622    VENDOR is the vendor id, BASE is the tag shifted right by the number
   1623    of bits in MASK, and bit N of MASK is set if tag BASE+N has been set.  */
   1624 struct recorded_attribute_info {
   1625   struct recorded_attribute_info *next;
   1626   int vendor;
   1627   unsigned int base;
   1628   unsigned long mask;
   1629 };
   1630 static struct recorded_attribute_info *recorded_attributes;
   1631 
   1632 /* Record that we have seen an explicit specification of attribute TAG
   1633    for vendor VENDOR.  */
   1634 
   1635 static void
   1636 record_attribute (int vendor, unsigned int tag)
   1637 {
   1638   unsigned int base;
   1639   unsigned long mask;
   1640   struct recorded_attribute_info *rai;
   1641 
   1642   base = tag / (8 * sizeof (rai->mask));
   1643   mask = 1UL << (tag % (8 * sizeof (rai->mask)));
   1644   for (rai = recorded_attributes; rai; rai = rai->next)
   1645     if (rai->vendor == vendor && rai->base == base)
   1646       {
   1647 	rai->mask |= mask;
   1648 	return;
   1649       }
   1650 
   1651   rai = XNEW (struct recorded_attribute_info);
   1652   rai->next = recorded_attributes;
   1653   rai->vendor = vendor;
   1654   rai->base = base;
   1655   rai->mask = mask;
   1656   recorded_attributes = rai;
   1657 }
   1658 
   1659 /* Return true if we have seen an explicit specification of attribute TAG
   1660    for vendor VENDOR.  */
   1661 
   1662 bfd_boolean
   1663 obj_elf_seen_attribute (int vendor, unsigned int tag)
   1664 {
   1665   unsigned int base;
   1666   unsigned long mask;
   1667   struct recorded_attribute_info *rai;
   1668 
   1669   base = tag / (8 * sizeof (rai->mask));
   1670   mask = 1UL << (tag % (8 * sizeof (rai->mask)));
   1671   for (rai = recorded_attributes; rai; rai = rai->next)
   1672     if (rai->vendor == vendor && rai->base == base)
   1673       return (rai->mask & mask) != 0;
   1674   return FALSE;
   1675 }
   1676 
   1677 /* Parse an attribute directive for VENDOR.
   1678    Returns the attribute number read, or zero on error.  */
   1679 
   1680 int
   1681 obj_elf_vendor_attribute (int vendor)
   1682 {
   1683   expressionS exp;
   1684   int type;
   1685   int tag;
   1686   unsigned int i = 0;
   1687   char *s = NULL;
   1688 
   1689   /* Read the first number or name.  */
   1690   skip_whitespace (input_line_pointer);
   1691   s = input_line_pointer;
   1692   if (ISDIGIT (*input_line_pointer))
   1693     {
   1694       expression (& exp);
   1695       if (exp.X_op != O_constant)
   1696 	goto bad;
   1697       tag = exp.X_add_number;
   1698     }
   1699   else
   1700     {
   1701       char *name;
   1702 
   1703       /* A name may contain '_', but no other punctuation.  */
   1704       for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
   1705 	   ++input_line_pointer)
   1706 	i++;
   1707       if (i == 0)
   1708 	goto bad;
   1709 
   1710       name = xstrndup (s, i);
   1711 
   1712 #ifndef CONVERT_SYMBOLIC_ATTRIBUTE
   1713 #define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
   1714 #endif
   1715 
   1716       tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
   1717       if (tag == -1)
   1718 	{
   1719 	  as_bad (_("Attribute name not recognised: %s"), name);
   1720 	  ignore_rest_of_line ();
   1721 	  free (name);
   1722 	  return 0;
   1723 	}
   1724       free (name);
   1725     }
   1726 
   1727   type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
   1728 
   1729   if (skip_past_comma (&input_line_pointer) == -1)
   1730     goto bad;
   1731   if (type & 1)
   1732     {
   1733       expression (& exp);
   1734       if (exp.X_op != O_constant)
   1735 	{
   1736 	  as_bad (_("expected numeric constant"));
   1737 	  ignore_rest_of_line ();
   1738 	  return 0;
   1739 	}
   1740       i = exp.X_add_number;
   1741     }
   1742   if ((type & 3) == 3
   1743       && skip_past_comma (&input_line_pointer) == -1)
   1744     {
   1745       as_bad (_("expected comma"));
   1746       ignore_rest_of_line ();
   1747       return 0;
   1748     }
   1749   if (type & 2)
   1750     {
   1751       int len;
   1752 
   1753       skip_whitespace (input_line_pointer);
   1754       if (*input_line_pointer != '"')
   1755 	goto bad_string;
   1756       s = demand_copy_C_string (&len);
   1757     }
   1758 
   1759   record_attribute (vendor, tag);
   1760   switch (type & 3)
   1761     {
   1762     case 3:
   1763       bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
   1764       break;
   1765     case 2:
   1766       bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
   1767       break;
   1768     case 1:
   1769       bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
   1770       break;
   1771     default:
   1772       abort ();
   1773     }
   1774 
   1775   demand_empty_rest_of_line ();
   1776   return tag;
   1777 bad_string:
   1778   as_bad (_("bad string constant"));
   1779   ignore_rest_of_line ();
   1780   return 0;
   1781 bad:
   1782   as_bad (_("expected <tag> , <value>"));
   1783   ignore_rest_of_line ();
   1784   return 0;
   1785 }
   1786 
   1787 /* Parse a .gnu_attribute directive.  */
   1788 
   1789 static void
   1790 obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
   1791 {
   1792   obj_elf_vendor_attribute (OBJ_ATTR_GNU);
   1793 }
   1794 
   1795 void
   1796 elf_obj_read_begin_hook (void)
   1797 {
   1798 #ifdef NEED_ECOFF_DEBUG
   1799   if (ECOFF_DEBUGGING)
   1800     ecoff_read_begin_hook ();
   1801 #endif
   1802 }
   1803 
   1804 void
   1805 elf_obj_symbol_new_hook (symbolS *symbolP)
   1806 {
   1807   struct elf_obj_sy *sy_obj;
   1808 
   1809   sy_obj = symbol_get_obj (symbolP);
   1810   sy_obj->size = NULL;
   1811   sy_obj->versioned_name = NULL;
   1812 
   1813 #ifdef NEED_ECOFF_DEBUG
   1814   if (ECOFF_DEBUGGING)
   1815     ecoff_symbol_new_hook (symbolP);
   1816 #endif
   1817 }
   1818 
   1819 /* When setting one symbol equal to another, by default we probably
   1820    want them to have the same "size", whatever it means in the current
   1821    context.  */
   1822 
   1823 void
   1824 elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
   1825 {
   1826   struct elf_obj_sy *srcelf = symbol_get_obj (src);
   1827   struct elf_obj_sy *destelf = symbol_get_obj (dest);
   1828   if (srcelf->size)
   1829     {
   1830       if (destelf->size == NULL)
   1831 	destelf->size = XNEW (expressionS);
   1832       *destelf->size = *srcelf->size;
   1833     }
   1834   else
   1835     {
   1836       if (destelf->size != NULL)
   1837 	free (destelf->size);
   1838       destelf->size = NULL;
   1839     }
   1840   S_SET_SIZE (dest, S_GET_SIZE (src));
   1841   /* Don't copy visibility.  */
   1842   S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
   1843 		      | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
   1844 }
   1845 
   1846 void
   1847 obj_elf_version (int ignore ATTRIBUTE_UNUSED)
   1848 {
   1849   char *name;
   1850   unsigned int c;
   1851   char *p;
   1852   asection *seg = now_seg;
   1853   subsegT subseg = now_subseg;
   1854   Elf_Internal_Note i_note;
   1855   Elf_External_Note e_note;
   1856   asection *note_secp = NULL;
   1857 
   1858   SKIP_WHITESPACE ();
   1859   if (*input_line_pointer == '\"')
   1860     {
   1861       unsigned int len;
   1862 
   1863       ++input_line_pointer;	/* -> 1st char of string.  */
   1864       name = input_line_pointer;
   1865 
   1866       while (is_a_char (c = next_char_of_string ()))
   1867 	;
   1868       c = *input_line_pointer;
   1869       *input_line_pointer = '\0';
   1870       *(input_line_pointer - 1) = '\0';
   1871       *input_line_pointer = c;
   1872 
   1873       /* Create the .note section.  */
   1874       note_secp = subseg_new (".note", 0);
   1875       bfd_set_section_flags (note_secp, SEC_HAS_CONTENTS | SEC_READONLY);
   1876       record_alignment (note_secp, 2);
   1877 
   1878       /* Process the version string.  */
   1879       len = strlen (name) + 1;
   1880 
   1881       /* PR 3456: Although the name field is padded out to an 4-byte
   1882 	 boundary, the namesz field should not be adjusted.  */
   1883       i_note.namesz = len;
   1884       i_note.descsz = 0;	/* No description.  */
   1885       i_note.type = NT_VERSION;
   1886       p = frag_more (sizeof (e_note.namesz));
   1887       md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
   1888       p = frag_more (sizeof (e_note.descsz));
   1889       md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
   1890       p = frag_more (sizeof (e_note.type));
   1891       md_number_to_chars (p, i_note.type, sizeof (e_note.type));
   1892       p = frag_more (len);
   1893       memcpy (p, name, len);
   1894 
   1895       frag_align (2, 0, 0);
   1896 
   1897       subseg_set (seg, subseg);
   1898     }
   1899   else
   1900     as_bad (_("expected quoted string"));
   1901 
   1902   demand_empty_rest_of_line ();
   1903 }
   1904 
   1905 static void
   1906 obj_elf_size (int ignore ATTRIBUTE_UNUSED)
   1907 {
   1908   char *name;
   1909   char c = get_symbol_name (&name);
   1910   char *p;
   1911   expressionS exp;
   1912   symbolS *sym;
   1913 
   1914   p = input_line_pointer;
   1915   *p = c;
   1916   SKIP_WHITESPACE_AFTER_NAME ();
   1917   if (*input_line_pointer != ',')
   1918     {
   1919       *p = 0;
   1920       as_bad (_("expected comma after name `%s' in .size directive"), name);
   1921       *p = c;
   1922       ignore_rest_of_line ();
   1923       return;
   1924     }
   1925   input_line_pointer++;
   1926   expression (&exp);
   1927   if (exp.X_op == O_absent)
   1928     {
   1929       as_bad (_("missing expression in .size directive"));
   1930       exp.X_op = O_constant;
   1931       exp.X_add_number = 0;
   1932     }
   1933   *p = 0;
   1934   sym = symbol_find_or_make (name);
   1935   *p = c;
   1936   if (exp.X_op == O_constant)
   1937     {
   1938       S_SET_SIZE (sym, exp.X_add_number);
   1939       if (symbol_get_obj (sym)->size)
   1940 	{
   1941 	  xfree (symbol_get_obj (sym)->size);
   1942 	  symbol_get_obj (sym)->size = NULL;
   1943 	}
   1944     }
   1945   else
   1946     {
   1947       symbol_get_obj (sym)->size = XNEW (expressionS);
   1948       *symbol_get_obj (sym)->size = exp;
   1949     }
   1950   demand_empty_rest_of_line ();
   1951 }
   1952 
   1953 /* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
   1954    There are six syntaxes:
   1955 
   1956    The first (used on Solaris) is
   1957        .type SYM,#function
   1958    The second (used on UnixWare) is
   1959        .type SYM,@function
   1960    The third (reportedly to be used on Irix 6.0) is
   1961        .type SYM STT_FUNC
   1962    The fourth (used on NetBSD/Arm and Linux/ARM) is
   1963        .type SYM,%function
   1964    The fifth (used on SVR4/860) is
   1965        .type SYM,"function"
   1966    The sixth (emitted by recent SunPRO under Solaris) is
   1967        .type SYM,[0-9]
   1968    where the integer is the STT_* value.
   1969    */
   1970 
   1971 static char *
   1972 obj_elf_type_name (char *cp)
   1973 {
   1974   char *p;
   1975 
   1976   p = input_line_pointer;
   1977   if (*input_line_pointer >= '0'
   1978       && *input_line_pointer <= '9')
   1979     {
   1980       while (*input_line_pointer >= '0'
   1981 	     && *input_line_pointer <= '9')
   1982 	++input_line_pointer;
   1983       *cp = *input_line_pointer;
   1984       *input_line_pointer = '\0';
   1985     }
   1986   else
   1987     *cp = get_symbol_name (&p);
   1988 
   1989   return p;
   1990 }
   1991 
   1992 static void
   1993 obj_elf_type (int ignore ATTRIBUTE_UNUSED)
   1994 {
   1995   char c;
   1996   int type;
   1997   const char *type_name;
   1998   symbolS *sym;
   1999   elf_symbol_type *elfsym;
   2000 
   2001   sym = get_sym_from_input_line_and_check ();
   2002   c = *input_line_pointer;
   2003   elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
   2004 
   2005   if (*input_line_pointer == ',')
   2006     ++input_line_pointer;
   2007 
   2008   SKIP_WHITESPACE ();
   2009   if (   *input_line_pointer == '#'
   2010       || *input_line_pointer == '@'
   2011       || *input_line_pointer == '"'
   2012       || *input_line_pointer == '%')
   2013     ++input_line_pointer;
   2014 
   2015   type_name = obj_elf_type_name (& c);
   2016 
   2017   type = 0;
   2018   if (strcmp (type_name, "function") == 0
   2019       || strcmp (type_name, "2") == 0
   2020       || strcmp (type_name, "STT_FUNC") == 0)
   2021     type = BSF_FUNCTION;
   2022   else if (strcmp (type_name, "object") == 0
   2023 	   || strcmp (type_name, "1") == 0
   2024 	   || strcmp (type_name, "STT_OBJECT") == 0)
   2025     type = BSF_OBJECT;
   2026   else if (strcmp (type_name, "tls_object") == 0
   2027 	   || strcmp (type_name, "6") == 0
   2028 	   || strcmp (type_name, "STT_TLS") == 0)
   2029     type = BSF_OBJECT | BSF_THREAD_LOCAL;
   2030   else if (strcmp (type_name, "notype") == 0
   2031 	   || strcmp (type_name, "0") == 0
   2032 	   || strcmp (type_name, "STT_NOTYPE") == 0)
   2033     ;
   2034   else if (strcmp (type_name, "common") == 0
   2035 	   || strcmp (type_name, "5") == 0
   2036 	   || strcmp (type_name, "STT_COMMON") == 0)
   2037     {
   2038       type = BSF_OBJECT;
   2039 
   2040       if (! S_IS_COMMON (sym))
   2041 	{
   2042 	  if (S_IS_VOLATILE (sym))
   2043 	    {
   2044 	      sym = symbol_clone (sym, 1);
   2045 	      S_SET_SEGMENT (sym, bfd_com_section_ptr);
   2046 	      S_SET_VALUE (sym, 0);
   2047 	      S_SET_EXTERNAL (sym);
   2048 	      symbol_set_frag (sym, &zero_address_frag);
   2049 	      S_CLEAR_VOLATILE (sym);
   2050 	    }
   2051 	  else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
   2052 	    as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
   2053 	  else
   2054 	    {
   2055 	      /* FIXME: Is it safe to just change the section ?  */
   2056 	      S_SET_SEGMENT (sym, bfd_com_section_ptr);
   2057 	      S_SET_VALUE (sym, 0);
   2058 	      S_SET_EXTERNAL (sym);
   2059 	    }
   2060 	}
   2061     }
   2062   else if (strcmp (type_name, "gnu_indirect_function") == 0
   2063 	   || strcmp (type_name, "10") == 0
   2064 	   || strcmp (type_name, "STT_GNU_IFUNC") == 0)
   2065     {
   2066 #if 0
   2067       struct elf_backend_data *bed;
   2068 
   2069       bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
   2070       if (bed->elf_osabi == ELFOSABI_NONE)
   2071 	bed->elf_osabi = ELFOSABI_GNU;
   2072       else if (bed->elf_osabi != ELFOSABI_GNU
   2073 	       && bed->elf_osabi != ELFOSABI_FREEBSD)
   2074 	as_bad (_("symbol type \"%s\" is supported only by GNU "
   2075 		  "and FreeBSD targets"), type_name);
   2076 #endif
   2077       elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
   2078       type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
   2079     }
   2080   else if (strcmp (type_name, "gnu_unique_object") == 0)
   2081     {
   2082       struct elf_backend_data *bed;
   2083 
   2084       bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
   2085       if (bed->elf_osabi == ELFOSABI_NONE)
   2086 	bed->elf_osabi = ELFOSABI_GNU;
   2087       else if (bed->elf_osabi != ELFOSABI_GNU)
   2088 	as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
   2089 		type_name);
   2090       elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_unique;
   2091       type = BSF_OBJECT | BSF_GNU_UNIQUE;
   2092     }
   2093 #ifdef md_elf_symbol_type
   2094   else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
   2095     ;
   2096 #endif
   2097   else
   2098     as_bad (_("unrecognized symbol type \"%s\""), type_name);
   2099 
   2100   *input_line_pointer = c;
   2101 
   2102   if (*input_line_pointer == '"')
   2103     ++input_line_pointer;
   2104 
   2105 #ifdef md_elf_symbol_type_change
   2106   if (!md_elf_symbol_type_change (sym, elfsym, type))
   2107 #endif
   2108     {
   2109       flagword mask = BSF_FUNCTION | BSF_OBJECT;
   2110 
   2111       if (type != BSF_FUNCTION)
   2112 	mask |= BSF_GNU_INDIRECT_FUNCTION;
   2113       if (type != BSF_OBJECT)
   2114 	{
   2115 	  mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
   2116 
   2117 	  if (S_IS_COMMON (sym))
   2118 	    {
   2119 	      as_bad (_("cannot change type of common symbol '%s'"),
   2120 		      S_GET_NAME (sym));
   2121 	      mask = type = 0;
   2122 	    }
   2123 	}
   2124 
   2125       /* Don't warn when changing to STT_NOTYPE.  */
   2126       if (type)
   2127 	{
   2128 	  flagword new = (elfsym->symbol.flags & ~mask) | type;
   2129 
   2130 	  if (new != (elfsym->symbol.flags | type))
   2131 	    as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
   2132 	  elfsym->symbol.flags = new;
   2133 	}
   2134       else
   2135 	elfsym->symbol.flags &= ~mask;
   2136     }
   2137 
   2138   demand_empty_rest_of_line ();
   2139 }
   2140 
   2141 static void
   2142 obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
   2143 {
   2144   static segT comment_section;
   2145   segT old_section = now_seg;
   2146   int old_subsection = now_subseg;
   2147 
   2148 #ifdef md_flush_pending_output
   2149   md_flush_pending_output ();
   2150 #endif
   2151 
   2152   if (!comment_section)
   2153     {
   2154       char *p;
   2155       comment_section = subseg_new (".comment", 0);
   2156       bfd_set_section_flags (comment_section, (SEC_READONLY | SEC_HAS_CONTENTS
   2157 					       | SEC_MERGE | SEC_STRINGS));
   2158       comment_section->entsize = 1;
   2159 #ifdef md_elf_section_change_hook
   2160       md_elf_section_change_hook ();
   2161 #endif
   2162       p = frag_more (1);
   2163       *p = 0;
   2164     }
   2165   else
   2166     subseg_set (comment_section, 0);
   2167   stringer (8 + 1);
   2168   subseg_set (old_section, old_subsection);
   2169 }
   2170 
   2171 #ifdef INIT_STAB_SECTION
   2172 
   2173 /* The first entry in a .stabs section is special.  */
   2174 
   2175 void
   2176 obj_elf_init_stab_section (segT seg)
   2177 {
   2178   const char *file;
   2179   char *p;
   2180   char *stabstr_name;
   2181   unsigned int stroff;
   2182 
   2183   /* Force the section to align to a longword boundary.  Without this,
   2184      UnixWare ar crashes.  */
   2185   bfd_set_section_alignment (seg, 2);
   2186 
   2187   /* Make space for this first symbol.  */
   2188   p = frag_more (12);
   2189   /* Zero it out.  */
   2190   memset (p, 0, 12);
   2191   file = as_where (NULL);
   2192   stabstr_name = concat (segment_name (seg), "str", (char *) NULL);
   2193   stroff = get_stab_string_offset (file, stabstr_name, TRUE);
   2194   know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
   2195   md_number_to_chars (p, stroff, 4);
   2196   seg_info (seg)->stabu.p = p;
   2197 }
   2198 
   2199 #endif
   2200 
   2201 /* Fill in the counts in the first entry in a .stabs section.  */
   2202 
   2203 static void
   2204 adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
   2205 {
   2206   char *name;
   2207   asection *strsec;
   2208   char *p;
   2209   int strsz, nsyms;
   2210 
   2211   if (strncmp (".stab", sec->name, 5))
   2212     return;
   2213   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
   2214     return;
   2215 
   2216   name = concat (sec->name, "str", NULL);
   2217   strsec = bfd_get_section_by_name (abfd, name);
   2218   if (strsec)
   2219     strsz = bfd_section_size (strsec);
   2220   else
   2221     strsz = 0;
   2222   nsyms = bfd_section_size (sec) / 12 - 1;
   2223 
   2224   p = seg_info (sec)->stabu.p;
   2225   gas_assert (p != 0);
   2226 
   2227   bfd_h_put_16 (abfd, nsyms, p + 6);
   2228   bfd_h_put_32 (abfd, strsz, p + 8);
   2229   free (name);
   2230 }
   2231 
   2232 #ifdef NEED_ECOFF_DEBUG
   2233 
   2234 /* This function is called by the ECOFF code.  It is supposed to
   2235    record the external symbol information so that the backend can
   2236    write it out correctly.  The ELF backend doesn't actually handle
   2237    this at the moment, so we do it ourselves.  We save the information
   2238    in the symbol.  */
   2239 
   2240 #ifdef OBJ_MAYBE_ELF
   2241 static
   2242 #endif
   2243 void
   2244 elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
   2245 {
   2246   symbol_get_bfdsym (sym)->udata.p = ext;
   2247 }
   2248 
   2249 /* This function is called by bfd_ecoff_debug_externals.  It is
   2250    supposed to *EXT to the external symbol information, and return
   2251    whether the symbol should be used at all.  */
   2252 
   2253 static bfd_boolean
   2254 elf_get_extr (asymbol *sym, EXTR *ext)
   2255 {
   2256   if (sym->udata.p == NULL)
   2257     return FALSE;
   2258   *ext = *(EXTR *) sym->udata.p;
   2259   return TRUE;
   2260 }
   2261 
   2262 /* This function is called by bfd_ecoff_debug_externals.  It has
   2263    nothing to do for ELF.  */
   2264 
   2265 static void
   2266 elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
   2267 	       bfd_size_type indx ATTRIBUTE_UNUSED)
   2268 {
   2269 }
   2270 
   2271 #endif /* NEED_ECOFF_DEBUG */
   2272 
   2273 void
   2274 elf_frob_symbol (symbolS *symp, int *puntp)
   2275 {
   2276   struct elf_obj_sy *sy_obj;
   2277   expressionS *size;
   2278 
   2279 #ifdef NEED_ECOFF_DEBUG
   2280   if (ECOFF_DEBUGGING)
   2281     ecoff_frob_symbol (symp);
   2282 #endif
   2283 
   2284   sy_obj = symbol_get_obj (symp);
   2285 
   2286   size = sy_obj->size;
   2287   if (size != NULL)
   2288     {
   2289       if (resolve_expression (size)
   2290 	  && size->X_op == O_constant)
   2291 	S_SET_SIZE (symp, size->X_add_number);
   2292       else
   2293 	{
   2294 	  if (!flag_allow_nonconst_size)
   2295 	    as_bad (_(".size expression for %s "
   2296 		      "does not evaluate to a constant"), S_GET_NAME (symp));
   2297 	  else
   2298 	    as_warn (_(".size expression for %s "
   2299 		       "does not evaluate to a constant"), S_GET_NAME (symp));
   2300 	}
   2301       free (sy_obj->size);
   2302       sy_obj->size = NULL;
   2303     }
   2304 
   2305   if (sy_obj->versioned_name != NULL)
   2306     {
   2307       char *p;
   2308 
   2309       p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
   2310       if (p == NULL)
   2311 	/* We will have already reported an error about a missing version.  */
   2312 	*puntp = TRUE;
   2313 
   2314       /* This symbol was given a new name with the .symver directive.
   2315 
   2316 	 If this is an external reference, just rename the symbol to
   2317 	 include the version string.  This will make the relocs be
   2318 	 against the correct versioned symbol.
   2319 
   2320 	 If this is a definition, add an alias.  FIXME: Using an alias
   2321 	 will permit the debugging information to refer to the right
   2322 	 symbol.  However, it's not clear whether it is the best
   2323 	 approach.  */
   2324 
   2325       else if (! S_IS_DEFINED (symp))
   2326 	{
   2327 	  /* Verify that the name isn't using the @@ syntax--this is
   2328 	     reserved for definitions of the default version to link
   2329 	     against.  */
   2330 	  if (p[1] == ELF_VER_CHR)
   2331 	    {
   2332 	      as_bad (_("invalid attempt to declare external version name"
   2333 			" as default in symbol `%s'"),
   2334 		      sy_obj->versioned_name);
   2335 	      *puntp = TRUE;
   2336 	    }
   2337 	  S_SET_NAME (symp, sy_obj->versioned_name);
   2338 	}
   2339       else
   2340 	{
   2341 	  if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
   2342 	    {
   2343 	      size_t l;
   2344 
   2345 	      /* The @@@ syntax is a special case. It renames the
   2346 		 symbol name to versioned_name with one `@' removed.  */
   2347 	      l = strlen (&p[3]) + 1;
   2348 	      memmove (&p[2], &p[3], l);
   2349 	      S_SET_NAME (symp, sy_obj->versioned_name);
   2350 	    }
   2351 	  else
   2352 	    {
   2353 	      symbolS *symp2;
   2354 
   2355 	      /* FIXME: Creating a new symbol here is risky.  We're
   2356 		 in the final loop over the symbol table.  We can
   2357 		 get away with it only because the symbol goes to
   2358 		 the end of the list, where the loop will still see
   2359 		 it.  It would probably be better to do this in
   2360 		 obj_frob_file_before_adjust.  */
   2361 
   2362 	      symp2 = symbol_find_or_make (sy_obj->versioned_name);
   2363 
   2364 	      /* Now we act as though we saw symp2 = sym.  */
   2365 	      if (S_IS_COMMON (symp))
   2366 		{
   2367 		  as_bad (_("`%s' can't be versioned to common symbol '%s'"),
   2368 			  sy_obj->versioned_name, S_GET_NAME (symp));
   2369 		  *puntp = TRUE;
   2370 		  return;
   2371 		}
   2372 
   2373 	      S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
   2374 
   2375 	      /* Subtracting out the frag address here is a hack
   2376 		 because we are in the middle of the final loop.  */
   2377 	      S_SET_VALUE (symp2,
   2378 			   (S_GET_VALUE (symp)
   2379 			    - symbol_get_frag (symp)->fr_address));
   2380 
   2381 	      symbol_set_frag (symp2, symbol_get_frag (symp));
   2382 
   2383 	      /* This will copy over the size information.  */
   2384 	      copy_symbol_attributes (symp2, symp);
   2385 
   2386 	      S_SET_OTHER (symp2, S_GET_OTHER (symp));
   2387 
   2388 	      if (S_IS_WEAK (symp))
   2389 		S_SET_WEAK (symp2);
   2390 
   2391 	      if (S_IS_EXTERNAL (symp))
   2392 		S_SET_EXTERNAL (symp2);
   2393 	    }
   2394 	}
   2395     }
   2396 
   2397   /* Double check weak symbols.  */
   2398   if (S_IS_WEAK (symp))
   2399     {
   2400       if (S_IS_COMMON (symp))
   2401 	as_bad (_("symbol `%s' can not be both weak and common"),
   2402 		S_GET_NAME (symp));
   2403     }
   2404 }
   2405 
   2406 struct group_list
   2407 {
   2408   asection **head;		/* Section lists.  */
   2409   unsigned int num_group;	/* Number of lists.  */
   2410   struct hash_control *indexes; /* Maps group name to index in head array.  */
   2411 };
   2412 
   2413 static struct group_list groups;
   2414 
   2415 /* Called via bfd_map_over_sections.  If SEC is a member of a group,
   2416    add it to a list of sections belonging to the group.  INF is a
   2417    pointer to a struct group_list, which is where we store the head of
   2418    each list.  */
   2419 
   2420 static void
   2421 build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
   2422 {
   2423   struct group_list *list = (struct group_list *) inf;
   2424   const char *group_name = elf_group_name (sec);
   2425   unsigned int i;
   2426   unsigned int *elem_idx;
   2427   unsigned int *idx_ptr;
   2428 
   2429   if (group_name == NULL)
   2430     return;
   2431 
   2432   /* If this group already has a list, add the section to the head of
   2433      the list.  */
   2434   elem_idx = (unsigned int *) hash_find (list->indexes, group_name);
   2435   if (elem_idx != NULL)
   2436     {
   2437       elf_next_in_group (sec) = list->head[*elem_idx];
   2438       list->head[*elem_idx] = sec;
   2439       return;
   2440     }
   2441 
   2442   /* New group.  Make the arrays bigger in chunks to minimize calls to
   2443      realloc.  */
   2444   i = list->num_group;
   2445   if ((i & 127) == 0)
   2446     {
   2447       unsigned int newsize = i + 128;
   2448       list->head = XRESIZEVEC (asection *, list->head, newsize);
   2449     }
   2450   list->head[i] = sec;
   2451   list->num_group += 1;
   2452 
   2453   /* Add index to hash.  */
   2454   idx_ptr = XNEW (unsigned int);
   2455   *idx_ptr = i;
   2456   hash_insert (list->indexes, group_name, idx_ptr);
   2457 }
   2458 
   2459 static void free_section_idx (const char *key ATTRIBUTE_UNUSED, void *val)
   2460 {
   2461   free ((unsigned int *) val);
   2462 }
   2463 
   2464 /* Create symbols for group signature.  */
   2465 
   2466 void
   2467 elf_adjust_symtab (void)
   2468 {
   2469   unsigned int i;
   2470 
   2471   /* Go find section groups.  */
   2472   groups.num_group = 0;
   2473   groups.head = NULL;
   2474   groups.indexes = hash_new ();
   2475   bfd_map_over_sections (stdoutput, build_group_lists, &groups);
   2476 
   2477   /* Make the SHT_GROUP sections that describe each section group.  We
   2478      can't set up the section contents here yet, because elf section
   2479      indices have yet to be calculated.  elf.c:set_group_contents does
   2480      the rest of the work.  */
   2481  for (i = 0; i < groups.num_group; i++)
   2482     {
   2483       const char *group_name = elf_group_name (groups.head[i]);
   2484       const char *sec_name;
   2485       asection *s;
   2486       flagword flags;
   2487       struct symbol *sy;
   2488 
   2489       flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
   2490       for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s))
   2491 	if ((s->flags ^ flags) & SEC_LINK_ONCE)
   2492 	  {
   2493 	    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
   2494 	    if (s != groups.head[i])
   2495 	      {
   2496 		as_warn (_("assuming all members of group `%s' are COMDAT"),
   2497 			 group_name);
   2498 		break;
   2499 	      }
   2500 	  }
   2501 
   2502       sec_name = ".group";
   2503       s = subseg_force_new (sec_name, 0);
   2504       if (s == NULL
   2505 	  || !bfd_set_section_flags (s, flags)
   2506 	  || !bfd_set_section_alignment (s, 2))
   2507 	{
   2508 	  as_fatal (_("can't create group: %s"),
   2509 		    bfd_errmsg (bfd_get_error ()));
   2510 	}
   2511       elf_section_type (s) = SHT_GROUP;
   2512 
   2513       /* Pass a pointer to the first section in this group.  */
   2514       elf_next_in_group (s) = groups.head[i];
   2515       elf_sec_group (groups.head[i]) = s;
   2516       /* Make sure that the signature symbol for the group has the
   2517 	 name of the group.  */
   2518       sy = symbol_find_exact (group_name);
   2519       if (!sy || !symbol_on_chain (sy, symbol_rootP, symbol_lastP))
   2520 	{
   2521 	  /* Create the symbol now.  */
   2522 	  sy = symbol_new (group_name, now_seg, (valueT) 0, frag_now);
   2523 #ifdef TE_SOLARIS
   2524 	  /* Before Solaris 11 build 154, Sun ld rejects local group
   2525 	     signature symbols, so make them weak hidden instead.  */
   2526 	  symbol_get_bfdsym (sy)->flags |= BSF_WEAK;
   2527 	  S_SET_OTHER (sy, STV_HIDDEN);
   2528 #else
   2529 	  symbol_get_obj (sy)->local = 1;
   2530 #endif
   2531 	  symbol_table_insert (sy);
   2532 	}
   2533       elf_group_id (s) = symbol_get_bfdsym (sy);
   2534     }
   2535 }
   2536 
   2537 void
   2538 elf_frob_file (void)
   2539 {
   2540   bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
   2541 
   2542 #ifdef elf_tc_final_processing
   2543   elf_tc_final_processing ();
   2544 #endif
   2545 }
   2546 
   2547 /* It removes any unneeded versioned symbols from the symbol table.  */
   2548 
   2549 void
   2550 elf_frob_file_before_adjust (void)
   2551 {
   2552   if (symbol_rootP)
   2553     {
   2554       symbolS *symp;
   2555 
   2556       for (symp = symbol_rootP; symp; symp = symbol_next (symp))
   2557 	if (!S_IS_DEFINED (symp))
   2558 	  {
   2559 	    if (symbol_get_obj (symp)->versioned_name)
   2560 	      {
   2561 		char *p;
   2562 
   2563 		/* The @@@ syntax is a special case. If the symbol is
   2564 		   not defined, 2 `@'s will be removed from the
   2565 		   versioned_name.  */
   2566 
   2567 		p = strchr (symbol_get_obj (symp)->versioned_name,
   2568 			    ELF_VER_CHR);
   2569 		if (p != NULL && p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
   2570 		  {
   2571 		    size_t l = strlen (&p[3]) + 1;
   2572 		    memmove (&p[1], &p[3], l);
   2573 		  }
   2574 		if (symbol_used_p (symp) == 0
   2575 		    && symbol_used_in_reloc_p (symp) == 0)
   2576 		  symbol_remove (symp, &symbol_rootP, &symbol_lastP);
   2577 	      }
   2578 
   2579 	    /* If there was .weak foo, but foo was neither defined nor
   2580 	       used anywhere, remove it.  */
   2581 
   2582 	    else if (S_IS_WEAK (symp)
   2583 		     && symbol_used_p (symp) == 0
   2584 		     && symbol_used_in_reloc_p (symp) == 0)
   2585 	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
   2586 	  }
   2587     }
   2588 }
   2589 
   2590 /* It is required that we let write_relocs have the opportunity to
   2591    optimize away fixups before output has begun, since it is possible
   2592    to eliminate all fixups for a section and thus we never should
   2593    have generated the relocation section.  */
   2594 
   2595 void
   2596 elf_frob_file_after_relocs (void)
   2597 {
   2598   unsigned int i;
   2599 
   2600   /* Set SHT_GROUP section size.  */
   2601   for (i = 0; i < groups.num_group; i++)
   2602     {
   2603       asection *s, *head, *group;
   2604       bfd_size_type size;
   2605 
   2606       head = groups.head[i];
   2607       size = 4;
   2608       for (s = head; s != NULL; s = elf_next_in_group (s))
   2609 	size += (s->flags & SEC_RELOC) != 0 ? 8 : 4;
   2610 
   2611       group = elf_sec_group (head);
   2612       subseg_set (group, 0);
   2613       bfd_set_section_size (group, size);
   2614       group->contents = (unsigned char *) frag_more (size);
   2615       frag_now->fr_fix = frag_now_fix_octets ();
   2616       frag_wane (frag_now);
   2617     }
   2618 
   2619   /* Cleanup hash.  */
   2620   hash_traverse (groups.indexes, free_section_idx);
   2621   hash_die (groups.indexes);
   2622 
   2623 #ifdef NEED_ECOFF_DEBUG
   2624   if (ECOFF_DEBUGGING)
   2625     /* Generate the ECOFF debugging information.  */
   2626     {
   2627       const struct ecoff_debug_swap *debug_swap;
   2628       struct ecoff_debug_info debug;
   2629       char *buf;
   2630       asection *sec;
   2631 
   2632       debug_swap
   2633 	= get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
   2634       know (debug_swap != NULL);
   2635       ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
   2636 
   2637       /* Set up the pointers in debug.  */
   2638 #define SET(ptr, offset, type) \
   2639     debug.ptr = (type) (buf + debug.symbolic_header.offset)
   2640 
   2641       SET (line, cbLineOffset, unsigned char *);
   2642       SET (external_dnr, cbDnOffset, void *);
   2643       SET (external_pdr, cbPdOffset, void *);
   2644       SET (external_sym, cbSymOffset, void *);
   2645       SET (external_opt, cbOptOffset, void *);
   2646       SET (external_aux, cbAuxOffset, union aux_ext *);
   2647       SET (ss, cbSsOffset, char *);
   2648       SET (external_fdr, cbFdOffset, void *);
   2649       SET (external_rfd, cbRfdOffset, void *);
   2650       /* ssext and external_ext are set up just below.  */
   2651 
   2652 #undef SET
   2653 
   2654       /* Set up the external symbols.  */
   2655       debug.ssext = debug.ssext_end = NULL;
   2656       debug.external_ext = debug.external_ext_end = NULL;
   2657       if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, TRUE,
   2658 				       elf_get_extr, elf_set_index))
   2659 	as_fatal (_("failed to set up debugging information: %s"),
   2660 		  bfd_errmsg (bfd_get_error ()));
   2661 
   2662       sec = bfd_get_section_by_name (stdoutput, ".mdebug");
   2663       gas_assert (sec != NULL);
   2664 
   2665       know (!stdoutput->output_has_begun);
   2666 
   2667       /* We set the size of the section, call bfd_set_section_contents
   2668 	 to force the ELF backend to allocate a file position, and then
   2669 	 write out the data.  FIXME: Is this really the best way to do
   2670 	 this?  */
   2671       bfd_set_section_size (sec, bfd_ecoff_debug_size (stdoutput, &debug,
   2672 						       debug_swap));
   2673 
   2674       /* Pass BUF to bfd_set_section_contents because this will
   2675 	 eventually become a call to fwrite, and ISO C prohibits
   2676 	 passing a NULL pointer to a stdio function even if the
   2677 	 pointer will not be used.  */
   2678       if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
   2679 	as_fatal (_("can't start writing .mdebug section: %s"),
   2680 		  bfd_errmsg (bfd_get_error ()));
   2681 
   2682       know (stdoutput->output_has_begun);
   2683       know (sec->filepos != 0);
   2684 
   2685       if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
   2686 				   sec->filepos))
   2687 	as_fatal (_("could not write .mdebug section: %s"),
   2688 		  bfd_errmsg (bfd_get_error ()));
   2689     }
   2690 #endif /* NEED_ECOFF_DEBUG */
   2691 }
   2692 
   2693 static void
   2694 elf_generate_asm_lineno (void)
   2695 {
   2696 #ifdef NEED_ECOFF_DEBUG
   2697   if (ECOFF_DEBUGGING)
   2698     ecoff_generate_asm_lineno ();
   2699 #endif
   2700 }
   2701 
   2702 static void
   2703 elf_process_stab (segT sec ATTRIBUTE_UNUSED,
   2704 		  int what ATTRIBUTE_UNUSED,
   2705 		  const char *string ATTRIBUTE_UNUSED,
   2706 		  int type ATTRIBUTE_UNUSED,
   2707 		  int other ATTRIBUTE_UNUSED,
   2708 		  int desc ATTRIBUTE_UNUSED)
   2709 {
   2710 #ifdef NEED_ECOFF_DEBUG
   2711   if (ECOFF_DEBUGGING)
   2712     ecoff_stab (sec, what, string, type, other, desc);
   2713 #endif
   2714 }
   2715 
   2716 static int
   2717 elf_separate_stab_sections (void)
   2718 {
   2719 #ifdef NEED_ECOFF_DEBUG
   2720   return (!ECOFF_DEBUGGING);
   2721 #else
   2722   return 1;
   2723 #endif
   2724 }
   2725 
   2726 static void
   2727 elf_init_stab_section (segT seg)
   2728 {
   2729 #ifdef NEED_ECOFF_DEBUG
   2730   if (!ECOFF_DEBUGGING)
   2731 #endif
   2732     obj_elf_init_stab_section (seg);
   2733 }
   2734 
   2735 const struct format_ops elf_format_ops =
   2736 {
   2737   bfd_target_elf_flavour,
   2738   0,	/* dfl_leading_underscore */
   2739   1,	/* emit_section_symbols */
   2740   elf_begin,
   2741   elf_file_symbol,
   2742   elf_frob_symbol,
   2743   elf_frob_file,
   2744   elf_frob_file_before_adjust,
   2745   0,	/* obj_frob_file_before_fix */
   2746   elf_frob_file_after_relocs,
   2747   elf_s_get_size, elf_s_set_size,
   2748   elf_s_get_align, elf_s_set_align,
   2749   elf_s_get_other,
   2750   elf_s_set_other,
   2751   0,	/* s_get_desc */
   2752   0,	/* s_set_desc */
   2753   0,	/* s_get_type */
   2754   0,	/* s_set_type */
   2755   elf_copy_symbol_attributes,
   2756   elf_generate_asm_lineno,
   2757   elf_process_stab,
   2758   elf_separate_stab_sections,
   2759   elf_init_stab_section,
   2760   elf_sec_sym_ok_for_reloc,
   2761   elf_pop_insert,
   2762 #ifdef NEED_ECOFF_DEBUG
   2763   elf_ecoff_set_ext,
   2764 #else
   2765   0,	/* ecoff_set_ext */
   2766 #endif
   2767   elf_obj_read_begin_hook,
   2768   elf_obj_symbol_new_hook,
   2769   0,
   2770   elf_adjust_symtab
   2771 };
   2772