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