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