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