]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/binutils/gas/config/obj-elf.c
This commit was generated by cvs2svn to compensate for changes in r52746,
[FreeBSD/FreeBSD.git] / contrib / binutils / gas / config / obj-elf.c
1 /* ELF object file format
2    Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as
8    published by the Free Software Foundation; either version 2,
9    or (at your option) any later version.
10
11    GAS is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14    the GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to the Free
18    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA. */
20
21 #define OBJ_HEADER "obj-elf.h"
22 #include "as.h"
23 #include "subsegs.h"
24 #include "obstack.h"
25
26 #ifndef ECOFF_DEBUGGING
27 #define ECOFF_DEBUGGING 0
28 #else
29 #define NEED_ECOFF_DEBUG
30 #endif
31
32 #ifdef NEED_ECOFF_DEBUG
33 #include "ecoff.h"
34 #endif
35
36 #ifdef TC_ALPHA
37 #include "elf/alpha.h"
38 #endif
39
40 #ifdef TC_MIPS
41 #include "elf/mips.h"
42 #endif
43
44 #ifdef TC_PPC
45 #include "elf/ppc.h"
46 #endif
47
48 static bfd_vma elf_s_get_size PARAMS ((symbolS *));
49 static void elf_s_set_size PARAMS ((symbolS *, bfd_vma));
50 static bfd_vma elf_s_get_align PARAMS ((symbolS *));
51 static void elf_s_set_align PARAMS ((symbolS *, bfd_vma));
52 static void elf_copy_symbol_attributes PARAMS ((symbolS *, symbolS *));
53 static int elf_sec_sym_ok_for_reloc PARAMS ((asection *));
54 static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
55
56 #ifdef NEED_ECOFF_DEBUG
57 static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
58 static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
59 #endif
60
61 static void obj_elf_line PARAMS ((int));
62 void obj_elf_version PARAMS ((int));
63 static void obj_elf_size PARAMS ((int));
64 static void obj_elf_type PARAMS ((int));
65 static void obj_elf_ident PARAMS ((int));
66 static void obj_elf_weak PARAMS ((int));
67 static void obj_elf_local PARAMS ((int));
68 static void obj_elf_common PARAMS ((int));
69 static void obj_elf_symver PARAMS ((int));
70 static void obj_elf_data PARAMS ((int));
71 static void obj_elf_text PARAMS ((int));
72 static void obj_elf_subsection PARAMS ((int));
73
74 static const pseudo_typeS elf_pseudo_table[] =
75 {
76   {"comm", obj_elf_common, 0},
77   {"ident", obj_elf_ident, 0},
78   {"local", obj_elf_local, 0},
79   {"previous", obj_elf_previous, 0},
80   {"section", obj_elf_section, 0},
81   {"section.s", obj_elf_section, 0},
82   {"sect", obj_elf_section, 0},
83   {"sect.s", obj_elf_section, 0},
84   {"size", obj_elf_size, 0},
85   {"type", obj_elf_type, 0},
86   {"version", obj_elf_version, 0},
87   {"weak", obj_elf_weak, 0},
88
89   /* These are used for stabs-in-elf configurations.  */
90   {"line", obj_elf_line, 0},
91
92   /* This is a GNU extension to handle symbol versions.  */
93   {"symver", obj_elf_symver, 0},
94
95   /* A GNU extension to change subsection only.  */
96   {"subsection", obj_elf_subsection, 0},
97
98   /* These are used for dwarf. */
99   {"2byte", cons, 2},
100   {"4byte", cons, 4},
101   {"8byte", cons, 8},
102
103   /* We need to trap the section changing calls to handle .previous.  */
104   {"data", obj_elf_data, 0},
105   {"text", obj_elf_text, 0},
106
107   /* End sentinel.  */
108   {NULL},
109 };
110
111 static const pseudo_typeS ecoff_debug_pseudo_table[] =
112 {
113 #ifdef NEED_ECOFF_DEBUG
114   /* COFF style debugging information for ECOFF. .ln is not used; .loc
115      is used instead.  */
116   { "def",      ecoff_directive_def,    0 },
117   { "dim",      ecoff_directive_dim,    0 },
118   { "endef",    ecoff_directive_endef,  0 },
119   { "file",     ecoff_directive_file,   0 },
120   { "scl",      ecoff_directive_scl,    0 },
121   { "tag",      ecoff_directive_tag,    0 },
122   { "val",      ecoff_directive_val,    0 },
123
124   /* COFF debugging requires pseudo-ops .size and .type, but ELF
125      already has meanings for those.  We use .esize and .etype
126      instead.  These are only generated by gcc anyhow.  */
127   { "esize",    ecoff_directive_size,   0 },
128   { "etype",    ecoff_directive_type,   0 },
129
130   /* ECOFF specific debugging information.  */
131   { "begin",    ecoff_directive_begin,  0 },
132   { "bend",     ecoff_directive_bend,   0 },
133   { "end",      ecoff_directive_end,    0 },
134   { "ent",      ecoff_directive_ent,    0 },
135   { "fmask",    ecoff_directive_fmask,  0 },
136   { "frame",    ecoff_directive_frame,  0 },
137   { "loc",      ecoff_directive_loc,    0 },
138   { "mask",     ecoff_directive_mask,   0 },
139
140   /* Other ECOFF directives.  */
141   { "extern",   ecoff_directive_extern, 0 },
142
143   /* These are used on Irix.  I don't know how to implement them.  */
144   { "alias",    s_ignore,               0 },
145   { "bgnb",     s_ignore,               0 },
146   { "endb",     s_ignore,               0 },
147   { "lab",      s_ignore,               0 },
148   { "noalias",  s_ignore,               0 },
149   { "verstamp", s_ignore,               0 },
150   { "vreg",     s_ignore,               0 },
151 #endif
152
153   {NULL}                        /* end sentinel */
154 };
155
156 #undef NO_RELOC
157 #include "aout/aout64.h"
158
159 /* This is called when the assembler starts.  */
160
161 void
162 elf_begin ()
163 {
164   /* Add symbols for the known sections to the symbol table.  */
165   symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
166                                                                 TEXT_SECTION_NAME)));
167   symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
168                                                                 DATA_SECTION_NAME)));
169   symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
170                                                                 BSS_SECTION_NAME)));
171 }
172
173 void
174 elf_pop_insert ()
175 {
176   pop_insert (elf_pseudo_table);
177   if (ECOFF_DEBUGGING)
178     pop_insert (ecoff_debug_pseudo_table);
179 }
180
181 static bfd_vma
182 elf_s_get_size (sym)
183      symbolS *sym;
184 {
185   return S_GET_SIZE (sym);
186 }
187
188 static void
189 elf_s_set_size (sym, sz)
190      symbolS *sym;
191      bfd_vma sz;
192 {
193   S_SET_SIZE (sym, sz);
194 }
195
196 static bfd_vma
197 elf_s_get_align (sym)
198      symbolS *sym;
199 {
200   return S_GET_ALIGN (sym);
201 }
202
203 static void
204 elf_s_set_align (sym, align)
205      symbolS *sym;
206      bfd_vma align;
207 {
208   S_SET_ALIGN (sym, align);
209 }
210
211 static void
212 elf_copy_symbol_attributes (dest, src)
213      symbolS *dest, *src;
214 {
215   OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
216 }
217
218 static int
219 elf_sec_sym_ok_for_reloc (sec)
220      asection *sec;
221 {
222   return obj_sec_sym_ok_for_reloc (sec);
223 }
224
225 void
226 elf_file_symbol (s)
227      char *s;
228 {
229   symbolS *sym;
230
231   sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
232   sym->sy_frag = &zero_address_frag;
233   sym->bsym->flags |= BSF_FILE;
234
235   if (symbol_rootP != sym)
236     {
237       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
238       symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
239 #ifdef DEBUG
240       verify_symbol_chain (symbol_rootP, symbol_lastP);
241 #endif
242     }
243
244 #ifdef NEED_ECOFF_DEBUG
245   ecoff_new_file (s);
246 #endif
247 }
248
249 static void
250 obj_elf_common (ignore)
251      int ignore;
252 {
253   char *name;
254   char c;
255   char *p;
256   int temp, size;
257   symbolS *symbolP;
258   int have_align;
259
260   name = input_line_pointer;
261   c = get_symbol_end ();
262   /* just after name is now '\0' */
263   p = input_line_pointer;
264   *p = c;
265   SKIP_WHITESPACE ();
266   if (*input_line_pointer != ',')
267     {
268       as_bad ("Expected comma after symbol-name");
269       ignore_rest_of_line ();
270       return;
271     }
272   input_line_pointer++;         /* skip ',' */
273   if ((temp = get_absolute_expression ()) < 0)
274     {
275       as_bad (".COMMon length (%d.) <0! Ignored.", temp);
276       ignore_rest_of_line ();
277       return;
278     }
279   size = temp;
280   *p = 0;
281   symbolP = symbol_find_or_make (name);
282   *p = c;
283   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
284     {
285       as_bad ("Ignoring attempt to re-define symbol");
286       ignore_rest_of_line ();
287       return;
288     }
289   if (S_GET_VALUE (symbolP) != 0)
290     {
291       if (S_GET_VALUE (symbolP) != size)
292         {
293           as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
294                    S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
295         }
296     }
297   know (symbolP->sy_frag == &zero_address_frag);
298   if (*input_line_pointer != ',')
299     have_align = 0;
300   else
301     {
302       have_align = 1;
303       input_line_pointer++;
304       SKIP_WHITESPACE ();
305     }
306   if (! have_align || *input_line_pointer != '"')
307     {
308       if (! have_align)
309         temp = 0;
310       else
311         {
312           temp = get_absolute_expression ();
313           if (temp < 0)
314             {
315               temp = 0;
316               as_warn ("Common alignment negative; 0 assumed");
317             }
318         }
319       if (symbolP->local)
320         {
321           segT old_sec;
322           int old_subsec;
323           char *pfrag;
324           int align;
325
326         /* allocate_bss: */
327           old_sec = now_seg;
328           old_subsec = now_subseg;
329           if (temp)
330             {
331               /* convert to a power of 2 alignment */
332               for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
333               if (temp != 1)
334                 {
335                   as_bad ("Common alignment not a power of 2");
336                   ignore_rest_of_line ();
337                   return;
338                 }
339             }
340           else
341             align = 0;
342           record_alignment (bss_section, align);
343           subseg_set (bss_section, 0);
344           if (align)
345             frag_align (align, 0, 0);
346           if (S_GET_SEGMENT (symbolP) == bss_section)
347             symbolP->sy_frag->fr_symbol = 0;
348           symbolP->sy_frag = frag_now;
349           pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
350                             (offsetT) size, (char *) 0);
351           *pfrag = 0;
352           S_SET_SIZE (symbolP, size);
353           S_SET_SEGMENT (symbolP, bss_section);
354           S_CLEAR_EXTERNAL (symbolP);
355           subseg_set (old_sec, old_subsec);
356         }
357       else
358         {
359         allocate_common:
360           S_SET_VALUE (symbolP, (valueT) size);
361           S_SET_ALIGN (symbolP, temp);
362           S_SET_EXTERNAL (symbolP);
363           S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
364         }
365     }
366   else
367     {
368       input_line_pointer++;
369       /* @@ Some use the dot, some don't.  Can we get some consistency??  */
370       if (*input_line_pointer == '.')
371         input_line_pointer++;
372       /* @@ Some say data, some say bss.  */
373       if (strncmp (input_line_pointer, "bss\"", 4)
374           && strncmp (input_line_pointer, "data\"", 5))
375         {
376           while (*--input_line_pointer != '"')
377             ;
378           input_line_pointer--;
379           goto bad_common_segment;
380         }
381       while (*input_line_pointer++ != '"')
382         ;
383       goto allocate_common;
384     }
385
386   symbolP->bsym->flags |= BSF_OBJECT;
387
388   demand_empty_rest_of_line ();
389   return;
390
391   {
392   bad_common_segment:
393     p = input_line_pointer;
394     while (*p && *p != '\n')
395       p++;
396     c = *p;
397     *p = '\0';
398     as_bad ("bad .common segment %s", input_line_pointer + 1);
399     *p = c;
400     input_line_pointer = p;
401     ignore_rest_of_line ();
402     return;
403   }
404 }
405
406 static void
407 obj_elf_local (ignore)
408      int ignore;
409 {
410   char *name;
411   int c;
412   symbolS *symbolP;
413
414   do
415     {
416       name = input_line_pointer;
417       c = get_symbol_end ();
418       symbolP = symbol_find_or_make (name);
419       *input_line_pointer = c;
420       SKIP_WHITESPACE ();
421       S_CLEAR_EXTERNAL (symbolP);
422       symbolP->local = 1;
423       if (c == ',')
424         {
425           input_line_pointer++;
426           SKIP_WHITESPACE ();
427           if (*input_line_pointer == '\n')
428             c = '\n';
429         }
430     }
431   while (c == ',');
432   demand_empty_rest_of_line ();
433 }
434
435 static void
436 obj_elf_weak (ignore)
437      int ignore;
438 {
439   char *name;
440   int c;
441   symbolS *symbolP;
442
443   do
444     {
445       name = input_line_pointer;
446       c = get_symbol_end ();
447       symbolP = symbol_find_or_make (name);
448       *input_line_pointer = c;
449       SKIP_WHITESPACE ();
450       S_SET_WEAK (symbolP);
451       symbolP->local = 1;
452       if (c == ',')
453         {
454           input_line_pointer++;
455           SKIP_WHITESPACE ();
456           if (*input_line_pointer == '\n')
457             c = '\n';
458         }
459     }
460   while (c == ',');
461   demand_empty_rest_of_line ();
462 }
463
464 static segT previous_section;
465 static int previous_subsection;
466
467 /* Handle the .section pseudo-op.  This code supports two different
468    syntaxes.
469
470    The first is found on Solaris, and looks like
471        .section ".sec1",#alloc,#execinstr,#write
472    Here the names after '#' are the SHF_* flags to turn on for the
473    section.  I'm not sure how it determines the SHT_* type (BFD
474    doesn't really give us control over the type, anyhow).
475
476    The second format is found on UnixWare, and probably most SVR4
477    machines, and looks like
478        .section .sec1,"a",@progbits
479    The quoted string may contain any combination of a, w, x, and
480    represents the SHF_* flags to turn on for the section.  The string
481    beginning with '@' can be progbits or nobits.  There should be
482    other possibilities, but I don't know what they are.  In any case,
483    BFD doesn't really let us set the section type.  */
484
485 /* Certain named sections have particular defined types, listed on p.
486    4-19 of the ABI.  */
487 struct special_section
488 {
489   const char *name;
490   int type;
491   int attributes;
492 };
493
494 static struct special_section special_sections[] =
495 {
496   { ".bss",     SHT_NOBITS,     SHF_ALLOC + SHF_WRITE           },
497   { ".comment", SHT_PROGBITS,   0                               },
498   { ".data",    SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
499   { ".data1",   SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
500   { ".debug",   SHT_PROGBITS,   0                               },
501   { ".fini",    SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
502   { ".init",    SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
503   { ".line",    SHT_PROGBITS,   0                               },
504   { ".note",    SHT_NOTE,       0                               },
505   { ".rodata",  SHT_PROGBITS,   SHF_ALLOC                       },
506   { ".rodata1", SHT_PROGBITS,   SHF_ALLOC                       },
507   { ".text",    SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
508
509 #ifdef ELF_TC_SPECIAL_SECTIONS
510   ELF_TC_SPECIAL_SECTIONS
511 #endif
512
513 #if 0
514   /* The following section names are special, but they can not
515      reasonably appear in assembler code.  Some of the attributes are
516      processor dependent.  */
517   { ".dynamic", SHT_DYNAMIC,    SHF_ALLOC /* + SHF_WRITE */     },
518   { ".dynstr",  SHT_STRTAB,     SHF_ALLOC                       },
519   { ".dynsym",  SHT_DYNSYM,     SHF_ALLOC                       },
520   { ".got",     SHT_PROGBITS,   0                               },
521   { ".hash",    SHT_HASH,       SHF_ALLOC                       },
522   { ".interp",  SHT_PROGBITS,   /* SHF_ALLOC */                 },
523   { ".plt",     SHT_PROGBITS,   0                               },
524   { ".shstrtab",SHT_STRTAB,     0                               },
525   { ".strtab",  SHT_STRTAB,     /* SHF_ALLOC */                 },
526   { ".symtab",  SHT_SYMTAB,     /* SHF_ALLOC */                 },
527 #endif
528
529   { NULL,       0,              0                               }
530 };
531
532 void
533 obj_elf_section (xxx)
534      int xxx;
535 {
536   char *string;
537   int new_sec;
538   segT sec;
539   int type, attr;
540   int i;
541   flagword flags;
542   symbolS *secsym;
543
544 #ifdef md_flush_pending_output
545   md_flush_pending_output ();
546 #endif
547
548   if (flag_mri)
549     {
550       char mri_type;
551
552       previous_section = now_seg;
553       previous_subsection = now_subseg;
554
555       s_mri_sect (&mri_type);
556
557 #ifdef md_elf_section_change_hook
558       md_elf_section_change_hook ();
559 #endif
560
561       return;
562     }
563
564   /* Get name of section.  */
565   SKIP_WHITESPACE ();
566   if (*input_line_pointer == '"')
567     {
568       string = demand_copy_C_string (&xxx);
569       if (string == NULL)
570         {
571           ignore_rest_of_line ();
572           return;
573         }
574     }
575   else
576     {
577       char *p = input_line_pointer;
578       char c;
579       while (0 == strchr ("\n\t,; ", *p))
580         p++;
581       if (p == input_line_pointer)
582         {
583           as_warn ("Missing section name");
584           ignore_rest_of_line ();
585           return;
586         }
587       c = *p;
588       *p = 0;
589       string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
590       strcpy (string, input_line_pointer);
591       *p = c;
592       input_line_pointer = p;
593     }
594
595   /* Switch to the section, creating it if necessary.  */
596   previous_section = now_seg;
597   previous_subsection = now_subseg;
598
599   new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
600   sec = subseg_new (string, 0);
601
602   /* If this section already existed, we don't bother to change the
603      flag values.  */
604   if (! new_sec)
605     {
606       while (! is_end_of_line[(unsigned char) *input_line_pointer])
607         ++input_line_pointer;
608       ++input_line_pointer;
609
610 #ifdef md_elf_section_change_hook
611       md_elf_section_change_hook ();
612 #endif
613
614       return;
615     }
616
617   SKIP_WHITESPACE ();
618
619   type = SHT_NULL;
620   attr = 0;
621
622   if (*input_line_pointer == ',')
623     {
624       /* Skip the comma.  */
625       ++input_line_pointer;
626
627       SKIP_WHITESPACE ();
628
629       if (*input_line_pointer == '"')
630         {
631           /* Pick up a string with a combination of a, w, x.  */
632           ++input_line_pointer;
633           while (*input_line_pointer != '"')
634             {
635               switch (*input_line_pointer)
636                 {
637                 case 'a':
638                   attr |= SHF_ALLOC;
639                   break;
640                 case 'w':
641                   attr |= SHF_WRITE;
642                   break;
643                 case 'x':
644                   attr |= SHF_EXECINSTR;
645                   break;
646                 default:
647                   {
648                     char *bad_msg = "Bad .section directive: want a,w,x in string";
649 #ifdef md_elf_section_letter
650                     int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
651                     if (md_attr)
652                       attr |= md_attr;
653                     else
654 #endif
655                       {
656                         as_warn (bad_msg);
657                         ignore_rest_of_line ();
658                         return;
659                       }
660                   }
661                 }
662               ++input_line_pointer;
663             }
664
665           /* Skip the closing quote.  */
666           ++input_line_pointer;
667
668           SKIP_WHITESPACE ();
669           if (*input_line_pointer == ',')
670             {
671               ++input_line_pointer;
672               SKIP_WHITESPACE ();
673               if (*input_line_pointer == '@')
674                 {
675                   ++input_line_pointer;
676                   if (strncmp (input_line_pointer, "progbits",
677                                sizeof "progbits" - 1) == 0)
678                     {
679                       type = SHT_PROGBITS;
680                       input_line_pointer += sizeof "progbits" - 1;
681                     }
682                   else if (strncmp (input_line_pointer, "nobits",
683                                     sizeof "nobits" - 1) == 0)
684                     {
685                       type = SHT_NOBITS;
686                       input_line_pointer += sizeof "nobits" - 1;
687                     }
688                   else
689                     {
690 #ifdef md_elf_section_type
691                     int md_type = md_elf_section_type (&input_line_pointer);
692                     if (md_type)
693                       type = md_type;
694                     else
695 #endif
696                       {
697                         as_warn ("Unrecognized section type");
698                         ignore_rest_of_line ();
699                       }
700                     }
701                 }
702             }
703         }
704       else
705         {
706           do
707             {
708               SKIP_WHITESPACE ();
709               if (*input_line_pointer != '#')
710                 {
711                   as_warn ("Bad .section directive - character following name is not '#'");
712                   ignore_rest_of_line ();
713                   return;
714                 }
715               ++input_line_pointer;
716               if (strncmp (input_line_pointer, "write",
717                            sizeof "write" - 1) == 0)
718                 {
719                   attr |= SHF_WRITE;
720                   input_line_pointer += sizeof "write" - 1;
721                 }
722               else if (strncmp (input_line_pointer, "alloc",
723                                 sizeof "alloc" - 1) == 0)
724                 {
725                   attr |= SHF_ALLOC;
726                   input_line_pointer += sizeof "alloc" - 1;
727                 }
728               else if (strncmp (input_line_pointer, "execinstr",
729                                 sizeof "execinstr" - 1) == 0)
730                 {
731                   attr |= SHF_EXECINSTR;
732                   input_line_pointer += sizeof "execinstr" - 1;
733                 }
734               else
735                 {
736 #ifdef md_elf_section_word
737                   int md_attr = md_elf_section_word (&input_line_pointer);
738                   if (md_attr)
739                     attr |= md_attr;
740                   else
741 #endif
742                     {
743                       as_warn ("Unrecognized section attribute");
744                       ignore_rest_of_line ();
745                       return;
746                     }
747                 }
748               SKIP_WHITESPACE ();
749             }
750           while (*input_line_pointer++ == ',');
751           --input_line_pointer;
752         }
753     }
754
755   /* See if this is one of the special sections.  */
756   for (i = 0; special_sections[i].name != NULL; i++)
757     {
758       if (string[1] == special_sections[i].name[1]
759           && strcmp (string, special_sections[i].name) == 0)
760         {
761           if (type == SHT_NULL)
762             type = special_sections[i].type;
763           else if (type != special_sections[i].type)
764             as_warn ("Setting incorrect section type for %s", string);
765
766           if ((attr &~ special_sections[i].attributes) != 0)
767             {
768               /* As a GNU extension, we permit a .note section to be
769                  allocatable.  If the linker sees an allocateable
770                  .note section, it will create a PT_NOTE segment in
771                  the output file.  */
772               if (strcmp (string, ".note") != 0
773                   || attr != SHF_ALLOC)
774                 as_warn ("Setting incorrect section attributes for %s",
775                          string);
776             }
777           attr |= special_sections[i].attributes;
778
779           break;
780         }
781     }
782
783   flags = (SEC_RELOC
784            | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
785            | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
786            | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
787            | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
788   if (special_sections[i].name == NULL)
789     {
790       if (type == SHT_PROGBITS)
791         flags |= SEC_ALLOC | SEC_LOAD;
792       else if (type == SHT_NOBITS)
793         {
794           flags |= SEC_ALLOC;
795           flags &=~ SEC_LOAD;
796         }
797
798 #ifdef md_elf_section_flags
799       flags = md_elf_section_flags (flags, attr, type);
800 #endif
801     }
802
803   /* Prevent SEC_HAS_CONTENTS from being inadvertently set.  */
804   if (type == SHT_NOBITS)
805     seg_info (sec)->bss = 1;
806
807   bfd_set_section_flags (stdoutput, sec, flags);
808
809   /* Add a symbol for this section to the symbol table.  */
810   secsym = symbol_find (string);
811   if (secsym != NULL)
812     secsym->bsym = sec->symbol;
813   else
814     symbol_table_insert (section_symbol (sec));
815
816 #ifdef md_elf_section_change_hook
817   md_elf_section_change_hook ();
818 #endif
819
820   demand_empty_rest_of_line ();
821 }
822
823 /* Change to the .data section.  */
824
825 static void
826 obj_elf_data (i)
827      int i;
828 {
829 #ifdef md_flush_pending_output
830   md_flush_pending_output ();
831 #endif
832
833   previous_section = now_seg;
834   previous_subsection = now_subseg;
835   s_data (i);
836
837 #ifdef md_elf_section_change_hook
838   md_elf_section_change_hook ();
839 #endif
840 }
841
842 /* Change to the .text section.  */
843
844 static void
845 obj_elf_text (i)
846      int i;
847 {
848 #ifdef md_flush_pending_output
849   md_flush_pending_output ();
850 #endif
851
852   previous_section = now_seg;
853   previous_subsection = now_subseg;
854   s_text (i);
855
856 #ifdef md_elf_section_change_hook
857   md_elf_section_change_hook ();
858 #endif
859 }
860
861 static void
862 obj_elf_subsection (ignore)
863      int ignore;
864 {
865   register int temp;
866
867 #ifdef md_flush_pending_output
868   md_flush_pending_output ();
869 #endif
870
871   previous_section = now_seg;
872   previous_subsection = now_subseg;
873
874   temp = get_absolute_expression ();
875   subseg_set (now_seg, (subsegT) temp);
876   demand_empty_rest_of_line ();
877
878 #ifdef md_elf_section_change_hook
879   md_elf_section_change_hook ();
880 #endif
881 }
882
883 /* This can be called from the processor backends if they change
884    sections.  */
885
886 void
887 obj_elf_section_change_hook ()
888 {
889   previous_section = now_seg;
890   previous_subsection = now_subseg;
891 }
892
893 void
894 obj_elf_previous (ignore)
895      int ignore;
896 {
897   if (previous_section == 0)
898     {
899       as_bad (".previous without corresponding .section; ignored");
900       return;
901     }
902
903 #ifdef md_flush_pending_output
904   md_flush_pending_output ();
905 #endif
906
907   subseg_set (previous_section, previous_subsection);
908   previous_section = 0;
909
910 #ifdef md_elf_section_change_hook
911   md_elf_section_change_hook ();
912 #endif
913 }
914
915 static void
916 obj_elf_line (ignore)
917      int ignore;
918 {
919   /* Assume delimiter is part of expression.  BSD4.2 as fails with
920      delightful bug, so we are not being incompatible here. */
921   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
922   demand_empty_rest_of_line ();
923 }
924
925 /* This handle the .symver pseudo-op, which is used to specify a
926    symbol version.  The syntax is ``.symver NAME,SYMVERNAME''.
927    SYMVERNAME may contain ELF_VER_CHR ('@') characters.  This
928    pseudo-op causes the assembler to emit a symbol named SYMVERNAME
929    with the same value as the symbol NAME.  */
930
931 static void
932 obj_elf_symver (ignore)
933      int ignore;
934 {
935   char *name;
936   char c;
937   symbolS *sym;
938
939   name = input_line_pointer;
940   c = get_symbol_end ();
941
942   sym = symbol_find_or_make (name);
943
944   *input_line_pointer = c;
945
946   if (sym->sy_obj.versioned_name != NULL)
947     {
948       as_bad ("multiple .symver directives for symbol `%s'",
949               S_GET_NAME (sym));
950       ignore_rest_of_line ();
951       return;
952     }
953
954   SKIP_WHITESPACE ();
955   if (*input_line_pointer != ',')
956     {
957       as_bad ("expected comma after name in .symver");
958       ignore_rest_of_line ();
959       return;
960     }
961
962   ++input_line_pointer;
963   name = input_line_pointer;
964   while (1)
965     {
966       c = get_symbol_end ();
967       if (c != ELF_VER_CHR)
968         break;
969       *input_line_pointer++ = c;
970     }
971
972   sym->sy_obj.versioned_name = xstrdup (name);
973
974   *input_line_pointer = c;
975
976   if (strchr (sym->sy_obj.versioned_name, ELF_VER_CHR) == NULL)
977     {
978       as_bad ("missing version name in `%s' for symbol `%s'",
979               sym->sy_obj.versioned_name, S_GET_NAME (sym));
980       ignore_rest_of_line ();
981       return;
982     }
983
984   demand_empty_rest_of_line ();
985 }
986
987 void
988 obj_read_begin_hook ()
989 {
990 #ifdef NEED_ECOFF_DEBUG
991   if (ECOFF_DEBUGGING)
992     ecoff_read_begin_hook ();
993 #endif
994 }
995
996 void
997 obj_symbol_new_hook (symbolP)
998      symbolS *symbolP;
999 {
1000   symbolP->sy_obj.size = NULL;
1001   symbolP->sy_obj.versioned_name = NULL;
1002
1003 #ifdef NEED_ECOFF_DEBUG
1004   if (ECOFF_DEBUGGING)
1005     ecoff_symbol_new_hook (symbolP);
1006 #endif
1007 }
1008
1009 void
1010 obj_elf_version (ignore)
1011      int ignore;
1012 {
1013   char *name;
1014   unsigned int c;
1015   char ch;
1016   char *p;
1017   asection *seg = now_seg;
1018   subsegT subseg = now_subseg;
1019   Elf_Internal_Note i_note;
1020   Elf_External_Note e_note;
1021   asection *note_secp = (asection *) NULL;
1022   int i, len;
1023
1024   SKIP_WHITESPACE ();
1025   if (*input_line_pointer == '\"')
1026     {
1027       ++input_line_pointer;     /* -> 1st char of string. */
1028       name = input_line_pointer;
1029
1030       while (is_a_char (c = next_char_of_string ()))
1031         ;
1032       c = *input_line_pointer;
1033       *input_line_pointer = '\0';
1034       *(input_line_pointer - 1) = '\0';
1035       *input_line_pointer = c;
1036
1037       /* create the .note section */
1038
1039       note_secp = subseg_new (".note", 0);
1040       bfd_set_section_flags (stdoutput,
1041                              note_secp,
1042                              SEC_HAS_CONTENTS | SEC_READONLY);
1043
1044       /* process the version string */
1045
1046       len = strlen (name);
1047
1048       i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
1049       i_note.descsz = 0;        /* no description */
1050       i_note.type = NT_VERSION;
1051       p = frag_more (sizeof (e_note.namesz));
1052       md_number_to_chars (p, (valueT) i_note.namesz, 4);
1053       p = frag_more (sizeof (e_note.descsz));
1054       md_number_to_chars (p, (valueT) i_note.descsz, 4);
1055       p = frag_more (sizeof (e_note.type));
1056       md_number_to_chars (p, (valueT) i_note.type, 4);
1057
1058       for (i = 0; i < len; i++)
1059         {
1060           ch = *(name + i);
1061           {
1062             FRAG_APPEND_1_CHAR (ch);
1063           }
1064         }
1065       frag_align (2, 0, 0);
1066
1067       subseg_set (seg, subseg);
1068     }
1069   else
1070     {
1071       as_bad ("Expected quoted string");
1072     }
1073   demand_empty_rest_of_line ();
1074 }
1075
1076 static void
1077 obj_elf_size (ignore)
1078      int ignore;
1079 {
1080   char *name = input_line_pointer;
1081   char c = get_symbol_end ();
1082   char *p;
1083   expressionS exp;
1084   symbolS *sym;
1085
1086   p = input_line_pointer;
1087   *p = c;
1088   SKIP_WHITESPACE ();
1089   if (*input_line_pointer != ',')
1090     {
1091       *p = 0;
1092       as_bad ("expected comma after name `%s' in .size directive", name);
1093       *p = c;
1094       ignore_rest_of_line ();
1095       return;
1096     }
1097   input_line_pointer++;
1098   expression (&exp);
1099   if (exp.X_op == O_absent)
1100     {
1101       as_bad ("missing expression in .size directive");
1102       exp.X_op = O_constant;
1103       exp.X_add_number = 0;
1104     }
1105   *p = 0;
1106   sym = symbol_find_or_make (name);
1107   *p = c;
1108   if (exp.X_op == O_constant)
1109     S_SET_SIZE (sym, exp.X_add_number);
1110   else
1111     {
1112       sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS));
1113       *sym->sy_obj.size = exp;
1114     }
1115   demand_empty_rest_of_line ();
1116 }
1117
1118 /* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
1119    There are three syntaxes.  The first (used on Solaris) is
1120        .type SYM,#function
1121    The second (used on UnixWare) is
1122        .type SYM,@function
1123    The third (reportedly to be used on Irix 6.0) is
1124        .type SYM STT_FUNC
1125    */
1126
1127 static void
1128 obj_elf_type (ignore)
1129      int ignore;
1130 {
1131   char *name;
1132   char c;
1133   int type;
1134   const char *typename;
1135   symbolS *sym;
1136
1137   name = input_line_pointer;
1138   c = get_symbol_end ();
1139   sym = symbol_find_or_make (name);
1140   *input_line_pointer = c;
1141
1142   SKIP_WHITESPACE ();
1143   if (*input_line_pointer == ',')
1144     ++input_line_pointer;
1145
1146   SKIP_WHITESPACE ();
1147   if (*input_line_pointer == '#' || *input_line_pointer == '@')
1148     ++input_line_pointer;
1149
1150   typename = input_line_pointer;
1151   c = get_symbol_end ();
1152
1153   type = 0;
1154   if (strcmp (typename, "function") == 0
1155       || strcmp (typename, "STT_FUNC") == 0)
1156     type = BSF_FUNCTION;
1157   else if (strcmp (typename, "object") == 0
1158            || strcmp (typename, "STT_OBJECT") == 0)
1159     type = BSF_OBJECT;
1160   else
1161     as_bad ("ignoring unrecognized symbol type \"%s\"", typename);
1162
1163   *input_line_pointer = c;
1164
1165   sym->bsym->flags |= type;
1166
1167   demand_empty_rest_of_line ();
1168 }
1169
1170 static void
1171 obj_elf_ident (ignore)
1172      int ignore;
1173 {
1174   static segT comment_section;
1175   segT old_section = now_seg;
1176   int old_subsection = now_subseg;
1177
1178   if (!comment_section)
1179     {
1180       char *p;
1181       comment_section = subseg_new (".comment", 0);
1182       bfd_set_section_flags (stdoutput, comment_section,
1183                              SEC_READONLY | SEC_HAS_CONTENTS);
1184       p = frag_more (1);
1185       *p = 0;
1186     }
1187   else
1188     subseg_set (comment_section, 0);
1189   stringer (1);
1190   subseg_set (old_section, old_subsection);
1191 }
1192
1193 #ifdef INIT_STAB_SECTION
1194
1195 /* The first entry in a .stabs section is special.  */
1196
1197 void
1198 obj_elf_init_stab_section (seg)
1199      segT seg;
1200 {
1201   char *file;
1202   char *p;
1203   char *stabstr_name;
1204   unsigned int stroff;
1205
1206   /* Force the section to align to a longword boundary.  Without this,
1207      UnixWare ar crashes.  */
1208   bfd_set_section_alignment (stdoutput, seg, 2);
1209
1210   /* Make space for this first symbol. */
1211   p = frag_more (12);
1212   /* Zero it out. */
1213   memset (p, 0, 12);
1214   as_where (&file, (unsigned int *) NULL);
1215   stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
1216   strcpy (stabstr_name, segment_name (seg));
1217   strcat (stabstr_name, "str");
1218   stroff = get_stab_string_offset (file, stabstr_name);
1219   know (stroff == 1);
1220   md_number_to_chars (p, stroff, 4);
1221   seg_info (seg)->stabu.p = p;
1222 }
1223
1224 #endif
1225
1226 /* Fill in the counts in the first entry in a .stabs section.  */
1227
1228 static void
1229 adjust_stab_sections (abfd, sec, xxx)
1230      bfd *abfd;
1231      asection *sec;
1232      PTR xxx;
1233 {
1234   char *name;
1235   asection *strsec;
1236   char *p;
1237   int strsz, nsyms;
1238
1239   if (strncmp (".stab", sec->name, 5))
1240     return;
1241   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1242     return;
1243
1244   name = (char *) alloca (strlen (sec->name) + 4);
1245   strcpy (name, sec->name);
1246   strcat (name, "str");
1247   strsec = bfd_get_section_by_name (abfd, name);
1248   if (strsec)
1249     strsz = bfd_section_size (abfd, strsec);
1250   else
1251     strsz = 0;
1252   nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1253
1254   p = seg_info (sec)->stabu.p;
1255   assert (p != 0);
1256
1257   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
1258   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
1259 }
1260
1261 #ifdef NEED_ECOFF_DEBUG
1262
1263 /* This function is called by the ECOFF code.  It is supposed to
1264    record the external symbol information so that the backend can
1265    write it out correctly.  The ELF backend doesn't actually handle
1266    this at the moment, so we do it ourselves.  We save the information
1267    in the symbol.  */
1268
1269 void
1270 elf_ecoff_set_ext (sym, ext)
1271      symbolS *sym;
1272      struct ecoff_extr *ext;
1273 {
1274   sym->bsym->udata.p = (PTR) ext;
1275 }
1276
1277 /* This function is called by bfd_ecoff_debug_externals.  It is
1278    supposed to *EXT to the external symbol information, and return
1279    whether the symbol should be used at all.  */
1280
1281 static boolean
1282 elf_get_extr (sym, ext)
1283      asymbol *sym;
1284      EXTR *ext;
1285 {
1286   if (sym->udata.p == NULL)
1287     return false;
1288   *ext = *(EXTR *) sym->udata.p;
1289   return true;
1290 }
1291
1292 /* This function is called by bfd_ecoff_debug_externals.  It has
1293    nothing to do for ELF.  */
1294
1295 /*ARGSUSED*/
1296 static void
1297 elf_set_index (sym, indx)
1298      asymbol *sym;
1299      bfd_size_type indx;
1300 {
1301 }
1302
1303 #endif /* NEED_ECOFF_DEBUG */
1304
1305 void
1306 elf_frob_symbol (symp, puntp)
1307      symbolS *symp;
1308      int *puntp;
1309 {
1310 #ifdef NEED_ECOFF_DEBUG
1311   if (ECOFF_DEBUGGING)
1312     ecoff_frob_symbol (symp);
1313 #endif
1314
1315   if (symp->sy_obj.size != NULL)
1316     {
1317       switch (symp->sy_obj.size->X_op)
1318         {
1319         case O_subtract:
1320           S_SET_SIZE (symp,
1321                       (S_GET_VALUE (symp->sy_obj.size->X_add_symbol)
1322                        + symp->sy_obj.size->X_add_number
1323                        - S_GET_VALUE (symp->sy_obj.size->X_op_symbol)));
1324           break;
1325         case O_constant:
1326           S_SET_SIZE (symp,
1327                       (S_GET_VALUE (symp->sy_obj.size->X_add_symbol)
1328                        + symp->sy_obj.size->X_add_number));
1329           break;
1330         default:
1331           as_bad (".size expression too complicated to fix up");
1332           break;
1333         }
1334       free (symp->sy_obj.size);
1335       symp->sy_obj.size = NULL;
1336     }
1337
1338   if (symp->sy_obj.versioned_name != NULL)
1339     {
1340       /* This symbol was given a new name with the .symver directive.
1341
1342          If this is an external reference, just rename the symbol to
1343          include the version string.  This will make the relocs be
1344          against the correct versioned symbol.
1345
1346          If this is a definition, add an alias.  FIXME: Using an alias
1347          will permit the debugging information to refer to the right
1348          symbol.  However, it's not clear whether it is the best
1349          approach.  */
1350
1351       if (! S_IS_DEFINED (symp))
1352         {
1353           char *p;
1354
1355           /* Verify that the name isn't using the @@ syntax--this is
1356              reserved for definitions of the default version to link
1357              against.  */
1358           p = strchr (symp->sy_obj.versioned_name, ELF_VER_CHR);
1359           know (p != NULL);
1360           if (p[1] == ELF_VER_CHR)
1361             {
1362               as_bad ("invalid attempt to declare external version name as default in symbol `%s'",
1363                       symp->sy_obj.versioned_name);
1364               *puntp = true;
1365             }
1366           S_SET_NAME (symp, symp->sy_obj.versioned_name);
1367         }
1368       else
1369         {
1370           symbolS *symp2;
1371
1372           /* FIXME: Creating a new symbol here is risky.  We're in the
1373              final loop over the symbol table.  We can get away with
1374              it only because the symbol goes to the end of the list,
1375              where the loop will still see it.  It would probably be
1376              better to do this in obj_frob_file_before_adjust. */
1377
1378           symp2 = symbol_find_or_make (symp->sy_obj.versioned_name);
1379
1380           /* Now we act as though we saw symp2 = sym.  */
1381
1382           S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
1383
1384           /* Subtracting out the frag address here is a hack because
1385              we are in the middle of the final loop.  */
1386           S_SET_VALUE (symp2, S_GET_VALUE (symp) - symp->sy_frag->fr_address);
1387
1388           symp2->sy_frag = symp->sy_frag;
1389
1390           /* This will copy over the size information.  */
1391           copy_symbol_attributes (symp2, symp);
1392
1393           if (S_IS_WEAK (symp))
1394             S_SET_WEAK (symp2);
1395
1396           if (S_IS_EXTERNAL (symp))
1397             S_SET_EXTERNAL (symp2);
1398         }
1399     }
1400
1401   /* Double check weak symbols.  */
1402   if (symp->bsym->flags & BSF_WEAK)
1403     {
1404       if (S_IS_COMMON (symp))
1405         as_bad ("Symbol `%s' can not be both weak and common",
1406                 S_GET_NAME (symp));
1407     }
1408
1409 #ifdef TC_MIPS
1410   /* The Irix 5 and 6 assemblers set the type of any common symbol and
1411      any undefined non-function symbol to STT_OBJECT.  We try to be
1412      compatible, since newer Irix 5 and 6 linkers care.  However, we
1413      only set undefined symbols to be STT_OBJECT if we are on Irix,
1414      because that is the only time gcc will generate the necessary
1415      .global directives to mark functions.  */
1416
1417   if (S_IS_COMMON (symp))
1418     symp->bsym->flags |= BSF_OBJECT;
1419
1420   if (strstr (TARGET_OS, "irix") != NULL
1421       && (! S_IS_DEFINED (symp) && ((symp->bsym->flags & BSF_FUNCTION) == 0)))
1422     symp->bsym->flags |= BSF_OBJECT;
1423 #endif
1424
1425 #ifdef TC_PPC
1426   /* Frob the PowerPC, so that the symbol always has object type
1427      if it is not some other type.  VxWorks needs this.  */
1428   if ((symp->bsym->flags & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
1429       && S_IS_DEFINED (symp))
1430     symp->bsym->flags |= BSF_OBJECT;
1431 #endif
1432 }
1433
1434 void
1435 elf_frob_file ()
1436 {
1437   bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1438
1439 #ifdef elf_tc_final_processing
1440   elf_tc_final_processing ();
1441 #endif
1442 }
1443
1444 /* It is required that we let write_relocs have the opportunity to
1445    optimize away fixups before output has begun, since it is possible
1446    to eliminate all fixups for a section and thus we never should
1447    have generated the relocation section.  */
1448
1449 void
1450 elf_frob_file_after_relocs ()
1451 {
1452 #ifdef NEED_ECOFF_DEBUG
1453   if (ECOFF_DEBUGGING)
1454     /* Generate the ECOFF debugging information.  */
1455     {
1456       const struct ecoff_debug_swap *debug_swap;
1457       struct ecoff_debug_info debug;
1458       char *buf;
1459       asection *sec;
1460
1461       debug_swap
1462         = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1463       know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1464       ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1465
1466       /* Set up the pointers in debug.  */
1467 #define SET(ptr, offset, type) \
1468     debug.ptr = (type) (buf + debug.symbolic_header.offset)
1469
1470       SET (line, cbLineOffset, unsigned char *);
1471       SET (external_dnr, cbDnOffset, PTR);
1472       SET (external_pdr, cbPdOffset, PTR);
1473       SET (external_sym, cbSymOffset, PTR);
1474       SET (external_opt, cbOptOffset, PTR);
1475       SET (external_aux, cbAuxOffset, union aux_ext *);
1476       SET (ss, cbSsOffset, char *);
1477       SET (external_fdr, cbFdOffset, PTR);
1478       SET (external_rfd, cbRfdOffset, PTR);
1479       /* ssext and external_ext are set up just below.  */
1480
1481 #undef SET
1482
1483       /* Set up the external symbols.  */
1484       debug.ssext = debug.ssext_end = NULL;
1485       debug.external_ext = debug.external_ext_end = NULL;
1486       if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1487                                        elf_get_extr, elf_set_index))
1488         as_fatal ("Failed to set up debugging information: %s",
1489                   bfd_errmsg (bfd_get_error ()));
1490
1491       sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1492       assert (sec != NULL);
1493
1494       know (stdoutput->output_has_begun == false);
1495
1496       /* We set the size of the section, call bfd_set_section_contents
1497          to force the ELF backend to allocate a file position, and then
1498          write out the data.  FIXME: Is this really the best way to do
1499          this?  */
1500       sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1501
1502       if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
1503                                       (file_ptr) 0, (bfd_size_type) 0))
1504         as_fatal ("Can't start writing .mdebug section: %s",
1505                   bfd_errmsg (bfd_get_error ()));
1506
1507       know (stdoutput->output_has_begun == true);
1508       know (sec->filepos != 0);
1509
1510       if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1511                                    sec->filepos))
1512         as_fatal ("Could not write .mdebug section: %s",
1513                   bfd_errmsg (bfd_get_error ()));
1514     }
1515 #endif /* NEED_ECOFF_DEBUG */
1516 }
1517
1518 #ifdef SCO_ELF
1519
1520 /* Heavily plagarized from obj_elf_version.  The idea is to emit the
1521    SCO specific identifier in the .notes section to satisfy the SCO
1522    linker.
1523
1524    This looks more complicated than it really is.  As opposed to the
1525    "obvious" solution, this should handle the cross dev cases
1526    correctly.  (i.e, hosting on a 64 bit big endian processor, but
1527    generating SCO Elf code) Efficiency isn't a concern, as there
1528    should be exactly one of these sections per object module.
1529
1530    SCO OpenServer 5 identifies it's ELF modules with a standard ELF
1531    .note section.
1532
1533    int_32 namesz  = 4 ;  Name size 
1534    int_32 descsz  = 12 ; Descriptive information 
1535    int_32 type    = 1 ;  
1536    char   name[4] = "SCO" ; Originator name ALWAYS SCO + NULL 
1537    int_32 version = (major ver # << 16)  | version of tools ;
1538    int_32 source  = (tool_id << 16 ) | 1 ;
1539    int_32 info    = 0 ;    These are set by the SCO tools, but we
1540                            don't know enough about the source 
1541                            environment to set them.  SCO ld currently
1542                            ignores them, and recommends we set them
1543                            to zero.  */
1544
1545 #define SCO_MAJOR_VERSION 0x1
1546 #define SCO_MINOR_VERSION 0x1
1547
1548 void
1549 sco_id ()
1550 {
1551
1552   char *name;
1553   unsigned int c;
1554   char ch;
1555   char *p;
1556   asection *seg = now_seg;
1557   subsegT subseg = now_subseg;
1558   Elf_Internal_Note i_note;
1559   Elf_External_Note e_note;
1560   asection *note_secp = (asection *) NULL;
1561   int i, len;
1562
1563   /* create the .note section */
1564
1565   note_secp = subseg_new (".note", 0);
1566   bfd_set_section_flags (stdoutput,
1567                          note_secp,
1568                          SEC_HAS_CONTENTS | SEC_READONLY);
1569
1570   /* process the version string */
1571
1572   i_note.namesz = 4; 
1573   i_note.descsz = 12;           /* 12 descriptive bytes */
1574   i_note.type = NT_VERSION;     /* Contains a version string */
1575
1576   p = frag_more (sizeof (i_note.namesz));
1577   md_number_to_chars (p, (valueT) i_note.namesz, 4);
1578
1579   p = frag_more (sizeof (i_note.descsz));
1580   md_number_to_chars (p, (valueT) i_note.descsz, 4);
1581
1582   p = frag_more (sizeof (i_note.type));
1583   md_number_to_chars (p, (valueT) i_note.type, 4);
1584
1585   p = frag_more (4);
1586   strcpy (p, "SCO"); 
1587
1588   /* Note: this is the version number of the ELF we're representing */
1589   p = frag_more (4);
1590   md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
1591
1592   /* Here, we pick a magic number for ourselves (yes, I "registered"
1593      it with SCO.  The bottom bit shows that we are compat with the
1594      SCO ABI.  */
1595   p = frag_more (4);
1596   md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
1597
1598   /* If we knew (or cared) what the source language options were, we'd
1599      fill them in here.  SCO has given us permission to ignore these
1600      and just set them to zero.  */
1601   p = frag_more (4);
1602   md_number_to_chars (p, 0x0000, 4);
1603  
1604   frag_align (2, 0, 0);
1605
1606   /* We probably can't restore the current segment, for there likely
1607      isn't one yet...  */
1608   if (seg && subseg)
1609     subseg_set (seg, subseg);
1610
1611 }
1612
1613 #endif /* SCO_ELF */
1614
1615 const struct format_ops elf_format_ops =
1616 {
1617   bfd_target_elf_flavour,
1618   0,
1619   1,
1620   elf_frob_symbol,
1621   elf_frob_file,
1622   elf_frob_file_after_relocs,
1623   elf_s_get_size, elf_s_set_size,
1624   elf_s_get_align, elf_s_set_align,
1625   elf_copy_symbol_attributes,
1626 #ifdef NEED_ECOFF_DEBUG
1627   ecoff_generate_asm_lineno,
1628   ecoff_stab,
1629 #else
1630   0,
1631   0,                            /* process_stab */
1632 #endif
1633   elf_sec_sym_ok_for_reloc,
1634   elf_pop_insert,
1635 #ifdef NEED_ECOFF_DEBUG
1636   elf_ecoff_set_ext,
1637 #else
1638   0,
1639 #endif
1640   obj_read_begin_hook,
1641   obj_symbol_new_hook,
1642 };