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