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