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