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