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