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