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