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