]> Git Repo - binutils.git/blob - gas/config/obj-elf.c
Mon Jul 8 14:23:26 1996 Andreas Schwab <[email protected]>
[binutils.git] / gas / config / obj-elf.c
1 /* ELF object file format
2    Copyright (C) 1992, 1993, 1994, 1995, 1996 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_data PARAMS ((int));
58 static void obj_elf_text PARAMS ((int));
59
60 static const pseudo_typeS elf_pseudo_table[] =
61 {
62   {"comm", obj_elf_common, 0},
63   {"ident", obj_elf_ident, 0},
64   {"local", obj_elf_local, 0},
65   {"previous", obj_elf_previous, 0},
66   {"section", obj_elf_section, 0},
67   {"section.s", obj_elf_section, 0},
68   {"sect", obj_elf_section, 0},
69   {"sect.s", obj_elf_section, 0},
70   {"size", obj_elf_size, 0},
71   {"type", obj_elf_type, 0},
72   {"version", obj_elf_version, 0},
73   {"weak", obj_elf_weak, 0},
74
75 /* These are used for stabs-in-elf configurations.  */
76   {"line", obj_elf_line, 0},
77
78   /* These are used for dwarf. */
79   {"2byte", cons, 2},
80   {"4byte", cons, 4},
81   {"8byte", cons, 8},
82
83   /* We need to trap the section changing calls to handle .previous.  */
84   {"data", obj_elf_data, 0},
85   {"text", obj_elf_text, 0},
86
87   /* End sentinel.  */
88   {NULL},
89 };
90
91 static const pseudo_typeS ecoff_debug_pseudo_table[] =
92 {
93 #ifdef NEED_ECOFF_DEBUG
94   /* COFF style debugging information for ECOFF. .ln is not used; .loc
95      is used instead.  */
96   { "def",      ecoff_directive_def,    0 },
97   { "dim",      ecoff_directive_dim,    0 },
98   { "endef",    ecoff_directive_endef,  0 },
99   { "file",     ecoff_directive_file,   0 },
100   { "scl",      ecoff_directive_scl,    0 },
101   { "tag",      ecoff_directive_tag,    0 },
102   { "val",      ecoff_directive_val,    0 },
103
104   /* COFF debugging requires pseudo-ops .size and .type, but ELF
105      already has meanings for those.  We use .esize and .etype
106      instead.  These are only generated by gcc anyhow.  */
107   { "esize",    ecoff_directive_size,   0 },
108   { "etype",    ecoff_directive_type,   0 },
109
110   /* ECOFF specific debugging information.  */
111   { "begin",    ecoff_directive_begin,  0 },
112   { "bend",     ecoff_directive_bend,   0 },
113   { "end",      ecoff_directive_end,    0 },
114   { "ent",      ecoff_directive_ent,    0 },
115   { "fmask",    ecoff_directive_fmask,  0 },
116   { "frame",    ecoff_directive_frame,  0 },
117   { "loc",      ecoff_directive_loc,    0 },
118   { "mask",     ecoff_directive_mask,   0 },
119
120   /* Other ECOFF directives.  */
121   { "extern",   ecoff_directive_extern, 0 },
122
123   /* These are used on Irix.  I don't know how to implement them.  */
124   { "alias",    s_ignore,               0 },
125   { "bgnb",     s_ignore,               0 },
126   { "endb",     s_ignore,               0 },
127   { "lab",      s_ignore,               0 },
128   { "noalias",  s_ignore,               0 },
129   { "verstamp", s_ignore,               0 },
130   { "vreg",     s_ignore,               0 },
131 #endif
132
133   {NULL}                        /* end sentinel */
134 };
135
136 #undef NO_RELOC
137 #include "aout/aout64.h"
138
139 void
140 elf_pop_insert ()
141 {
142   pop_insert (elf_pseudo_table);
143   if (ECOFF_DEBUGGING)
144     pop_insert (ecoff_debug_pseudo_table);
145 }
146
147 static bfd_vma
148 elf_s_get_size (sym)
149      symbolS *sym;
150 {
151   return S_GET_SIZE (sym);
152 }
153
154 static void
155 elf_s_set_size (sym, sz)
156      symbolS *sym;
157      bfd_vma sz;
158 {
159   S_SET_SIZE (sym, sz);
160 }
161
162 static bfd_vma
163 elf_s_get_align (sym)
164      symbolS *sym;
165 {
166   return S_GET_ALIGN (sym);
167 }
168
169 static void
170 elf_s_set_align (sym, align)
171      symbolS *sym;
172      bfd_vma align;
173 {
174   S_SET_ALIGN (sym, align);
175 }
176
177 static void
178 elf_copy_symbol_attributes (dest, src)
179      symbolS *dest, *src;
180 {
181   OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
182 }
183
184 static int
185 elf_sec_sym_ok_for_reloc (sec)
186      asection *sec;
187 {
188   return obj_sec_sym_ok_for_reloc (sec);
189 }
190
191 void
192 elf_file_symbol (s)
193      char *s;
194 {
195   symbolS *sym;
196
197   sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
198   sym->sy_frag = &zero_address_frag;
199   sym->bsym->flags |= BSF_FILE;
200
201   if (symbol_rootP != sym)
202     {
203       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
204       symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
205 #ifdef DEBUG
206       verify_symbol_chain (symbol_rootP, symbol_lastP);
207 #endif
208     }
209 }
210
211 static void
212 obj_elf_common (ignore)
213      int ignore;
214 {
215   char *name;
216   char c;
217   char *p;
218   int temp, size;
219   symbolS *symbolP;
220   int have_align;
221
222   name = input_line_pointer;
223   c = get_symbol_end ();
224   /* just after name is now '\0' */
225   p = input_line_pointer;
226   *p = c;
227   SKIP_WHITESPACE ();
228   if (*input_line_pointer != ',')
229     {
230       as_bad ("Expected comma after symbol-name");
231       ignore_rest_of_line ();
232       return;
233     }
234   input_line_pointer++;         /* skip ',' */
235   if ((temp = get_absolute_expression ()) < 0)
236     {
237       as_bad (".COMMon length (%d.) <0! Ignored.", temp);
238       ignore_rest_of_line ();
239       return;
240     }
241   size = temp;
242   *p = 0;
243   symbolP = symbol_find_or_make (name);
244   *p = c;
245   if (S_IS_DEFINED (symbolP))
246     {
247       as_bad ("Ignoring attempt to re-define symbol");
248       ignore_rest_of_line ();
249       return;
250     }
251   if (S_GET_VALUE (symbolP) != 0)
252     {
253       if (S_GET_VALUE (symbolP) != size)
254         {
255           as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
256                    S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
257         }
258     }
259   know (symbolP->sy_frag == &zero_address_frag);
260   if (*input_line_pointer != ',')
261     have_align = 0;
262   else
263     {
264       have_align = 1;
265       input_line_pointer++;
266       SKIP_WHITESPACE ();
267     }
268   if (! have_align || *input_line_pointer != '"')
269     {
270       if (! have_align)
271         temp = 0;
272       else
273         {
274           temp = get_absolute_expression ();
275           if (temp < 0)
276             {
277               temp = 0;
278               as_warn ("Common alignment negative; 0 assumed");
279             }
280         }
281       if (symbolP->local)
282         {
283           segT old_sec;
284           int old_subsec;
285           char *pfrag;
286           int align;
287
288         /* allocate_bss: */
289           old_sec = now_seg;
290           old_subsec = now_subseg;
291           if (temp)
292             {
293               /* convert to a power of 2 alignment */
294               for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
295               if (temp != 1)
296                 {
297                   as_bad ("Common alignment not a power of 2");
298                   ignore_rest_of_line ();
299                   return;
300                 }
301             }
302           else
303             align = 0;
304           record_alignment (bss_section, align);
305           subseg_set (bss_section, 0);
306           if (align)
307             frag_align (align, 0);
308           if (S_GET_SEGMENT (symbolP) == bss_section)
309             symbolP->sy_frag->fr_symbol = 0;
310           symbolP->sy_frag = frag_now;
311           pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
312                             (char *) 0);
313           *pfrag = 0;
314           S_SET_SIZE (symbolP, size);
315           S_SET_SEGMENT (symbolP, bss_section);
316           S_CLEAR_EXTERNAL (symbolP);
317           subseg_set (old_sec, old_subsec);
318         }
319       else
320         {
321         allocate_common:
322           S_SET_VALUE (symbolP, (valueT) size);
323           S_SET_ALIGN (symbolP, temp);
324           S_SET_EXTERNAL (symbolP);
325           /* should be common, but this is how gas does it for now */
326           S_SET_SEGMENT (symbolP, bfd_und_section_ptr);
327         }
328     }
329   else
330     {
331       input_line_pointer++;
332       /* @@ Some use the dot, some don't.  Can we get some consistency??  */
333       if (*input_line_pointer == '.')
334         input_line_pointer++;
335       /* @@ Some say data, some say bss.  */
336       if (strncmp (input_line_pointer, "bss\"", 4)
337           && strncmp (input_line_pointer, "data\"", 5))
338         {
339           while (*--input_line_pointer != '"')
340             ;
341           input_line_pointer--;
342           goto bad_common_segment;
343         }
344       while (*input_line_pointer++ != '"')
345         ;
346       goto allocate_common;
347     }
348   demand_empty_rest_of_line ();
349   return;
350
351   {
352   bad_common_segment:
353     p = input_line_pointer;
354     while (*p && *p != '\n')
355       p++;
356     c = *p;
357     *p = '\0';
358     as_bad ("bad .common segment %s", input_line_pointer + 1);
359     *p = c;
360     input_line_pointer = p;
361     ignore_rest_of_line ();
362     return;
363   }
364 }
365
366 static void 
367 obj_elf_local (ignore)
368      int ignore;
369 {
370   char *name;
371   int c;
372   symbolS *symbolP;
373
374   do
375     {
376       name = input_line_pointer;
377       c = get_symbol_end ();
378       symbolP = symbol_find_or_make (name);
379       *input_line_pointer = c;
380       SKIP_WHITESPACE ();
381       S_CLEAR_EXTERNAL (symbolP);
382       symbolP->local = 1;
383       if (c == ',')
384         {
385           input_line_pointer++;
386           SKIP_WHITESPACE ();
387           if (*input_line_pointer == '\n')
388             c = '\n';
389         }
390     }
391   while (c == ',');
392   demand_empty_rest_of_line ();
393 }
394
395 static void 
396 obj_elf_weak (ignore)
397      int ignore;
398 {
399   char *name;
400   int c;
401   symbolS *symbolP;
402
403   do
404     {
405       name = input_line_pointer;
406       c = get_symbol_end ();
407       symbolP = symbol_find_or_make (name);
408       *input_line_pointer = c;
409       SKIP_WHITESPACE ();
410       S_SET_WEAK (symbolP);
411       symbolP->local = 1;
412       if (c == ',')
413         {
414           input_line_pointer++;
415           SKIP_WHITESPACE ();
416           if (*input_line_pointer == '\n')
417             c = '\n';
418         }
419     }
420   while (c == ',');
421   demand_empty_rest_of_line ();
422 }
423
424 static segT previous_section;
425 static int previous_subsection;
426
427 /* Handle the .section pseudo-op.  This code supports two different
428    syntaxes.  
429
430    The first is found on Solaris, and looks like
431        .section ".sec1",#alloc,#execinstr,#write
432    Here the names after '#' are the SHF_* flags to turn on for the
433    section.  I'm not sure how it determines the SHT_* type (BFD
434    doesn't really give us control over the type, anyhow).
435
436    The second format is found on UnixWare, and probably most SVR4
437    machines, and looks like
438        .section .sec1,"a",@progbits
439    The quoted string may contain any combination of a, w, x, and
440    represents the SHF_* flags to turn on for the section.  The string
441    beginning with '@' can be progbits or nobits.  There should be
442    other possibilities, but I don't know what they are.  In any case,
443    BFD doesn't really let us set the section type.  */
444
445 /* Certain named sections have particular defined types, listed on p.
446    4-19 of the ABI.  */
447 struct special_section
448 {
449   const char *name;
450   int type;
451   int attributes;
452 };
453
454 static struct special_section special_sections[] =
455 {
456   { ".bss",     SHT_NOBITS,     SHF_ALLOC + SHF_WRITE           },
457   { ".comment", SHT_PROGBITS,   0                               },
458   { ".data",    SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
459   { ".data1",   SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           },
460   { ".debug",   SHT_PROGBITS,   0                               },
461   { ".fini",    SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
462   { ".init",    SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
463   { ".line",    SHT_PROGBITS,   0                               },
464   { ".note",    SHT_NOTE,       0                               },
465   { ".rodata",  SHT_PROGBITS,   SHF_ALLOC                       },
466   { ".rodata1", SHT_PROGBITS,   SHF_ALLOC                       },
467   { ".text",    SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
468
469 #ifdef ELF_TC_SPECIAL_SECTIONS
470   ELF_TC_SPECIAL_SECTIONS
471 #endif
472
473 #if 0
474   /* The following section names are special, but they can not
475      reasonably appear in assembler code.  Some of the attributes are
476      processor dependent.  */
477   { ".dynamic", SHT_DYNAMIC,    SHF_ALLOC /* + SHF_WRITE */     },
478   { ".dynstr",  SHT_STRTAB,     SHF_ALLOC                       },
479   { ".dynsym",  SHT_DYNSYM,     SHF_ALLOC                       },
480   { ".got",     SHT_PROGBITS,   0                               },
481   { ".hash",    SHT_HASH,       SHF_ALLOC                       },
482   { ".interp",  SHT_PROGBITS,   /* SHF_ALLOC */                 },
483   { ".plt",     SHT_PROGBITS,   0                               },
484   { ".shstrtab",SHT_STRTAB,     0                               },
485   { ".strtab",  SHT_STRTAB,     /* SHF_ALLOC */                 },
486   { ".symtab",  SHT_SYMTAB,     /* SHF_ALLOC */                 },
487 #endif
488
489   { NULL,       0,              0                               }
490 };
491
492 void
493 obj_elf_section (xxx)
494      int xxx;
495 {
496   char *string;
497   int new_sec;
498   segT sec;
499   int type, attr;
500   int i;
501   flagword flags;
502
503 #ifdef md_flush_pending_output
504   md_flush_pending_output ();
505 #endif
506
507   if (flag_mri)
508     {
509       char mri_type;
510
511       previous_section = now_seg;
512       previous_subsection = now_subseg;
513
514       s_mri_sect (&mri_type);
515
516 #ifdef md_elf_section_change_hook
517       md_elf_section_change_hook ();
518 #endif
519
520       return;
521     }
522
523   /* Get name of section.  */
524   SKIP_WHITESPACE ();
525   if (*input_line_pointer == '"')
526     {
527       string = demand_copy_C_string (&xxx);
528       if (string == NULL)
529         {
530           ignore_rest_of_line ();
531           return;
532         }
533     }
534   else
535     {
536       char *p = input_line_pointer;
537       char c;
538       while (0 == strchr ("\n\t,; ", *p))
539         p++;
540       if (p == input_line_pointer)
541         {
542           as_warn ("Missing section name");
543           ignore_rest_of_line ();
544           return;
545         }
546       c = *p;
547       *p = 0;
548       string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
549       strcpy (string, input_line_pointer);
550       *p = c;
551       input_line_pointer = p;
552     }
553
554   /* Switch to the section, creating it if necessary.  */
555   previous_section = now_seg;
556   previous_subsection = now_subseg;
557
558   new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
559   sec = subseg_new (string, 0);
560
561   /* If this section already existed, we don't bother to change the
562      flag values.  */
563   if (! new_sec)
564     {
565       while (! is_end_of_line[(unsigned char) *input_line_pointer])
566         ++input_line_pointer;
567       ++input_line_pointer;
568
569 #ifdef md_elf_section_change_hook
570       md_elf_section_change_hook ();
571 #endif
572
573       return;
574     }
575
576   SKIP_WHITESPACE ();
577
578   type = SHT_NULL;
579   attr = 0;
580
581   if (*input_line_pointer == ',')
582     {
583       /* Skip the comma.  */
584       ++input_line_pointer;
585
586       SKIP_WHITESPACE ();
587       if (*input_line_pointer == '"')
588         {
589           /* Pick up a string with a combination of a, w, x.  */
590           ++input_line_pointer;
591           while (*input_line_pointer != '"')
592             {
593               switch (*input_line_pointer)
594                 {
595                 case 'a':
596                   attr |= SHF_ALLOC;
597                   break;
598                 case 'w':
599                   attr |= SHF_WRITE;
600                   break;
601                 case 'x':
602                   attr |= SHF_EXECINSTR;
603                   break;
604                 default:
605                   {
606                     char *bad_msg = "Bad .section directive: want a,w,x in string";
607 #ifdef md_elf_section_letter
608                     int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
609                     if (md_attr)
610                       attr |= md_attr;
611                     else
612 #endif
613                       {
614                         as_warn (bad_msg);
615                         ignore_rest_of_line ();
616                         return;
617                       }
618                   }
619                 }
620               ++input_line_pointer;
621             }
622
623           /* Skip the closing quote.  */
624           ++input_line_pointer;
625
626           SKIP_WHITESPACE ();
627           if (*input_line_pointer == ',')
628             {
629               ++input_line_pointer;
630               SKIP_WHITESPACE ();
631               if (*input_line_pointer == '@')
632                 {
633                   ++input_line_pointer;
634                   if (strncmp (input_line_pointer, "progbits",
635                                sizeof "progbits" - 1) == 0)
636                     {
637                       type = SHT_PROGBITS;
638                       input_line_pointer += sizeof "progbits" - 1;
639                     }
640                   else if (strncmp (input_line_pointer, "nobits",
641                                     sizeof "nobits" - 1) == 0)
642                     {
643                       type = SHT_NOBITS;
644                       input_line_pointer += sizeof "nobits" - 1;
645                     }
646                   else
647                     {
648 #ifdef md_elf_section_type
649                     int md_type = md_elf_section_type (&input_line_pointer);
650                     if (md_type)
651                       type = md_type;
652                     else
653 #endif
654                       {
655                         as_warn ("Unrecognized section type");
656                         ignore_rest_of_line ();
657                       }
658                     }
659                 }
660             }
661         }
662       else
663         {
664           do
665             {
666               SKIP_WHITESPACE ();
667               if (*input_line_pointer != '#')
668                 {
669                   as_warn ("Bad .section directive");
670                   ignore_rest_of_line ();
671                   return;
672                 }
673               ++input_line_pointer;
674               if (strncmp (input_line_pointer, "write",
675                            sizeof "write" - 1) == 0)
676                 {
677                   attr |= SHF_WRITE;
678                   input_line_pointer += sizeof "write" - 1;
679                 }
680               else if (strncmp (input_line_pointer, "alloc",
681                                 sizeof "alloc" - 1) == 0)
682                 {
683                   attr |= SHF_ALLOC;
684                   input_line_pointer += sizeof "alloc" - 1;
685                 }
686               else if (strncmp (input_line_pointer, "execinstr",
687                                 sizeof "execinstr" - 1) == 0)
688                 {
689                   attr |= SHF_EXECINSTR;
690                   input_line_pointer += sizeof "execinstr" - 1;
691                 }
692               else
693                 {
694 #ifdef md_elf_section_word
695                   int md_attr = md_elf_section_word (&input_line_pointer);
696                   if (md_attr)
697                     attr |= md_attr;
698                   else
699 #endif
700                     {
701                       as_warn ("Unrecognized section attribute");
702                       ignore_rest_of_line ();
703                       return;
704                     }
705                 }
706               SKIP_WHITESPACE ();
707             }
708           while (*input_line_pointer++ == ',');
709           --input_line_pointer;
710         }
711     }
712
713   /* See if this is one of the special sections.  */
714   for (i = 0; special_sections[i].name != NULL; i++)
715     {
716       if (string[1] == special_sections[i].name[1]
717           && strcmp (string, special_sections[i].name) == 0)
718         {
719           if (type == SHT_NULL)
720             type = special_sections[i].type;
721           else if (type != special_sections[i].type)
722             as_warn ("Setting incorrect section type for %s", string);
723
724           if ((attr &~ special_sections[i].attributes) != 0)
725             as_warn ("Setting incorrect section attributes for %s", string);
726           attr |= special_sections[i].attributes;
727
728           break;
729         }
730     }
731
732   flags = (SEC_RELOC
733            | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
734            | ((attr & SHF_ALLOC) ? SEC_ALLOC | SEC_LOAD : 0)
735            | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
736
737   if (type == SHT_PROGBITS)
738     flags |= SEC_ALLOC | SEC_LOAD;
739   else if (type == SHT_NOBITS)
740     {
741       flags |= SEC_ALLOC;
742       flags &=~ SEC_LOAD;
743     }
744
745 #ifdef md_elf_section_flags
746   if (special_sections[i].name == NULL)
747     flags = md_elf_section_flags (flags, attr, type);
748 #endif
749
750   bfd_set_section_flags (stdoutput, sec, flags);
751
752 #ifdef md_elf_section_change_hook
753   md_elf_section_change_hook ();
754 #endif
755
756   demand_empty_rest_of_line ();
757 }
758
759 /* Change to the .data section.  */
760
761 static void
762 obj_elf_data (i)
763      int i;
764 {
765   previous_section = now_seg;
766   previous_subsection = now_subseg;
767   s_data (i);
768 }
769
770 /* Change to the .text section.  */
771
772 static void
773 obj_elf_text (i)
774      int i;
775 {
776   previous_section = now_seg;
777   previous_subsection = now_subseg;
778   s_text (i);
779 }
780
781 void
782 obj_elf_previous (ignore)
783      int ignore;
784 {
785   if (previous_section == 0)
786     {
787       as_bad (".previous without corresponding .section; ignored");
788       return;
789     }
790   subseg_set (previous_section, previous_subsection);
791   previous_section = 0;
792 }
793
794 static void
795 obj_elf_line (ignore)
796      int ignore;
797 {
798   /* Assume delimiter is part of expression.  BSD4.2 as fails with
799      delightful bug, so we are not being incompatible here. */
800   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
801   demand_empty_rest_of_line ();
802 }
803
804 void 
805 obj_read_begin_hook ()
806 {
807 #ifdef NEED_ECOFF_DEBUG
808   if (ECOFF_DEBUGGING)
809     ecoff_read_begin_hook ();
810 #endif
811 }
812
813 void 
814 obj_symbol_new_hook (symbolP)
815      symbolS *symbolP;
816 {
817   symbolP->sy_obj = 0;
818
819 #ifdef NEED_ECOFF_DEBUG
820   if (ECOFF_DEBUGGING)
821     ecoff_symbol_new_hook (symbolP);
822 #endif
823 }
824
825 void 
826 obj_elf_version (ignore)
827      int ignore;
828 {
829   char *name;
830   unsigned int c;
831   char ch;
832   char *p;
833   asection *seg = now_seg;
834   subsegT subseg = now_subseg;
835   Elf_Internal_Note i_note;
836   Elf_External_Note e_note;
837   asection *note_secp = (asection *) NULL;
838   int i, len;
839
840   SKIP_WHITESPACE ();
841   if (*input_line_pointer == '\"')
842     {
843       ++input_line_pointer;     /* -> 1st char of string. */
844       name = input_line_pointer;
845
846       while (is_a_char (c = next_char_of_string ()))
847         ;
848       c = *input_line_pointer;
849       *input_line_pointer = '\0';
850       *(input_line_pointer - 1) = '\0';
851       *input_line_pointer = c;
852
853       /* create the .note section */
854
855       note_secp = subseg_new (".note", 0);
856       bfd_set_section_flags (stdoutput,
857                              note_secp,
858                              SEC_HAS_CONTENTS | SEC_READONLY);
859
860       /* process the version string */
861
862       len = strlen (name);
863
864       i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
865       i_note.descsz = 0;        /* no description */
866       i_note.type = NT_VERSION;
867       p = frag_more (sizeof (e_note.namesz));
868       md_number_to_chars (p, (valueT) i_note.namesz, 4);
869       p = frag_more (sizeof (e_note.descsz));
870       md_number_to_chars (p, (valueT) i_note.descsz, 4);
871       p = frag_more (sizeof (e_note.type));
872       md_number_to_chars (p, (valueT) i_note.type, 4);
873
874       for (i = 0; i < len; i++)
875         {
876           ch = *(name + i);
877           {
878             FRAG_APPEND_1_CHAR (ch);
879           }
880         }
881       frag_align (2, 0);
882
883       subseg_set (seg, subseg);
884     }
885   else
886     {
887       as_bad ("Expected quoted string");
888     }
889   demand_empty_rest_of_line ();
890 }
891
892 static void
893 obj_elf_size (ignore)
894      int ignore;
895 {
896   char *name = input_line_pointer;
897   char c = get_symbol_end ();
898   char *p;
899   expressionS exp;
900   symbolS *sym;
901
902   p = input_line_pointer;
903   *p = c;
904   SKIP_WHITESPACE ();
905   if (*input_line_pointer != ',')
906     {
907       *p = 0;
908       as_bad ("expected comma after name `%s' in .size directive", name);
909       *p = c;
910       ignore_rest_of_line ();
911       return;
912     }
913   input_line_pointer++;
914   expression (&exp);
915   if (exp.X_op == O_absent)
916     {
917       as_bad ("missing expression in .size directive");
918       exp.X_op = O_constant;
919       exp.X_add_number = 0;
920     }
921   *p = 0;
922   sym = symbol_find_or_make (name);
923   *p = c;
924   if (exp.X_op == O_constant)
925     S_SET_SIZE (sym, exp.X_add_number);
926   else
927     {
928       sym->sy_obj = (expressionS *) xmalloc (sizeof (expressionS));
929       *sym->sy_obj = exp;
930     }
931   demand_empty_rest_of_line ();
932 }
933
934 /* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
935    There are three syntaxes.  The first (used on Solaris) is
936        .type SYM,#function
937    The second (used on UnixWare) is
938        .type SYM,@function
939    The third (reportedly to be used on Irix 6.0) is
940        .type SYM STT_FUNC
941    */
942
943 static void
944 obj_elf_type (ignore)
945      int ignore;
946 {
947   char *name;
948   char c;
949   int type;
950   const char *typename;
951   symbolS *sym;
952
953   name = input_line_pointer;
954   c = get_symbol_end ();
955   sym = symbol_find_or_make (name);
956   *input_line_pointer = c;
957
958   SKIP_WHITESPACE ();
959   if (*input_line_pointer == ',')
960     ++input_line_pointer;
961
962   SKIP_WHITESPACE ();
963   if (*input_line_pointer == '#' || *input_line_pointer == '@')
964     ++input_line_pointer;
965
966   typename = input_line_pointer;
967   c = get_symbol_end ();
968
969   type = 0;
970   if (strcmp (typename, "function") == 0
971       || strcmp (typename, "STT_FUNC") == 0)
972     type = BSF_FUNCTION;
973   else if (strcmp (typename, "object") == 0
974            || strcmp (typename, "STT_OBJECT") == 0)
975     type = BSF_OBJECT;
976   else
977     as_bad ("ignoring unrecognized symbol type \"%s\"", typename);
978
979   *input_line_pointer = c;
980
981   sym->bsym->flags |= type;
982
983   demand_empty_rest_of_line ();
984 }
985
986 static void
987 obj_elf_ident (ignore)
988      int ignore;
989 {
990   static segT comment_section;
991   segT old_section = now_seg;
992   int old_subsection = now_subseg;
993
994   if (!comment_section)
995     {
996       char *p;
997       comment_section = subseg_new (".comment", 0);
998       bfd_set_section_flags (stdoutput, comment_section,
999                              SEC_READONLY | SEC_HAS_CONTENTS);
1000       p = frag_more (1);
1001       *p = 0;
1002     }
1003   else
1004     subseg_set (comment_section, 0);
1005   stringer (1);
1006   subseg_set (old_section, old_subsection);
1007 }
1008
1009 #ifdef INIT_STAB_SECTION
1010
1011 /* The first entry in a .stabs section is special.  */
1012
1013 void
1014 obj_elf_init_stab_section (seg)
1015      segT seg;
1016 {
1017   char *file;
1018   char *p;
1019   char *stabstr_name;
1020   unsigned int stroff;
1021
1022   /* Force the section to align to a longword boundary.  Without this,
1023      UnixWare ar crashes.  */
1024   bfd_set_section_alignment (stdoutput, seg, 2);
1025
1026   /* Make space for this first symbol. */
1027   p = frag_more (12);
1028   /* Zero it out. */
1029   memset (p, 0, 12);
1030   as_where (&file, (unsigned int *) NULL);
1031   stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
1032   strcpy (stabstr_name, segment_name (seg));
1033   strcat (stabstr_name, "str");
1034   stroff = get_stab_string_offset (file, stabstr_name);
1035   know (stroff == 1);
1036   md_number_to_chars (p, stroff, 4);
1037   seg_info (seg)->stabu.p = p;
1038 }
1039
1040 #endif
1041
1042 /* Fill in the counts in the first entry in a .stabs section.  */
1043
1044 static void
1045 adjust_stab_sections (abfd, sec, xxx)
1046      bfd *abfd;
1047      asection *sec;
1048      PTR xxx;
1049 {
1050   char *name;
1051   asection *strsec;
1052   char *p;
1053   int strsz, nsyms;
1054
1055   if (strncmp (".stab", sec->name, 5))
1056     return;
1057   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1058     return;
1059
1060   name = (char *) alloca (strlen (sec->name) + 4);
1061   strcpy (name, sec->name);
1062   strcat (name, "str");
1063   strsec = bfd_get_section_by_name (abfd, name);
1064   if (strsec)
1065     strsz = bfd_section_size (abfd, strsec);
1066   else
1067     strsz = 0;
1068   nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1069
1070   p = seg_info (sec)->stabu.p;
1071   assert (p != 0);
1072
1073   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
1074   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
1075 }
1076
1077 #ifdef NEED_ECOFF_DEBUG
1078
1079 /* This function is called by the ECOFF code.  It is supposed to
1080    record the external symbol information so that the backend can
1081    write it out correctly.  The ELF backend doesn't actually handle
1082    this at the moment, so we do it ourselves.  We save the information
1083    in the symbol.  */
1084
1085 void
1086 elf_ecoff_set_ext (sym, ext)
1087      symbolS *sym;
1088      struct ecoff_extr *ext;
1089 {
1090   sym->bsym->udata.p = (PTR) ext;
1091 }
1092
1093 /* This function is called by bfd_ecoff_debug_externals.  It is
1094    supposed to *EXT to the external symbol information, and return
1095    whether the symbol should be used at all.  */
1096
1097 static boolean
1098 elf_get_extr (sym, ext)
1099      asymbol *sym;
1100      EXTR *ext;
1101 {
1102   if (sym->udata.p == NULL)
1103     return false;
1104   *ext = *(EXTR *) sym->udata.p;
1105   return true;
1106 }
1107
1108 /* This function is called by bfd_ecoff_debug_externals.  It has
1109    nothing to do for ELF.  */
1110
1111 /*ARGSUSED*/
1112 static void
1113 elf_set_index (sym, indx)
1114      asymbol *sym;
1115      bfd_size_type indx;
1116 {
1117 }
1118
1119 #endif /* NEED_ECOFF_DEBUG */
1120
1121 void
1122 elf_frob_symbol (symp, puntp)
1123      symbolS *symp;
1124      int *puntp;
1125 {
1126 #ifdef NEED_ECOFF_DEBUG
1127   if (ECOFF_DEBUGGING)
1128     ecoff_frob_symbol (symp);
1129 #endif
1130
1131   if (symp->sy_obj)
1132     {
1133       switch (symp->sy_obj->X_op)
1134         {
1135         case O_subtract:
1136           S_SET_SIZE (symp,
1137                       (S_GET_VALUE (symp->sy_obj->X_add_symbol)
1138                        + symp->sy_obj->X_add_number
1139                        - S_GET_VALUE (symp->sy_obj->X_op_symbol)));
1140           break;
1141         case O_constant:
1142           S_SET_SIZE (symp,
1143                       (S_GET_VALUE (symp->sy_obj->X_add_symbol)
1144                        + symp->sy_obj->X_add_number));
1145           break;
1146         default:
1147           as_bad (".size expression too complicated to fix up");
1148           break;
1149         }
1150       free (symp->sy_obj);
1151       symp->sy_obj = 0;
1152     }
1153
1154   /* Double check weak symbols.  */
1155   if (symp->bsym->flags & BSF_WEAK)
1156     {
1157       if (S_IS_COMMON (symp))
1158         as_bad ("Symbol `%s' can not be both weak and common",
1159                 S_GET_NAME (symp));
1160     }
1161
1162 #ifdef TC_MIPS
1163   /* The Irix 5 assembler appears to set the type of any common symbol
1164      to STT_OBJECT.  We try to be compatible, since the Irix 5 linker
1165      apparently sometimes cares.  FIXME: What about Irix 6?  */
1166   if (S_IS_COMMON (symp))
1167     symp->bsym->flags |= BSF_OBJECT;
1168 #endif
1169
1170 #ifdef TC_PPC
1171   /* Frob the PowerPC, so that the symbol always has object type
1172      if it is not some other type.  VxWorks needs this.  */
1173   if ((symp->bsym->flags & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
1174       && S_IS_DEFINED (symp))
1175     symp->bsym->flags |= BSF_OBJECT;
1176 #endif
1177 }
1178
1179 void 
1180 elf_frob_file ()
1181 {
1182   bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1183
1184 #ifdef elf_tc_final_processing
1185   elf_tc_final_processing ();
1186 #endif
1187
1188 #ifdef NEED_ECOFF_DEBUG
1189   if (ECOFF_DEBUGGING)
1190     /* Generate the ECOFF debugging information.  */
1191     {
1192       const struct ecoff_debug_swap *debug_swap;
1193       struct ecoff_debug_info debug;
1194       char *buf;
1195       asection *sec;
1196
1197       debug_swap
1198         = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1199       know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1200       ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1201
1202       /* Set up the pointers in debug.  */
1203 #define SET(ptr, offset, type) \
1204     debug.ptr = (type) (buf + debug.symbolic_header.offset)
1205
1206         SET (line, cbLineOffset, unsigned char *);
1207       SET (external_dnr, cbDnOffset, PTR);
1208       SET (external_pdr, cbPdOffset, PTR);
1209       SET (external_sym, cbSymOffset, PTR);
1210       SET (external_opt, cbOptOffset, PTR);
1211       SET (external_aux, cbAuxOffset, union aux_ext *);
1212       SET (ss, cbSsOffset, char *);
1213       SET (external_fdr, cbFdOffset, PTR);
1214       SET (external_rfd, cbRfdOffset, PTR);
1215       /* ssext and external_ext are set up just below.  */
1216
1217 #undef SET    
1218
1219       /* Set up the external symbols.  */
1220       debug.ssext = debug.ssext_end = NULL;
1221       debug.external_ext = debug.external_ext_end = NULL;
1222       if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1223                                        elf_get_extr, elf_set_index))
1224         as_fatal ("Failed to set up debugging information: %s",
1225                   bfd_errmsg (bfd_get_error ()));
1226
1227       sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1228       assert (sec != NULL);
1229
1230       know (stdoutput->output_has_begun == false);
1231
1232       /* We set the size of the section, call bfd_set_section_contents
1233          to force the ELF backend to allocate a file position, and then
1234          write out the data.  FIXME: Is this really the best way to do
1235          this?  */
1236       sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1237
1238       if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
1239                                       (file_ptr) 0, (bfd_size_type) 0))
1240         as_fatal ("Can't start writing .mdebug section: %s",
1241                   bfd_errmsg (bfd_get_error ()));
1242
1243       know (stdoutput->output_has_begun == true);
1244       know (sec->filepos != 0);
1245
1246       if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1247                                    sec->filepos))
1248         as_fatal ("Could not write .mdebug section: %s",
1249                   bfd_errmsg (bfd_get_error ()));
1250     }
1251 #endif /* NEED_ECOFF_DEBUG */
1252 }
1253
1254 const struct format_ops elf_format_ops =
1255 {
1256   bfd_target_elf_flavour,
1257   0,
1258   1,
1259   elf_frob_symbol,
1260   elf_frob_file,
1261   elf_s_get_size, elf_s_set_size,
1262   elf_s_get_align, elf_s_set_align,
1263   elf_copy_symbol_attributes,
1264 #ifdef NEED_ECOFF_DEBUG
1265   ecoff_generate_asm_lineno,
1266   ecoff_stab,
1267 #else
1268   0,
1269   0,                            /* process_stab */
1270 #endif
1271   elf_sec_sym_ok_for_reloc,
1272   elf_pop_insert,
1273 #ifdef NEED_ECOFF_DEBUG
1274   elf_ecoff_set_ext,
1275 #else
1276   0,
1277 #endif
1278   obj_read_begin_hook,
1279   obj_symbol_new_hook,
1280 };
This page took 0.0928020000000001 seconds and 4 git commands to generate.