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