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