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