OSDN Git Service

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