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