This set of patches add support for aout emulation on the x86
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
CommitLineData
252b5132 1/* ELF object file format
4c63da97 2 Copyright (C) 1992, 93-99, 2000 Free Software Foundation, Inc.
252b5132
RH
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2,
9 or (at your option) any later version.
10
11 GAS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21#define OBJ_HEADER "obj-elf.h"
22#include "as.h"
23#include "subsegs.h"
24#include "obstack.h"
25
26#ifndef ECOFF_DEBUGGING
27#define ECOFF_DEBUGGING 0
28#else
29#define NEED_ECOFF_DEBUG
30#endif
31
32#ifdef NEED_ECOFF_DEBUG
33#include "ecoff.h"
34#endif
35
36#ifdef TC_ALPHA
37#include "elf/alpha.h"
38#endif
39
40#ifdef TC_MIPS
41#include "elf/mips.h"
42#endif
43
44#ifdef TC_PPC
45#include "elf/ppc.h"
46#endif
47
48static bfd_vma elf_s_get_size PARAMS ((symbolS *));
49static void elf_s_set_size PARAMS ((symbolS *, bfd_vma));
50static bfd_vma elf_s_get_align PARAMS ((symbolS *));
51static void elf_s_set_align PARAMS ((symbolS *, bfd_vma));
52static void elf_copy_symbol_attributes PARAMS ((symbolS *, symbolS *));
53static int elf_sec_sym_ok_for_reloc PARAMS ((asection *));
54static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
55
56#ifdef NEED_ECOFF_DEBUG
57static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
58static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
59#endif
60
61static void obj_elf_line PARAMS ((int));
62void obj_elf_version PARAMS ((int));
63static void obj_elf_size PARAMS ((int));
64static void obj_elf_type PARAMS ((int));
65static void obj_elf_ident PARAMS ((int));
66static void obj_elf_weak PARAMS ((int));
67static void obj_elf_local PARAMS ((int));
2e13b764 68static void obj_elf_visibility PARAMS ((int));
252b5132
RH
69static void obj_elf_symver PARAMS ((int));
70static void obj_elf_vtable_inherit PARAMS ((int));
71static void obj_elf_vtable_entry PARAMS ((int));
252b5132 72static void obj_elf_subsection PARAMS ((int));
9de8d8f1 73static void obj_elf_popsection PARAMS ((int));
252b5132
RH
74
75static const pseudo_typeS elf_pseudo_table[] =
76{
77 {"comm", obj_elf_common, 0},
9be1cda6 78 {"common", obj_elf_common, 1},
252b5132
RH
79 {"ident", obj_elf_ident, 0},
80 {"local", obj_elf_local, 0},
81 {"previous", obj_elf_previous, 0},
82 {"section", obj_elf_section, 0},
83 {"section.s", obj_elf_section, 0},
84 {"sect", obj_elf_section, 0},
85 {"sect.s", obj_elf_section, 0},
9de8d8f1
RH
86 {"pushsection", obj_elf_section, 1},
87 {"popsection", obj_elf_popsection, 0},
252b5132
RH
88 {"size", obj_elf_size, 0},
89 {"type", obj_elf_type, 0},
90 {"version", obj_elf_version, 0},
91 {"weak", obj_elf_weak, 0},
92
2e13b764
NC
93 /* These define symbol visibility. */
94 {"internal", obj_elf_visibility, STV_INTERNAL},
95 {"hidden", obj_elf_visibility, STV_HIDDEN},
96 {"protected", obj_elf_visibility, STV_PROTECTED},
97
252b5132
RH
98 /* These are used for stabs-in-elf configurations. */
99 {"line", obj_elf_line, 0},
100
101 /* This is a GNU extension to handle symbol versions. */
102 {"symver", obj_elf_symver, 0},
103
104 /* A GNU extension to change subsection only. */
105 {"subsection", obj_elf_subsection, 0},
106
107 /* These are GNU extensions to aid in garbage collecting C++ vtables. */
108 {"vtable_inherit", obj_elf_vtable_inherit, 0},
109 {"vtable_entry", obj_elf_vtable_entry, 0},
110
111 /* These are used for dwarf. */
112 {"2byte", cons, 2},
113 {"4byte", cons, 4},
114 {"8byte", cons, 8},
115
116 /* We need to trap the section changing calls to handle .previous. */
117 {"data", obj_elf_data, 0},
118 {"text", obj_elf_text, 0},
119
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
175elf_begin ()
176{
177 /* Add symbols for the known sections to the symbol table. */
178 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
179 TEXT_SECTION_NAME)));
180 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
181 DATA_SECTION_NAME)));
182 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
183 BSS_SECTION_NAME)));
184}
185
186void
187elf_pop_insert ()
188{
189 pop_insert (elf_pseudo_table);
190 if (ECOFF_DEBUGGING)
191 pop_insert (ecoff_debug_pseudo_table);
192}
193
194static bfd_vma
195elf_s_get_size (sym)
196 symbolS *sym;
197{
198 return S_GET_SIZE (sym);
199}
200
201static void
202elf_s_set_size (sym, sz)
203 symbolS *sym;
204 bfd_vma sz;
205{
206 S_SET_SIZE (sym, sz);
207}
208
209static bfd_vma
210elf_s_get_align (sym)
211 symbolS *sym;
212{
213 return S_GET_ALIGN (sym);
214}
215
216static void
217elf_s_set_align (sym, align)
218 symbolS *sym;
219 bfd_vma align;
220{
221 S_SET_ALIGN (sym, align);
222}
223
4c63da97
AM
224int
225elf_s_get_other (sym)
226 symbolS *sym;
227{
228 return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
229}
230
252b5132
RH
231static void
232elf_copy_symbol_attributes (dest, src)
233 symbolS *dest, *src;
234{
235 OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
236}
237
238static int
239elf_sec_sym_ok_for_reloc (sec)
240 asection *sec;
241{
242 return obj_sec_sym_ok_for_reloc (sec);
243}
244
245void
246elf_file_symbol (s)
247 char *s;
248{
249 symbolS *sym;
250
251 sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
49309057
ILT
252 symbol_set_frag (sym, &zero_address_frag);
253 symbol_get_bfdsym (sym)->flags |= BSF_FILE;
252b5132
RH
254
255 if (symbol_rootP != sym)
256 {
257 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
258 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
259#ifdef DEBUG
260 verify_symbol_chain (symbol_rootP, symbol_lastP);
261#endif
262 }
263
264#ifdef NEED_ECOFF_DEBUG
265 ecoff_new_file (s);
266#endif
267}
268
16b93d88 269void
9be1cda6
AS
270obj_elf_common (is_common)
271 int is_common;
252b5132
RH
272{
273 char *name;
274 char c;
275 char *p;
276 int temp, size;
277 symbolS *symbolP;
278 int have_align;
279
9be1cda6
AS
280 if (flag_mri && is_common)
281 {
282 s_mri_common (0);
283 return;
284 }
285
252b5132
RH
286 name = input_line_pointer;
287 c = get_symbol_end ();
288 /* just after name is now '\0' */
289 p = input_line_pointer;
290 *p = c;
291 SKIP_WHITESPACE ();
292 if (*input_line_pointer != ',')
293 {
294 as_bad (_("Expected comma after symbol-name"));
295 ignore_rest_of_line ();
296 return;
297 }
298 input_line_pointer++; /* skip ',' */
299 if ((temp = get_absolute_expression ()) < 0)
300 {
301 as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
302 ignore_rest_of_line ();
303 return;
304 }
305 size = temp;
306 *p = 0;
307 symbolP = symbol_find_or_make (name);
308 *p = c;
309 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
310 {
311 as_bad (_("Ignoring attempt to re-define symbol"));
312 ignore_rest_of_line ();
313 return;
314 }
315 if (S_GET_VALUE (symbolP) != 0)
316 {
ab9da554 317 if (S_GET_VALUE (symbolP) != (valueT) size)
252b5132
RH
318 {
319 as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
320 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
321 }
322 }
323 know (symbolP->sy_frag == &zero_address_frag);
324 if (*input_line_pointer != ',')
325 have_align = 0;
326 else
327 {
328 have_align = 1;
329 input_line_pointer++;
330 SKIP_WHITESPACE ();
331 }
332 if (! have_align || *input_line_pointer != '"')
333 {
334 if (! have_align)
335 temp = 0;
336 else
337 {
338 temp = get_absolute_expression ();
339 if (temp < 0)
340 {
341 temp = 0;
342 as_warn (_("Common alignment negative; 0 assumed"));
343 }
344 }
49309057 345 if (symbol_get_obj (symbolP)->local)
252b5132
RH
346 {
347 segT old_sec;
348 int old_subsec;
349 char *pfrag;
350 int align;
351
352 /* allocate_bss: */
353 old_sec = now_seg;
354 old_subsec = now_subseg;
355 if (temp)
356 {
357 /* convert to a power of 2 alignment */
358 for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
359 if (temp != 1)
360 {
361 as_bad (_("Common alignment not a power of 2"));
362 ignore_rest_of_line ();
363 return;
364 }
365 }
366 else
367 align = 0;
368 record_alignment (bss_section, align);
369 subseg_set (bss_section, 0);
370 if (align)
371 frag_align (align, 0, 0);
372 if (S_GET_SEGMENT (symbolP) == bss_section)
49309057
ILT
373 symbol_get_frag (symbolP)->fr_symbol = 0;
374 symbol_set_frag (symbolP, frag_now);
252b5132
RH
375 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
376 (offsetT) size, (char *) 0);
377 *pfrag = 0;
378 S_SET_SIZE (symbolP, size);
379 S_SET_SEGMENT (symbolP, bss_section);
380 S_CLEAR_EXTERNAL (symbolP);
381 subseg_set (old_sec, old_subsec);
382 }
383 else
384 {
385 allocate_common:
386 S_SET_VALUE (symbolP, (valueT) size);
387 S_SET_ALIGN (symbolP, temp);
388 S_SET_EXTERNAL (symbolP);
389 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
390 }
391 }
392 else
393 {
394 input_line_pointer++;
395 /* @@ Some use the dot, some don't. Can we get some consistency?? */
396 if (*input_line_pointer == '.')
397 input_line_pointer++;
398 /* @@ Some say data, some say bss. */
399 if (strncmp (input_line_pointer, "bss\"", 4)
400 && strncmp (input_line_pointer, "data\"", 5))
401 {
402 while (*--input_line_pointer != '"')
403 ;
404 input_line_pointer--;
405 goto bad_common_segment;
406 }
407 while (*input_line_pointer++ != '"')
408 ;
409 goto allocate_common;
410 }
411
49309057 412 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
252b5132
RH
413
414 demand_empty_rest_of_line ();
415 return;
416
417 {
418 bad_common_segment:
419 p = input_line_pointer;
420 while (*p && *p != '\n')
421 p++;
422 c = *p;
423 *p = '\0';
424 as_bad (_("bad .common segment %s"), input_line_pointer + 1);
425 *p = c;
426 input_line_pointer = p;
427 ignore_rest_of_line ();
428 return;
429 }
430}
431
432static void
433obj_elf_local (ignore)
ab9da554 434 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
435{
436 char *name;
437 int c;
438 symbolS *symbolP;
439
440 do
441 {
442 name = input_line_pointer;
443 c = get_symbol_end ();
444 symbolP = symbol_find_or_make (name);
445 *input_line_pointer = c;
446 SKIP_WHITESPACE ();
447 S_CLEAR_EXTERNAL (symbolP);
49309057 448 symbol_get_obj (symbolP)->local = 1;
252b5132
RH
449 if (c == ',')
450 {
451 input_line_pointer++;
452 SKIP_WHITESPACE ();
453 if (*input_line_pointer == '\n')
454 c = '\n';
455 }
456 }
457 while (c == ',');
458 demand_empty_rest_of_line ();
459}
460
461static void
462obj_elf_weak (ignore)
ab9da554 463 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
464{
465 char *name;
466 int c;
467 symbolS *symbolP;
468
469 do
470 {
471 name = input_line_pointer;
472 c = get_symbol_end ();
473 symbolP = symbol_find_or_make (name);
474 *input_line_pointer = c;
475 SKIP_WHITESPACE ();
476 S_SET_WEAK (symbolP);
49309057 477 symbol_get_obj (symbolP)->local = 1;
252b5132
RH
478 if (c == ',')
479 {
480 input_line_pointer++;
481 SKIP_WHITESPACE ();
482 if (*input_line_pointer == '\n')
483 c = '\n';
484 }
485 }
486 while (c == ',');
487 demand_empty_rest_of_line ();
488}
489
2e13b764
NC
490static void
491obj_elf_visibility (visibility)
492 int visibility;
493{
494 char *name;
495 int c;
496 symbolS *symbolP;
497 asymbol *bfdsym;
498 elf_symbol_type *elfsym;
499
500 do
501 {
502 name = input_line_pointer;
503 c = get_symbol_end ();
504 symbolP = symbol_find_or_make (name);
505 *input_line_pointer = c;
506
507 SKIP_WHITESPACE ();
508
509 bfdsym = symbol_get_bfdsym (symbolP);
510 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
511
512 assert (elfsym);
513
514 elfsym->internal_elf_sym.st_other = visibility;
515
516 if (c == ',')
517 {
518 input_line_pointer ++;
519
520 SKIP_WHITESPACE ();
521
522 if (*input_line_pointer == '\n')
523 c = '\n';
524 }
525 }
526 while (c == ',');
527
528 demand_empty_rest_of_line ();
529}
530
531
252b5132
RH
532static segT previous_section;
533static int previous_subsection;
534
9de8d8f1
RH
535struct section_stack
536{
537 struct section_stack *next;
538 segT seg, prev_seg;
539 int subseg, prev_subseg;
540};
541
542static struct section_stack *section_stack;
543
544
252b5132
RH
545/* Handle the .section pseudo-op. This code supports two different
546 syntaxes.
547
548 The first is found on Solaris, and looks like
549 .section ".sec1",#alloc,#execinstr,#write
550 Here the names after '#' are the SHF_* flags to turn on for the
551 section. I'm not sure how it determines the SHT_* type (BFD
552 doesn't really give us control over the type, anyhow).
553
554 The second format is found on UnixWare, and probably most SVR4
555 machines, and looks like
556 .section .sec1,"a",@progbits
557 The quoted string may contain any combination of a, w, x, and
558 represents the SHF_* flags to turn on for the section. The string
559 beginning with '@' can be progbits or nobits. There should be
560 other possibilities, but I don't know what they are. In any case,
561 BFD doesn't really let us set the section type. */
562
563/* Certain named sections have particular defined types, listed on p.
564 4-19 of the ABI. */
565struct special_section
566{
567 const char *name;
568 int type;
569 int attributes;
570};
571
9de8d8f1 572static struct special_section const special_sections[] =
252b5132
RH
573{
574 { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
575 { ".comment", SHT_PROGBITS, 0 },
576 { ".data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
577 { ".data1", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
578 { ".debug", SHT_PROGBITS, 0 },
579 { ".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
580 { ".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
581 { ".line", SHT_PROGBITS, 0 },
582 { ".note", SHT_NOTE, 0 },
583 { ".rodata", SHT_PROGBITS, SHF_ALLOC },
584 { ".rodata1", SHT_PROGBITS, SHF_ALLOC },
585 { ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
586
587#ifdef ELF_TC_SPECIAL_SECTIONS
588 ELF_TC_SPECIAL_SECTIONS
589#endif
590
591#if 0
592 /* The following section names are special, but they can not
593 reasonably appear in assembler code. Some of the attributes are
594 processor dependent. */
595 { ".dynamic", SHT_DYNAMIC, SHF_ALLOC /* + SHF_WRITE */ },
596 { ".dynstr", SHT_STRTAB, SHF_ALLOC },
597 { ".dynsym", SHT_DYNSYM, SHF_ALLOC },
598 { ".got", SHT_PROGBITS, 0 },
599 { ".hash", SHT_HASH, SHF_ALLOC },
600 { ".interp", SHT_PROGBITS, /* SHF_ALLOC */ },
601 { ".plt", SHT_PROGBITS, 0 },
602 { ".shstrtab",SHT_STRTAB, 0 },
603 { ".strtab", SHT_STRTAB, /* SHF_ALLOC */ },
604 { ".symtab", SHT_SYMTAB, /* SHF_ALLOC */ },
605#endif
606
607 { NULL, 0, 0 }
608};
609
610void
9de8d8f1
RH
611obj_elf_change_section (name, type, attr, push)
612 char *name;
613 int type, attr, push;
252b5132 614{
252b5132
RH
615 int new_sec;
616 segT sec;
252b5132
RH
617
618#ifdef md_flush_pending_output
619 md_flush_pending_output ();
620#endif
621
9de8d8f1
RH
622 /* Switch to the section, creating it if necessary. */
623 if (push)
624 {
625 struct section_stack *elt;
626 elt = xmalloc (sizeof (struct section_stack));
627 elt->next = section_stack;
628 elt->seg = now_seg;
629 elt->prev_seg = previous_section;
630 elt->subseg = now_subseg;
631 elt->prev_subseg = previous_subsection;
632 section_stack = elt;
633 }
634 previous_section = now_seg;
635 previous_subsection = now_subseg;
636
637 new_sec = bfd_get_section_by_name (stdoutput, name) == NULL;
638 sec = subseg_new (name, 0);
639
640 if (new_sec)
641 {
642 flagword flags;
643 symbolS *secsym;
644 int i;
645
646 /* See if this is one of the special sections. */
647 for (i = 0; special_sections[i].name != NULL; i++)
648 if (strcmp (name, special_sections[i].name) == 0)
649 {
650 if (type == SHT_NULL)
651 type = special_sections[i].type;
652 else if (type != special_sections[i].type)
653 as_warn (_("Setting incorrect section type for %s"), name);
654
655 if ((attr &~ special_sections[i].attributes) != 0)
656 {
657 /* As a GNU extension, we permit a .note section to be
658 allocatable. If the linker sees an allocateable .note
659 section, it will create a PT_NOTE segment in the output
660 file. */
661 if (strcmp (name, ".note") != 0
662 || attr != SHF_ALLOC)
663 as_warn (_("Setting incorrect section attributes for %s"),
664 name);
665 }
666 attr |= special_sections[i].attributes;
667 break;
668 }
669
670 /* Convert ELF type and flags to BFD flags. */
671 flags = (SEC_RELOC
672 | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
673 | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
674 | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
675 | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
676#ifdef md_elf_section_flags
677 flags = md_elf_section_flags (flags, attr, type);
678#endif
679
680 /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
681 if (type == SHT_NOBITS)
682 seg_info (sec)->bss = 1;
683
684 bfd_set_section_flags (stdoutput, sec, flags);
685
686 /* Add a symbol for this section to the symbol table. */
687 secsym = symbol_find (name);
688 if (secsym != NULL)
689 symbol_set_bfdsym (secsym, sec->symbol);
690 else
691 symbol_table_insert (section_symbol (sec));
692 }
693
694#ifdef md_elf_section_change_hook
695 md_elf_section_change_hook ();
696#endif
697}
698
699int
700obj_elf_parse_section_letters (str, len)
701 char *str;
702 size_t len;
703{
704 int attr = 0;
705
706 while (len > 0)
707 {
708 switch (*str)
709 {
710 case 'a':
711 attr |= SHF_ALLOC;
712 break;
713 case 'w':
714 attr |= SHF_WRITE;
715 break;
716 case 'x':
717 attr |= SHF_EXECINSTR;
718 break;
719 default:
720 {
721 char *bad_msg = _("Unrecognized .section attribute: want a,w,x");
722#ifdef md_elf_section_letter
723 int md_attr = md_elf_section_letter (*str, &bad_msg);
724 if (md_attr >= 0)
725 attr |= md_attr;
726 else
727#endif
728 {
4c63da97 729 as_warn ("%s", bad_msg);
9de8d8f1
RH
730 attr = -1;
731 }
732 }
733 break;
734 }
735 str++, len--;
736 }
737
738 return attr;
739}
740
741int
742obj_elf_section_word (str, len)
743 char *str;
744 size_t len;
745{
746 if (len == 5 && strncmp (str, "write", 5) == 0)
747 return SHF_WRITE;
748 if (len == 5 && strncmp (str, "alloc", 5) == 0)
749 return SHF_ALLOC;
750 if (len == 9 && strncmp (str, "execinstr", 9) == 0)
751 return SHF_EXECINSTR;
752
753#ifdef md_elf_section_word
754 {
755 int md_attr = md_elf_section_word (str, len);
756 if (md_attr >= 0)
757 return md_attr;
758 }
759#endif
760
761 as_warn (_("Unrecognized section attribute"));
762 return 0;
763}
764
765int
766obj_elf_section_type (str, len)
767 char *str;
768 size_t len;
769{
770 if (len == 8 && strncmp (str, "progbits", 8) == 0)
771 return SHT_PROGBITS;
772 if (len == 6 && strncmp (str, "nobits", 6) == 0)
773 return SHT_NOBITS;
774
775#ifdef md_elf_section_type
776 {
777 int md_type = md_elf_section_type (str, len);
778 if (md_type >= 0)
779 return md_type;
780 }
781#endif
782
783 as_warn (_("Unrecognized section type"));
784 return 0;
785}
786
787void
788obj_elf_section (push)
789 int push;
790{
791 char *name, *beg, *end;
792 int type, attr, dummy;
793
252b5132
RH
794 if (flag_mri)
795 {
796 char mri_type;
797
9de8d8f1
RH
798#ifdef md_flush_pending_output
799 md_flush_pending_output ();
800#endif
801
252b5132
RH
802 previous_section = now_seg;
803 previous_subsection = now_subseg;
804
805 s_mri_sect (&mri_type);
806
807#ifdef md_elf_section_change_hook
808 md_elf_section_change_hook ();
809#endif
810
811 return;
812 }
813
814 /* Get name of section. */
815 SKIP_WHITESPACE ();
816 if (*input_line_pointer == '"')
817 {
9de8d8f1
RH
818 name = demand_copy_C_string (&dummy);
819 if (name == NULL)
252b5132
RH
820 {
821 ignore_rest_of_line ();
822 return;
823 }
824 }
825 else
826 {
9de8d8f1
RH
827 end = input_line_pointer;
828 while (0 == strchr ("\n\t,; ", *end))
829 end++;
830 if (end == input_line_pointer)
252b5132
RH
831 {
832 as_warn (_("Missing section name"));
833 ignore_rest_of_line ();
834 return;
835 }
9de8d8f1
RH
836
837 name = xmalloc (end - input_line_pointer + 1);
838 memcpy (name, input_line_pointer, end - input_line_pointer);
839 name[end - input_line_pointer] = '\0';
840 input_line_pointer = end;
252b5132 841 }
252b5132
RH
842 SKIP_WHITESPACE ();
843
844 type = SHT_NULL;
845 attr = 0;
846
847 if (*input_line_pointer == ',')
848 {
849 /* Skip the comma. */
850 ++input_line_pointer;
252b5132
RH
851 SKIP_WHITESPACE ();
852
853 if (*input_line_pointer == '"')
854 {
9de8d8f1
RH
855 beg = demand_copy_C_string (&dummy);
856 if (beg == NULL)
252b5132 857 {
9de8d8f1
RH
858 ignore_rest_of_line ();
859 return;
252b5132 860 }
9de8d8f1 861 attr |= obj_elf_parse_section_letters (beg, strlen (beg));
252b5132
RH
862
863 SKIP_WHITESPACE ();
864 if (*input_line_pointer == ',')
865 {
9de8d8f1 866 char c;
252b5132
RH
867 ++input_line_pointer;
868 SKIP_WHITESPACE ();
9de8d8f1
RH
869 c = *input_line_pointer;
870 if (c == '"')
252b5132 871 {
9de8d8f1
RH
872 beg = demand_copy_C_string (&dummy);
873 if (beg == NULL)
252b5132 874 {
9de8d8f1
RH
875 ignore_rest_of_line ();
876 return;
252b5132 877 }
9de8d8f1 878 type = obj_elf_section_type (beg, strlen (beg));
9de8d8f1
RH
879 }
880 else if (c == '@' || c == '%')
881 {
882 beg = ++input_line_pointer;
883 c = get_symbol_end ();
884 *input_line_pointer = c;
885 type = obj_elf_section_type (beg, input_line_pointer - beg);
252b5132
RH
886 }
887 }
888 }
889 else
890 {
891 do
892 {
9de8d8f1
RH
893 char c;
894
252b5132
RH
895 SKIP_WHITESPACE ();
896 if (*input_line_pointer != '#')
897 {
898 as_warn (_("Bad .section directive - character following name is not '#'"));
899 ignore_rest_of_line ();
900 return;
901 }
9de8d8f1
RH
902 beg = ++input_line_pointer;
903 c = get_symbol_end ();
904 *input_line_pointer = c;
905
906 attr |= obj_elf_section_word (beg, input_line_pointer - beg);
907
252b5132
RH
908 SKIP_WHITESPACE ();
909 }
910 while (*input_line_pointer++ == ',');
911 --input_line_pointer;
912 }
913 }
914
252b5132 915 demand_empty_rest_of_line ();
9de8d8f1
RH
916
917 obj_elf_change_section (name, type, attr, push);
252b5132
RH
918}
919
920/* Change to the .data section. */
921
16b93d88 922void
252b5132
RH
923obj_elf_data (i)
924 int i;
925{
926#ifdef md_flush_pending_output
927 md_flush_pending_output ();
928#endif
929
930 previous_section = now_seg;
931 previous_subsection = now_subseg;
932 s_data (i);
933
934#ifdef md_elf_section_change_hook
935 md_elf_section_change_hook ();
936#endif
937}
938
939/* Change to the .text section. */
940
16b93d88 941void
252b5132
RH
942obj_elf_text (i)
943 int i;
944{
945#ifdef md_flush_pending_output
946 md_flush_pending_output ();
947#endif
948
949 previous_section = now_seg;
950 previous_subsection = now_subseg;
951 s_text (i);
952
953#ifdef md_elf_section_change_hook
954 md_elf_section_change_hook ();
955#endif
956}
957
958static void
959obj_elf_subsection (ignore)
ab9da554 960 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
961{
962 register int temp;
963
964#ifdef md_flush_pending_output
965 md_flush_pending_output ();
966#endif
967
968 previous_section = now_seg;
969 previous_subsection = now_subseg;
970
971 temp = get_absolute_expression ();
972 subseg_set (now_seg, (subsegT) temp);
973 demand_empty_rest_of_line ();
974
975#ifdef md_elf_section_change_hook
976 md_elf_section_change_hook ();
977#endif
978}
979
980/* This can be called from the processor backends if they change
981 sections. */
982
983void
984obj_elf_section_change_hook ()
985{
986 previous_section = now_seg;
987 previous_subsection = now_subseg;
988}
989
990void
991obj_elf_previous (ignore)
ab9da554 992 int ignore ATTRIBUTE_UNUSED;
252b5132 993{
9de8d8f1
RH
994 segT new_section;
995 int new_subsection;
996
252b5132
RH
997 if (previous_section == 0)
998 {
999 as_bad (_(".previous without corresponding .section; ignored"));
1000 return;
1001 }
1002
1003#ifdef md_flush_pending_output
1004 md_flush_pending_output ();
1005#endif
1006
9de8d8f1
RH
1007 new_section = previous_section;
1008 new_subsection = previous_subsection;
1009 previous_section = now_seg;
1010 previous_subsection = now_subseg;
1011 subseg_set (new_section, new_subsection);
1012
1013#ifdef md_elf_section_change_hook
1014 md_elf_section_change_hook ();
1015#endif
1016}
1017
1018static void
1019obj_elf_popsection (xxx)
ab9da554 1020 int xxx ATTRIBUTE_UNUSED;
9de8d8f1
RH
1021{
1022 struct section_stack *top = section_stack;
1023
1024 if (top == NULL)
1025 {
1026 as_bad (_(".popsection without corresponding .pushsection; ignored"));
1027 return;
1028 }
1029
1030#ifdef md_flush_pending_output
1031 md_flush_pending_output ();
1032#endif
1033
1034 section_stack = top->next;
1035 previous_section = top->prev_seg;
1036 previous_subsection = top->prev_subseg;
1037 subseg_set (top->seg, top->subseg);
1038 free (top);
252b5132
RH
1039
1040#ifdef md_elf_section_change_hook
1041 md_elf_section_change_hook ();
1042#endif
1043}
1044
1045static void
1046obj_elf_line (ignore)
ab9da554 1047 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1048{
1049 /* Assume delimiter is part of expression. BSD4.2 as fails with
1050 delightful bug, so we are not being incompatible here. */
1051 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
1052 demand_empty_rest_of_line ();
1053}
1054
1055/* This handles the .symver pseudo-op, which is used to specify a
1056 symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
1057 SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
1058 pseudo-op causes the assembler to emit a symbol named SYMVERNAME
1059 with the same value as the symbol NAME. */
1060
1061static void
1062obj_elf_symver (ignore)
ab9da554 1063 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1064{
1065 char *name;
1066 char c;
1067 symbolS *sym;
1068
1069 name = input_line_pointer;
1070 c = get_symbol_end ();
1071
1072 sym = symbol_find_or_make (name);
1073
1074 *input_line_pointer = c;
1075
49309057 1076 if (symbol_get_obj (sym)->versioned_name != NULL)
252b5132
RH
1077 {
1078 as_bad (_("multiple .symver directives for symbol `%s'"),
1079 S_GET_NAME (sym));
1080 ignore_rest_of_line ();
1081 return;
1082 }
1083
1084 SKIP_WHITESPACE ();
1085 if (*input_line_pointer != ',')
1086 {
1087 as_bad (_("expected comma after name in .symver"));
1088 ignore_rest_of_line ();
1089 return;
1090 }
1091
1092 ++input_line_pointer;
1093 name = input_line_pointer;
1094 while (1)
1095 {
1096 c = get_symbol_end ();
1097 if (c != ELF_VER_CHR)
1098 break;
1099 *input_line_pointer++ = c;
1100 }
1101
49309057 1102 symbol_get_obj (sym)->versioned_name = xstrdup (name);
252b5132
RH
1103
1104 *input_line_pointer = c;
1105
49309057 1106 if (strchr (symbol_get_obj (sym)->versioned_name, ELF_VER_CHR) == NULL)
252b5132
RH
1107 {
1108 as_bad (_("missing version name in `%s' for symbol `%s'"),
49309057 1109 symbol_get_obj (sym)->versioned_name, S_GET_NAME (sym));
252b5132
RH
1110 ignore_rest_of_line ();
1111 return;
1112 }
1113
1114 demand_empty_rest_of_line ();
1115}
1116
1117/* This handles the .vtable_inherit pseudo-op, which is used to indicate
1118 to the linker the hierarchy in which a particular table resides. The
1119 syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
1120
1121static void
1122obj_elf_vtable_inherit (ignore)
ab9da554 1123 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1124{
1125 char *cname, *pname;
1126 symbolS *csym, *psym;
1127 char c, bad = 0;
1128
1129 if (*input_line_pointer == '#')
1130 ++input_line_pointer;
1131
1132 cname = input_line_pointer;
1133 c = get_symbol_end ();
1134 csym = symbol_find (cname);
1135
1136 /* GCFIXME: should check that we don't have two .vtable_inherits for
1137 the same child symbol. Also, we can currently only do this if the
1138 child symbol is already exists and is placed in a fragment. */
1139
49309057 1140 if (csym == NULL || symbol_get_frag (csym) == NULL)
252b5132
RH
1141 {
1142 as_bad ("expected `%s' to have already been set for .vtable_inherit",
1143 cname);
1144 bad = 1;
1145 }
1146
1147 *input_line_pointer = c;
1148
1149 SKIP_WHITESPACE ();
1150 if (*input_line_pointer != ',')
1151 {
1152 as_bad ("expected comma after name in .vtable_inherit");
1153 ignore_rest_of_line ();
1154 return;
1155 }
1156
1157 ++input_line_pointer;
1158 SKIP_WHITESPACE ();
1159
1160 if (*input_line_pointer == '#')
1161 ++input_line_pointer;
1162
1163 if (input_line_pointer[0] == '0'
1164 && (input_line_pointer[1] == '\0'
d9a62219 1165 || isspace ((unsigned char) input_line_pointer[1])))
252b5132
RH
1166 {
1167 psym = section_symbol (absolute_section);
1168 ++input_line_pointer;
1169 }
1170 else
1171 {
1172 pname = input_line_pointer;
1173 c = get_symbol_end ();
1174 psym = symbol_find_or_make (pname);
1175 *input_line_pointer = c;
1176 }
1177
1178 demand_empty_rest_of_line ();
1179
1180 if (bad)
1181 return;
1182
49309057
ILT
1183 assert (symbol_get_value_expression (csym)->X_op == O_constant);
1184 fix_new (symbol_get_frag (csym),
1185 symbol_get_value_expression (csym)->X_add_number, 0, psym, 0, 0,
252b5132
RH
1186 BFD_RELOC_VTABLE_INHERIT);
1187}
1188
1189/* This handles the .vtable_entry pseudo-op, which is used to indicate
1190 to the linker that a vtable slot was used. The syntax is
1191 ".vtable_entry tablename, offset". */
1192
1193static void
1194obj_elf_vtable_entry (ignore)
ab9da554 1195 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1196{
1197 char *name;
1198 symbolS *sym;
1199 offsetT offset;
1200 char c;
1201
1202 if (*input_line_pointer == '#')
1203 ++input_line_pointer;
1204
1205 name = input_line_pointer;
1206 c = get_symbol_end ();
1207 sym = symbol_find_or_make (name);
1208 *input_line_pointer = c;
1209
1210 SKIP_WHITESPACE ();
1211 if (*input_line_pointer != ',')
1212 {
1213 as_bad ("expected comma after name in .vtable_entry");
1214 ignore_rest_of_line ();
1215 return;
1216 }
1217
1218 ++input_line_pointer;
1219 if (*input_line_pointer == '#')
1220 ++input_line_pointer;
1221
1222 offset = get_absolute_expression ();
1223
1224 fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
1225 BFD_RELOC_VTABLE_ENTRY);
1226
1227 demand_empty_rest_of_line ();
1228}
1229
1230void
4c63da97 1231elf_obj_read_begin_hook ()
252b5132
RH
1232{
1233#ifdef NEED_ECOFF_DEBUG
1234 if (ECOFF_DEBUGGING)
1235 ecoff_read_begin_hook ();
1236#endif
1237}
1238
1239void
4c63da97 1240elf_obj_symbol_new_hook (symbolP)
252b5132
RH
1241 symbolS *symbolP;
1242{
49309057
ILT
1243 struct elf_obj_sy *sy_obj;
1244
1245 sy_obj = symbol_get_obj (symbolP);
1246 sy_obj->size = NULL;
1247 sy_obj->versioned_name = NULL;
252b5132
RH
1248
1249#ifdef NEED_ECOFF_DEBUG
1250 if (ECOFF_DEBUGGING)
1251 ecoff_symbol_new_hook (symbolP);
1252#endif
1253}
1254
1255void
1256obj_elf_version (ignore)
ab9da554 1257 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1258{
1259 char *name;
1260 unsigned int c;
1261 char ch;
1262 char *p;
1263 asection *seg = now_seg;
1264 subsegT subseg = now_subseg;
1265 Elf_Internal_Note i_note;
1266 Elf_External_Note e_note;
1267 asection *note_secp = (asection *) NULL;
1268 int i, len;
1269
1270 SKIP_WHITESPACE ();
1271 if (*input_line_pointer == '\"')
1272 {
1273 ++input_line_pointer; /* -> 1st char of string. */
1274 name = input_line_pointer;
1275
1276 while (is_a_char (c = next_char_of_string ()))
1277 ;
1278 c = *input_line_pointer;
1279 *input_line_pointer = '\0';
1280 *(input_line_pointer - 1) = '\0';
1281 *input_line_pointer = c;
1282
1283 /* create the .note section */
1284
1285 note_secp = subseg_new (".note", 0);
1286 bfd_set_section_flags (stdoutput,
1287 note_secp,
1288 SEC_HAS_CONTENTS | SEC_READONLY);
1289
1290 /* process the version string */
1291
1292 len = strlen (name);
1293
1294 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
1295 i_note.descsz = 0; /* no description */
1296 i_note.type = NT_VERSION;
1297 p = frag_more (sizeof (e_note.namesz));
1298 md_number_to_chars (p, (valueT) i_note.namesz, 4);
1299 p = frag_more (sizeof (e_note.descsz));
1300 md_number_to_chars (p, (valueT) i_note.descsz, 4);
1301 p = frag_more (sizeof (e_note.type));
1302 md_number_to_chars (p, (valueT) i_note.type, 4);
1303
1304 for (i = 0; i < len; i++)
1305 {
1306 ch = *(name + i);
1307 {
1308 FRAG_APPEND_1_CHAR (ch);
1309 }
1310 }
1311 frag_align (2, 0, 0);
1312
1313 subseg_set (seg, subseg);
1314 }
1315 else
1316 {
1317 as_bad (_("Expected quoted string"));
1318 }
1319 demand_empty_rest_of_line ();
1320}
1321
1322static void
1323obj_elf_size (ignore)
ab9da554 1324 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1325{
1326 char *name = input_line_pointer;
1327 char c = get_symbol_end ();
1328 char *p;
1329 expressionS exp;
1330 symbolS *sym;
1331
1332 p = input_line_pointer;
1333 *p = c;
1334 SKIP_WHITESPACE ();
1335 if (*input_line_pointer != ',')
1336 {
1337 *p = 0;
1338 as_bad (_("expected comma after name `%s' in .size directive"), name);
1339 *p = c;
1340 ignore_rest_of_line ();
1341 return;
1342 }
1343 input_line_pointer++;
1344 expression (&exp);
1345 if (exp.X_op == O_absent)
1346 {
1347 as_bad (_("missing expression in .size directive"));
1348 exp.X_op = O_constant;
1349 exp.X_add_number = 0;
1350 }
1351 *p = 0;
1352 sym = symbol_find_or_make (name);
1353 *p = c;
1354 if (exp.X_op == O_constant)
1355 S_SET_SIZE (sym, exp.X_add_number);
1356 else
1357 {
49309057
ILT
1358 symbol_get_obj (sym)->size =
1359 (expressionS *) xmalloc (sizeof (expressionS));
1360 *symbol_get_obj (sym)->size = exp;
252b5132
RH
1361 }
1362 demand_empty_rest_of_line ();
1363}
1364
1365/* Handle the ELF .type pseudo-op. This sets the type of a symbol.
1366 There are four syntaxes:
1367
1368 The first (used on Solaris) is
1369 .type SYM,#function
1370 The second (used on UnixWare) is
1371 .type SYM,@function
1372 The third (reportedly to be used on Irix 6.0) is
1373 .type SYM STT_FUNC
1374 The fourth (used on NetBSD/Arm and Linux/ARM) is
1375 .type SYM,%function
1376 */
1377
1378static void
1379obj_elf_type (ignore)
ab9da554 1380 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1381{
1382 char *name;
1383 char c;
1384 int type;
1385 const char *typename;
1386 symbolS *sym;
1387
1388 name = input_line_pointer;
1389 c = get_symbol_end ();
1390 sym = symbol_find_or_make (name);
1391 *input_line_pointer = c;
1392
1393 SKIP_WHITESPACE ();
1394 if (*input_line_pointer == ',')
1395 ++input_line_pointer;
1396
1397 SKIP_WHITESPACE ();
1398 if ( *input_line_pointer == '#'
1399 || *input_line_pointer == '@'
1400 || *input_line_pointer == '%')
1401 ++input_line_pointer;
1402
1403 typename = input_line_pointer;
1404 c = get_symbol_end ();
1405
1406 type = 0;
1407 if (strcmp (typename, "function") == 0
1408 || strcmp (typename, "STT_FUNC") == 0)
1409 type = BSF_FUNCTION;
1410 else if (strcmp (typename, "object") == 0
1411 || strcmp (typename, "STT_OBJECT") == 0)
1412 type = BSF_OBJECT;
1413 else
1414 as_bad (_("ignoring unrecognized symbol type \"%s\""), typename);
1415
1416 *input_line_pointer = c;
1417
49309057 1418 symbol_get_bfdsym (sym)->flags |= type;
252b5132
RH
1419
1420 demand_empty_rest_of_line ();
1421}
1422
1423static void
1424obj_elf_ident (ignore)
ab9da554 1425 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1426{
1427 static segT comment_section;
1428 segT old_section = now_seg;
1429 int old_subsection = now_subseg;
1430
5f91fe03
ILT
1431#ifdef md_flush_pending_output
1432 md_flush_pending_output ();
1433#endif
1434
252b5132
RH
1435 if (!comment_section)
1436 {
1437 char *p;
1438 comment_section = subseg_new (".comment", 0);
1439 bfd_set_section_flags (stdoutput, comment_section,
1440 SEC_READONLY | SEC_HAS_CONTENTS);
1441 p = frag_more (1);
1442 *p = 0;
1443 }
1444 else
1445 subseg_set (comment_section, 0);
1446 stringer (1);
1447 subseg_set (old_section, old_subsection);
1448}
1449
1450#ifdef INIT_STAB_SECTION
1451
1452/* The first entry in a .stabs section is special. */
1453
1454void
1455obj_elf_init_stab_section (seg)
1456 segT seg;
1457{
1458 char *file;
1459 char *p;
1460 char *stabstr_name;
1461 unsigned int stroff;
1462
1463 /* Force the section to align to a longword boundary. Without this,
1464 UnixWare ar crashes. */
1465 bfd_set_section_alignment (stdoutput, seg, 2);
1466
1467 /* Make space for this first symbol. */
1468 p = frag_more (12);
1469 /* Zero it out. */
1470 memset (p, 0, 12);
1471 as_where (&file, (unsigned int *) NULL);
1472 stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
1473 strcpy (stabstr_name, segment_name (seg));
1474 strcat (stabstr_name, "str");
1475 stroff = get_stab_string_offset (file, stabstr_name);
1476 know (stroff == 1);
1477 md_number_to_chars (p, stroff, 4);
1478 seg_info (seg)->stabu.p = p;
1479}
1480
1481#endif
1482
1483/* Fill in the counts in the first entry in a .stabs section. */
1484
1485static void
1486adjust_stab_sections (abfd, sec, xxx)
1487 bfd *abfd;
1488 asection *sec;
ab9da554 1489 PTR xxx ATTRIBUTE_UNUSED;
252b5132
RH
1490{
1491 char *name;
1492 asection *strsec;
1493 char *p;
1494 int strsz, nsyms;
1495
1496 if (strncmp (".stab", sec->name, 5))
1497 return;
1498 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1499 return;
1500
1501 name = (char *) alloca (strlen (sec->name) + 4);
1502 strcpy (name, sec->name);
1503 strcat (name, "str");
1504 strsec = bfd_get_section_by_name (abfd, name);
1505 if (strsec)
1506 strsz = bfd_section_size (abfd, strsec);
1507 else
1508 strsz = 0;
1509 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1510
1511 p = seg_info (sec)->stabu.p;
1512 assert (p != 0);
1513
1514 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
1515 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
1516}
1517
1518#ifdef NEED_ECOFF_DEBUG
1519
1520/* This function is called by the ECOFF code. It is supposed to
1521 record the external symbol information so that the backend can
1522 write it out correctly. The ELF backend doesn't actually handle
1523 this at the moment, so we do it ourselves. We save the information
1524 in the symbol. */
1525
1526void
1527elf_ecoff_set_ext (sym, ext)
1528 symbolS *sym;
1529 struct ecoff_extr *ext;
1530{
49309057 1531 symbol_get_bfdsym (sym)->udata.p = (PTR) ext;
252b5132
RH
1532}
1533
1534/* This function is called by bfd_ecoff_debug_externals. It is
1535 supposed to *EXT to the external symbol information, and return
1536 whether the symbol should be used at all. */
1537
1538static boolean
1539elf_get_extr (sym, ext)
1540 asymbol *sym;
1541 EXTR *ext;
1542{
1543 if (sym->udata.p == NULL)
1544 return false;
1545 *ext = *(EXTR *) sym->udata.p;
1546 return true;
1547}
1548
1549/* This function is called by bfd_ecoff_debug_externals. It has
1550 nothing to do for ELF. */
1551
1552/*ARGSUSED*/
1553static void
1554elf_set_index (sym, indx)
5f91fe03
ILT
1555 asymbol *sym ATTRIBUTE_UNUSED;
1556 bfd_size_type indx ATTRIBUTE_UNUSED;
252b5132
RH
1557{
1558}
1559
1560#endif /* NEED_ECOFF_DEBUG */
1561
1562void
1563elf_frob_symbol (symp, puntp)
1564 symbolS *symp;
1565 int *puntp;
1566{
49309057
ILT
1567 struct elf_obj_sy *sy_obj;
1568
252b5132
RH
1569#ifdef NEED_ECOFF_DEBUG
1570 if (ECOFF_DEBUGGING)
1571 ecoff_frob_symbol (symp);
1572#endif
1573
49309057
ILT
1574 sy_obj = symbol_get_obj (symp);
1575
1576 if (sy_obj->size != NULL)
252b5132 1577 {
49309057 1578 switch (sy_obj->size->X_op)
252b5132
RH
1579 {
1580 case O_subtract:
1581 S_SET_SIZE (symp,
49309057
ILT
1582 (S_GET_VALUE (sy_obj->size->X_add_symbol)
1583 + sy_obj->size->X_add_number
1584 - S_GET_VALUE (sy_obj->size->X_op_symbol)));
252b5132
RH
1585 break;
1586 case O_constant:
1587 S_SET_SIZE (symp,
49309057
ILT
1588 (S_GET_VALUE (sy_obj->size->X_add_symbol)
1589 + sy_obj->size->X_add_number));
252b5132
RH
1590 break;
1591 default:
1592 as_bad (_(".size expression too complicated to fix up"));
1593 break;
1594 }
49309057
ILT
1595 free (sy_obj->size);
1596 sy_obj->size = NULL;
252b5132
RH
1597 }
1598
49309057 1599 if (sy_obj->versioned_name != NULL)
252b5132
RH
1600 {
1601 /* This symbol was given a new name with the .symver directive.
1602
1603 If this is an external reference, just rename the symbol to
1604 include the version string. This will make the relocs be
1605 against the correct versioned symbol.
1606
1607 If this is a definition, add an alias. FIXME: Using an alias
1608 will permit the debugging information to refer to the right
1609 symbol. However, it's not clear whether it is the best
1610 approach. */
1611
1612 if (! S_IS_DEFINED (symp))
1613 {
1614 char *p;
1615
1616 /* Verify that the name isn't using the @@ syntax--this is
1617 reserved for definitions of the default version to link
1618 against. */
49309057 1619 p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
252b5132
RH
1620 know (p != NULL);
1621 if (p[1] == ELF_VER_CHR)
1622 {
1623 as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
49309057 1624 sy_obj->versioned_name);
252b5132
RH
1625 *puntp = true;
1626 }
49309057 1627 S_SET_NAME (symp, sy_obj->versioned_name);
252b5132
RH
1628 }
1629 else
1630 {
1631 symbolS *symp2;
1632
1633 /* FIXME: Creating a new symbol here is risky. We're in the
1634 final loop over the symbol table. We can get away with
1635 it only because the symbol goes to the end of the list,
1636 where the loop will still see it. It would probably be
1637 better to do this in obj_frob_file_before_adjust. */
1638
49309057 1639 symp2 = symbol_find_or_make (sy_obj->versioned_name);
252b5132
RH
1640
1641 /* Now we act as though we saw symp2 = sym. */
1642
1643 S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
1644
1645 /* Subtracting out the frag address here is a hack because
1646 we are in the middle of the final loop. */
49309057
ILT
1647 S_SET_VALUE (symp2,
1648 (S_GET_VALUE (symp)
1649 - symbol_get_frag (symp)->fr_address));
252b5132 1650
49309057 1651 symbol_set_frag (symp2, symbol_get_frag (symp));
252b5132
RH
1652
1653 /* This will copy over the size information. */
1654 copy_symbol_attributes (symp2, symp);
1655
1656 if (S_IS_WEAK (symp))
1657 S_SET_WEAK (symp2);
1658
1659 if (S_IS_EXTERNAL (symp))
1660 S_SET_EXTERNAL (symp2);
1661 }
1662 }
1663
1664 /* Double check weak symbols. */
49309057 1665 if (S_IS_WEAK (symp))
252b5132
RH
1666 {
1667 if (S_IS_COMMON (symp))
1668 as_bad (_("Symbol `%s' can not be both weak and common"),
1669 S_GET_NAME (symp));
1670 }
1671
1672#ifdef TC_MIPS
1673 /* The Irix 5 and 6 assemblers set the type of any common symbol and
1674 any undefined non-function symbol to STT_OBJECT. We try to be
1675 compatible, since newer Irix 5 and 6 linkers care. However, we
1676 only set undefined symbols to be STT_OBJECT if we are on Irix,
1677 because that is the only time gcc will generate the necessary
1678 .global directives to mark functions. */
1679
1680 if (S_IS_COMMON (symp))
49309057 1681 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1682
1683 if (strstr (TARGET_OS, "irix") != NULL
49309057
ILT
1684 && ! S_IS_DEFINED (symp)
1685 && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
1686 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1687#endif
1688
1689#ifdef TC_PPC
1690 /* Frob the PowerPC, so that the symbol always has object type
1691 if it is not some other type. VxWorks needs this. */
49309057
ILT
1692 if ((symbol_get_bfdsym (symp)->flags
1693 & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
252b5132 1694 && S_IS_DEFINED (symp))
49309057 1695 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1696#endif
1697}
1698
1699void
1700elf_frob_file ()
1701{
1702 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1703
1704#ifdef elf_tc_final_processing
1705 elf_tc_final_processing ();
1706#endif
1707}
1708
1709/* It is required that we let write_relocs have the opportunity to
1710 optimize away fixups before output has begun, since it is possible
1711 to eliminate all fixups for a section and thus we never should
1712 have generated the relocation section. */
1713
1714void
1715elf_frob_file_after_relocs ()
1716{
1717#ifdef NEED_ECOFF_DEBUG
1718 if (ECOFF_DEBUGGING)
1719 /* Generate the ECOFF debugging information. */
1720 {
1721 const struct ecoff_debug_swap *debug_swap;
1722 struct ecoff_debug_info debug;
1723 char *buf;
1724 asection *sec;
1725
1726 debug_swap
1727 = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1728 know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1729 ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1730
1731 /* Set up the pointers in debug. */
1732#define SET(ptr, offset, type) \
1733 debug.ptr = (type) (buf + debug.symbolic_header.offset)
1734
1735 SET (line, cbLineOffset, unsigned char *);
1736 SET (external_dnr, cbDnOffset, PTR);
1737 SET (external_pdr, cbPdOffset, PTR);
1738 SET (external_sym, cbSymOffset, PTR);
1739 SET (external_opt, cbOptOffset, PTR);
1740 SET (external_aux, cbAuxOffset, union aux_ext *);
1741 SET (ss, cbSsOffset, char *);
1742 SET (external_fdr, cbFdOffset, PTR);
1743 SET (external_rfd, cbRfdOffset, PTR);
1744 /* ssext and external_ext are set up just below. */
1745
1746#undef SET
1747
1748 /* Set up the external symbols. */
1749 debug.ssext = debug.ssext_end = NULL;
1750 debug.external_ext = debug.external_ext_end = NULL;
1751 if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1752 elf_get_extr, elf_set_index))
1753 as_fatal (_("Failed to set up debugging information: %s"),
1754 bfd_errmsg (bfd_get_error ()));
1755
1756 sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1757 assert (sec != NULL);
1758
1759 know (stdoutput->output_has_begun == false);
1760
1761 /* We set the size of the section, call bfd_set_section_contents
1762 to force the ELF backend to allocate a file position, and then
1763 write out the data. FIXME: Is this really the best way to do
1764 this? */
1765 sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1766
5f91fe03
ILT
1767 /* Pass BUF to bfd_set_section_contents because this will
1768 eventually become a call to fwrite, and ISO C prohibits
1769 passing a NULL pointer to a stdio function even if the
1770 pointer will not be used. */
1771 if (! bfd_set_section_contents (stdoutput, sec, (PTR) buf,
252b5132
RH
1772 (file_ptr) 0, (bfd_size_type) 0))
1773 as_fatal (_("Can't start writing .mdebug section: %s"),
1774 bfd_errmsg (bfd_get_error ()));
1775
1776 know (stdoutput->output_has_begun == true);
1777 know (sec->filepos != 0);
1778
1779 if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1780 sec->filepos))
1781 as_fatal (_("Could not write .mdebug section: %s"),
1782 bfd_errmsg (bfd_get_error ()));
1783 }
1784#endif /* NEED_ECOFF_DEBUG */
1785}
1786
1787#ifdef SCO_ELF
1788
1789/* Heavily plagarized from obj_elf_version. The idea is to emit the
1790 SCO specific identifier in the .notes section to satisfy the SCO
1791 linker.
1792
1793 This looks more complicated than it really is. As opposed to the
1794 "obvious" solution, this should handle the cross dev cases
1795 correctly. (i.e, hosting on a 64 bit big endian processor, but
1796 generating SCO Elf code) Efficiency isn't a concern, as there
1797 should be exactly one of these sections per object module.
1798
1799 SCO OpenServer 5 identifies it's ELF modules with a standard ELF
1800 .note section.
1801
1802 int_32 namesz = 4 ; Name size
1803 int_32 descsz = 12 ; Descriptive information
1804 int_32 type = 1 ;
1805 char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
1806 int_32 version = (major ver # << 16) | version of tools ;
1807 int_32 source = (tool_id << 16 ) | 1 ;
1808 int_32 info = 0 ; These are set by the SCO tools, but we
1809 don't know enough about the source
1810 environment to set them. SCO ld currently
1811 ignores them, and recommends we set them
1812 to zero. */
1813
1814#define SCO_MAJOR_VERSION 0x1
1815#define SCO_MINOR_VERSION 0x1
1816
1817void
1818sco_id ()
1819{
1820
1821 char *name;
1822 unsigned int c;
1823 char ch;
1824 char *p;
1825 asection *seg = now_seg;
1826 subsegT subseg = now_subseg;
1827 Elf_Internal_Note i_note;
1828 Elf_External_Note e_note;
1829 asection *note_secp = (asection *) NULL;
1830 int i, len;
1831
1832 /* create the .note section */
1833
1834 note_secp = subseg_new (".note", 0);
1835 bfd_set_section_flags (stdoutput,
1836 note_secp,
1837 SEC_HAS_CONTENTS | SEC_READONLY);
1838
1839 /* process the version string */
1840
1841 i_note.namesz = 4;
1842 i_note.descsz = 12; /* 12 descriptive bytes */
1843 i_note.type = NT_VERSION; /* Contains a version string */
1844
1845 p = frag_more (sizeof (i_note.namesz));
1846 md_number_to_chars (p, (valueT) i_note.namesz, 4);
1847
1848 p = frag_more (sizeof (i_note.descsz));
1849 md_number_to_chars (p, (valueT) i_note.descsz, 4);
1850
1851 p = frag_more (sizeof (i_note.type));
1852 md_number_to_chars (p, (valueT) i_note.type, 4);
1853
1854 p = frag_more (4);
1855 strcpy (p, "SCO");
1856
1857 /* Note: this is the version number of the ELF we're representing */
1858 p = frag_more (4);
1859 md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
1860
1861 /* Here, we pick a magic number for ourselves (yes, I "registered"
1862 it with SCO. The bottom bit shows that we are compat with the
1863 SCO ABI. */
1864 p = frag_more (4);
1865 md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
1866
1867 /* If we knew (or cared) what the source language options were, we'd
1868 fill them in here. SCO has given us permission to ignore these
1869 and just set them to zero. */
1870 p = frag_more (4);
1871 md_number_to_chars (p, 0x0000, 4);
1872
1873 frag_align (2, 0, 0);
1874
1875 /* We probably can't restore the current segment, for there likely
1876 isn't one yet... */
1877 if (seg && subseg)
1878 subseg_set (seg, subseg);
1879
1880}
1881
1882#endif /* SCO_ELF */
1883
1884const struct format_ops elf_format_ops =
1885{
1886 bfd_target_elf_flavour,
4c63da97
AM
1887 0, /* dfl_leading_underscore */
1888 1, /* emit_section_symbols */
252b5132
RH
1889 elf_frob_symbol,
1890 elf_frob_file,
1891 elf_frob_file_after_relocs,
1892 elf_s_get_size, elf_s_set_size,
1893 elf_s_get_align, elf_s_set_align,
4c63da97
AM
1894 elf_s_get_other,
1895 0, /* s_get_desc */
252b5132
RH
1896 elf_copy_symbol_attributes,
1897#ifdef NEED_ECOFF_DEBUG
1898 ecoff_generate_asm_lineno,
1899 ecoff_stab,
1900#else
4c63da97
AM
1901 0, /* generate_asm_lineno */
1902 0, /* process_stab */
252b5132
RH
1903#endif
1904 elf_sec_sym_ok_for_reloc,
1905 elf_pop_insert,
1906#ifdef NEED_ECOFF_DEBUG
1907 elf_ecoff_set_ext,
1908#else
4c63da97 1909 0, /* ecoff_set_ext */
252b5132 1910#endif
4c63da97
AM
1911 elf_obj_read_begin_hook,
1912 elf_obj_symbol_new_hook,
252b5132 1913};
This page took 0.169719 seconds and 4 git commands to generate.