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