]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/obj-elf.c
2004-09-08 Andrew Cagney <cagney@gnu.org>
[thirdparty/binutils-gdb.git] / gas / config / obj-elf.c
CommitLineData
252b5132 1/* ELF object file format
cc8a6dd0 2 Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
587aac4e 3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
252b5132
RH
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2,
10 or (at your option) any later version.
11
12 GAS is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
bf514e21 20 02111-1307, USA. */
252b5132
RH
21
22#define OBJ_HEADER "obj-elf.h"
23#include "as.h"
3882b010 24#include "safe-ctype.h"
252b5132
RH
25#include "subsegs.h"
26#include "obstack.h"
9758f3fc 27#include "struc-symbol.h"
87ccc1b0 28#include "dwarf2dbg.h"
252b5132
RH
29
30#ifndef ECOFF_DEBUGGING
31#define ECOFF_DEBUGGING 0
32#else
33#define NEED_ECOFF_DEBUG
34#endif
35
36#ifdef NEED_ECOFF_DEBUG
37#include "ecoff.h"
38#endif
39
40#ifdef TC_ALPHA
41#include "elf/alpha.h"
42#endif
43
44#ifdef TC_MIPS
45#include "elf/mips.h"
46#endif
47
48#ifdef TC_PPC
49#include "elf/ppc.h"
50#endif
51
5b93d8bb
AM
52#ifdef TC_I370
53#include "elf/i370.h"
54#endif
55
dbe2df79
AM
56static void obj_elf_line (int);
57static void obj_elf_size (int);
58static void obj_elf_type (int);
59static void obj_elf_ident (int);
60static void obj_elf_weak (int);
61static void obj_elf_local (int);
62static void obj_elf_visibility (int);
63static void obj_elf_symver (int);
64static void obj_elf_subsection (int);
65static void obj_elf_popsection (int);
66static void obj_elf_tls_common (int);
13c56984 67static void obj_elf_lcomm (int);
252b5132
RH
68
69static const pseudo_typeS elf_pseudo_table[] =
70{
71 {"comm", obj_elf_common, 0},
9be1cda6 72 {"common", obj_elf_common, 1},
252b5132 73 {"ident", obj_elf_ident, 0},
13c56984 74 {"lcomm", obj_elf_lcomm, 0},
252b5132
RH
75 {"local", obj_elf_local, 0},
76 {"previous", obj_elf_previous, 0},
77 {"section", obj_elf_section, 0},
78 {"section.s", obj_elf_section, 0},
79 {"sect", obj_elf_section, 0},
80 {"sect.s", obj_elf_section, 0},
9de8d8f1
RH
81 {"pushsection", obj_elf_section, 1},
82 {"popsection", obj_elf_popsection, 0},
252b5132
RH
83 {"size", obj_elf_size, 0},
84 {"type", obj_elf_type, 0},
85 {"version", obj_elf_version, 0},
86 {"weak", obj_elf_weak, 0},
87
bf514e21 88 /* These define symbol visibility. */
2e13b764
NC
89 {"internal", obj_elf_visibility, STV_INTERNAL},
90 {"hidden", obj_elf_visibility, STV_HIDDEN},
91 {"protected", obj_elf_visibility, STV_PROTECTED},
92
252b5132
RH
93 /* These are used for stabs-in-elf configurations. */
94 {"line", obj_elf_line, 0},
95
96 /* This is a GNU extension to handle symbol versions. */
97 {"symver", obj_elf_symver, 0},
98
99 /* A GNU extension to change subsection only. */
100 {"subsection", obj_elf_subsection, 0},
101
102 /* These are GNU extensions to aid in garbage collecting C++ vtables. */
dbe2df79
AM
103 {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
104 {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
252b5132 105
bf514e21 106 /* These are used for dwarf. */
252b5132
RH
107 {"2byte", cons, 2},
108 {"4byte", cons, 4},
109 {"8byte", cons, 8},
87ccc1b0 110 /* These are used for dwarf2. */
dbe2df79 111 { "file", (void (*) (int)) dwarf2_directive_file, 0 },
87ccc1b0 112 { "loc", dwarf2_directive_loc, 0 },
252b5132
RH
113
114 /* We need to trap the section changing calls to handle .previous. */
115 {"data", obj_elf_data, 0},
116 {"text", obj_elf_text, 0},
117
13ae64f3
JJ
118 {"tls_common", obj_elf_tls_common, 0},
119
252b5132 120 /* End sentinel. */
ab9da554 121 {NULL, NULL, 0},
252b5132
RH
122};
123
124static const pseudo_typeS ecoff_debug_pseudo_table[] =
125{
126#ifdef NEED_ECOFF_DEBUG
127 /* COFF style debugging information for ECOFF. .ln is not used; .loc
128 is used instead. */
129 { "def", ecoff_directive_def, 0 },
130 { "dim", ecoff_directive_dim, 0 },
131 { "endef", ecoff_directive_endef, 0 },
132 { "file", ecoff_directive_file, 0 },
133 { "scl", ecoff_directive_scl, 0 },
134 { "tag", ecoff_directive_tag, 0 },
135 { "val", ecoff_directive_val, 0 },
136
137 /* COFF debugging requires pseudo-ops .size and .type, but ELF
138 already has meanings for those. We use .esize and .etype
139 instead. These are only generated by gcc anyhow. */
140 { "esize", ecoff_directive_size, 0 },
141 { "etype", ecoff_directive_type, 0 },
142
143 /* ECOFF specific debugging information. */
144 { "begin", ecoff_directive_begin, 0 },
145 { "bend", ecoff_directive_bend, 0 },
146 { "end", ecoff_directive_end, 0 },
147 { "ent", ecoff_directive_ent, 0 },
148 { "fmask", ecoff_directive_fmask, 0 },
149 { "frame", ecoff_directive_frame, 0 },
150 { "loc", ecoff_directive_loc, 0 },
151 { "mask", ecoff_directive_mask, 0 },
152
153 /* Other ECOFF directives. */
154 { "extern", ecoff_directive_extern, 0 },
155
156 /* These are used on Irix. I don't know how to implement them. */
157 { "alias", s_ignore, 0 },
158 { "bgnb", s_ignore, 0 },
159 { "endb", s_ignore, 0 },
160 { "lab", s_ignore, 0 },
161 { "noalias", s_ignore, 0 },
162 { "verstamp", s_ignore, 0 },
163 { "vreg", s_ignore, 0 },
164#endif
165
ab9da554 166 {NULL, NULL, 0} /* end sentinel */
252b5132
RH
167};
168
169#undef NO_RELOC
170#include "aout/aout64.h"
171
172/* This is called when the assembler starts. */
173
174void
dbe2df79 175elf_begin (void)
252b5132 176{
dbe2df79
AM
177 asection *s;
178
252b5132 179 /* Add symbols for the known sections to the symbol table. */
dbe2df79
AM
180 s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
181 symbol_table_insert (section_symbol (s));
182 s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
183 symbol_table_insert (section_symbol (s));
184 s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
185 symbol_table_insert (section_symbol (s));
252b5132
RH
186}
187
188void
dbe2df79 189elf_pop_insert (void)
252b5132
RH
190{
191 pop_insert (elf_pseudo_table);
192 if (ECOFF_DEBUGGING)
193 pop_insert (ecoff_debug_pseudo_table);
194}
195
196static bfd_vma
dbe2df79 197elf_s_get_size (symbolS *sym)
252b5132
RH
198{
199 return S_GET_SIZE (sym);
200}
201
202static void
dbe2df79 203elf_s_set_size (symbolS *sym, bfd_vma sz)
252b5132
RH
204{
205 S_SET_SIZE (sym, sz);
206}
207
208static bfd_vma
dbe2df79 209elf_s_get_align (symbolS *sym)
252b5132
RH
210{
211 return S_GET_ALIGN (sym);
212}
213
214static void
dbe2df79 215elf_s_set_align (symbolS *sym, bfd_vma align)
252b5132
RH
216{
217 S_SET_ALIGN (sym, align);
218}
219
4c63da97 220int
dbe2df79 221elf_s_get_other (symbolS *sym)
4c63da97
AM
222{
223 return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
224}
225
5110c57e 226static void
dbe2df79 227elf_s_set_other (symbolS *sym, int other)
5110c57e
HPN
228{
229 S_SET_OTHER (sym, other);
230}
231
252b5132 232static int
dbe2df79 233elf_sec_sym_ok_for_reloc (asection *sec)
252b5132
RH
234{
235 return obj_sec_sym_ok_for_reloc (sec);
236}
237
238void
dbe2df79 239elf_file_symbol (const char *s)
252b5132
RH
240{
241 symbolS *sym;
242
dbe2df79 243 sym = symbol_new (s, absolute_section, 0, NULL);
49309057
ILT
244 symbol_set_frag (sym, &zero_address_frag);
245 symbol_get_bfdsym (sym)->flags |= BSF_FILE;
252b5132
RH
246
247 if (symbol_rootP != sym)
248 {
249 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
250 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
251#ifdef DEBUG
252 verify_symbol_chain (symbol_rootP, symbol_lastP);
253#endif
254 }
255
256#ifdef NEED_ECOFF_DEBUG
257 ecoff_new_file (s);
258#endif
259}
260
e13bab5a
AM
261/* Called from read.c:s_comm after we've parsed .comm symbol, size.
262 Parse a possible alignment value. */
263
13ae64f3 264static symbolS *
e13bab5a 265elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
252b5132 266{
e13bab5a
AM
267 addressT align = 0;
268 int is_local = symbol_get_obj (symbolP)->local;
252b5132 269
e13bab5a 270 if (*input_line_pointer == ',')
9be1cda6 271 {
e13bab5a 272 char *save = input_line_pointer;
9be1cda6 273
252b5132
RH
274 input_line_pointer++;
275 SKIP_WHITESPACE ();
e13bab5a
AM
276
277 if (*input_line_pointer == '"')
252b5132 278 {
e13bab5a
AM
279 /* For sparc. Accept .common symbol, length, "bss" */
280 input_line_pointer++;
281 /* Some use the dot, some don't. */
282 if (*input_line_pointer == '.')
283 input_line_pointer++;
284 /* Some say data, some say bss. */
285 if (strncmp (input_line_pointer, "bss\"", 4) == 0)
286 input_line_pointer += 4;
287 else if (strncmp (input_line_pointer, "data\"", 5) == 0)
288 input_line_pointer += 5;
289 else
252b5132 290 {
e13bab5a
AM
291 char *p = input_line_pointer;
292 char c;
293
294 while (*--p != '"')
295 ;
296 while (!is_end_of_line[(unsigned char) *input_line_pointer])
297 if (*input_line_pointer++ == '"')
298 break;
299 c = *input_line_pointer;
300 *input_line_pointer = '\0';
301 as_bad (_("bad .common segment %s"), p);
302 *input_line_pointer = c;
303 ignore_rest_of_line ();
304 return NULL;
252b5132 305 }
e13bab5a
AM
306 /* ??? Don't ask me why these are always global. */
307 is_local = 0;
252b5132
RH
308 }
309 else
310 {
e13bab5a
AM
311 input_line_pointer = save;
312 align = parse_align (is_local);
313 if (align == (addressT) -1)
314 return NULL;
252b5132
RH
315 }
316 }
e13bab5a
AM
317
318 if (is_local)
319 {
320 bss_alloc (symbolP, size, align);
321 S_CLEAR_EXTERNAL (symbolP);
322 }
252b5132
RH
323 else
324 {
e13bab5a
AM
325 S_SET_VALUE (symbolP, size);
326 S_SET_ALIGN (symbolP, align);
327 S_SET_EXTERNAL (symbolP);
328 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
252b5132
RH
329 }
330
49309057 331 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
252b5132 332
13ae64f3 333 return symbolP;
252b5132
RH
334}
335
13ae64f3 336void
dbe2df79 337obj_elf_common (int is_common)
13ae64f3 338{
e13bab5a
AM
339 if (flag_mri && is_common)
340 s_mri_common (0);
341 else
342 s_comm_internal (0, elf_common_parse);
13ae64f3
JJ
343}
344
345static void
dbe2df79 346obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
13ae64f3 347{
e13bab5a 348 symbolS *symbolP = s_comm_internal (0, elf_common_parse);
13ae64f3
JJ
349
350 if (symbolP)
351 symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
352}
353
13c56984
AM
354static void
355obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
356{
357 symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
358
359 if (symbolP)
360 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
361}
362
252b5132 363static void
dbe2df79 364obj_elf_local (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
365{
366 char *name;
367 int c;
368 symbolS *symbolP;
369
370 do
371 {
372 name = input_line_pointer;
373 c = get_symbol_end ();
374 symbolP = symbol_find_or_make (name);
375 *input_line_pointer = c;
376 SKIP_WHITESPACE ();
377 S_CLEAR_EXTERNAL (symbolP);
49309057 378 symbol_get_obj (symbolP)->local = 1;
252b5132
RH
379 if (c == ',')
380 {
381 input_line_pointer++;
382 SKIP_WHITESPACE ();
383 if (*input_line_pointer == '\n')
384 c = '\n';
385 }
386 }
387 while (c == ',');
388 demand_empty_rest_of_line ();
389}
390
391static void
dbe2df79 392obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
393{
394 char *name;
395 int c;
396 symbolS *symbolP;
397
398 do
399 {
400 name = input_line_pointer;
401 c = get_symbol_end ();
402 symbolP = symbol_find_or_make (name);
403 *input_line_pointer = c;
404 SKIP_WHITESPACE ();
405 S_SET_WEAK (symbolP);
49309057 406 symbol_get_obj (symbolP)->local = 1;
252b5132
RH
407 if (c == ',')
408 {
409 input_line_pointer++;
410 SKIP_WHITESPACE ();
411 if (*input_line_pointer == '\n')
412 c = '\n';
413 }
414 }
415 while (c == ',');
416 demand_empty_rest_of_line ();
417}
418
2e13b764 419static void
dbe2df79 420obj_elf_visibility (int visibility)
2e13b764
NC
421{
422 char *name;
423 int c;
424 symbolS *symbolP;
425 asymbol *bfdsym;
426 elf_symbol_type *elfsym;
427
428 do
429 {
430 name = input_line_pointer;
431 c = get_symbol_end ();
432 symbolP = symbol_find_or_make (name);
433 *input_line_pointer = c;
fa306131 434
2e13b764 435 SKIP_WHITESPACE ();
fa306131 436
2e13b764
NC
437 bfdsym = symbol_get_bfdsym (symbolP);
438 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
fa306131 439
2e13b764 440 assert (elfsym);
fa306131 441
20e420c2
RH
442 elfsym->internal_elf_sym.st_other &= ~3;
443 elfsym->internal_elf_sym.st_other |= visibility;
fa306131 444
2e13b764
NC
445 if (c == ',')
446 {
447 input_line_pointer ++;
fa306131 448
2e13b764 449 SKIP_WHITESPACE ();
fa306131 450
2e13b764
NC
451 if (*input_line_pointer == '\n')
452 c = '\n';
453 }
454 }
455 while (c == ',');
fa306131 456
2e13b764
NC
457 demand_empty_rest_of_line ();
458}
459
252b5132
RH
460static segT previous_section;
461static int previous_subsection;
462
9de8d8f1
RH
463struct section_stack
464{
465 struct section_stack *next;
466 segT seg, prev_seg;
467 int subseg, prev_subseg;
468};
469
470static struct section_stack *section_stack;
471
fafe6678 472static bfd_boolean
86654c12
L
473get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
474{
fafe6678 475 const char *gname = inf;
86654c12
L
476 const char *group_name = elf_group_name (sec);
477
fafe6678 478 return (group_name == gname
86654c12 479 || (group_name != NULL
fafe6678
L
480 && gname != NULL
481 && strcmp (group_name, gname) == 0));
86654c12
L
482}
483
252b5132
RH
484/* Handle the .section pseudo-op. This code supports two different
485 syntaxes.
486
487 The first is found on Solaris, and looks like
488 .section ".sec1",#alloc,#execinstr,#write
489 Here the names after '#' are the SHF_* flags to turn on for the
490 section. I'm not sure how it determines the SHT_* type (BFD
491 doesn't really give us control over the type, anyhow).
492
493 The second format is found on UnixWare, and probably most SVR4
494 machines, and looks like
495 .section .sec1,"a",@progbits
496 The quoted string may contain any combination of a, w, x, and
497 represents the SHF_* flags to turn on for the section. The string
498 beginning with '@' can be progbits or nobits. There should be
499 other possibilities, but I don't know what they are. In any case,
500 BFD doesn't really let us set the section type. */
501
cca86cc8 502void
dbe2df79
AM
503obj_elf_change_section (const char *name,
504 int type,
505 int attr,
506 int entsize,
507 const char *group_name,
508 int linkonce,
509 int push)
252b5132 510{
fafe6678 511 asection *old_sec;
252b5132 512 segT sec;
742f45cf 513 flagword flags;
f61e8019 514 const struct bfd_elf_special_section *ssect;
252b5132
RH
515
516#ifdef md_flush_pending_output
517 md_flush_pending_output ();
518#endif
519
9de8d8f1
RH
520 /* Switch to the section, creating it if necessary. */
521 if (push)
522 {
523 struct section_stack *elt;
524 elt = xmalloc (sizeof (struct section_stack));
525 elt->next = section_stack;
526 elt->seg = now_seg;
527 elt->prev_seg = previous_section;
528 elt->subseg = now_subseg;
529 elt->prev_subseg = previous_subsection;
530 section_stack = elt;
531 }
532 previous_section = now_seg;
533 previous_subsection = now_subseg;
534
fafe6678
L
535 old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
536 (void *) group_name);
537 if (old_sec)
86654c12 538 {
fafe6678 539 sec = old_sec;
86654c12
L
540 subseg_set (sec, 0);
541 }
542 else
543 sec = subseg_force_new (name, 0);
544
f61e8019 545 ssect = _bfd_elf_get_sec_type_attr (stdoutput, name);
9de8d8f1 546
f61e8019 547 if (ssect != NULL)
2f89ff8d 548 {
ea8f8eab
L
549 bfd_boolean override = FALSE;
550
2f89ff8d 551 if (type == SHT_NULL)
f61e8019
AM
552 type = ssect->type;
553 else if (type != ssect->type)
2f89ff8d 554 {
fafe6678 555 if (old_sec == NULL
2f89ff8d 556 /* FIXME: gcc, as of 2002-10-22, will emit
7ed1d346 557
2f89ff8d 558 .section .init_array,"aw",@progbits
7ed1d346 559
2f89ff8d
L
560 for __attribute__ ((section (".init_array"))).
561 "@progbits" is incorrect. */
f61e8019
AM
562 && ssect->type != SHT_INIT_ARRAY
563 && ssect->type != SHT_FINI_ARRAY
564 && ssect->type != SHT_PREINIT_ARRAY)
2f89ff8d
L
565 {
566 /* We allow to specify any type for a .note section. */
f61e8019 567 if (ssect->type != SHT_NOTE)
2f89ff8d
L
568 as_warn (_("setting incorrect section type for %s"),
569 name);
570 }
571 else
572 {
573 as_warn (_("ignoring incorrect section type for %s"),
742f45cf 574 name);
f61e8019 575 type = ssect->type;
2f89ff8d
L
576 }
577 }
578
fafe6678 579 if (old_sec == NULL && (attr & ~ssect->attr) != 0)
2f89ff8d
L
580 {
581 /* As a GNU extension, we permit a .note section to be
f61e8019 582 allocatable. If the linker sees an allocatable .note
2f89ff8d 583 section, it will create a PT_NOTE segment in the output
92191b29 584 file. We also allow "x" for .note.GNU-stack. */
f61e8019
AM
585 if (ssect->type == SHT_NOTE
586 && (attr == SHF_ALLOC || attr == SHF_EXECINSTR))
587 ;
588 /* Allow different SHF_MERGE and SHF_STRINGS if we have
589 something like .rodata.str. */
590 else if (ssect->suffix_length == -2
591 && name[ssect->prefix_length] == '.'
ea8f8eab
L
592 && (attr
593 & ~ssect->attr
594 & ~SHF_MERGE
595 & ~SHF_STRINGS) == 0)
f61e8019 596 ;
ea8f8eab
L
597 /* .interp, .strtab and .symtab can have SHF_ALLOC. */
598 else if (attr == SHF_ALLOC
599 && (strcmp (name, ".interp") == 0
600 || strcmp (name, ".strtab") == 0
601 || strcmp (name, ".symtab") == 0))
602 override = TRUE;
b9f18452
L
603 /* .note.GNU-stack can have SHF_EXECINSTR. */
604 else if (attr == SHF_EXECINSTR
605 && strcmp (name, ".note.GNU-stack") == 0)
606 override = TRUE;
f61e8019 607 else
ea8f8eab 608 {
86654c12
L
609 if (group_name == NULL)
610 as_warn (_("setting incorrect section attributes for %s"),
611 name);
ea8f8eab
L
612 override = TRUE;
613 }
2f89ff8d 614 }
fafe6678 615 if (!override && old_sec == NULL)
f61e8019 616 attr |= ssect->attr;
2f89ff8d 617 }
742f45cf 618
3cddba1e
L
619 if (type != SHT_NULL)
620 elf_section_type (sec) = type;
621 if (attr != 0)
622 elf_section_flags (sec) = attr;
8e8c182c 623
742f45cf
AM
624 /* Convert ELF type and flags to BFD flags. */
625 flags = (SEC_RELOC
626 | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
627 | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
628 | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
f5fa8ca2
JJ
629 | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
630 | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
13ae64f3
JJ
631 | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
632 | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
9de8d8f1 633#ifdef md_elf_section_flags
742f45cf 634 flags = md_elf_section_flags (flags, attr, type);
9de8d8f1
RH
635#endif
636
86654c12
L
637 if (linkonce)
638 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
639
fafe6678 640 if (old_sec == NULL)
742f45cf
AM
641 {
642 symbolS *secsym;
643
9de8d8f1
RH
644 /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
645 if (type == SHT_NOBITS)
13c56984 646 seg_info (sec)->bss = 1;
9de8d8f1
RH
647
648 bfd_set_section_flags (stdoutput, sec, flags);
f5fa8ca2
JJ
649 if (flags & SEC_MERGE)
650 sec->entsize = entsize;
aa1f4858 651 elf_group_name (sec) = group_name;
9de8d8f1
RH
652
653 /* Add a symbol for this section to the symbol table. */
654 secsym = symbol_find (name);
655 if (secsym != NULL)
656 symbol_set_bfdsym (secsym, sec->symbol);
657 else
13c56984 658 symbol_table_insert (section_symbol (sec));
9de8d8f1 659 }
742f45cf
AM
660 else if (attr != 0)
661 {
662 /* If section attributes are specified the second time we see a
663 particular section, then check that they are the same as we
664 saw the first time. */
fafe6678 665 if (((old_sec->flags ^ flags)
d2dab548
AM
666 & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
667 | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
68bfbfcc
AM
668 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
669 | SEC_THREAD_LOCAL)))
6ce8b369 670 as_warn (_("ignoring changed section attributes for %s"), name);
fafe6678 671 if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
6ce8b369 672 as_warn (_("ignoring changed section entity size for %s"), name);
742f45cf 673 }
9de8d8f1
RH
674
675#ifdef md_elf_section_change_hook
742f45cf 676 md_elf_section_change_hook ();
9de8d8f1
RH
677#endif
678}
679
8d28c9d7 680static int
dbe2df79 681obj_elf_parse_section_letters (char *str, size_t len)
9de8d8f1
RH
682{
683 int attr = 0;
684
685 while (len > 0)
686 {
687 switch (*str)
688 {
689 case 'a':
690 attr |= SHF_ALLOC;
691 break;
692 case 'w':
693 attr |= SHF_WRITE;
694 break;
695 case 'x':
696 attr |= SHF_EXECINSTR;
697 break;
9469ddf0 698 case 'M':
f5fa8ca2
JJ
699 attr |= SHF_MERGE;
700 break;
9469ddf0 701 case 'S':
f5fa8ca2
JJ
702 attr |= SHF_STRINGS;
703 break;
060adf0e
AM
704 case 'G':
705 attr |= SHF_GROUP;
706 break;
13ae64f3
JJ
707 case 'T':
708 attr |= SHF_TLS;
709 break;
34105363
L
710 /* Compatibility. */
711 case 'm':
712 if (*(str - 1) == 'a')
713 {
714 attr |= SHF_MERGE;
715 if (len > 1 && str[1] == 's')
716 {
717 attr |= SHF_STRINGS;
718 str++, len--;
719 }
720 break;
721 }
9de8d8f1
RH
722 default:
723 {
13ae64f3 724 char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G,T");
9de8d8f1
RH
725#ifdef md_elf_section_letter
726 int md_attr = md_elf_section_letter (*str, &bad_msg);
727 if (md_attr >= 0)
728 attr |= md_attr;
729 else
730#endif
711ef82f 731 as_fatal ("%s", bad_msg);
9de8d8f1
RH
732 }
733 break;
734 }
735 str++, len--;
736 }
737
738 return attr;
739}
740
8d28c9d7 741static int
dbe2df79 742obj_elf_section_word (char *str, size_t len)
9de8d8f1
RH
743{
744 if (len == 5 && strncmp (str, "write", 5) == 0)
745 return SHF_WRITE;
746 if (len == 5 && strncmp (str, "alloc", 5) == 0)
747 return SHF_ALLOC;
748 if (len == 9 && strncmp (str, "execinstr", 9) == 0)
749 return SHF_EXECINSTR;
b9734f35
JJ
750 if (len == 3 && strncmp (str, "tls", 3) == 0)
751 return SHF_TLS;
9de8d8f1
RH
752
753#ifdef md_elf_section_word
754 {
755 int md_attr = md_elf_section_word (str, len);
756 if (md_attr >= 0)
757 return md_attr;
758 }
759#endif
760
6ce8b369 761 as_warn (_("unrecognized section attribute"));
9de8d8f1
RH
762 return 0;
763}
764
8d28c9d7 765static int
dbe2df79 766obj_elf_section_type (char *str, size_t len)
9de8d8f1
RH
767{
768 if (len == 8 && strncmp (str, "progbits", 8) == 0)
769 return SHT_PROGBITS;
770 if (len == 6 && strncmp (str, "nobits", 6) == 0)
771 return SHT_NOBITS;
34f70875
L
772 if (len == 4 && strncmp (str, "note", 4) == 0)
773 return SHT_NOTE;
9de8d8f1
RH
774
775#ifdef md_elf_section_type
776 {
777 int md_type = md_elf_section_type (str, len);
778 if (md_type >= 0)
779 return md_type;
780 }
781#endif
782
6ce8b369 783 as_warn (_("unrecognized section type"));
9de8d8f1
RH
784 return 0;
785}
786
6ce8b369
AM
787/* Get name of section. */
788static char *
dbe2df79 789obj_elf_section_name (void)
6ce8b369
AM
790{
791 char *name;
792
793 SKIP_WHITESPACE ();
794 if (*input_line_pointer == '"')
795 {
796 int dummy;
797
798 name = demand_copy_C_string (&dummy);
799 if (name == NULL)
800 {
801 ignore_rest_of_line ();
802 return NULL;
803 }
804 }
805 else
806 {
807 char *end = input_line_pointer;
808
809 while (0 == strchr ("\n\t,; ", *end))
810 end++;
811 if (end == input_line_pointer)
812 {
c95b35a9 813 as_bad (_("missing name"));
6ce8b369
AM
814 ignore_rest_of_line ();
815 return NULL;
816 }
817
818 name = xmalloc (end - input_line_pointer + 1);
819 memcpy (name, input_line_pointer, end - input_line_pointer);
820 name[end - input_line_pointer] = '\0';
612d7b83
L
821#ifdef tc_canonicalize_section_name
822 name = tc_canonicalize_section_name (name);
823#endif
6ce8b369
AM
824 input_line_pointer = end;
825 }
826 SKIP_WHITESPACE ();
827 return name;
828}
829
9de8d8f1 830void
dbe2df79 831obj_elf_section (int push)
9de8d8f1 832{
aa1f4858 833 char *name, *group_name, *beg;
9de8d8f1 834 int type, attr, dummy;
f5fa8ca2 835 int entsize;
d2dab548 836 int linkonce;
9de8d8f1 837
5b93d8bb 838#ifndef TC_I370
252b5132
RH
839 if (flag_mri)
840 {
841 char mri_type;
842
9de8d8f1 843#ifdef md_flush_pending_output
60bcf0fa 844 md_flush_pending_output ();
9de8d8f1
RH
845#endif
846
252b5132
RH
847 previous_section = now_seg;
848 previous_subsection = now_subseg;
849
850 s_mri_sect (&mri_type);
851
852#ifdef md_elf_section_change_hook
853 md_elf_section_change_hook ();
854#endif
855
856 return;
857 }
5b93d8bb 858#endif /* ! defined (TC_I370) */
252b5132 859
6ce8b369
AM
860 name = obj_elf_section_name ();
861 if (name == NULL)
862 return;
252b5132
RH
863 type = SHT_NULL;
864 attr = 0;
aa1f4858 865 group_name = NULL;
f5fa8ca2 866 entsize = 0;
d2dab548 867 linkonce = 0;
252b5132
RH
868
869 if (*input_line_pointer == ',')
870 {
871 /* Skip the comma. */
872 ++input_line_pointer;
252b5132
RH
873 SKIP_WHITESPACE ();
874
875 if (*input_line_pointer == '"')
876 {
9de8d8f1
RH
877 beg = demand_copy_C_string (&dummy);
878 if (beg == NULL)
252b5132 879 {
9de8d8f1
RH
880 ignore_rest_of_line ();
881 return;
252b5132 882 }
9de8d8f1 883 attr |= obj_elf_parse_section_letters (beg, strlen (beg));
252b5132
RH
884
885 SKIP_WHITESPACE ();
886 if (*input_line_pointer == ',')
887 {
9de8d8f1 888 char c;
060adf0e
AM
889 char *save = input_line_pointer;
890
252b5132
RH
891 ++input_line_pointer;
892 SKIP_WHITESPACE ();
9de8d8f1
RH
893 c = *input_line_pointer;
894 if (c == '"')
252b5132 895 {
9de8d8f1
RH
896 beg = demand_copy_C_string (&dummy);
897 if (beg == NULL)
252b5132 898 {
9de8d8f1
RH
899 ignore_rest_of_line ();
900 return;
252b5132 901 }
9de8d8f1 902 type = obj_elf_section_type (beg, strlen (beg));
9de8d8f1
RH
903 }
904 else if (c == '@' || c == '%')
905 {
906 beg = ++input_line_pointer;
907 c = get_symbol_end ();
908 *input_line_pointer = c;
909 type = obj_elf_section_type (beg, input_line_pointer - beg);
252b5132 910 }
060adf0e
AM
911 else
912 input_line_pointer = save;
252b5132 913 }
f5fa8ca2
JJ
914
915 SKIP_WHITESPACE ();
6ce8b369 916 if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
f5fa8ca2
JJ
917 {
918 ++input_line_pointer;
919 SKIP_WHITESPACE ();
920 entsize = get_absolute_expression ();
6ce8b369 921 SKIP_WHITESPACE ();
f5fa8ca2
JJ
922 if (entsize < 0)
923 {
6ce8b369 924 as_warn (_("invalid merge entity size"));
f5fa8ca2
JJ
925 attr &= ~SHF_MERGE;
926 entsize = 0;
927 }
928 }
6ce8b369
AM
929 else if ((attr & SHF_MERGE) != 0)
930 {
931 as_warn (_("entity size for SHF_MERGE not specified"));
932 attr &= ~SHF_MERGE;
933 }
060adf0e
AM
934
935 if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
936 {
937 ++input_line_pointer;
aa1f4858
AM
938 group_name = obj_elf_section_name ();
939 if (group_name == NULL)
060adf0e 940 attr &= ~SHF_GROUP;
d2dab548
AM
941 else if (strncmp (input_line_pointer, ",comdat", 7) == 0)
942 {
943 input_line_pointer += 7;
944 linkonce = 1;
945 }
946 else if (strncmp (name, ".gnu.linkonce", 13) == 0)
947 linkonce = 1;
060adf0e
AM
948 }
949 else if ((attr & SHF_GROUP) != 0)
950 {
951 as_warn (_("group name for SHF_GROUP not specified"));
952 attr &= ~SHF_GROUP;
953 }
252b5132
RH
954 }
955 else
956 {
957 do
958 {
9de8d8f1
RH
959 char c;
960
252b5132
RH
961 SKIP_WHITESPACE ();
962 if (*input_line_pointer != '#')
963 {
c95b35a9 964 as_bad (_("character following name is not '#'"));
252b5132
RH
965 ignore_rest_of_line ();
966 return;
967 }
9de8d8f1
RH
968 beg = ++input_line_pointer;
969 c = get_symbol_end ();
970 *input_line_pointer = c;
971
972 attr |= obj_elf_section_word (beg, input_line_pointer - beg);
973
252b5132
RH
974 SKIP_WHITESPACE ();
975 }
976 while (*input_line_pointer++ == ',');
977 --input_line_pointer;
978 }
979 }
980
252b5132 981 demand_empty_rest_of_line ();
9de8d8f1 982
d2dab548 983 obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push);
252b5132
RH
984}
985
986/* Change to the .data section. */
987
16b93d88 988void
dbe2df79 989obj_elf_data (int i)
252b5132
RH
990{
991#ifdef md_flush_pending_output
992 md_flush_pending_output ();
993#endif
994
995 previous_section = now_seg;
996 previous_subsection = now_subseg;
997 s_data (i);
998
999#ifdef md_elf_section_change_hook
1000 md_elf_section_change_hook ();
1001#endif
1002}
1003
1004/* Change to the .text section. */
1005
16b93d88 1006void
dbe2df79 1007obj_elf_text (int i)
252b5132
RH
1008{
1009#ifdef md_flush_pending_output
1010 md_flush_pending_output ();
1011#endif
1012
1013 previous_section = now_seg;
1014 previous_subsection = now_subseg;
1015 s_text (i);
1016
1017#ifdef md_elf_section_change_hook
1018 md_elf_section_change_hook ();
1019#endif
1020}
1021
1022static void
dbe2df79 1023obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1024{
1025 register int temp;
1026
1027#ifdef md_flush_pending_output
1028 md_flush_pending_output ();
1029#endif
1030
1031 previous_section = now_seg;
1032 previous_subsection = now_subseg;
1033
1034 temp = get_absolute_expression ();
1035 subseg_set (now_seg, (subsegT) temp);
1036 demand_empty_rest_of_line ();
1037
1038#ifdef md_elf_section_change_hook
1039 md_elf_section_change_hook ();
1040#endif
1041}
1042
1043/* This can be called from the processor backends if they change
1044 sections. */
1045
1046void
dbe2df79 1047obj_elf_section_change_hook (void)
252b5132
RH
1048{
1049 previous_section = now_seg;
1050 previous_subsection = now_subseg;
1051}
1052
1053void
dbe2df79 1054obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
252b5132 1055{
9de8d8f1
RH
1056 segT new_section;
1057 int new_subsection;
1058
252b5132
RH
1059 if (previous_section == 0)
1060 {
6ce8b369 1061 as_warn (_(".previous without corresponding .section; ignored"));
252b5132
RH
1062 return;
1063 }
1064
1065#ifdef md_flush_pending_output
1066 md_flush_pending_output ();
1067#endif
1068
9de8d8f1
RH
1069 new_section = previous_section;
1070 new_subsection = previous_subsection;
1071 previous_section = now_seg;
1072 previous_subsection = now_subseg;
1073 subseg_set (new_section, new_subsection);
1074
1075#ifdef md_elf_section_change_hook
1076 md_elf_section_change_hook ();
1077#endif
1078}
1079
1080static void
dbe2df79 1081obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
9de8d8f1
RH
1082{
1083 struct section_stack *top = section_stack;
1084
1085 if (top == NULL)
1086 {
6ce8b369 1087 as_warn (_(".popsection without corresponding .pushsection; ignored"));
9de8d8f1
RH
1088 return;
1089 }
1090
1091#ifdef md_flush_pending_output
1092 md_flush_pending_output ();
1093#endif
1094
1095 section_stack = top->next;
1096 previous_section = top->prev_seg;
1097 previous_subsection = top->prev_subseg;
1098 subseg_set (top->seg, top->subseg);
1099 free (top);
252b5132
RH
1100
1101#ifdef md_elf_section_change_hook
1102 md_elf_section_change_hook ();
1103#endif
1104}
1105
1106static void
dbe2df79 1107obj_elf_line (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1108{
1109 /* Assume delimiter is part of expression. BSD4.2 as fails with
bf514e21 1110 delightful bug, so we are not being incompatible here. */
dbe2df79 1111 new_logical_line (NULL, get_absolute_expression ());
252b5132
RH
1112 demand_empty_rest_of_line ();
1113}
1114
1115/* This handles the .symver pseudo-op, which is used to specify a
1116 symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
1117 SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
1118 pseudo-op causes the assembler to emit a symbol named SYMVERNAME
1119 with the same value as the symbol NAME. */
1120
1121static void
dbe2df79 1122obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1123{
1124 char *name;
1125 char c;
468cced8 1126 char old_lexat;
252b5132
RH
1127 symbolS *sym;
1128
1129 name = input_line_pointer;
1130 c = get_symbol_end ();
1131
1132 sym = symbol_find_or_make (name);
1133
1134 *input_line_pointer = c;
1135
252b5132
RH
1136 SKIP_WHITESPACE ();
1137 if (*input_line_pointer != ',')
1138 {
1139 as_bad (_("expected comma after name in .symver"));
1140 ignore_rest_of_line ();
1141 return;
1142 }
1143
1144 ++input_line_pointer;
eba874d8 1145 SKIP_WHITESPACE ();
252b5132 1146 name = input_line_pointer;
468cced8
AM
1147
1148 /* Temporarily include '@' in symbol names. */
1149 old_lexat = lex_type[(unsigned char) '@'];
1150 lex_type[(unsigned char) '@'] |= LEX_NAME;
1151 c = get_symbol_end ();
1152 lex_type[(unsigned char) '@'] = old_lexat;
252b5132 1153
339681c0
L
1154 if (symbol_get_obj (sym)->versioned_name == NULL)
1155 {
1156 symbol_get_obj (sym)->versioned_name = xstrdup (name);
252b5132 1157
339681c0 1158 *input_line_pointer = c;
252b5132 1159
6f620856
L
1160 if (strchr (symbol_get_obj (sym)->versioned_name,
1161 ELF_VER_CHR) == NULL)
339681c0
L
1162 {
1163 as_bad (_("missing version name in `%s' for symbol `%s'"),
1164 symbol_get_obj (sym)->versioned_name,
1165 S_GET_NAME (sym));
1166 ignore_rest_of_line ();
1167 return;
1168 }
1169 }
1170 else
252b5132 1171 {
339681c0
L
1172 if (strcmp (symbol_get_obj (sym)->versioned_name, name))
1173 {
1174 as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"),
1175 name, symbol_get_obj (sym)->versioned_name,
1176 S_GET_NAME (sym));
1177 ignore_rest_of_line ();
1178 return;
1179 }
1180
1181 *input_line_pointer = c;
252b5132
RH
1182 }
1183
1184 demand_empty_rest_of_line ();
1185}
1186
1187/* This handles the .vtable_inherit pseudo-op, which is used to indicate
1188 to the linker the hierarchy in which a particular table resides. The
1189 syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
1190
904a31bf 1191struct fix *
dbe2df79 1192obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1193{
1194 char *cname, *pname;
1195 symbolS *csym, *psym;
1196 char c, bad = 0;
1197
1198 if (*input_line_pointer == '#')
1199 ++input_line_pointer;
1200
1201 cname = input_line_pointer;
1202 c = get_symbol_end ();
1203 csym = symbol_find (cname);
1204
1205 /* GCFIXME: should check that we don't have two .vtable_inherits for
1206 the same child symbol. Also, we can currently only do this if the
1207 child symbol is already exists and is placed in a fragment. */
1208
49309057 1209 if (csym == NULL || symbol_get_frag (csym) == NULL)
252b5132
RH
1210 {
1211 as_bad ("expected `%s' to have already been set for .vtable_inherit",
1212 cname);
1213 bad = 1;
1214 }
1215
1216 *input_line_pointer = c;
1217
1218 SKIP_WHITESPACE ();
1219 if (*input_line_pointer != ',')
1220 {
1221 as_bad ("expected comma after name in .vtable_inherit");
1222 ignore_rest_of_line ();
904a31bf 1223 return NULL;
252b5132
RH
1224 }
1225
1226 ++input_line_pointer;
1227 SKIP_WHITESPACE ();
1228
1229 if (*input_line_pointer == '#')
1230 ++input_line_pointer;
1231
1232 if (input_line_pointer[0] == '0'
1233 && (input_line_pointer[1] == '\0'
3882b010 1234 || ISSPACE (input_line_pointer[1])))
252b5132
RH
1235 {
1236 psym = section_symbol (absolute_section);
1237 ++input_line_pointer;
1238 }
1239 else
1240 {
1241 pname = input_line_pointer;
1242 c = get_symbol_end ();
1243 psym = symbol_find_or_make (pname);
1244 *input_line_pointer = c;
1245 }
1246
1247 demand_empty_rest_of_line ();
1248
1249 if (bad)
904a31bf 1250 return NULL;
252b5132 1251
49309057 1252 assert (symbol_get_value_expression (csym)->X_op == O_constant);
904a31bf
AM
1253 return fix_new (symbol_get_frag (csym),
1254 symbol_get_value_expression (csym)->X_add_number,
1255 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
252b5132 1256}
fa306131 1257
252b5132
RH
1258/* This handles the .vtable_entry pseudo-op, which is used to indicate
1259 to the linker that a vtable slot was used. The syntax is
1260 ".vtable_entry tablename, offset". */
1261
904a31bf 1262struct fix *
dbe2df79 1263obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1264{
1265 char *name;
1266 symbolS *sym;
1267 offsetT offset;
1268 char c;
1269
1270 if (*input_line_pointer == '#')
1271 ++input_line_pointer;
1272
1273 name = input_line_pointer;
1274 c = get_symbol_end ();
1275 sym = symbol_find_or_make (name);
1276 *input_line_pointer = c;
1277
1278 SKIP_WHITESPACE ();
1279 if (*input_line_pointer != ',')
1280 {
1281 as_bad ("expected comma after name in .vtable_entry");
1282 ignore_rest_of_line ();
904a31bf 1283 return NULL;
252b5132
RH
1284 }
1285
1286 ++input_line_pointer;
1287 if (*input_line_pointer == '#')
1288 ++input_line_pointer;
1289
1290 offset = get_absolute_expression ();
1291
252b5132 1292 demand_empty_rest_of_line ();
904a31bf
AM
1293
1294 return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
1295 BFD_RELOC_VTABLE_ENTRY);
252b5132
RH
1296}
1297
1298void
dbe2df79 1299elf_obj_read_begin_hook (void)
252b5132
RH
1300{
1301#ifdef NEED_ECOFF_DEBUG
1302 if (ECOFF_DEBUGGING)
1303 ecoff_read_begin_hook ();
1304#endif
1305}
1306
1307void
dbe2df79 1308elf_obj_symbol_new_hook (symbolS *symbolP)
252b5132 1309{
49309057
ILT
1310 struct elf_obj_sy *sy_obj;
1311
1312 sy_obj = symbol_get_obj (symbolP);
1313 sy_obj->size = NULL;
1314 sy_obj->versioned_name = NULL;
252b5132
RH
1315
1316#ifdef NEED_ECOFF_DEBUG
1317 if (ECOFF_DEBUGGING)
1318 ecoff_symbol_new_hook (symbolP);
1319#endif
1320}
1321
8fd3e36b
AM
1322/* When setting one symbol equal to another, by default we probably
1323 want them to have the same "size", whatever it means in the current
1324 context. */
1325
1326void
dbe2df79 1327elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
8fd3e36b 1328{
060adf0e
AM
1329 struct elf_obj_sy *srcelf = symbol_get_obj (src);
1330 struct elf_obj_sy *destelf = symbol_get_obj (dest);
1331 if (srcelf->size)
1332 {
1333 if (destelf->size == NULL)
dbe2df79 1334 destelf->size = xmalloc (sizeof (expressionS));
060adf0e
AM
1335 *destelf->size = *srcelf->size;
1336 }
1337 else
1338 {
1339 if (destelf->size != NULL)
1340 free (destelf->size);
1341 destelf->size = NULL;
1342 }
1343 S_SET_SIZE (dest, S_GET_SIZE (src));
26eb4093
JJ
1344 /* Don't copy visibility. */
1345 S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
1346 | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
8fd3e36b
AM
1347}
1348
252b5132 1349void
dbe2df79 1350obj_elf_version (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1351{
1352 char *name;
1353 unsigned int c;
252b5132
RH
1354 char *p;
1355 asection *seg = now_seg;
1356 subsegT subseg = now_subseg;
1357 Elf_Internal_Note i_note;
1358 Elf_External_Note e_note;
dbe2df79 1359 asection *note_secp = NULL;
e4afe742 1360 int len;
252b5132
RH
1361
1362 SKIP_WHITESPACE ();
1363 if (*input_line_pointer == '\"')
1364 {
bf514e21 1365 ++input_line_pointer; /* -> 1st char of string. */
252b5132
RH
1366 name = input_line_pointer;
1367
1368 while (is_a_char (c = next_char_of_string ()))
1369 ;
1370 c = *input_line_pointer;
1371 *input_line_pointer = '\0';
1372 *(input_line_pointer - 1) = '\0';
1373 *input_line_pointer = c;
1374
1375 /* create the .note section */
1376
1377 note_secp = subseg_new (".note", 0);
1378 bfd_set_section_flags (stdoutput,
1379 note_secp,
1380 SEC_HAS_CONTENTS | SEC_READONLY);
1381
1382 /* process the version string */
1383
1384 len = strlen (name);
1385
1386 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
1387 i_note.descsz = 0; /* no description */
1388 i_note.type = NT_VERSION;
1389 p = frag_more (sizeof (e_note.namesz));
dbe2df79 1390 md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
252b5132 1391 p = frag_more (sizeof (e_note.descsz));
dbe2df79 1392 md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
252b5132 1393 p = frag_more (sizeof (e_note.type));
dbe2df79 1394 md_number_to_chars (p, i_note.type, sizeof (e_note.type));
e4afe742
AM
1395 p = frag_more (len + 1);
1396 strcpy (p, name);
252b5132 1397
252b5132
RH
1398 frag_align (2, 0, 0);
1399
1400 subseg_set (seg, subseg);
1401 }
1402 else
1403 {
6ce8b369 1404 as_bad (_("expected quoted string"));
252b5132
RH
1405 }
1406 demand_empty_rest_of_line ();
1407}
1408
1409static void
dbe2df79 1410obj_elf_size (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1411{
1412 char *name = input_line_pointer;
1413 char c = get_symbol_end ();
1414 char *p;
1415 expressionS exp;
1416 symbolS *sym;
1417
1418 p = input_line_pointer;
1419 *p = c;
1420 SKIP_WHITESPACE ();
1421 if (*input_line_pointer != ',')
1422 {
1423 *p = 0;
1424 as_bad (_("expected comma after name `%s' in .size directive"), name);
1425 *p = c;
1426 ignore_rest_of_line ();
1427 return;
1428 }
1429 input_line_pointer++;
1430 expression (&exp);
1431 if (exp.X_op == O_absent)
1432 {
1433 as_bad (_("missing expression in .size directive"));
1434 exp.X_op = O_constant;
1435 exp.X_add_number = 0;
1436 }
1437 *p = 0;
1438 sym = symbol_find_or_make (name);
1439 *p = c;
1440 if (exp.X_op == O_constant)
c538998c
JJ
1441 {
1442 S_SET_SIZE (sym, exp.X_add_number);
1443 if (symbol_get_obj (sym)->size)
1444 {
1445 xfree (symbol_get_obj (sym)->size);
1446 symbol_get_obj (sym)->size = NULL;
1447 }
1448 }
252b5132
RH
1449 else
1450 {
dbe2df79 1451 symbol_get_obj (sym)->size = xmalloc (sizeof (expressionS));
49309057 1452 *symbol_get_obj (sym)->size = exp;
252b5132
RH
1453 }
1454 demand_empty_rest_of_line ();
1455}
1456
1457/* Handle the ELF .type pseudo-op. This sets the type of a symbol.
aa8c34c3 1458 There are five syntaxes:
fa306131 1459
252b5132
RH
1460 The first (used on Solaris) is
1461 .type SYM,#function
1462 The second (used on UnixWare) is
1463 .type SYM,@function
1464 The third (reportedly to be used on Irix 6.0) is
1465 .type SYM STT_FUNC
1466 The fourth (used on NetBSD/Arm and Linux/ARM) is
1467 .type SYM,%function
aa8c34c3
JE
1468 The fifth (used on SVR4/860) is
1469 .type SYM,"function"
252b5132
RH
1470 */
1471
1472static void
dbe2df79 1473obj_elf_type (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1474{
1475 char *name;
1476 char c;
1477 int type;
1478 const char *typename;
1479 symbolS *sym;
904a31bf 1480 elf_symbol_type *elfsym;
252b5132
RH
1481
1482 name = input_line_pointer;
1483 c = get_symbol_end ();
1484 sym = symbol_find_or_make (name);
904a31bf 1485 elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
252b5132
RH
1486 *input_line_pointer = c;
1487
1488 SKIP_WHITESPACE ();
1489 if (*input_line_pointer == ',')
1490 ++input_line_pointer;
1491
1492 SKIP_WHITESPACE ();
1493 if ( *input_line_pointer == '#'
1494 || *input_line_pointer == '@'
aa8c34c3 1495 || *input_line_pointer == '"'
252b5132
RH
1496 || *input_line_pointer == '%')
1497 ++input_line_pointer;
1498
1499 typename = input_line_pointer;
1500 c = get_symbol_end ();
1501
1502 type = 0;
1503 if (strcmp (typename, "function") == 0
1504 || strcmp (typename, "STT_FUNC") == 0)
1505 type = BSF_FUNCTION;
1506 else if (strcmp (typename, "object") == 0
1507 || strcmp (typename, "STT_OBJECT") == 0)
1508 type = BSF_OBJECT;
b9734f35
JJ
1509 else if (strcmp (typename, "tls_object") == 0
1510 || strcmp (typename, "STT_TLS") == 0)
1511 type = BSF_OBJECT | BSF_THREAD_LOCAL;
e7b9a8c1
L
1512 else if (strcmp (typename, "notype") == 0
1513 || strcmp (typename, "STT_NOTYPE") == 0)
1514 ;
904a31bf
AM
1515#ifdef md_elf_symbol_type
1516 else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1)
1517 ;
1518#endif
252b5132 1519 else
6ce8b369 1520 as_bad (_("unrecognized symbol type \"%s\""), typename);
252b5132
RH
1521
1522 *input_line_pointer = c;
1523
aa8c34c3
JE
1524 if (*input_line_pointer == '"')
1525 ++input_line_pointer;
1526
904a31bf 1527 elfsym->symbol.flags |= type;
252b5132
RH
1528
1529 demand_empty_rest_of_line ();
1530}
1531
1532static void
dbe2df79 1533obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1534{
1535 static segT comment_section;
1536 segT old_section = now_seg;
1537 int old_subsection = now_subseg;
1538
5f91fe03
ILT
1539#ifdef md_flush_pending_output
1540 md_flush_pending_output ();
1541#endif
1542
252b5132
RH
1543 if (!comment_section)
1544 {
1545 char *p;
1546 comment_section = subseg_new (".comment", 0);
1547 bfd_set_section_flags (stdoutput, comment_section,
1548 SEC_READONLY | SEC_HAS_CONTENTS);
1549 p = frag_more (1);
1550 *p = 0;
1551 }
1552 else
1553 subseg_set (comment_section, 0);
1554 stringer (1);
1555 subseg_set (old_section, old_subsection);
1556}
1557
1558#ifdef INIT_STAB_SECTION
1559
1560/* The first entry in a .stabs section is special. */
1561
1562void
dbe2df79 1563obj_elf_init_stab_section (segT seg)
252b5132
RH
1564{
1565 char *file;
1566 char *p;
1567 char *stabstr_name;
1568 unsigned int stroff;
1569
1570 /* Force the section to align to a longword boundary. Without this,
1571 UnixWare ar crashes. */
1572 bfd_set_section_alignment (stdoutput, seg, 2);
1573
bf514e21 1574 /* Make space for this first symbol. */
252b5132 1575 p = frag_more (12);
bf514e21 1576 /* Zero it out. */
252b5132 1577 memset (p, 0, 12);
dbe2df79
AM
1578 as_where (&file, NULL);
1579 stabstr_name = xmalloc (strlen (segment_name (seg)) + 4);
252b5132
RH
1580 strcpy (stabstr_name, segment_name (seg));
1581 strcat (stabstr_name, "str");
1582 stroff = get_stab_string_offset (file, stabstr_name);
1583 know (stroff == 1);
1584 md_number_to_chars (p, stroff, 4);
1585 seg_info (seg)->stabu.p = p;
1586}
1587
1588#endif
1589
1590/* Fill in the counts in the first entry in a .stabs section. */
1591
1592static void
dbe2df79 1593adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
252b5132
RH
1594{
1595 char *name;
1596 asection *strsec;
1597 char *p;
1598 int strsz, nsyms;
1599
1600 if (strncmp (".stab", sec->name, 5))
1601 return;
1602 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1603 return;
1604
dbe2df79 1605 name = alloca (strlen (sec->name) + 4);
252b5132
RH
1606 strcpy (name, sec->name);
1607 strcat (name, "str");
1608 strsec = bfd_get_section_by_name (abfd, name);
1609 if (strsec)
1610 strsz = bfd_section_size (abfd, strsec);
1611 else
1612 strsz = 0;
1613 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1614
1615 p = seg_info (sec)->stabu.p;
1616 assert (p != 0);
1617
dbe2df79
AM
1618 bfd_h_put_16 (abfd, nsyms, p + 6);
1619 bfd_h_put_32 (abfd, strsz, p + 8);
252b5132
RH
1620}
1621
1622#ifdef NEED_ECOFF_DEBUG
1623
1624/* This function is called by the ECOFF code. It is supposed to
1625 record the external symbol information so that the backend can
1626 write it out correctly. The ELF backend doesn't actually handle
1627 this at the moment, so we do it ourselves. We save the information
1628 in the symbol. */
1629
1630void
dbe2df79 1631elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
252b5132 1632{
dbe2df79 1633 symbol_get_bfdsym (sym)->udata.p = ext;
252b5132
RH
1634}
1635
1636/* This function is called by bfd_ecoff_debug_externals. It is
1637 supposed to *EXT to the external symbol information, and return
1638 whether the symbol should be used at all. */
1639
b34976b6 1640static bfd_boolean
dbe2df79 1641elf_get_extr (asymbol *sym, EXTR *ext)
252b5132
RH
1642{
1643 if (sym->udata.p == NULL)
b34976b6 1644 return FALSE;
252b5132 1645 *ext = *(EXTR *) sym->udata.p;
b34976b6 1646 return TRUE;
252b5132
RH
1647}
1648
1649/* This function is called by bfd_ecoff_debug_externals. It has
1650 nothing to do for ELF. */
1651
252b5132 1652static void
dbe2df79
AM
1653elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
1654 bfd_size_type indx ATTRIBUTE_UNUSED)
252b5132
RH
1655{
1656}
1657
1658#endif /* NEED_ECOFF_DEBUG */
1659
1660void
dbe2df79 1661elf_frob_symbol (symbolS *symp, int *puntp)
252b5132 1662{
49309057
ILT
1663 struct elf_obj_sy *sy_obj;
1664
252b5132
RH
1665#ifdef NEED_ECOFF_DEBUG
1666 if (ECOFF_DEBUGGING)
1667 ecoff_frob_symbol (symp);
1668#endif
1669
49309057
ILT
1670 sy_obj = symbol_get_obj (symp);
1671
1672 if (sy_obj->size != NULL)
252b5132 1673 {
49309057 1674 switch (sy_obj->size->X_op)
252b5132
RH
1675 {
1676 case O_subtract:
1677 S_SET_SIZE (symp,
49309057
ILT
1678 (S_GET_VALUE (sy_obj->size->X_add_symbol)
1679 + sy_obj->size->X_add_number
1680 - S_GET_VALUE (sy_obj->size->X_op_symbol)));
252b5132
RH
1681 break;
1682 case O_constant:
1683 S_SET_SIZE (symp,
49309057
ILT
1684 (S_GET_VALUE (sy_obj->size->X_add_symbol)
1685 + sy_obj->size->X_add_number));
252b5132
RH
1686 break;
1687 default:
1688 as_bad (_(".size expression too complicated to fix up"));
1689 break;
1690 }
49309057
ILT
1691 free (sy_obj->size);
1692 sy_obj->size = NULL;
252b5132
RH
1693 }
1694
49309057 1695 if (sy_obj->versioned_name != NULL)
252b5132 1696 {
79082ff0
L
1697 char *p;
1698
1699 p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
1700 know (p != NULL);
1701
252b5132
RH
1702 /* This symbol was given a new name with the .symver directive.
1703
13c56984
AM
1704 If this is an external reference, just rename the symbol to
1705 include the version string. This will make the relocs be
1706 against the correct versioned symbol.
252b5132
RH
1707
1708 If this is a definition, add an alias. FIXME: Using an alias
1709 will permit the debugging information to refer to the right
1710 symbol. However, it's not clear whether it is the best
1711 approach. */
1712
1713 if (! S_IS_DEFINED (symp))
1714 {
252b5132 1715 /* Verify that the name isn't using the @@ syntax--this is
13c56984
AM
1716 reserved for definitions of the default version to link
1717 against. */
252b5132
RH
1718 if (p[1] == ELF_VER_CHR)
1719 {
1720 as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
49309057 1721 sy_obj->versioned_name);
b34976b6 1722 *puntp = TRUE;
252b5132 1723 }
49309057 1724 S_SET_NAME (symp, sy_obj->versioned_name);
252b5132
RH
1725 }
1726 else
1727 {
dbe2df79 1728 if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
79082ff0
L
1729 {
1730 size_t l;
1731
1732 /* The @@@ syntax is a special case. It renames the
1733 symbol name to versioned_name with one `@' removed. */
1734 l = strlen (&p[3]) + 1;
dbe2df79 1735 memmove (&p[2], &p[3], l);
79082ff0
L
1736 S_SET_NAME (symp, sy_obj->versioned_name);
1737 }
1738 else
1739 {
1740 symbolS *symp2;
252b5132 1741
79082ff0
L
1742 /* FIXME: Creating a new symbol here is risky. We're
1743 in the final loop over the symbol table. We can
1744 get away with it only because the symbol goes to
1745 the end of the list, where the loop will still see
1746 it. It would probably be better to do this in
1747 obj_frob_file_before_adjust. */
252b5132 1748
79082ff0 1749 symp2 = symbol_find_or_make (sy_obj->versioned_name);
252b5132 1750
79082ff0 1751 /* Now we act as though we saw symp2 = sym. */
252b5132 1752
79082ff0 1753 S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
252b5132 1754
79082ff0
L
1755 /* Subtracting out the frag address here is a hack
1756 because we are in the middle of the final loop. */
1757 S_SET_VALUE (symp2,
1758 (S_GET_VALUE (symp)
1759 - symbol_get_frag (symp)->fr_address));
252b5132 1760
79082ff0 1761 symbol_set_frag (symp2, symbol_get_frag (symp));
252b5132 1762
79082ff0
L
1763 /* This will copy over the size information. */
1764 copy_symbol_attributes (symp2, symp);
252b5132 1765
26eb4093
JJ
1766 S_SET_OTHER (symp2, S_GET_OTHER (symp));
1767
79082ff0
L
1768 if (S_IS_WEAK (symp))
1769 S_SET_WEAK (symp2);
252b5132 1770
79082ff0
L
1771 if (S_IS_EXTERNAL (symp))
1772 S_SET_EXTERNAL (symp2);
1773 }
252b5132
RH
1774 }
1775 }
1776
1777 /* Double check weak symbols. */
49309057 1778 if (S_IS_WEAK (symp))
252b5132
RH
1779 {
1780 if (S_IS_COMMON (symp))
6ce8b369 1781 as_bad (_("symbol `%s' can not be both weak and common"),
252b5132
RH
1782 S_GET_NAME (symp));
1783 }
1784
1785#ifdef TC_MIPS
1786 /* The Irix 5 and 6 assemblers set the type of any common symbol and
1787 any undefined non-function symbol to STT_OBJECT. We try to be
1788 compatible, since newer Irix 5 and 6 linkers care. However, we
1789 only set undefined symbols to be STT_OBJECT if we are on Irix,
1790 because that is the only time gcc will generate the necessary
1791 .global directives to mark functions. */
1792
1793 if (S_IS_COMMON (symp))
49309057 1794 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1795
1796 if (strstr (TARGET_OS, "irix") != NULL
49309057
ILT
1797 && ! S_IS_DEFINED (symp)
1798 && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
1799 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1800#endif
1801
c5e54cc2
ILT
1802#if 0 /* TC_PPC */
1803 /* If TC_PPC is defined, we used to force the type of a symbol to be
1804 BSF_OBJECT if it was otherwise unset. This was required by some
1805 version of VxWorks. Thomas de Lellis <tdel@windriver.com> says
1806 that this is no longer needed, so it is now commented out. */
49309057
ILT
1807 if ((symbol_get_bfdsym (symp)->flags
1808 & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
252b5132 1809 && S_IS_DEFINED (symp))
49309057 1810 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1811#endif
1812}
1813
060adf0e
AM
1814struct group_list
1815{
1816 asection **head; /* Section lists. */
1817 unsigned int *elt_count; /* Number of sections in each list. */
1818 unsigned int num_group; /* Number of lists. */
1819};
1820
1821/* Called via bfd_map_over_sections. If SEC is a member of a group,
1822 add it to a list of sections belonging to the group. INF is a
1823 pointer to a struct group_list, which is where we store the head of
1824 each list. */
1825
1826static void
dbe2df79 1827build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
060adf0e 1828{
dbe2df79 1829 struct group_list *list = inf;
aa1f4858 1830 const char *group_name = elf_group_name (sec);
060adf0e
AM
1831 unsigned int i;
1832
1833 if (group_name == NULL)
1834 return;
1835
1836 /* If this group already has a list, add the section to the head of
1837 the list. */
1838 for (i = 0; i < list->num_group; i++)
1839 {
aa1f4858 1840 if (strcmp (group_name, elf_group_name (list->head[i])) == 0)
060adf0e 1841 {
aa1f4858 1842 elf_next_in_group (sec) = list->head[i];
060adf0e
AM
1843 list->head[i] = sec;
1844 list->elt_count[i] += 1;
1845 return;
1846 }
1847 }
1848
1849 /* New group. Make the arrays bigger in chunks to minimize calls to
1850 realloc. */
1851 i = list->num_group;
1852 if ((i & 127) == 0)
1853 {
1854 unsigned int newsize = i + 128;
1855 list->head = xrealloc (list->head, newsize * sizeof (*list->head));
1856 list->elt_count = xrealloc (list->elt_count,
1857 newsize * sizeof (*list->elt_count));
1858 }
1859 list->head[i] = sec;
1860 list->elt_count[i] = 1;
1861 list->num_group += 1;
1862}
1863
252b5132 1864void
dbe2df79 1865elf_frob_file (void)
252b5132 1866{
060adf0e
AM
1867 struct group_list list;
1868 unsigned int i;
1869
dbe2df79 1870 bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
252b5132 1871
060adf0e
AM
1872 /* Go find section groups. */
1873 list.num_group = 0;
1874 list.head = NULL;
1875 list.elt_count = NULL;
dbe2df79 1876 bfd_map_over_sections (stdoutput, build_group_lists, &list);
060adf0e
AM
1877
1878 /* Make the SHT_GROUP sections that describe each section group. We
1879 can't set up the section contents here yet, because elf section
1880 indices have yet to be calculated. elf.c:set_group_contents does
1881 the rest of the work. */
1882 for (i = 0; i < list.num_group; i++)
1883 {
aa1f4858 1884 const char *group_name = elf_group_name (list.head[i]);
9758f3fc 1885 const char *sec_name;
060adf0e
AM
1886 asection *s;
1887 flagword flags;
9758f3fc
AM
1888 struct symbol *sy;
1889 int has_sym;
587aac4e 1890 bfd_size_type size;
060adf0e 1891
060adf0e 1892 flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
d2dab548 1893 for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
68bfbfcc 1894 if ((s->flags ^ flags) & SEC_LINK_ONCE)
d2dab548
AM
1895 {
1896 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1897 if (s != list.head[i])
1898 {
1899 as_warn (_("assuming all members of group `%s' are COMDAT"),
1900 group_name);
1901 break;
1902 }
1903 }
1904
9758f3fc
AM
1905 sec_name = group_name;
1906 sy = symbol_find_exact (group_name);
1907 has_sym = 0;
1908 if (sy != NULL
1909 && (sy == symbol_lastP
1910 || (sy->sy_next != NULL
1911 && sy->sy_next->sy_previous == sy)))
1912 {
1913 has_sym = 1;
1914 sec_name = ".group";
1915 }
1916 s = subseg_force_new (sec_name, 0);
060adf0e
AM
1917 if (s == NULL
1918 || !bfd_set_section_flags (stdoutput, s, flags)
1919 || !bfd_set_section_alignment (stdoutput, s, 2))
1920 {
1921 as_fatal (_("can't create group: %s"),
1922 bfd_errmsg (bfd_get_error ()));
1923 }
2f89ff8d 1924 elf_section_type (s) = SHT_GROUP;
060adf0e 1925
aa1f4858
AM
1926 /* Pass a pointer to the first section in this group. */
1927 elf_next_in_group (s) = list.head[i];
9758f3fc
AM
1928 if (has_sym)
1929 elf_group_id (s) = sy->bsym;
060adf0e 1930
587aac4e
AM
1931 size = 4 * (list.elt_count[i] + 1);
1932 bfd_set_section_size (stdoutput, s, size);
1933 s->contents = frag_more (size);
060adf0e
AM
1934 frag_now->fr_fix = frag_now_fix_octets ();
1935 }
1936
252b5132
RH
1937#ifdef elf_tc_final_processing
1938 elf_tc_final_processing ();
1939#endif
1940}
1941
4a1805b1 1942/* It removes any unneeded versioned symbols from the symbol table. */
339681c0
L
1943
1944void
dbe2df79 1945elf_frob_file_before_adjust (void)
339681c0
L
1946{
1947 if (symbol_rootP)
1948 {
1949 symbolS *symp;
1950
1951 for (symp = symbol_rootP; symp; symp = symbol_next (symp))
00e6e13d 1952 if (!S_IS_DEFINED (symp))
79082ff0 1953 {
00e6e13d 1954 if (symbol_get_obj (symp)->versioned_name)
79082ff0
L
1955 {
1956 char *p;
1957
1958 /* The @@@ syntax is a special case. If the symbol is
1959 not defined, 2 `@'s will be removed from the
1960 versioned_name. */
1961
1962 p = strchr (symbol_get_obj (symp)->versioned_name,
1963 ELF_VER_CHR);
1964 know (p != NULL);
dbe2df79 1965 if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
79082ff0
L
1966 {
1967 size_t l = strlen (&p[3]) + 1;
dbe2df79 1968 memmove (&p[1], &p[3], l);
79082ff0
L
1969 }
1970 if (symbol_used_p (symp) == 0
1971 && symbol_used_in_reloc_p (symp) == 0)
1972 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
1973 }
00e6e13d
JJ
1974
1975 /* If there was .weak foo, but foo was neither defined nor
1976 used anywhere, remove it. */
1977
1978 else if (S_IS_WEAK (symp)
1979 && symbol_used_p (symp) == 0
1980 && symbol_used_in_reloc_p (symp) == 0)
1981 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
79082ff0 1982 }
339681c0
L
1983 }
1984}
1985
252b5132
RH
1986/* It is required that we let write_relocs have the opportunity to
1987 optimize away fixups before output has begun, since it is possible
1988 to eliminate all fixups for a section and thus we never should
1989 have generated the relocation section. */
1990
1991void
dbe2df79 1992elf_frob_file_after_relocs (void)
252b5132
RH
1993{
1994#ifdef NEED_ECOFF_DEBUG
1995 if (ECOFF_DEBUGGING)
1996 /* Generate the ECOFF debugging information. */
1997 {
1998 const struct ecoff_debug_swap *debug_swap;
1999 struct ecoff_debug_info debug;
2000 char *buf;
2001 asection *sec;
2002
2003 debug_swap
2004 = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
dbe2df79 2005 know (debug_swap != NULL);
252b5132
RH
2006 ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
2007
2008 /* Set up the pointers in debug. */
2009#define SET(ptr, offset, type) \
2010 debug.ptr = (type) (buf + debug.symbolic_header.offset)
2011
2012 SET (line, cbLineOffset, unsigned char *);
dbe2df79
AM
2013 SET (external_dnr, cbDnOffset, void *);
2014 SET (external_pdr, cbPdOffset, void *);
2015 SET (external_sym, cbSymOffset, void *);
2016 SET (external_opt, cbOptOffset, void *);
252b5132
RH
2017 SET (external_aux, cbAuxOffset, union aux_ext *);
2018 SET (ss, cbSsOffset, char *);
dbe2df79
AM
2019 SET (external_fdr, cbFdOffset, void *);
2020 SET (external_rfd, cbRfdOffset, void *);
252b5132
RH
2021 /* ssext and external_ext are set up just below. */
2022
2023#undef SET
2024
2025 /* Set up the external symbols. */
2026 debug.ssext = debug.ssext_end = NULL;
2027 debug.external_ext = debug.external_ext_end = NULL;
b34976b6 2028 if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, TRUE,
252b5132 2029 elf_get_extr, elf_set_index))
6ce8b369 2030 as_fatal (_("failed to set up debugging information: %s"),
252b5132
RH
2031 bfd_errmsg (bfd_get_error ()));
2032
2033 sec = bfd_get_section_by_name (stdoutput, ".mdebug");
2034 assert (sec != NULL);
2035
b34976b6 2036 know (!stdoutput->output_has_begun);
252b5132
RH
2037
2038 /* We set the size of the section, call bfd_set_section_contents
2039 to force the ELF backend to allocate a file position, and then
2040 write out the data. FIXME: Is this really the best way to do
2041 this? */
587aac4e
AM
2042 bfd_set_section_size
2043 (stdoutput, sec, bfd_ecoff_debug_size (stdoutput, &debug, debug_swap));
252b5132 2044
5f91fe03 2045 /* Pass BUF to bfd_set_section_contents because this will
13c56984
AM
2046 eventually become a call to fwrite, and ISO C prohibits
2047 passing a NULL pointer to a stdio function even if the
2048 pointer will not be used. */
dbe2df79 2049 if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
6ce8b369 2050 as_fatal (_("can't start writing .mdebug section: %s"),
252b5132
RH
2051 bfd_errmsg (bfd_get_error ()));
2052
b34976b6 2053 know (stdoutput->output_has_begun);
252b5132
RH
2054 know (sec->filepos != 0);
2055
2056 if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
2057 sec->filepos))
6ce8b369 2058 as_fatal (_("could not write .mdebug section: %s"),
252b5132
RH
2059 bfd_errmsg (bfd_get_error ()));
2060 }
2061#endif /* NEED_ECOFF_DEBUG */
2062}
2063
2064#ifdef SCO_ELF
2065
aaa2624b 2066/* Heavily plagiarized from obj_elf_version. The idea is to emit the
252b5132
RH
2067 SCO specific identifier in the .notes section to satisfy the SCO
2068 linker.
2069
2070 This looks more complicated than it really is. As opposed to the
2071 "obvious" solution, this should handle the cross dev cases
2072 correctly. (i.e, hosting on a 64 bit big endian processor, but
2073 generating SCO Elf code) Efficiency isn't a concern, as there
2074 should be exactly one of these sections per object module.
2075
2076 SCO OpenServer 5 identifies it's ELF modules with a standard ELF
2077 .note section.
2078
fa306131
AM
2079 int_32 namesz = 4 ; Name size
2080 int_32 descsz = 12 ; Descriptive information
2081 int_32 type = 1 ;
2082 char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
252b5132
RH
2083 int_32 version = (major ver # << 16) | version of tools ;
2084 int_32 source = (tool_id << 16 ) | 1 ;
2085 int_32 info = 0 ; These are set by the SCO tools, but we
13c56984 2086 don't know enough about the source
252b5132
RH
2087 environment to set them. SCO ld currently
2088 ignores them, and recommends we set them
2089 to zero. */
2090
2091#define SCO_MAJOR_VERSION 0x1
2092#define SCO_MINOR_VERSION 0x1
2093
2094void
dbe2df79 2095sco_id (void)
252b5132
RH
2096{
2097
2098 char *name;
2099 unsigned int c;
2100 char ch;
2101 char *p;
2102 asection *seg = now_seg;
2103 subsegT subseg = now_subseg;
2104 Elf_Internal_Note i_note;
2105 Elf_External_Note e_note;
dbe2df79 2106 asection *note_secp = NULL;
252b5132
RH
2107 int i, len;
2108
2109 /* create the .note section */
2110
2111 note_secp = subseg_new (".note", 0);
2112 bfd_set_section_flags (stdoutput,
2113 note_secp,
2114 SEC_HAS_CONTENTS | SEC_READONLY);
2115
2116 /* process the version string */
2117
fa306131 2118 i_note.namesz = 4;
252b5132
RH
2119 i_note.descsz = 12; /* 12 descriptive bytes */
2120 i_note.type = NT_VERSION; /* Contains a version string */
2121
2122 p = frag_more (sizeof (i_note.namesz));
dbe2df79 2123 md_number_to_chars (p, i_note.namesz, 4);
252b5132
RH
2124
2125 p = frag_more (sizeof (i_note.descsz));
dbe2df79 2126 md_number_to_chars (p, i_note.descsz, 4);
252b5132
RH
2127
2128 p = frag_more (sizeof (i_note.type));
dbe2df79 2129 md_number_to_chars (p, i_note.type, 4);
252b5132
RH
2130
2131 p = frag_more (4);
fa306131 2132 strcpy (p, "SCO");
252b5132
RH
2133
2134 /* Note: this is the version number of the ELF we're representing */
2135 p = frag_more (4);
2136 md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
2137
2138 /* Here, we pick a magic number for ourselves (yes, I "registered"
2139 it with SCO. The bottom bit shows that we are compat with the
2140 SCO ABI. */
2141 p = frag_more (4);
2142 md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
2143
2144 /* If we knew (or cared) what the source language options were, we'd
2145 fill them in here. SCO has given us permission to ignore these
2146 and just set them to zero. */
2147 p = frag_more (4);
2148 md_number_to_chars (p, 0x0000, 4);
fa306131 2149
252b5132
RH
2150 frag_align (2, 0, 0);
2151
2152 /* We probably can't restore the current segment, for there likely
2153 isn't one yet... */
2154 if (seg && subseg)
2155 subseg_set (seg, subseg);
2156
2157}
2158
2159#endif /* SCO_ELF */
2160
5110c57e 2161static int
dbe2df79 2162elf_separate_stab_sections (void)
5110c57e
HPN
2163{
2164#ifdef NEED_ECOFF_DEBUG
2165 return (!ECOFF_DEBUGGING);
2166#else
2167 return 1;
2168#endif
2169}
2170
2171static void
dbe2df79 2172elf_init_stab_section (segT seg)
5110c57e
HPN
2173{
2174#ifdef NEED_ECOFF_DEBUG
2175 if (!ECOFF_DEBUGGING)
2176#endif
2177 obj_elf_init_stab_section (seg);
2178}
2179
252b5132
RH
2180const struct format_ops elf_format_ops =
2181{
2182 bfd_target_elf_flavour,
4c63da97
AM
2183 0, /* dfl_leading_underscore */
2184 1, /* emit_section_symbols */
5110c57e
HPN
2185 elf_begin,
2186 elf_file_symbol,
252b5132
RH
2187 elf_frob_symbol,
2188 elf_frob_file,
339681c0 2189 elf_frob_file_before_adjust,
a161fe53 2190 0, /* obj_frob_file_before_fix */
252b5132
RH
2191 elf_frob_file_after_relocs,
2192 elf_s_get_size, elf_s_set_size,
2193 elf_s_get_align, elf_s_set_align,
4c63da97 2194 elf_s_get_other,
5110c57e 2195 elf_s_set_other,
4c63da97 2196 0, /* s_get_desc */
5110c57e
HPN
2197 0, /* s_set_desc */
2198 0, /* s_get_type */
2199 0, /* s_set_type */
252b5132
RH
2200 elf_copy_symbol_attributes,
2201#ifdef NEED_ECOFF_DEBUG
2202 ecoff_generate_asm_lineno,
2203 ecoff_stab,
2204#else
4c63da97
AM
2205 0, /* generate_asm_lineno */
2206 0, /* process_stab */
252b5132 2207#endif
5110c57e
HPN
2208 elf_separate_stab_sections,
2209 elf_init_stab_section,
252b5132
RH
2210 elf_sec_sym_ok_for_reloc,
2211 elf_pop_insert,
2212#ifdef NEED_ECOFF_DEBUG
2213 elf_ecoff_set_ext,
2214#else
4c63da97 2215 0, /* ecoff_set_ext */
252b5132 2216#endif
4c63da97 2217 elf_obj_read_begin_hook,
5110c57e 2218 elf_obj_symbol_new_hook
252b5132 2219};