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