]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/obj-elf.c
Revert "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 {
b5c37946
SJ
1091 if (strcmp (elf_group_name (now_seg), gname) != 0)
1092 as_warn (_("section %s already has a group (%s)"),
1093 bfd_section_name (now_seg), elf_group_name (now_seg));
642f545a
NC
1094 return;
1095 }
1096
15797439 1097 elf_group_name (now_seg) = gname;
642f545a
NC
1098 elf_section_flags (now_seg) |= SHF_GROUP;
1099}
1100
9de8d8f1 1101void
dbe2df79 1102obj_elf_section (int push)
9de8d8f1 1103{
a8c4d40b 1104 const char *name;
82b8a785 1105 char *beg;
01e1a5bc
NC
1106 int type, dummy;
1107 bfd_vma attr;
df3a023b 1108 bfd_vma gnu_attr;
f5fa8ca2 1109 int entsize;
d2dab548 1110 int linkonce;
6f932bce 1111 subsegT new_subsection = -1;
a8c4d40b 1112 struct elf_section_match match;
b71702f1 1113 unsigned long linked_to_section_index = -1UL;
9de8d8f1 1114
252b5132
RH
1115 if (flag_mri)
1116 {
1117 char mri_type;
1118
9de8d8f1 1119#ifdef md_flush_pending_output
60bcf0fa 1120 md_flush_pending_output ();
9de8d8f1
RH
1121#endif
1122
476654be 1123 obj_elf_section_change_hook ();
252b5132
RH
1124
1125 s_mri_sect (&mri_type);
1126
1127#ifdef md_elf_section_change_hook
1128 md_elf_section_change_hook ();
1129#endif
1130
1131 return;
1132 }
1133
6ce8b369
AM
1134 name = obj_elf_section_name ();
1135 if (name == NULL)
1136 return;
f1f28025 1137
a8c4d40b
L
1138 memset (&match, 0, sizeof (match));
1139
f1f28025
NC
1140 symbolS * sym;
1141 if ((sym = symbol_find (name)) != NULL
1142 && ! symbol_section_p (sym)
1143 && S_IS_DEFINED (sym)
1144 && ! S_IS_VOLATILE (sym)
1145 && ! S_CAN_BE_REDEFINED (sym))
1146 {
1147 as_bad (_("section name '%s' already defined as another symbol"), name);
1148 ignore_rest_of_line ();
1149 return;
1150 }
252b5132
RH
1151 type = SHT_NULL;
1152 attr = 0;
df3a023b 1153 gnu_attr = 0;
f5fa8ca2 1154 entsize = 0;
d2dab548 1155 linkonce = 0;
252b5132
RH
1156
1157 if (*input_line_pointer == ',')
1158 {
1159 /* Skip the comma. */
1160 ++input_line_pointer;
252b5132
RH
1161 SKIP_WHITESPACE ();
1162
9cfc3331 1163 if (push && ISDIGIT (*input_line_pointer))
6f932bce 1164 {
9cfc3331 1165 /* .pushsection has an optional subsection. */
6f932bce 1166 new_subsection = (subsegT) get_absolute_expression ();
9cfc3331
L
1167
1168 SKIP_WHITESPACE ();
1169
1170 /* Stop if we don't see a comma. */
1171 if (*input_line_pointer != ',')
1172 goto done;
1173
1174 /* Skip the comma. */
1175 ++input_line_pointer;
1176 SKIP_WHITESPACE ();
6f932bce 1177 }
9cfc3331
L
1178
1179 if (*input_line_pointer == '"')
252b5132 1180 {
5b7c81bd 1181 bool is_clone;
01642c12 1182
9de8d8f1
RH
1183 beg = demand_copy_C_string (&dummy);
1184 if (beg == NULL)
252b5132 1185 {
9de8d8f1
RH
1186 ignore_rest_of_line ();
1187 return;
252b5132 1188 }
df3a023b
AM
1189 attr |= obj_elf_parse_section_letters (beg, strlen (beg),
1190 &is_clone, &gnu_attr);
252b5132
RH
1191
1192 SKIP_WHITESPACE ();
1193 if (*input_line_pointer == ',')
1194 {
9de8d8f1 1195 char c;
060adf0e
AM
1196 char *save = input_line_pointer;
1197
252b5132
RH
1198 ++input_line_pointer;
1199 SKIP_WHITESPACE ();
9de8d8f1
RH
1200 c = *input_line_pointer;
1201 if (c == '"')
252b5132 1202 {
9de8d8f1
RH
1203 beg = demand_copy_C_string (&dummy);
1204 if (beg == NULL)
252b5132 1205 {
9de8d8f1
RH
1206 ignore_rest_of_line ();
1207 return;
252b5132 1208 }
5b7c81bd 1209 type = obj_elf_section_type (beg, strlen (beg), true);
9de8d8f1
RH
1210 }
1211 else if (c == '@' || c == '%')
1212 {
d02603dc 1213 ++input_line_pointer;
9fb71ee4
NC
1214
1215 if (ISDIGIT (* input_line_pointer))
df3a023b 1216 type = strtoul (input_line_pointer, &input_line_pointer, 0);
9fb71ee4
NC
1217 else
1218 {
1219 c = get_symbol_name (& beg);
1220 (void) restore_line_pointer (c);
df3a023b
AM
1221 type = obj_elf_section_type (beg,
1222 input_line_pointer - beg,
5b7c81bd 1223 true);
9fb71ee4 1224 }
252b5132 1225 }
060adf0e
AM
1226 else
1227 input_line_pointer = save;
252b5132 1228 }
f5fa8ca2
JJ
1229
1230 SKIP_WHITESPACE ();
6ce8b369 1231 if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
f5fa8ca2
JJ
1232 {
1233 ++input_line_pointer;
1234 SKIP_WHITESPACE ();
1235 entsize = get_absolute_expression ();
6ce8b369 1236 SKIP_WHITESPACE ();
f5fa8ca2
JJ
1237 if (entsize < 0)
1238 {
6ce8b369 1239 as_warn (_("invalid merge entity size"));
f5fa8ca2
JJ
1240 attr &= ~SHF_MERGE;
1241 entsize = 0;
1242 }
1243 }
6ce8b369
AM
1244 else if ((attr & SHF_MERGE) != 0)
1245 {
1246 as_warn (_("entity size for SHF_MERGE not specified"));
1247 attr &= ~SHF_MERGE;
1248 }
060adf0e 1249
b7d07216
L
1250 if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
1251 {
b7d07216
L
1252 ++input_line_pointer;
1253 SKIP_WHITESPACE ();
b71702f1
NC
1254 /* Check for a numeric section index, rather than a symbol name. */
1255 if (ISDIGIT (* input_line_pointer))
1256 {
1257 linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
1258 }
1259 else
1260 {
1261 char c;
1262 unsigned int length;
1263
1264 c = get_symbol_name (& beg);
1265 (void) restore_line_pointer (c);
1266 length = input_line_pointer - beg;
1267 if (length)
1268 match.linked_to_symbol_name = xmemdup0 (beg, length);
1269 }
b7d07216
L
1270 }
1271
f6616a06 1272 if ((attr & SHF_GROUP) != 0 && is_clone)
01642c12
RM
1273 {
1274 as_warn (_("? section flag ignored with G present"));
5b7c81bd 1275 is_clone = false;
01642c12 1276 }
b71702f1 1277
060adf0e
AM
1278 if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
1279 {
1280 ++input_line_pointer;
a8c4d40b
L
1281 match.group_name = obj_elf_section_name ();
1282 if (match.group_name == NULL)
060adf0e 1283 attr &= ~SHF_GROUP;
59365e19 1284 else if (*input_line_pointer == ',')
d2dab548 1285 {
59365e19
AM
1286 ++input_line_pointer;
1287 SKIP_WHITESPACE ();
d34049e8 1288 if (startswith (input_line_pointer, "comdat"))
59365e19
AM
1289 {
1290 input_line_pointer += 6;
1291 linkonce = 1;
1292 }
d2dab548 1293 }
d34049e8 1294 else if (startswith (name, ".gnu.linkonce"))
d2dab548 1295 linkonce = 1;
060adf0e
AM
1296 }
1297 else if ((attr & SHF_GROUP) != 0)
1298 {
1299 as_warn (_("group name for SHF_GROUP not specified"));
1300 attr &= ~SHF_GROUP;
1301 }
01642c12 1302
f6616a06 1303 if (is_clone)
01642c12
RM
1304 {
1305 const char *now_group = elf_group_name (now_seg);
1306 if (now_group != NULL)
1307 {
15797439 1308 match.group_name = now_group;
01642c12
RM
1309 linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
1310 }
1311 }
a91e1603 1312
df3a023b 1313 if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
a91e1603 1314 {
a8c4d40b 1315 char *save = input_line_pointer;
a91e1603
L
1316 ++input_line_pointer;
1317 SKIP_WHITESPACE ();
1318 if (ISDIGIT (* input_line_pointer))
1319 {
1320 char *t = input_line_pointer;
037311d1 1321 match.sh_info = strtoul (input_line_pointer,
a8c4d40b 1322 &input_line_pointer, 0);
037311d1 1323 if (match.sh_info == (unsigned int) -1)
a91e1603
L
1324 {
1325 as_warn (_("unsupported mbind section info: %s"), t);
037311d1 1326 match.sh_info = 0;
a91e1603
L
1327 }
1328 }
a8c4d40b
L
1329 else
1330 input_line_pointer = save;
1331 }
1332
037311d1
L
1333 if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1334 match.sh_flags |= SHF_GNU_RETAIN;
1335
a8c4d40b
L
1336 if (*input_line_pointer == ',')
1337 {
1338 char *save = input_line_pointer;
b71702f1 1339
a8c4d40b
L
1340 ++input_line_pointer;
1341 SKIP_WHITESPACE ();
d34049e8 1342 if (startswith (input_line_pointer, "unique"))
a8c4d40b
L
1343 {
1344 input_line_pointer += 6;
1345 SKIP_WHITESPACE ();
1346 if (*input_line_pointer == ',')
1347 {
1348 ++input_line_pointer;
1349 SKIP_WHITESPACE ();
1350 if (ISDIGIT (* input_line_pointer))
1351 {
1352 bfd_vma id;
5b7c81bd 1353 bool overflow;
a8c4d40b
L
1354 char *t = input_line_pointer;
1355 if (sizeof (bfd_vma) <= sizeof (unsigned long))
1356 {
1357 errno = 0;
1358 id = strtoul (input_line_pointer,
1359 &input_line_pointer, 0);
1360 overflow = (id == (unsigned long) -1
1361 && errno == ERANGE);
1362 }
1363 else
1364 {
1365 id = bfd_scan_vma
1366 (input_line_pointer,
1367 (const char **) &input_line_pointer, 0);
1368 overflow = id == ~(bfd_vma) 0;
1369 }
1370 if (overflow || id > (unsigned int) -1)
1371 {
1372 char *linefeed, saved_char = 0;
1373 if ((linefeed = strchr (t, '\n')) != NULL)
1374 {
1375 saved_char = *linefeed;
1376 *linefeed = '\0';
1377 }
1378 as_bad (_("unsupported section id: %s"), t);
1379 if (saved_char)
1380 *linefeed = saved_char;
1381 }
1382 else
1383 {
1384 match.section_id = id;
1385 match.flags |= SEC_ASSEMBLER_SECTION_ID;
1386 }
1387 }
1388 }
1389 }
1390 else
1391 input_line_pointer = save;
a91e1603 1392 }
252b5132 1393 }
4cb88cfa 1394#ifdef TC_SPARC
252b5132
RH
1395 else
1396 {
1397 do
1398 {
9de8d8f1
RH
1399 char c;
1400
252b5132
RH
1401 SKIP_WHITESPACE ();
1402 if (*input_line_pointer != '#')
1403 {
c95b35a9 1404 as_bad (_("character following name is not '#'"));
252b5132
RH
1405 ignore_rest_of_line ();
1406 return;
1407 }
d02603dc
NC
1408 ++input_line_pointer;
1409 c = get_symbol_name (& beg);
1410 (void) restore_line_pointer (c);
9de8d8f1 1411
df3a023b
AM
1412 attr |= obj_elf_section_word (beg, input_line_pointer - beg,
1413 &type);
9de8d8f1 1414
252b5132
RH
1415 SKIP_WHITESPACE ();
1416 }
1417 while (*input_line_pointer++ == ',');
1418 --input_line_pointer;
1419 }
4cb88cfa 1420#endif
252b5132
RH
1421 }
1422
dc1e8a47 1423 done:
252b5132 1424 demand_empty_rest_of_line ();
9de8d8f1 1425
99fabbc9 1426 if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
df3a023b 1427 {
c410035d 1428 const struct elf_backend_data *bed;
5b7c81bd 1429 bool mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
df3a023b 1430
99fabbc9 1431 if (mbind_p && (attr & SHF_ALLOC) == 0)
df3a023b
AM
1432 as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
1433
c410035d 1434 bed = get_elf_backend_data (stdoutput);
99fabbc9
JL
1435
1436 if (bed->elf_osabi != ELFOSABI_GNU
1437 && bed->elf_osabi != ELFOSABI_FREEBSD
1438 && bed->elf_osabi != ELFOSABI_NONE)
1439 as_bad (_("%s section is supported only by GNU and FreeBSD targets"),
1440 mbind_p ? "GNU_MBIND" : "GNU_RETAIN");
1441 else
1442 {
99fabbc9
JL
1443 if (mbind_p)
1444 elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
1445 if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1446 elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
1447
1448 attr |= gnu_attr;
1449 }
df3a023b 1450 }
99fabbc9
JL
1451
1452 obj_elf_change_section (name, type, attr, entsize, &match, linkonce,
1453 push);
df3a023b 1454
b71702f1
NC
1455 if (linked_to_section_index != -1UL)
1456 {
1457 elf_section_flags (now_seg) |= SHF_LINK_ORDER;
1458 elf_section_data (now_seg)->this_hdr.sh_link = linked_to_section_index;
1459 /* FIXME: Should we perform some sanity checking on the section index ? */
1460 }
1461
6f932bce
NC
1462 if (push && new_subsection != -1)
1463 subseg_set (now_seg, new_subsection);
252b5132
RH
1464}
1465
476654be
NC
1466/* Change to the .bss section. */
1467
1468void
1469obj_elf_bss (int i ATTRIBUTE_UNUSED)
1470{
1471 int temp;
1472
1473#ifdef md_flush_pending_output
1474 md_flush_pending_output ();
1475#endif
1476
1477 obj_elf_section_change_hook ();
1478
1479 temp = get_absolute_expression ();
1480 subseg_set (bss_section, (subsegT) temp);
1481 demand_empty_rest_of_line ();
1482
1483#ifdef md_elf_section_change_hook
1484 md_elf_section_change_hook ();
1485#endif
1486}
1487
252b5132
RH
1488/* Change to the .data section. */
1489
16b93d88 1490void
dbe2df79 1491obj_elf_data (int i)
252b5132
RH
1492{
1493#ifdef md_flush_pending_output
1494 md_flush_pending_output ();
1495#endif
1496
476654be
NC
1497 obj_elf_section_change_hook ();
1498
252b5132
RH
1499 s_data (i);
1500
1501#ifdef md_elf_section_change_hook
1502 md_elf_section_change_hook ();
1503#endif
1504}
1505
1506/* Change to the .text section. */
1507
16b93d88 1508void
dbe2df79 1509obj_elf_text (int i)
252b5132
RH
1510{
1511#ifdef md_flush_pending_output
1512 md_flush_pending_output ();
1513#endif
1514
476654be
NC
1515 obj_elf_section_change_hook ();
1516
252b5132
RH
1517 s_text (i);
1518
1519#ifdef md_elf_section_change_hook
1520 md_elf_section_change_hook ();
1521#endif
1522}
1523
8fe53b44
JB
1524/* Change to the *ABS* section. */
1525
1526void
1527obj_elf_struct (int i)
1528{
1529#ifdef md_flush_pending_output
1530 md_flush_pending_output ();
1531#endif
1532
476654be
NC
1533 obj_elf_section_change_hook ();
1534
8fe53b44
JB
1535 s_struct (i);
1536
1537#ifdef md_elf_section_change_hook
1538 md_elf_section_change_hook ();
1539#endif
1540}
1541
252b5132 1542static void
dbe2df79 1543obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
252b5132 1544{
6f932bce 1545 int temp;
252b5132
RH
1546
1547#ifdef md_flush_pending_output
1548 md_flush_pending_output ();
1549#endif
1550
476654be 1551 obj_elf_section_change_hook ();
252b5132
RH
1552
1553 temp = get_absolute_expression ();
1554 subseg_set (now_seg, (subsegT) temp);
1555 demand_empty_rest_of_line ();
1556
1557#ifdef md_elf_section_change_hook
1558 md_elf_section_change_hook ();
1559#endif
1560}
1561
1562/* This can be called from the processor backends if they change
1563 sections. */
1564
1565void
dbe2df79 1566obj_elf_section_change_hook (void)
252b5132
RH
1567{
1568 previous_section = now_seg;
1569 previous_subsection = now_subseg;
1570}
1571
1572void
dbe2df79 1573obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
252b5132 1574{
9de8d8f1
RH
1575 segT new_section;
1576 int new_subsection;
1577
252b5132
RH
1578 if (previous_section == 0)
1579 {
6ce8b369 1580 as_warn (_(".previous without corresponding .section; ignored"));
252b5132
RH
1581 return;
1582 }
1583
1584#ifdef md_flush_pending_output
1585 md_flush_pending_output ();
1586#endif
1587
9de8d8f1
RH
1588 new_section = previous_section;
1589 new_subsection = previous_subsection;
476654be
NC
1590 obj_elf_section_change_hook ();
1591
9de8d8f1
RH
1592 subseg_set (new_section, new_subsection);
1593
1594#ifdef md_elf_section_change_hook
1595 md_elf_section_change_hook ();
1596#endif
1597}
1598
1599static void
dbe2df79 1600obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
9de8d8f1
RH
1601{
1602 struct section_stack *top = section_stack;
1603
1604 if (top == NULL)
1605 {
6ce8b369 1606 as_warn (_(".popsection without corresponding .pushsection; ignored"));
9de8d8f1
RH
1607 return;
1608 }
1609
1610#ifdef md_flush_pending_output
1611 md_flush_pending_output ();
1612#endif
1613
1614 section_stack = top->next;
1615 previous_section = top->prev_seg;
1616 previous_subsection = top->prev_subseg;
1617 subseg_set (top->seg, top->subseg);
1618 free (top);
252b5132
RH
1619
1620#ifdef md_elf_section_change_hook
1621 md_elf_section_change_hook ();
1622#endif
1623}
1624
1625static void
dbe2df79 1626obj_elf_line (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1627{
1628 /* Assume delimiter is part of expression. BSD4.2 as fails with
bf514e21 1629 delightful bug, so we are not being incompatible here. */
dbe2df79 1630 new_logical_line (NULL, get_absolute_expression ());
252b5132
RH
1631 demand_empty_rest_of_line ();
1632}
1633
6914be53
L
1634static struct elf_versioned_name_list *
1635obj_elf_find_and_add_versioned_name (const char *version_name,
1636 const char *sym_name,
1637 const char *ver,
1638 struct elf_obj_sy *sy_obj)
1639{
1640 struct elf_versioned_name_list *versioned_name;
1641 const char *p;
1642
1643 for (p = ver + 1; *p == ELF_VER_CHR; p++)
1644 ;
1645
1646 /* NB: Since some tests in ld/testsuite/ld-elfvers have no version
1647 names, we have to disable this. */
1648 if (0 && *p == '\0')
1649 {
1650 as_bad (_("missing version name in `%s' for symbol `%s'"),
1651 version_name, sym_name);
1652 return NULL;
1653 }
1654
1655 versioned_name = sy_obj->versioned_name;
1656
1657 switch (p - ver)
1658 {
1659 case 1:
1660 case 2:
1661 break;
1662 case 3:
1663 if (sy_obj->rename)
1664 {
1665 if (strcmp (versioned_name->name, version_name) == 0)
1666 return versioned_name;
1667 else
1668 {
1669 as_bad (_("only one version name with `@@@' is allowed "
1670 "for symbol `%s'"), sym_name);
1671 return NULL;
1672 }
1673 }
5b7c81bd 1674 sy_obj->rename = true;
6914be53
L
1675 break;
1676 default:
1677 as_bad (_("invalid version name '%s' for symbol `%s'"),
1678 version_name, sym_name);
1679 return NULL;
1680 }
1681
1682 for (;
1683 versioned_name != NULL;
1684 versioned_name = versioned_name->next)
1685 if (strcmp (versioned_name->name, version_name) == 0)
1686 return versioned_name;
1687
1688 /* Add this versioned name to the head of the list, */
1689 versioned_name = (struct elf_versioned_name_list *)
1690 xmalloc (sizeof (*versioned_name));
1691 versioned_name->name = xstrdup (version_name);
1692 versioned_name->next = sy_obj->versioned_name;
1693 sy_obj->versioned_name = versioned_name;
1694
1695 return versioned_name;
1696}
1697
252b5132
RH
1698/* This handles the .symver pseudo-op, which is used to specify a
1699 symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
1700 SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
1701 pseudo-op causes the assembler to emit a symbol named SYMVERNAME
1702 with the same value as the symbol NAME. */
1703
1704static void
dbe2df79 1705obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1706{
1707 char *name;
6914be53 1708 const char *sym_name;
252b5132 1709 char c;
468cced8 1710 char old_lexat;
252b5132 1711 symbolS *sym;
6914be53
L
1712 struct elf_obj_sy *sy_obj;
1713 char *p;
252b5132 1714
6e8bd58f 1715 sym = get_sym_from_input_line_and_check ();
252b5132 1716
252b5132
RH
1717 if (*input_line_pointer != ',')
1718 {
1719 as_bad (_("expected comma after name in .symver"));
1720 ignore_rest_of_line ();
1721 return;
1722 }
1723
1724 ++input_line_pointer;
eba874d8 1725 SKIP_WHITESPACE ();
468cced8
AM
1726
1727 /* Temporarily include '@' in symbol names. */
1728 old_lexat = lex_type[(unsigned char) '@'];
1729 lex_type[(unsigned char) '@'] |= LEX_NAME;
d02603dc 1730 c = get_symbol_name (& name);
468cced8 1731 lex_type[(unsigned char) '@'] = old_lexat;
6914be53 1732 sym_name = S_GET_NAME (sym);
252b5132 1733
a3aea05a
L
1734 if (S_IS_COMMON (sym))
1735 {
1736 as_bad (_("`%s' can't be versioned to common symbol '%s'"),
6914be53 1737 name, sym_name);
a3aea05a
L
1738 ignore_rest_of_line ();
1739 return;
1740 }
1741
6914be53
L
1742 p = strchr (name, ELF_VER_CHR);
1743 if (p == NULL)
339681c0 1744 {
6914be53
L
1745 as_bad (_("missing version name in `%s' for symbol `%s'"),
1746 name, sym_name);
1747 ignore_rest_of_line ();
1748 return;
1749 }
1750
1751 sy_obj = symbol_get_obj (sym);
1752 if (obj_elf_find_and_add_versioned_name (name, sym_name,
1753 p, sy_obj) == NULL)
1754 {
5b7c81bd 1755 sy_obj->bad_version = true;
6914be53
L
1756 ignore_rest_of_line ();
1757 return;
1758 }
252b5132 1759
6914be53 1760 (void) restore_line_pointer (c);
252b5132 1761
6914be53
L
1762 if (*input_line_pointer == ',')
1763 {
1764 char *save = input_line_pointer;
1765
1766 ++input_line_pointer;
1767 SKIP_WHITESPACE ();
d34049e8 1768 if (startswith (input_line_pointer, "local"))
339681c0 1769 {
6914be53
L
1770 input_line_pointer += 5;
1771 sy_obj->visibility = visibility_local;
339681c0 1772 }
d34049e8 1773 else if (startswith (input_line_pointer, "hidden"))
339681c0 1774 {
6914be53
L
1775 input_line_pointer += 6;
1776 sy_obj->visibility = visibility_hidden;
339681c0 1777 }
d34049e8 1778 else if (startswith (input_line_pointer, "remove"))
6914be53
L
1779 {
1780 input_line_pointer += 6;
1781 sy_obj->visibility = visibility_remove;
1782 }
1783 else
1784 input_line_pointer = save;
252b5132
RH
1785 }
1786
1787 demand_empty_rest_of_line ();
1788}
1789
1790/* This handles the .vtable_inherit pseudo-op, which is used to indicate
1791 to the linker the hierarchy in which a particular table resides. The
1792 syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
1793
904a31bf 1794struct fix *
68d20676 1795obj_elf_get_vtable_inherit (void)
252b5132
RH
1796{
1797 char *cname, *pname;
1798 symbolS *csym, *psym;
1799 char c, bad = 0;
1800
1801 if (*input_line_pointer == '#')
1802 ++input_line_pointer;
1803
d02603dc 1804 c = get_symbol_name (& cname);
252b5132
RH
1805 csym = symbol_find (cname);
1806
1807 /* GCFIXME: should check that we don't have two .vtable_inherits for
1808 the same child symbol. Also, we can currently only do this if the
1809 child symbol is already exists and is placed in a fragment. */
1810
49309057 1811 if (csym == NULL || symbol_get_frag (csym) == NULL)
252b5132 1812 {
bd3ba5d1 1813 as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
252b5132
RH
1814 cname);
1815 bad = 1;
1816 }
1817
1818 *input_line_pointer = c;
1819
d02603dc 1820 SKIP_WHITESPACE_AFTER_NAME ();
252b5132
RH
1821 if (*input_line_pointer != ',')
1822 {
bd3ba5d1 1823 as_bad (_("expected comma after name in .vtable_inherit"));
252b5132 1824 ignore_rest_of_line ();
904a31bf 1825 return NULL;
252b5132
RH
1826 }
1827
1828 ++input_line_pointer;
1829 SKIP_WHITESPACE ();
1830
1831 if (*input_line_pointer == '#')
1832 ++input_line_pointer;
1833
1834 if (input_line_pointer[0] == '0'
1835 && (input_line_pointer[1] == '\0'
3882b010 1836 || ISSPACE (input_line_pointer[1])))
252b5132
RH
1837 {
1838 psym = section_symbol (absolute_section);
1839 ++input_line_pointer;
1840 }
1841 else
1842 {
d02603dc 1843 c = get_symbol_name (& pname);
252b5132 1844 psym = symbol_find_or_make (pname);
d02603dc 1845 restore_line_pointer (c);
252b5132
RH
1846 }
1847
1848 demand_empty_rest_of_line ();
1849
1850 if (bad)
904a31bf 1851 return NULL;
252b5132 1852
9c2799c2 1853 gas_assert (symbol_get_value_expression (csym)->X_op == O_constant);
904a31bf
AM
1854 return fix_new (symbol_get_frag (csym),
1855 symbol_get_value_expression (csym)->X_add_number,
1856 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
252b5132 1857}
fa306131 1858
68d20676
NC
1859/* This is a version of obj_elf_get_vtable_inherit() that is
1860 suitable for use in struct _pseudo_type tables. */
1861
1862void
1863obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
1864{
1865 (void) obj_elf_get_vtable_inherit ();
1866}
1867
252b5132
RH
1868/* This handles the .vtable_entry pseudo-op, which is used to indicate
1869 to the linker that a vtable slot was used. The syntax is
1870 ".vtable_entry tablename, offset". */
1871
904a31bf 1872struct fix *
68d20676 1873obj_elf_get_vtable_entry (void)
252b5132 1874{
252b5132
RH
1875 symbolS *sym;
1876 offsetT offset;
252b5132
RH
1877
1878 if (*input_line_pointer == '#')
1879 ++input_line_pointer;
1880
6e8bd58f 1881 sym = get_sym_from_input_line_and_check ();
252b5132
RH
1882 if (*input_line_pointer != ',')
1883 {
bd3ba5d1 1884 as_bad (_("expected comma after name in .vtable_entry"));
252b5132 1885 ignore_rest_of_line ();
904a31bf 1886 return NULL;
252b5132
RH
1887 }
1888
1889 ++input_line_pointer;
1890 if (*input_line_pointer == '#')
1891 ++input_line_pointer;
1892
1893 offset = get_absolute_expression ();
1894
252b5132 1895 demand_empty_rest_of_line ();
904a31bf
AM
1896
1897 return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
1898 BFD_RELOC_VTABLE_ENTRY);
252b5132
RH
1899}
1900
68d20676
NC
1901/* This is a version of obj_elf_get_vtable_entry() that is
1902 suitable for use in struct _pseudo_type tables. */
1903
1904void
1905obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
1906{
1907 (void) obj_elf_get_vtable_entry ();
1908}
1909
0420f52b
MR
1910#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1911
1912static inline int
1913skip_past_char (char ** str, char c)
1914{
1915 if (**str == c)
1916 {
1917 (*str)++;
1918 return 0;
1919 }
1920 else
1921 return -1;
1922}
1923#define skip_past_comma(str) skip_past_char (str, ',')
1924
9440a904
RS
1925/* A list of attributes that have been explicitly set by the assembly code.
1926 VENDOR is the vendor id, BASE is the tag shifted right by the number
1927 of bits in MASK, and bit N of MASK is set if tag BASE+N has been set. */
1928struct recorded_attribute_info {
1929 struct recorded_attribute_info *next;
1930 int vendor;
1931 unsigned int base;
1932 unsigned long mask;
1933};
1934static struct recorded_attribute_info *recorded_attributes;
1935
1936/* Record that we have seen an explicit specification of attribute TAG
1937 for vendor VENDOR. */
1938
1939static void
1940record_attribute (int vendor, unsigned int tag)
1941{
1942 unsigned int base;
1943 unsigned long mask;
1944 struct recorded_attribute_info *rai;
1945
1946 base = tag / (8 * sizeof (rai->mask));
1947 mask = 1UL << (tag % (8 * sizeof (rai->mask)));
1948 for (rai = recorded_attributes; rai; rai = rai->next)
1949 if (rai->vendor == vendor && rai->base == base)
1950 {
1951 rai->mask |= mask;
1952 return;
1953 }
1954
1955 rai = XNEW (struct recorded_attribute_info);
1956 rai->next = recorded_attributes;
1957 rai->vendor = vendor;
1958 rai->base = base;
1959 rai->mask = mask;
1960 recorded_attributes = rai;
1961}
1962
1963/* Return true if we have seen an explicit specification of attribute TAG
1964 for vendor VENDOR. */
1965
5b7c81bd 1966bool
9440a904
RS
1967obj_elf_seen_attribute (int vendor, unsigned int tag)
1968{
1969 unsigned int base;
1970 unsigned long mask;
1971 struct recorded_attribute_info *rai;
1972
1973 base = tag / (8 * sizeof (rai->mask));
1974 mask = 1UL << (tag % (8 * sizeof (rai->mask)));
1975 for (rai = recorded_attributes; rai; rai = rai->next)
1976 if (rai->vendor == vendor && rai->base == base)
1977 return (rai->mask & mask) != 0;
5b7c81bd 1978 return false;
9440a904
RS
1979}
1980
0420f52b
MR
1981/* Parse an attribute directive for VENDOR.
1982 Returns the attribute number read, or zero on error. */
1983
1984int
1985obj_elf_vendor_attribute (int vendor)
1986{
1987 expressionS exp;
1988 int type;
1989 int tag;
1990 unsigned int i = 0;
1991 char *s = NULL;
1992
1993 /* Read the first number or name. */
1994 skip_whitespace (input_line_pointer);
1995 s = input_line_pointer;
1996 if (ISDIGIT (*input_line_pointer))
1997 {
1998 expression (& exp);
1999 if (exp.X_op != O_constant)
2000 goto bad;
2001 tag = exp.X_add_number;
2002 }
2003 else
2004 {
2005 char *name;
2006
2007 /* A name may contain '_', but no other punctuation. */
2008 for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
2009 ++input_line_pointer)
2010 i++;
2011 if (i == 0)
2012 goto bad;
2013
15797439 2014 name = xmemdup0 (s, i);
0420f52b
MR
2015
2016#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
2017#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
2018#endif
2019
2020 tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
2021 if (tag == -1)
2022 {
2023 as_bad (_("Attribute name not recognised: %s"), name);
2024 ignore_rest_of_line ();
e1fa0163 2025 free (name);
0420f52b
MR
2026 return 0;
2027 }
e1fa0163 2028 free (name);
0420f52b
MR
2029 }
2030
2031 type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
2032
2033 if (skip_past_comma (&input_line_pointer) == -1)
2034 goto bad;
2035 if (type & 1)
2036 {
2037 expression (& exp);
2038 if (exp.X_op != O_constant)
2039 {
2040 as_bad (_("expected numeric constant"));
2041 ignore_rest_of_line ();
2042 return 0;
2043 }
2044 i = exp.X_add_number;
2045 }
2046 if ((type & 3) == 3
2047 && skip_past_comma (&input_line_pointer) == -1)
2048 {
2049 as_bad (_("expected comma"));
2050 ignore_rest_of_line ();
2051 return 0;
2052 }
2053 if (type & 2)
2054 {
2055 int len;
2056
2057 skip_whitespace (input_line_pointer);
2058 if (*input_line_pointer != '"')
2059 goto bad_string;
2060 s = demand_copy_C_string (&len);
2061 }
2062
9440a904 2063 record_attribute (vendor, tag);
0420f52b
MR
2064 switch (type & 3)
2065 {
2066 case 3:
2067 bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
2068 break;
2069 case 2:
2070 bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
2071 break;
2072 case 1:
2073 bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
2074 break;
2075 default:
2076 abort ();
2077 }
2078
2079 demand_empty_rest_of_line ();
2080 return tag;
dc1e8a47 2081 bad_string:
0420f52b
MR
2082 as_bad (_("bad string constant"));
2083 ignore_rest_of_line ();
2084 return 0;
dc1e8a47 2085 bad:
0420f52b
MR
2086 as_bad (_("expected <tag> , <value>"));
2087 ignore_rest_of_line ();
2088 return 0;
2089}
2090
2091/* Parse a .gnu_attribute directive. */
2092
2093static void
2094obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
2095{
2096 obj_elf_vendor_attribute (OBJ_ATTR_GNU);
2097}
2098
252b5132 2099void
dbe2df79 2100elf_obj_read_begin_hook (void)
252b5132
RH
2101{
2102#ifdef NEED_ECOFF_DEBUG
2103 if (ECOFF_DEBUGGING)
2104 ecoff_read_begin_hook ();
2105#endif
2106}
2107
2108void
dbe2df79 2109elf_obj_symbol_new_hook (symbolS *symbolP)
252b5132 2110{
49309057
ILT
2111 struct elf_obj_sy *sy_obj;
2112
2113 sy_obj = symbol_get_obj (symbolP);
2114 sy_obj->size = NULL;
2115 sy_obj->versioned_name = NULL;
252b5132
RH
2116
2117#ifdef NEED_ECOFF_DEBUG
2118 if (ECOFF_DEBUGGING)
2119 ecoff_symbol_new_hook (symbolP);
2120#endif
2121}
2122
7bed8466
AM
2123/* Deduplicate size expressions. We might get into trouble with
2124 multiple freeing or use after free if we leave them pointing to the
2125 same expressionS. */
2126
2127void
2128elf_obj_symbol_clone_hook (symbolS *newsym, symbolS *orgsym ATTRIBUTE_UNUSED)
2129{
2130 struct elf_obj_sy *newelf = symbol_get_obj (newsym);
2131 if (newelf->size)
2132 {
2133 expressionS *exp = XNEW (expressionS);
2134 *exp = *newelf->size;
2135 newelf->size = exp;
2136 }
2137}
2138
8fd3e36b 2139void
dbe2df79 2140elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
8fd3e36b 2141{
060adf0e
AM
2142 struct elf_obj_sy *srcelf = symbol_get_obj (src);
2143 struct elf_obj_sy *destelf = symbol_get_obj (dest);
867b8c30
FS
2144 /* If size is unset, copy size from src. Because we don't track whether
2145 .size has been used, we can't differentiate .size dest, 0 from the case
2146 where dest's size is unset. */
2147 if (!destelf->size && S_GET_SIZE (dest) == 0)
060adf0e 2148 {
867b8c30
FS
2149 if (srcelf->size)
2150 {
2151 destelf->size = XNEW (expressionS);
2152 *destelf->size = *srcelf->size;
2153 }
2154 S_SET_SIZE (dest, S_GET_SIZE (src));
060adf0e 2155 }
26eb4093
JJ
2156 /* Don't copy visibility. */
2157 S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
2158 | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
8fd3e36b
AM
2159}
2160
252b5132 2161void
dbe2df79 2162obj_elf_version (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
2163{
2164 char *name;
2165 unsigned int c;
252b5132
RH
2166 char *p;
2167 asection *seg = now_seg;
2168 subsegT subseg = now_subseg;
2169 Elf_Internal_Note i_note;
2170 Elf_External_Note e_note;
dbe2df79 2171 asection *note_secp = NULL;
252b5132
RH
2172
2173 SKIP_WHITESPACE ();
2174 if (*input_line_pointer == '\"')
2175 {
6afdfa61
NC
2176 unsigned int len;
2177
bf514e21 2178 ++input_line_pointer; /* -> 1st char of string. */
252b5132
RH
2179 name = input_line_pointer;
2180
2181 while (is_a_char (c = next_char_of_string ()))
2182 ;
2183 c = *input_line_pointer;
2184 *input_line_pointer = '\0';
2185 *(input_line_pointer - 1) = '\0';
2186 *input_line_pointer = c;
2187
6afdfa61 2188 /* Create the .note section. */
252b5132 2189 note_secp = subseg_new (".note", 0);
fd361982 2190 bfd_set_section_flags (note_secp, SEC_HAS_CONTENTS | SEC_READONLY);
ed9c7ee0 2191 record_alignment (note_secp, 2);
252b5132 2192
6afdfa61
NC
2193 /* Process the version string. */
2194 len = strlen (name) + 1;
252b5132 2195
6afdfa61
NC
2196 /* PR 3456: Although the name field is padded out to an 4-byte
2197 boundary, the namesz field should not be adjusted. */
2198 i_note.namesz = len;
2199 i_note.descsz = 0; /* No description. */
252b5132
RH
2200 i_note.type = NT_VERSION;
2201 p = frag_more (sizeof (e_note.namesz));
dbe2df79 2202 md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
252b5132 2203 p = frag_more (sizeof (e_note.descsz));
dbe2df79 2204 md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
252b5132 2205 p = frag_more (sizeof (e_note.type));
dbe2df79 2206 md_number_to_chars (p, i_note.type, sizeof (e_note.type));
6afdfa61 2207 p = frag_more (len);
5ab504f9 2208 memcpy (p, name, len);
252b5132 2209
252b5132
RH
2210 frag_align (2, 0, 0);
2211
2212 subseg_set (seg, subseg);
2213 }
2214 else
6afdfa61
NC
2215 as_bad (_("expected quoted string"));
2216
252b5132
RH
2217 demand_empty_rest_of_line ();
2218}
2219
2220static void
dbe2df79 2221obj_elf_size (int ignore ATTRIBUTE_UNUSED)
252b5132 2222{
d02603dc
NC
2223 char *name;
2224 char c = get_symbol_name (&name);
252b5132
RH
2225 char *p;
2226 expressionS exp;
2227 symbolS *sym;
2228
2229 p = input_line_pointer;
2230 *p = c;
d02603dc 2231 SKIP_WHITESPACE_AFTER_NAME ();
252b5132
RH
2232 if (*input_line_pointer != ',')
2233 {
2234 *p = 0;
2235 as_bad (_("expected comma after name `%s' in .size directive"), name);
2236 *p = c;
2237 ignore_rest_of_line ();
2238 return;
2239 }
2240 input_line_pointer++;
2241 expression (&exp);
2242 if (exp.X_op == O_absent)
2243 {
2244 as_bad (_("missing expression in .size directive"));
2245 exp.X_op = O_constant;
2246 exp.X_add_number = 0;
2247 }
2248 *p = 0;
2249 sym = symbol_find_or_make (name);
2250 *p = c;
2251 if (exp.X_op == O_constant)
c538998c
JJ
2252 {
2253 S_SET_SIZE (sym, exp.X_add_number);
9fbb53c7
AM
2254 xfree (symbol_get_obj (sym)->size);
2255 symbol_get_obj (sym)->size = NULL;
c538998c 2256 }
252b5132
RH
2257 else
2258 {
325801bd 2259 symbol_get_obj (sym)->size = XNEW (expressionS);
49309057 2260 *symbol_get_obj (sym)->size = exp;
252b5132
RH
2261 }
2262 demand_empty_rest_of_line ();
2263}
2264
2265/* Handle the ELF .type pseudo-op. This sets the type of a symbol.
44bf2362 2266 There are six syntaxes:
fa306131 2267
252b5132
RH
2268 The first (used on Solaris) is
2269 .type SYM,#function
2270 The second (used on UnixWare) is
2271 .type SYM,@function
2272 The third (reportedly to be used on Irix 6.0) is
2273 .type SYM STT_FUNC
2274 The fourth (used on NetBSD/Arm and Linux/ARM) is
2275 .type SYM,%function
aa8c34c3
JE
2276 The fifth (used on SVR4/860) is
2277 .type SYM,"function"
44bf2362
NC
2278 The sixth (emitted by recent SunPRO under Solaris) is
2279 .type SYM,[0-9]
2280 where the integer is the STT_* value.
252b5132
RH
2281 */
2282
44bf2362
NC
2283static char *
2284obj_elf_type_name (char *cp)
2285{
2286 char *p;
2287
2288 p = input_line_pointer;
2289 if (*input_line_pointer >= '0'
2290 && *input_line_pointer <= '9')
2291 {
2292 while (*input_line_pointer >= '0'
2293 && *input_line_pointer <= '9')
2294 ++input_line_pointer;
2295 *cp = *input_line_pointer;
2296 *input_line_pointer = '\0';
2297 }
2298 else
d02603dc 2299 *cp = get_symbol_name (&p);
44bf2362
NC
2300
2301 return p;
2302}
2303
252b5132 2304static void
dbe2df79 2305obj_elf_type (int ignore ATTRIBUTE_UNUSED)
252b5132 2306{
252b5132
RH
2307 char c;
2308 int type;
1e9cc1c2 2309 const char *type_name;
252b5132 2310 symbolS *sym;
904a31bf 2311 elf_symbol_type *elfsym;
252b5132 2312
6e8bd58f
NS
2313 sym = get_sym_from_input_line_and_check ();
2314 c = *input_line_pointer;
904a31bf 2315 elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
252b5132 2316
252b5132
RH
2317 if (*input_line_pointer == ',')
2318 ++input_line_pointer;
2319
2320 SKIP_WHITESPACE ();
2321 if ( *input_line_pointer == '#'
2322 || *input_line_pointer == '@'
aa8c34c3 2323 || *input_line_pointer == '"'
252b5132
RH
2324 || *input_line_pointer == '%')
2325 ++input_line_pointer;
2326
1e9cc1c2 2327 type_name = obj_elf_type_name (& c);
252b5132
RH
2328
2329 type = 0;
1e9cc1c2
NC
2330 if (strcmp (type_name, "function") == 0
2331 || strcmp (type_name, "2") == 0
2332 || strcmp (type_name, "STT_FUNC") == 0)
252b5132 2333 type = BSF_FUNCTION;
1e9cc1c2
NC
2334 else if (strcmp (type_name, "object") == 0
2335 || strcmp (type_name, "1") == 0
2336 || strcmp (type_name, "STT_OBJECT") == 0)
252b5132 2337 type = BSF_OBJECT;
1e9cc1c2
NC
2338 else if (strcmp (type_name, "tls_object") == 0
2339 || strcmp (type_name, "6") == 0
2340 || strcmp (type_name, "STT_TLS") == 0)
b9734f35 2341 type = BSF_OBJECT | BSF_THREAD_LOCAL;
1e9cc1c2
NC
2342 else if (strcmp (type_name, "notype") == 0
2343 || strcmp (type_name, "0") == 0
2344 || strcmp (type_name, "STT_NOTYPE") == 0)
e7b9a8c1 2345 ;
1e9cc1c2
NC
2346 else if (strcmp (type_name, "common") == 0
2347 || strcmp (type_name, "5") == 0
2348 || strcmp (type_name, "STT_COMMON") == 0)
504b7d20
NC
2349 {
2350 type = BSF_OBJECT;
2351
2352 if (! S_IS_COMMON (sym))
2353 {
2354 if (S_IS_VOLATILE (sym))
2355 {
2356 sym = symbol_clone (sym, 1);
2357 S_SET_SEGMENT (sym, bfd_com_section_ptr);
2358 S_SET_VALUE (sym, 0);
2359 S_SET_EXTERNAL (sym);
2360 symbol_set_frag (sym, &zero_address_frag);
2361 S_CLEAR_VOLATILE (sym);
2362 }
2363 else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
2364 as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
2365 else
2366 {
2367 /* FIXME: Is it safe to just change the section ? */
2368 S_SET_SEGMENT (sym, bfd_com_section_ptr);
2369 S_SET_VALUE (sym, 0);
2370 S_SET_EXTERNAL (sym);
2371 }
2372 }
2373 }
1e9cc1c2
NC
2374 else if (strcmp (type_name, "gnu_indirect_function") == 0
2375 || strcmp (type_name, "10") == 0
2376 || strcmp (type_name, "STT_GNU_IFUNC") == 0)
d8045f23 2377 {
c410035d 2378 const struct elf_backend_data *bed;
df3a023b 2379
c410035d
AM
2380 bed = get_elf_backend_data (stdoutput);
2381 if (bed->elf_osabi != ELFOSABI_NONE
2382 && bed->elf_osabi != ELFOSABI_GNU
2383 && bed->elf_osabi != ELFOSABI_FREEBSD)
df3a023b
AM
2384 as_bad (_("symbol type \"%s\" is supported only by GNU "
2385 "and FreeBSD targets"), type_name);
8e4979ac
NC
2386 /* MIPS targets do not support IFUNCS. */
2387 else if (bed->target_id == MIPS_ELF_DATA)
2388 as_bad (_("symbol type \"%s\" is not supported by "
2389 "MIPS targets"), type_name);
cc364be6 2390 elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
d8045f23
NC
2391 type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
2392 }
1e9cc1c2 2393 else if (strcmp (type_name, "gnu_unique_object") == 0)
3e7a7d11 2394 {
c410035d 2395 const struct elf_backend_data *bed;
3e7a7d11 2396
c410035d
AM
2397 bed = get_elf_backend_data (stdoutput);
2398 if (bed->elf_osabi != ELFOSABI_NONE
2399 && bed->elf_osabi != ELFOSABI_GNU)
3e7a7d11 2400 as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
1e9cc1c2 2401 type_name);
cc364be6 2402 elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_unique;
3e7a7d11
NC
2403 type = BSF_OBJECT | BSF_GNU_UNIQUE;
2404 }
904a31bf 2405#ifdef md_elf_symbol_type
1e9cc1c2 2406 else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
904a31bf
AM
2407 ;
2408#endif
252b5132 2409 else
1e9cc1c2 2410 as_bad (_("unrecognized symbol type \"%s\""), type_name);
252b5132
RH
2411
2412 *input_line_pointer = c;
2413
aa8c34c3
JE
2414 if (*input_line_pointer == '"')
2415 ++input_line_pointer;
2416
f2d4ba38
JB
2417#ifdef md_elf_symbol_type_change
2418 if (!md_elf_symbol_type_change (sym, elfsym, type))
2419#endif
2420 {
2421 flagword mask = BSF_FUNCTION | BSF_OBJECT;
2422
2423 if (type != BSF_FUNCTION)
2424 mask |= BSF_GNU_INDIRECT_FUNCTION;
2425 if (type != BSF_OBJECT)
2426 {
2427 mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
2428
2429 if (S_IS_COMMON (sym))
2430 {
2431 as_bad (_("cannot change type of common symbol '%s'"),
2432 S_GET_NAME (sym));
2433 mask = type = 0;
2434 }
2435 }
2436
2437 /* Don't warn when changing to STT_NOTYPE. */
2438 if (type)
2439 {
2440 flagword new = (elfsym->symbol.flags & ~mask) | type;
2441
2442 if (new != (elfsym->symbol.flags | type))
2443 as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
2444 elfsym->symbol.flags = new;
2445 }
2446 else
2447 elfsym->symbol.flags &= ~mask;
2448 }
252b5132
RH
2449
2450 demand_empty_rest_of_line ();
2451}
2452
2ccd2276
AM
2453static segT comment_section;
2454
252b5132 2455static void
dbe2df79 2456obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
252b5132 2457{
252b5132
RH
2458 segT old_section = now_seg;
2459 int old_subsection = now_subseg;
2460
5f91fe03
ILT
2461#ifdef md_flush_pending_output
2462 md_flush_pending_output ();
2463#endif
2464
252b5132
RH
2465 if (!comment_section)
2466 {
2467 char *p;
2468 comment_section = subseg_new (".comment", 0);
fd361982
AM
2469 bfd_set_section_flags (comment_section, (SEC_READONLY | SEC_HAS_CONTENTS
2470 | SEC_MERGE | SEC_STRINGS));
01fb1836 2471 comment_section->entsize = 1;
cd000bff
DJ
2472#ifdef md_elf_section_change_hook
2473 md_elf_section_change_hook ();
2474#endif
252b5132
RH
2475 p = frag_more (1);
2476 *p = 0;
2477 }
2478 else
2479 subseg_set (comment_section, 0);
38a57ae7 2480 stringer (8 + 1);
252b5132
RH
2481 subseg_set (old_section, old_subsection);
2482}
2483
2484#ifdef INIT_STAB_SECTION
2485
2486/* The first entry in a .stabs section is special. */
2487
2488void
dbe2df79 2489obj_elf_init_stab_section (segT seg)
252b5132 2490{
82cb2524 2491 char *file;
252b5132
RH
2492 char *p;
2493 char *stabstr_name;
2494 unsigned int stroff;
2495
2496 /* Force the section to align to a longword boundary. Without this,
2497 UnixWare ar crashes. */
fd361982 2498 bfd_set_section_alignment (seg, 2);
252b5132 2499
bf514e21 2500 /* Make space for this first symbol. */
252b5132 2501 p = frag_more (12);
bf514e21 2502 /* Zero it out. */
252b5132 2503 memset (p, 0, 12);
05412017 2504 file = remap_debug_filename (as_where (NULL));
29a2809e 2505 stabstr_name = concat (segment_name (seg), "str", (char *) NULL);
5b7c81bd 2506 stroff = get_stab_string_offset (file, stabstr_name, true);
91952a06 2507 know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
252b5132
RH
2508 md_number_to_chars (p, stroff, 4);
2509 seg_info (seg)->stabu.p = p;
82cb2524 2510 free (file);
252b5132
RH
2511}
2512
2513#endif
2514
2515/* Fill in the counts in the first entry in a .stabs section. */
2516
2517static void
dbe2df79 2518adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
252b5132
RH
2519{
2520 char *name;
2521 asection *strsec;
2522 char *p;
2523 int strsz, nsyms;
2524
d34049e8 2525 if (!startswith (sec->name, ".stab"))
252b5132
RH
2526 return;
2527 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
2528 return;
2529
e1fa0163 2530 name = concat (sec->name, "str", NULL);
252b5132
RH
2531 strsec = bfd_get_section_by_name (abfd, name);
2532 if (strsec)
fd361982 2533 strsz = bfd_section_size (strsec);
252b5132
RH
2534 else
2535 strsz = 0;
fd361982 2536 nsyms = bfd_section_size (sec) / 12 - 1;
252b5132
RH
2537
2538 p = seg_info (sec)->stabu.p;
9c2799c2 2539 gas_assert (p != 0);
252b5132 2540
dbe2df79
AM
2541 bfd_h_put_16 (abfd, nsyms, p + 6);
2542 bfd_h_put_32 (abfd, strsz, p + 8);
e1fa0163 2543 free (name);
252b5132
RH
2544}
2545
2546#ifdef NEED_ECOFF_DEBUG
2547
2548/* This function is called by the ECOFF code. It is supposed to
2549 record the external symbol information so that the backend can
2550 write it out correctly. The ELF backend doesn't actually handle
2551 this at the moment, so we do it ourselves. We save the information
2552 in the symbol. */
2553
ae4a729b
AM
2554#ifdef OBJ_MAYBE_ELF
2555static
2556#endif
252b5132 2557void
dbe2df79 2558elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
252b5132 2559{
dbe2df79 2560 symbol_get_bfdsym (sym)->udata.p = ext;
252b5132
RH
2561}
2562
2563/* This function is called by bfd_ecoff_debug_externals. It is
2564 supposed to *EXT to the external symbol information, and return
2565 whether the symbol should be used at all. */
2566
5b7c81bd 2567static bool
dbe2df79 2568elf_get_extr (asymbol *sym, EXTR *ext)
252b5132
RH
2569{
2570 if (sym->udata.p == NULL)
5b7c81bd 2571 return false;
252b5132 2572 *ext = *(EXTR *) sym->udata.p;
5b7c81bd 2573 return true;
252b5132
RH
2574}
2575
2576/* This function is called by bfd_ecoff_debug_externals. It has
2577 nothing to do for ELF. */
2578
252b5132 2579static void
dbe2df79
AM
2580elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
2581 bfd_size_type indx ATTRIBUTE_UNUSED)
252b5132
RH
2582{
2583}
2584
2585#endif /* NEED_ECOFF_DEBUG */
2586
2587void
dbe2df79 2588elf_frob_symbol (symbolS *symp, int *puntp)
252b5132 2589{
49309057 2590 struct elf_obj_sy *sy_obj;
49002d7f 2591 expressionS *size;
6914be53 2592 struct elf_versioned_name_list *versioned_name;
49309057 2593
252b5132
RH
2594#ifdef NEED_ECOFF_DEBUG
2595 if (ECOFF_DEBUGGING)
2596 ecoff_frob_symbol (symp);
2597#endif
2598
49309057
ILT
2599 sy_obj = symbol_get_obj (symp);
2600
49002d7f
L
2601 size = sy_obj->size;
2602 if (size != NULL)
252b5132 2603 {
49002d7f
L
2604 if (resolve_expression (size)
2605 && size->X_op == O_constant)
2606 S_SET_SIZE (symp, size->X_add_number);
e1e90034 2607 else
49002d7f 2608 {
a90fb5e3 2609 if (!flag_allow_nonconst_size)
869fe6ea
AM
2610 as_bad (_(".size expression for %s "
2611 "does not evaluate to a constant"), S_GET_NAME (symp));
21be61f5 2612 else
869fe6ea
AM
2613 as_warn (_(".size expression for %s "
2614 "does not evaluate to a constant"), S_GET_NAME (symp));
49002d7f 2615 }
49309057
ILT
2616 free (sy_obj->size);
2617 sy_obj->size = NULL;
252b5132
RH
2618 }
2619
6914be53
L
2620 versioned_name = sy_obj->versioned_name;
2621 if (versioned_name)
252b5132
RH
2622 {
2623 /* This symbol was given a new name with the .symver directive.
13c56984
AM
2624 If this is an external reference, just rename the symbol to
2625 include the version string. This will make the relocs be
6914be53 2626 against the correct versioned symbol. */
252b5132 2627
6914be53
L
2628 /* We will have already reported an version error. */
2629 if (sy_obj->bad_version)
5b7c81bd 2630 *puntp = true;
6914be53
L
2631 /* elf_frob_file_before_adjust only allows one version symbol for
2632 renamed symbol. */
2633 else if (sy_obj->rename)
2634 S_SET_NAME (symp, versioned_name->name);
2635 else if (S_IS_COMMON (symp))
252b5132 2636 {
6914be53
L
2637 as_bad (_("`%s' can't be versioned to common symbol '%s'"),
2638 versioned_name->name, S_GET_NAME (symp));
5b7c81bd 2639 *puntp = true;
252b5132
RH
2640 }
2641 else
2642 {
6914be53
L
2643 asymbol *bfdsym;
2644 elf_symbol_type *elfsym;
2645
2646 /* This is a definition. Add an alias for each version.
2647 FIXME: Using an alias will permit the debugging information
2648 to refer to the right symbol. However, it's not clear
2649 whether it is the best approach. */
2650
2651 /* FIXME: Creating a new symbol here is risky. We're
2652 in the final loop over the symbol table. We can
2653 get away with it only because the symbol goes to
2654 the end of the list, where the loop will still see
2655 it. It would probably be better to do this in
2656 obj_frob_file_before_adjust. */
2657 for (; versioned_name != NULL;
2658 versioned_name = versioned_name->next)
79082ff0 2659 {
6914be53 2660 symbolS *symp2 = symbol_find_or_make (versioned_name->name);
252b5132 2661
79082ff0 2662 S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
252b5132 2663
79082ff0
L
2664 /* Subtracting out the frag address here is a hack
2665 because we are in the middle of the final loop. */
2666 S_SET_VALUE (symp2,
2667 (S_GET_VALUE (symp)
05862db7
CE
2668 - (symbol_get_frag (symp)->fr_address
2669 / OCTETS_PER_BYTE)));
252b5132 2670
79082ff0 2671 symbol_set_frag (symp2, symbol_get_frag (symp));
252b5132 2672
79082ff0
L
2673 /* This will copy over the size information. */
2674 copy_symbol_attributes (symp2, symp);
252b5132 2675
26eb4093
JJ
2676 S_SET_OTHER (symp2, S_GET_OTHER (symp));
2677
79082ff0
L
2678 if (S_IS_WEAK (symp))
2679 S_SET_WEAK (symp2);
252b5132 2680
79082ff0
L
2681 if (S_IS_EXTERNAL (symp))
2682 S_SET_EXTERNAL (symp2);
2683 }
6914be53 2684
eb09df16 2685 switch (sy_obj->visibility)
6914be53
L
2686 {
2687 case visibility_unchanged:
2688 break;
2689 case visibility_hidden:
2690 bfdsym = symbol_get_bfdsym (symp);
c1229f84 2691 elfsym = elf_symbol_from (bfdsym);
6914be53
L
2692 elfsym->internal_elf_sym.st_other &= ~3;
2693 elfsym->internal_elf_sym.st_other |= STV_HIDDEN;
2694 break;
2695 case visibility_remove:
eb09df16
L
2696 /* Don't remove the symbol if it is used in relocation.
2697 Instead, mark it as to be removed and issue an error
2698 if the symbol has more than one versioned name. */
2699 if (symbol_used_in_reloc_p (symp))
2700 {
2701 if (sy_obj->versioned_name->next != NULL)
2702 as_bad (_("symbol '%s' with multiple versions cannot be used in relocation"),
2703 S_GET_NAME (symp));
2704 symbol_mark_removed (symp);
2705 }
2706 else
2707 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
6914be53
L
2708 break;
2709 case visibility_local:
2710 S_CLEAR_EXTERNAL (symp);
2711 break;
2712 }
252b5132
RH
2713 }
2714 }
2715
2716 /* Double check weak symbols. */
49309057 2717 if (S_IS_WEAK (symp))
252b5132
RH
2718 {
2719 if (S_IS_COMMON (symp))
6ce8b369 2720 as_bad (_("symbol `%s' can not be both weak and common"),
252b5132
RH
2721 S_GET_NAME (symp));
2722 }
252b5132
RH
2723}
2724
eb09df16
L
2725/* Fix up SYMPP which has been marked to be removed by .symver. */
2726
2727void
2728elf_fixup_removed_symbol (symbolS **sympp)
2729{
2730 symbolS *symp = *sympp;
2731 struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2732
2733 /* Replace the removed symbol with the versioned symbol. */
2734 symp = symbol_find (sy_obj->versioned_name->name);
2735 *sympp = symp;
2736}
2737
060adf0e
AM
2738struct group_list
2739{
2740 asection **head; /* Section lists. */
060adf0e 2741 unsigned int num_group; /* Number of lists. */
629310ab 2742 htab_t indexes; /* Maps group name to index in head array. */
060adf0e
AM
2743};
2744
db4677b8
AM
2745static struct group_list groups;
2746
060adf0e
AM
2747/* Called via bfd_map_over_sections. If SEC is a member of a group,
2748 add it to a list of sections belonging to the group. INF is a
2749 pointer to a struct group_list, which is where we store the head of
b7d07216
L
2750 each list. If its link_to_symbol_name isn't NULL, set up its
2751 linked-to section. */
060adf0e
AM
2752
2753static void
b7d07216
L
2754build_additional_section_info (bfd *abfd ATTRIBUTE_UNUSED,
2755 asection *sec, void *inf)
060adf0e 2756{
1e9cc1c2 2757 struct group_list *list = (struct group_list *) inf;
aa1f4858 2758 const char *group_name = elf_group_name (sec);
060adf0e 2759 unsigned int i;
1e9cc1c2
NC
2760 unsigned int *elem_idx;
2761 unsigned int *idx_ptr;
060adf0e 2762
b7d07216
L
2763 if (sec->map_head.linked_to_symbol_name)
2764 {
2765 symbolS *linked_to_sym;
2766 linked_to_sym = symbol_find (sec->map_head.linked_to_symbol_name);
2767 if (!linked_to_sym || !S_IS_DEFINED (linked_to_sym))
2768 as_bad (_("undefined linked-to symbol `%s' on section `%s'"),
2769 sec->map_head.linked_to_symbol_name,
2770 bfd_section_name (sec));
2771 else
2772 elf_linked_to_section (sec) = S_GET_SEGMENT (linked_to_sym);
2773 }
2774
060adf0e
AM
2775 if (group_name == NULL)
2776 return;
2777
2778 /* If this group already has a list, add the section to the head of
2779 the list. */
629310ab 2780 elem_idx = (unsigned int *) str_hash_find (list->indexes, group_name);
1e9cc1c2 2781 if (elem_idx != NULL)
060adf0e 2782 {
1e9cc1c2
NC
2783 elf_next_in_group (sec) = list->head[*elem_idx];
2784 list->head[*elem_idx] = sec;
1e9cc1c2 2785 return;
060adf0e
AM
2786 }
2787
2788 /* New group. Make the arrays bigger in chunks to minimize calls to
2789 realloc. */
2790 i = list->num_group;
2791 if ((i & 127) == 0)
2792 {
2793 unsigned int newsize = i + 128;
add39d23 2794 list->head = XRESIZEVEC (asection *, list->head, newsize);
060adf0e
AM
2795 }
2796 list->head[i] = sec;
060adf0e 2797 list->num_group += 1;
1e9cc1c2
NC
2798
2799 /* Add index to hash. */
325801bd 2800 idx_ptr = XNEW (unsigned int);
1e9cc1c2 2801 *idx_ptr = i;
fe0e921f 2802 str_hash_insert (list->indexes, group_name, idx_ptr, 0);
1e9cc1c2
NC
2803}
2804
2ccd2276
AM
2805static void
2806free_section_idx (void *ent)
1e9cc1c2 2807{
2ccd2276
AM
2808 string_tuple_t *tuple = ent;
2809 free ((char *) tuple->value);
060adf0e
AM
2810}
2811
db4677b8
AM
2812/* Create symbols for group signature. */
2813
252b5132 2814void
709001e9 2815elf_adjust_symtab (void)
252b5132 2816{
060adf0e
AM
2817 unsigned int i;
2818
060adf0e 2819 /* Go find section groups. */
db4677b8
AM
2820 groups.num_group = 0;
2821 groups.head = NULL;
2ccd2276
AM
2822 groups.indexes = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
2823 free_section_idx, notes_calloc, NULL);
b7d07216
L
2824 bfd_map_over_sections (stdoutput, build_additional_section_info,
2825 &groups);
3739860c 2826
060adf0e
AM
2827 /* Make the SHT_GROUP sections that describe each section group. We
2828 can't set up the section contents here yet, because elf section
2829 indices have yet to be calculated. elf.c:set_group_contents does
2830 the rest of the work. */
db4677b8 2831 for (i = 0; i < groups.num_group; i++)
060adf0e 2832 {
db4677b8 2833 const char *group_name = elf_group_name (groups.head[i]);
9758f3fc 2834 const char *sec_name;
060adf0e
AM
2835 asection *s;
2836 flagword flags;
9758f3fc 2837 struct symbol *sy;
060adf0e 2838
060adf0e 2839 flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
db4677b8 2840 for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s))
68bfbfcc 2841 if ((s->flags ^ flags) & SEC_LINK_ONCE)
d2dab548
AM
2842 {
2843 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
db4677b8 2844 if (s != groups.head[i])
d2dab548
AM
2845 {
2846 as_warn (_("assuming all members of group `%s' are COMDAT"),
2847 group_name);
2848 break;
2849 }
2850 }
2851
709001e9 2852 sec_name = ".group";
9758f3fc 2853 s = subseg_force_new (sec_name, 0);
060adf0e 2854 if (s == NULL
fd361982
AM
2855 || !bfd_set_section_flags (s, flags)
2856 || !bfd_set_section_alignment (s, 2))
060adf0e
AM
2857 {
2858 as_fatal (_("can't create group: %s"),
2859 bfd_errmsg (bfd_get_error ()));
2860 }
2f89ff8d 2861 elf_section_type (s) = SHT_GROUP;
060adf0e 2862
aa1f4858 2863 /* Pass a pointer to the first section in this group. */
db4677b8
AM
2864 elf_next_in_group (s) = groups.head[i];
2865 elf_sec_group (groups.head[i]) = s;
709001e9
MM
2866 /* Make sure that the signature symbol for the group has the
2867 name of the group. */
2868 sy = symbol_find_exact (group_name);
8d1015a8 2869 if (!sy || !symbol_on_chain (sy, symbol_rootP, symbol_lastP))
709001e9
MM
2870 {
2871 /* Create the symbol now. */
e01e1cee 2872 sy = symbol_new (group_name, now_seg, frag_now, 0);
69b70cfe
RO
2873#ifdef TE_SOLARIS
2874 /* Before Solaris 11 build 154, Sun ld rejects local group
2875 signature symbols, so make them weak hidden instead. */
2876 symbol_get_bfdsym (sy)->flags |= BSF_WEAK;
2877 S_SET_OTHER (sy, STV_HIDDEN);
2878#else
709001e9 2879 symbol_get_obj (sy)->local = 1;
69b70cfe 2880#endif
709001e9
MM
2881 symbol_table_insert (sy);
2882 }
2883 elf_group_id (s) = symbol_get_bfdsym (sy);
d1bcae83
L
2884 /* Mark the group signature symbol as used so that it will be
2885 included in the symbol table. */
2886 symbol_mark_used_in_reloc (sy);
060adf0e 2887 }
252b5132
RH
2888}
2889
709001e9
MM
2890void
2891elf_frob_file (void)
2892{
2893 bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
2894
2895#ifdef elf_tc_final_processing
2896 elf_tc_final_processing ();
2897#endif
2898}
2899
4a1805b1 2900/* It removes any unneeded versioned symbols from the symbol table. */
339681c0
L
2901
2902void
dbe2df79 2903elf_frob_file_before_adjust (void)
339681c0
L
2904{
2905 if (symbol_rootP)
2906 {
2907 symbolS *symp;
2908
2909 for (symp = symbol_rootP; symp; symp = symbol_next (symp))
6914be53
L
2910 {
2911 struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2912 int is_defined = !!S_IS_DEFINED (symp);
00e6e13d 2913
6914be53
L
2914 if (sy_obj->versioned_name)
2915 {
2916 char *p = strchr (sy_obj->versioned_name->name,
2917 ELF_VER_CHR);
00e6e13d 2918
6914be53
L
2919 if (sy_obj->rename)
2920 {
2921 /* The @@@ syntax is a special case. If the symbol is
2922 not defined, 2 `@'s will be removed from the
2923 versioned_name. Otherwise, 1 `@' will be removed. */
2924 size_t l = strlen (&p[3]) + 1;
2925 memmove (&p[1 + is_defined], &p[3], l);
2926 }
2927
2928 if (!is_defined)
2929 {
2930 /* Verify that the name isn't using the @@ syntax--this
2931 is reserved for definitions of the default version
2932 to link against. */
2933 if (!sy_obj->rename && p[1] == ELF_VER_CHR)
2934 {
2935 as_bad (_("invalid attempt to declare external "
2936 "version name as default in symbol `%s'"),
2937 sy_obj->versioned_name->name);
2938 return;
2939 }
2940
2941 /* Only one version symbol is allowed for undefined
2942 symbol. */
2943 if (sy_obj->versioned_name->next)
2944 {
2945 as_bad (_("multiple versions [`%s'|`%s'] for "
2946 "symbol `%s'"),
2947 sy_obj->versioned_name->name,
2948 sy_obj->versioned_name->next->name,
2949 S_GET_NAME (symp));
2950 return;
2951 }
2952
5b7c81bd 2953 sy_obj->rename = true;
6914be53
L
2954 }
2955 }
2956
2957 /* If there was .symver or .weak, but symbol was neither
2958 defined nor used anywhere, remove it. */
2959 if (!is_defined
2960 && (sy_obj->versioned_name || S_IS_WEAK (symp))
2961 && symbol_used_p (symp) == 0
2962 && symbol_used_in_reloc_p (symp) == 0)
2963 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
2964 }
339681c0
L
2965 }
2966}
2967
252b5132
RH
2968/* It is required that we let write_relocs have the opportunity to
2969 optimize away fixups before output has begun, since it is possible
2970 to eliminate all fixups for a section and thus we never should
2971 have generated the relocation section. */
2972
2973void
dbe2df79 2974elf_frob_file_after_relocs (void)
252b5132 2975{
db4677b8
AM
2976 unsigned int i;
2977
2978 /* Set SHT_GROUP section size. */
2979 for (i = 0; i < groups.num_group; i++)
2980 {
2981 asection *s, *head, *group;
2982 bfd_size_type size;
2983
2984 head = groups.head[i];
2985 size = 4;
2986 for (s = head; s != NULL; s = elf_next_in_group (s))
2987 size += (s->flags & SEC_RELOC) != 0 ? 8 : 4;
2988
2989 group = elf_sec_group (head);
2990 subseg_set (group, 0);
fd361982 2991 bfd_set_section_size (group, size);
db4677b8
AM
2992 group->contents = (unsigned char *) frag_more (size);
2993 frag_now->fr_fix = frag_now_fix_octets ();
2994 frag_wane (frag_now);
2995 }
2996
252b5132
RH
2997#ifdef NEED_ECOFF_DEBUG
2998 if (ECOFF_DEBUGGING)
2999 /* Generate the ECOFF debugging information. */
3000 {
3001 const struct ecoff_debug_swap *debug_swap;
3002 struct ecoff_debug_info debug;
3003 char *buf;
3004 asection *sec;
3005
3006 debug_swap
3007 = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
dbe2df79 3008 know (debug_swap != NULL);
252b5132
RH
3009 ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
3010
3011 /* Set up the pointers in debug. */
ce3ab55f 3012 debug.alloc_syments = true;
252b5132
RH
3013#define SET(ptr, offset, type) \
3014 debug.ptr = (type) (buf + debug.symbolic_header.offset)
3015
3016 SET (line, cbLineOffset, unsigned char *);
dbe2df79
AM
3017 SET (external_dnr, cbDnOffset, void *);
3018 SET (external_pdr, cbPdOffset, void *);
3019 SET (external_sym, cbSymOffset, void *);
3020 SET (external_opt, cbOptOffset, void *);
252b5132
RH
3021 SET (external_aux, cbAuxOffset, union aux_ext *);
3022 SET (ss, cbSsOffset, char *);
dbe2df79
AM
3023 SET (external_fdr, cbFdOffset, void *);
3024 SET (external_rfd, cbRfdOffset, void *);
252b5132
RH
3025 /* ssext and external_ext are set up just below. */
3026
3027#undef SET
3028
3029 /* Set up the external symbols. */
3030 debug.ssext = debug.ssext_end = NULL;
3031 debug.external_ext = debug.external_ext_end = NULL;
5b7c81bd 3032 if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
252b5132 3033 elf_get_extr, elf_set_index))
6ce8b369 3034 as_fatal (_("failed to set up debugging information: %s"),
252b5132
RH
3035 bfd_errmsg (bfd_get_error ()));
3036
3037 sec = bfd_get_section_by_name (stdoutput, ".mdebug");
9c2799c2 3038 gas_assert (sec != NULL);
252b5132 3039
b34976b6 3040 know (!stdoutput->output_has_begun);
252b5132
RH
3041
3042 /* We set the size of the section, call bfd_set_section_contents
3043 to force the ELF backend to allocate a file position, and then
3044 write out the data. FIXME: Is this really the best way to do
3045 this? */
fd361982
AM
3046 bfd_set_section_size (sec, bfd_ecoff_debug_size (stdoutput, &debug,
3047 debug_swap));
252b5132 3048
5f91fe03 3049 /* Pass BUF to bfd_set_section_contents because this will
13c56984
AM
3050 eventually become a call to fwrite, and ISO C prohibits
3051 passing a NULL pointer to a stdio function even if the
3052 pointer will not be used. */
dbe2df79 3053 if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
6ce8b369 3054 as_fatal (_("can't start writing .mdebug section: %s"),
252b5132
RH
3055 bfd_errmsg (bfd_get_error ()));
3056
b34976b6 3057 know (stdoutput->output_has_begun);
252b5132
RH
3058 know (sec->filepos != 0);
3059
3060 if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
3061 sec->filepos))
6ce8b369 3062 as_fatal (_("could not write .mdebug section: %s"),
252b5132
RH
3063 bfd_errmsg (bfd_get_error ()));
3064 }
3065#endif /* NEED_ECOFF_DEBUG */
3066}
3067
bc6b4acc
RO
3068static void
3069elf_generate_asm_lineno (void)
3070{
3071#ifdef NEED_ECOFF_DEBUG
3072 if (ECOFF_DEBUGGING)
3073 ecoff_generate_asm_lineno ();
3074#endif
3075}
3076
3077static void
bd937d21
L
3078elf_process_stab (segT sec ATTRIBUTE_UNUSED,
3079 int what ATTRIBUTE_UNUSED,
3080 const char *string ATTRIBUTE_UNUSED,
3081 int type ATTRIBUTE_UNUSED,
3082 int other ATTRIBUTE_UNUSED,
3083 int desc ATTRIBUTE_UNUSED)
bc6b4acc
RO
3084{
3085#ifdef NEED_ECOFF_DEBUG
3086 if (ECOFF_DEBUGGING)
3087 ecoff_stab (sec, what, string, type, other, desc);
3088#endif
3089}
3090
5110c57e 3091static int
dbe2df79 3092elf_separate_stab_sections (void)
5110c57e
HPN
3093{
3094#ifdef NEED_ECOFF_DEBUG
3095 return (!ECOFF_DEBUGGING);
3096#else
3097 return 1;
3098#endif
3099}
3100
3101static void
dbe2df79 3102elf_init_stab_section (segT seg)
5110c57e
HPN
3103{
3104#ifdef NEED_ECOFF_DEBUG
3105 if (!ECOFF_DEBUGGING)
3106#endif
3107 obj_elf_init_stab_section (seg);
3108}
3109
2ccd2276
AM
3110/* This is called when the assembler starts. */
3111
3112void
3113elf_begin (void)
3114{
3115 asection *s;
3116
3117 /* Add symbols for the known sections to the symbol table. */
3118 s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
3119 symbol_table_insert (section_symbol (s));
3120 s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
3121 symbol_table_insert (section_symbol (s));
3122 s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
3123 symbol_table_insert (section_symbol (s));
3124 elf_com_section_ptr = bfd_com_section_ptr;
3125 previous_section = NULL;
3126 previous_subsection = 0;
3127 comment_section = NULL;
3128 memset (&groups, 0, sizeof (groups));
3129}
3130
3131void
3132elf_end (void)
3133{
3134 while (section_stack)
3135 {
3136 struct section_stack *top = section_stack;
3137 section_stack = top->next;
3138 free (top);
3139 }
3140 while (recorded_attributes)
3141 {
3142 struct recorded_attribute_info *rai = recorded_attributes;
3143 recorded_attributes = rai->next;
3144 free (rai);
3145 }
3146 if (groups.indexes)
3147 {
3148 htab_delete (groups.indexes);
3149 free (groups.head);
3150 }
3151}
3152
252b5132
RH
3153const struct format_ops elf_format_ops =
3154{
3155 bfd_target_elf_flavour,
4c63da97
AM
3156 0, /* dfl_leading_underscore */
3157 1, /* emit_section_symbols */
5110c57e 3158 elf_begin,
2ccd2276 3159 elf_end,
5110c57e 3160 elf_file_symbol,
252b5132
RH
3161 elf_frob_symbol,
3162 elf_frob_file,
339681c0 3163 elf_frob_file_before_adjust,
a161fe53 3164 0, /* obj_frob_file_before_fix */
252b5132
RH
3165 elf_frob_file_after_relocs,
3166 elf_s_get_size, elf_s_set_size,
3167 elf_s_get_align, elf_s_set_align,
4c63da97 3168 elf_s_get_other,
5110c57e 3169 elf_s_set_other,
4c63da97 3170 0, /* s_get_desc */
5110c57e
HPN
3171 0, /* s_set_desc */
3172 0, /* s_get_type */
3173 0, /* s_set_type */
252b5132 3174 elf_copy_symbol_attributes,
bc6b4acc
RO
3175 elf_generate_asm_lineno,
3176 elf_process_stab,
5110c57e
HPN
3177 elf_separate_stab_sections,
3178 elf_init_stab_section,
252b5132
RH
3179 elf_sec_sym_ok_for_reloc,
3180 elf_pop_insert,
3181#ifdef NEED_ECOFF_DEBUG
3182 elf_ecoff_set_ext,
3183#else
4c63da97 3184 0, /* ecoff_set_ext */
252b5132 3185#endif
4c63da97 3186 elf_obj_read_begin_hook,
4cae74aa 3187 elf_obj_symbol_new_hook,
7bed8466 3188 elf_obj_symbol_clone_hook,
645ea3ea 3189 elf_adjust_symtab
252b5132 3190};