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