* ecoff.c (ecoff_setup_ext): Renamed from ecoff_build_ext.
[binutils.git] / gas / config / obj-elf.c
1 /* ELF object file format
2    Copyright (C) 1992, 1993 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
17    License along with GAS; see the file COPYING.  If not, write
18    to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "as.h"
21 #include "subsegs.h"
22 #include "obstack.h"
23
24 #ifdef ECOFF_DEBUGGING
25 #include "ecoff.h"
26 #endif
27
28 static int obj_elf_write_symbol_p PARAMS ((symbolS *sym));
29
30 #ifdef ECOFF_DEBUGGING
31 static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
32 static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
33 #endif
34
35 static void obj_elf_line PARAMS ((int));
36 void obj_elf_version PARAMS ((int));
37 static void obj_elf_size PARAMS ((int));
38 static void obj_elf_type PARAMS ((int));
39 static void obj_elf_ident PARAMS ((int));
40 static void obj_elf_weak PARAMS ((int));
41 static void obj_elf_local PARAMS ((int));
42 static void obj_elf_common PARAMS ((int));
43 static void obj_elf_data PARAMS ((int));
44 static void obj_elf_text PARAMS ((int));
45
46 const pseudo_typeS obj_pseudo_table[] =
47 {
48   {"comm", obj_elf_common, 0},
49   {"ident", obj_elf_ident, 0},
50   {"local", obj_elf_local, 0},
51   {"previous", obj_elf_previous, 0},
52   {"section", obj_elf_section, 0},
53   {"size", obj_elf_size, 0},
54   {"type", obj_elf_type, 0},
55   {"version", obj_elf_version, 0},
56   {"weak", obj_elf_weak, 0},
57
58 /* These are used for stabs-in-elf configurations.  */
59   {"line", obj_elf_line, 0},
60
61   /* These are used for dwarf. */
62   {"2byte", cons, 2},
63   {"4byte", cons, 4},
64   {"8byte", cons, 8},
65
66   /* We need to trap the section changing calls to handle .previous.  */
67   {"data", obj_elf_data, 0},
68   {"text", obj_elf_text, 0},
69
70 #ifdef ECOFF_DEBUGGING
71   /* COFF style debugging information for ECOFF. .ln is not used; .loc
72      is used instead.  */
73   { "def",      ecoff_directive_def,    0 },
74   { "dim",      ecoff_directive_dim,    0 },
75   { "endef",    ecoff_directive_endef,  0 },
76   { "file",     ecoff_directive_file,   0 },
77   { "scl",      ecoff_directive_scl,    0 },
78   { "tag",      ecoff_directive_tag,    0 },
79   { "val",      ecoff_directive_val,    0 },
80
81   /* COFF debugging requires pseudo-ops .size and .type, but ELF
82      already has meanings for those.  We use .esize and .etype
83      instead.  These are only generated by gcc anyhow.  */
84   { "esize",    ecoff_directive_size,   0 },
85   { "etype",    ecoff_directive_type,   0 },
86
87   /* ECOFF specific debugging information.  */
88   { "begin",    ecoff_directive_begin,  0 },
89   { "bend",     ecoff_directive_bend,   0 },
90   { "end",      ecoff_directive_end,    0 },
91   { "ent",      ecoff_directive_ent,    0 },
92   { "fmask",    ecoff_directive_fmask,  0 },
93   { "frame",    ecoff_directive_frame,  0 },
94   { "loc",      ecoff_directive_loc,    0 },
95   { "mask",     ecoff_directive_mask,   0 },
96
97   /* These are used on Irix.  I don't know how to implement them.  */
98   { "alias",    s_ignore,               0 },
99   { "bgnb",     s_ignore,               0 },
100   { "endb",     s_ignore,               0 },
101   { "lab",      s_ignore,               0 },
102   { "noalias",  s_ignore,               0 },
103   { "verstamp", s_ignore,               0 },
104   { "vreg",     s_ignore,               0 },
105 #endif /* ECOFF_DEBUGGING */
106
107   {NULL}                        /* end sentinel */
108 };
109
110 #undef NO_RELOC
111 #include "aout/aout64.h"
112
113 void
114 elf_file_symbol (s)
115      char *s;
116 {
117   symbolS *sym;
118
119   sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
120   sym->sy_frag = &zero_address_frag;
121   sym->bsym->flags |= BSF_FILE;
122
123   if (symbol_rootP != sym)
124     {
125       symbol_remove (sym, &symbol_rootP, &symbol_lastP);
126       symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
127 #ifdef DEBUG
128       verify_symbol_chain (symbol_rootP, symbol_lastP);
129 #endif
130     }
131 }
132
133 static void
134 obj_elf_common (ignore)
135      int ignore;
136 {
137   char *name;
138   char c;
139   char *p;
140   int temp, size;
141   symbolS *symbolP;
142   int have_align;
143
144   name = input_line_pointer;
145   c = get_symbol_end ();
146   /* just after name is now '\0' */
147   p = input_line_pointer;
148   *p = c;
149   SKIP_WHITESPACE ();
150   if (*input_line_pointer != ',')
151     {
152       as_bad ("Expected comma after symbol-name");
153       ignore_rest_of_line ();
154       return;
155     }
156   input_line_pointer++;         /* skip ',' */
157   if ((temp = get_absolute_expression ()) < 0)
158     {
159       as_bad (".COMMon length (%d.) <0! Ignored.", temp);
160       ignore_rest_of_line ();
161       return;
162     }
163   size = temp;
164   *p = 0;
165   symbolP = symbol_find_or_make (name);
166   *p = c;
167   if (S_IS_DEFINED (symbolP))
168     {
169       as_bad ("Ignoring attempt to re-define symbol");
170       ignore_rest_of_line ();
171       return;
172     }
173   if (S_GET_VALUE (symbolP) != 0)
174     {
175       if (S_GET_VALUE (symbolP) != size)
176         {
177           as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
178                    S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
179         }
180     }
181   know (symbolP->sy_frag == &zero_address_frag);
182   if (*input_line_pointer != ',')
183     have_align = 0;
184   else
185     {
186       have_align = 1;
187       input_line_pointer++;
188       SKIP_WHITESPACE ();
189     }
190   if (! have_align || *input_line_pointer != '"')
191     {
192       if (! have_align)
193         temp = 0;
194       else
195         {
196           temp = get_absolute_expression ();
197           if (temp < 0)
198             {
199               temp = 0;
200               as_warn ("Common alignment negative; 0 assumed");
201             }
202         }
203       if (symbolP->local)
204         {
205           segT old_sec;
206           int old_subsec;
207           char *pfrag;
208           int align;
209
210         /* allocate_bss: */
211           old_sec = now_seg;
212           old_subsec = now_subseg;
213           align = temp;
214           record_alignment (bss_section, align);
215           subseg_set (bss_section, 0);
216           if (align)
217             frag_align (align, 0);
218           if (S_GET_SEGMENT (symbolP) == bss_section)
219             symbolP->sy_frag->fr_symbol = 0;
220           symbolP->sy_frag = frag_now;
221           pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
222                             (char *) 0);
223           *pfrag = 0;
224           S_SET_SEGMENT (symbolP, bss_section);
225           S_CLEAR_EXTERNAL (symbolP);
226           subseg_set (old_sec, old_subsec);
227         }
228       else
229         {
230         allocate_common:
231           S_SET_VALUE (symbolP, (valueT) size);
232           S_SET_EXTERNAL (symbolP);
233           /* should be common, but this is how gas does it for now */
234           S_SET_SEGMENT (symbolP, &bfd_und_section);
235         }
236     }
237   else
238     {
239       input_line_pointer++;
240       /* @@ Some use the dot, some don't.  Can we get some consistency??  */
241       if (*input_line_pointer == '.')
242         input_line_pointer++;
243       /* @@ Some say data, some say bss.  */
244       if (strncmp (input_line_pointer, "bss\"", 4)
245           && strncmp (input_line_pointer, "data\"", 5))
246         {
247           while (*--input_line_pointer != '"')
248             ;
249           input_line_pointer--;
250           goto bad_common_segment;
251         }
252       while (*input_line_pointer++ != '"')
253         ;
254       goto allocate_common;
255     }
256   demand_empty_rest_of_line ();
257   return;
258
259   {
260   bad_common_segment:
261     p = input_line_pointer;
262     while (*p && *p != '\n')
263       p++;
264     c = *p;
265     *p = '\0';
266     as_bad ("bad .common segment %s", input_line_pointer + 1);
267     *p = c;
268     input_line_pointer = p;
269     ignore_rest_of_line ();
270     return;
271   }
272 }
273
274 static void 
275 obj_elf_local (ignore)
276      int ignore;
277 {
278   char *name;
279   int c;
280   symbolS *symbolP;
281
282   do
283     {
284       name = input_line_pointer;
285       c = get_symbol_end ();
286       symbolP = symbol_find_or_make (name);
287       *input_line_pointer = c;
288       SKIP_WHITESPACE ();
289       S_CLEAR_EXTERNAL (symbolP);
290       symbolP->local = 1;
291       if (c == ',')
292         {
293           input_line_pointer++;
294           SKIP_WHITESPACE ();
295           if (*input_line_pointer == '\n')
296             c = '\n';
297         }
298     }
299   while (c == ',');
300   demand_empty_rest_of_line ();
301 }
302
303 static void 
304 obj_elf_weak (ignore)
305      int ignore;
306 {
307   char *name;
308   int c;
309   symbolS *symbolP;
310
311   do
312     {
313       name = input_line_pointer;
314       c = get_symbol_end ();
315       symbolP = symbol_find_or_make (name);
316       *input_line_pointer = c;
317       SKIP_WHITESPACE ();
318       S_SET_WEAK (symbolP);
319       symbolP->local = 1;
320       if (c == ',')
321         {
322           input_line_pointer++;
323           SKIP_WHITESPACE ();
324           if (*input_line_pointer == '\n')
325             c = '\n';
326         }
327     }
328   while (c == ',');
329   demand_empty_rest_of_line ();
330 }
331
332 static segT previous_section;
333 static int previous_subsection;
334
335 /* Handle the .section pseudo-op.  This code supports two different
336    syntaxes.  
337
338    The first is found on Solaris, and looks like
339        .section ".sec1",#alloc,#execinstr,#write
340    Here the names after '#' are the SHF_* flags to turn on for the
341    section.  I'm not sure how it determines the SHT_* type (BFD
342    doesn't really give us control over the type, anyhow).
343
344    The second format is found on UnixWare, and probably most SVR4
345    machines, and looks like
346        .section .sec1,"a",@progbits
347    The quoted string may contain any combination of a, w, x, and
348    represents the SHF_* flags to turn on for the section.  The string
349    beginning with '@' can be progbits or nobits.  There should be
350    other possibilities, but I don't know what they are.  In any case,
351    BFD doesn't really let us set the section type.  */
352
353 void
354 obj_elf_section (xxx)
355      int xxx;
356 {
357   char *string;
358   int new_sec;
359   segT sec;
360   flagword flags;
361
362   /* Get name of section.  */
363   SKIP_WHITESPACE ();
364   if (*input_line_pointer == '"')
365     {
366       string = demand_copy_C_string (&xxx);
367       if (string == NULL)
368         {
369           ignore_rest_of_line ();
370           return;
371         }
372     }
373   else
374     {
375       char *p = input_line_pointer;
376       char c;
377       while (0 == strchr ("\n\t,; ", *p))
378         p++;
379       if (p == input_line_pointer)
380         {
381           as_warn ("Missing section name");
382           ignore_rest_of_line ();
383           return;
384         }
385       c = *p;
386       *p = 0;
387       string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
388       strcpy (string, input_line_pointer);
389       *p = c;
390       input_line_pointer = p;
391     }
392
393   /* Switch to the section, creating it if necessary.  */
394   previous_section = now_seg;
395   previous_subsection = now_subseg;
396
397   new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
398   sec = subseg_new (string, 0);
399
400   /* If this section already existed, we don't bother to change the
401      flag values.  */
402   if (! new_sec)
403     {
404       while (! is_end_of_line[(unsigned char) *input_line_pointer])
405         ++input_line_pointer;
406       ++input_line_pointer;
407       return;
408     }
409
410   SKIP_WHITESPACE ();
411   if (*input_line_pointer != ',')
412     {
413       /* No flags given.  Guess at some useful defaults.  */
414       if (strcmp (string, ".data") == 0
415           || strcmp (string, ".data1") == 0
416           || strcmp (string, ".sdata") == 0
417           || strcmp (string, ".rodata") == 0
418           || strcmp (string, ".rodata1") == 0)
419         flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA;
420       else if (strcmp (string, ".text") == 0
421                || strcmp (string, ".init") == 0
422                || strcmp (string, ".fini") == 0)
423         flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_CODE;
424       else if (strcmp (string, ".bss") == 0
425                || strcmp (string, ".sbss") == 0)
426         flags = SEC_ALLOC;
427       else
428         flags = SEC_RELOC;
429     }
430   else
431     {
432       /* Skip the comma.  */
433       ++input_line_pointer;
434
435       SKIP_WHITESPACE ();
436       if (*input_line_pointer == '"')
437         {
438           /* Pick up a string with a combination of a, w, x.  */
439           flags = SEC_READONLY | SEC_RELOC;
440           ++input_line_pointer;
441           while (*input_line_pointer != '"')
442             {
443               switch (*input_line_pointer)
444                 {
445                 case 'a':
446                   flags |= SEC_ALLOC | SEC_LOAD;
447                   break;
448                 case 'w':
449                   flags &=~ SEC_READONLY;
450                   break;
451                 case 'x':
452                   flags |= SEC_CODE;
453                   break;
454                 default:
455                   as_warn ("Bad .section directive: want a,w,x in string");
456                   ignore_rest_of_line ();
457                   return;
458                 }
459               ++input_line_pointer;
460             }
461
462           /* Skip the closing quote.  */
463           ++input_line_pointer;
464
465           SKIP_WHITESPACE ();
466           if (*input_line_pointer == ',')
467             {
468               ++input_line_pointer;
469               SKIP_WHITESPACE ();
470               if (*input_line_pointer == '@')
471                 {
472                   ++input_line_pointer;
473                   if (strncmp (input_line_pointer, "progbits",
474                                sizeof "progbits" - 1) == 0)
475                     {
476                       flags |= SEC_ALLOC | SEC_LOAD;
477                       input_line_pointer += sizeof "progbits" - 1;
478                     }
479                   else if (strncmp (input_line_pointer, "nobits",
480                                     sizeof "nobits" - 1) == 0)
481                     {
482                       flags &=~ SEC_LOAD;
483                       input_line_pointer += sizeof "nobits" - 1;
484                     }
485                   else
486                     {
487                       as_warn ("Unrecognized section type");
488                       ignore_rest_of_line ();
489                     }
490                 }
491             }
492         }
493       else
494         {
495           flags = SEC_READONLY | SEC_RELOC;
496           do
497             {
498               SKIP_WHITESPACE ();
499               if (*input_line_pointer != '#')
500                 {
501                   as_warn ("Bad .section directive");
502                   ignore_rest_of_line ();
503                   return;
504                 }
505               ++input_line_pointer;
506               if (strncmp (input_line_pointer, "write",
507                            sizeof "write" - 1) == 0)
508                 {
509                   flags &=~ SEC_READONLY;
510                   input_line_pointer += sizeof "write" - 1;
511                 }
512               else if (strncmp (input_line_pointer, "alloc",
513                                 sizeof "alloc" - 1) == 0)
514                 {
515                   flags |= SEC_ALLOC | SEC_LOAD;
516                   input_line_pointer += sizeof "alloc" - 1;
517                 }
518               else if (strncmp (input_line_pointer, "execinstr",
519                                 sizeof "execinstr" - 1) == 0)
520                 {
521                   flags |= SEC_CODE;
522                   input_line_pointer += sizeof "execinstr" - 1;
523                 }
524               else
525                 {
526                   as_warn ("Unrecognized section attribute");
527                   ignore_rest_of_line ();
528                   return;
529                 }
530               SKIP_WHITESPACE ();
531             }
532           while (*input_line_pointer++ == ',');
533           --input_line_pointer;
534         }
535     }
536
537   bfd_set_section_flags (stdoutput, sec, flags);
538
539   demand_empty_rest_of_line ();
540 }
541
542 /* Change to the .data section.  */
543
544 static void
545 obj_elf_data (i)
546      int i;
547 {
548   previous_section = now_seg;
549   previous_subsection = now_subseg;
550   s_data (i);
551 }
552
553 /* Change to the .text section.  */
554
555 static void
556 obj_elf_text (i)
557      int i;
558 {
559   previous_section = now_seg;
560   previous_subsection = now_subseg;
561   s_text (i);
562 }
563
564 void
565 obj_elf_previous (ignore)
566      int ignore;
567 {
568   if (previous_section == 0)
569     {
570       as_bad (".previous without corresponding .section; ignored");
571       return;
572     }
573   subseg_set (previous_section, previous_subsection);
574   previous_section = 0;
575 }
576
577 static int
578 obj_elf_write_symbol_p (sym)
579      symbolS *sym;
580 {
581   /* If this is a local symbol, are there any relocations for which
582      need this symbol? */
583
584   /* To find this out, we examine all relocations in all bfd sections
585      that have relocations.  If there is one that references this
586      symbol, we need to keep this symbol.  In this case, we return a
587      true status.  In all other cases, we return a false status. */
588
589   if (S_IS_LOCAL (sym))
590     {
591       asymbol *bsym = sym->bsym;
592       bfd *abfd = bsym->the_bfd;
593       asection *bsec;
594
595       for (bsec = abfd->sections; bsec; bsec = bsec->next)
596         {
597           struct reloc_cache_entry **rlocs = bsec->orelocation;
598           int rcnt = bsec->reloc_count;
599
600           if (rlocs)
601             {
602               int i;
603
604               for (i = 0; i < rcnt; i++)
605                 if (rlocs[i]->sym_ptr_ptr
606                     && rlocs[i]->sym_ptr_ptr[0] == bsym)
607                   return 1;
608             }
609           else
610             {
611               /* No relocations for this section.  Check the seg_info
612                  structure to see if there are any fixups for this
613                  section. */
614               segment_info_type *seginfo = seg_info (bsec);
615               fixS *fixp;
616
617               for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
618                 if ((fixp->fx_addsy && fixp->fx_addsy->bsym == bsym)
619                     || (fixp->fx_subsy && fixp->fx_subsy->bsym == bsym))
620                   return 1;
621             }
622         }
623     }
624   return 0;
625 }
626
627 int
628 obj_elf_write_symbol (sym)
629      symbolS *sym;
630 {
631   return /* obj_elf_write_symbol_p (sym) || */ !S_IS_LOCAL (sym);
632 }
633
634 int
635 obj_elf_frob_symbol (sym, punt)
636      symbolS *sym;
637      int *punt;
638 {
639 #if 0 /* ?? The return value is ignored.  Only the value of *punt is
640          relevant.  */
641   return obj_elf_write_symbol_p (sym);
642 #endif
643  /* FIXME: Just return 0 until is fixed.  */
644  return 0;
645 }
646
647 static void
648 obj_elf_line (ignore)
649      int ignore;
650 {
651   /* Assume delimiter is part of expression.  BSD4.2 as fails with
652      delightful bug, so we are not being incompatible here. */
653   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
654   demand_empty_rest_of_line ();
655 }
656
657 void 
658 obj_read_begin_hook ()
659 {
660 #ifdef ECOFF_DEBUGGING
661   ecoff_read_begin_hook ();
662 #endif
663 }
664
665 void 
666 obj_symbol_new_hook (symbolP)
667      symbolS *symbolP;
668 {
669 #if 0 /* BFD already takes care of this */
670   elf32_symbol_type *esym = (elf32_symbol_type *) symbolP;
671
672   /* There is an Elf_Internal_Sym and an Elf_External_Sym.  For now,
673      just zero them out.  */
674
675   bzero ((char *) &esym->internal_elf_sym, sizeof (esym->internal_elf_sym));
676   bzero ((char *) &esym->native_elf_sym, sizeof (esym->native_elf_sym));
677   bzero ((char *) &esym->tc_data, sizeof (esym->tc_data));
678 #endif
679 #ifdef ECOFF_DEBUGGING
680   ecoff_symbol_new_hook (symbolP);
681 #endif
682 }
683
684 void 
685 obj_elf_version (ignore)
686      int ignore;
687 {
688   char *name;
689   unsigned int c;
690   char ch;
691   char *p;
692   asection *seg = now_seg;
693   subsegT subseg = now_subseg;
694   Elf_Internal_Note i_note;
695   Elf_External_Note e_note;
696   asection *note_secp = (asection *) NULL;
697   int i, len;
698
699   SKIP_WHITESPACE ();
700   if (*input_line_pointer == '\"')
701     {
702       ++input_line_pointer;     /* -> 1st char of string. */
703       name = input_line_pointer;
704
705       while (is_a_char (c = next_char_of_string ()))
706         ;
707       c = *input_line_pointer;
708       *input_line_pointer = '\0';
709       *(input_line_pointer - 1) = '\0';
710       *input_line_pointer = c;
711
712       /* create the .note section */
713
714       note_secp = subseg_new (".note", 0);
715       bfd_set_section_flags (stdoutput,
716                              note_secp,
717                              SEC_HAS_CONTENTS | SEC_READONLY);
718
719       /* process the version string */
720
721       len = strlen (name);
722
723       i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
724       i_note.descsz = 0;        /* no description */
725       i_note.type = NT_VERSION;
726       p = frag_more (sizeof (e_note.namesz));
727       md_number_to_chars (p, (valueT) i_note.namesz, 4);
728       p = frag_more (sizeof (e_note.descsz));
729       md_number_to_chars (p, (valueT) i_note.descsz, 4);
730       p = frag_more (sizeof (e_note.type));
731       md_number_to_chars (p, (valueT) i_note.type, 4);
732
733       for (i = 0; i < len; i++)
734         {
735           ch = *(name + i);
736           {
737             FRAG_APPEND_1_CHAR (ch);
738           }
739         }
740       frag_align (2, 0);
741
742       subseg_set (seg, subseg);
743     }
744   else
745     {
746       as_bad ("Expected quoted string");
747     }
748   demand_empty_rest_of_line ();
749 }
750
751 static void
752 obj_elf_size (ignore)
753      int ignore;
754 {
755   char *name = input_line_pointer;
756   char c = get_symbol_end ();
757   char *p;
758   expressionS exp;
759   symbolS *sym;
760
761   p = input_line_pointer;
762   *p = c;
763   SKIP_WHITESPACE ();
764   if (*input_line_pointer != ',')
765     {
766       *p = 0;
767       as_bad ("expected comma after name `%s' in .size directive", name);
768       *p = c;
769       ignore_rest_of_line ();
770       return;
771     }
772   input_line_pointer++;
773   expression (&exp);
774   if (exp.X_op == O_absent)
775     {
776       as_bad ("missing expression in .size directive");
777       exp.X_op = O_constant;
778       exp.X_add_number = 0;
779     }
780   *p = 0;
781   sym = symbol_find_or_make (name);
782   *p = c;
783   if (exp.X_op == O_constant)
784     S_SET_SIZE (sym, exp.X_add_number);
785   else
786     {
787 #if 0
788       static int warned;
789       if (!warned)
790         {
791           as_tsktsk (".size expressions not yet supported, ignored");
792           warned++;
793         }
794 #endif
795     }
796   demand_empty_rest_of_line ();
797 }
798
799 static void
800 obj_elf_type (ignore)
801      int ignore;
802 {
803   char *name = input_line_pointer;
804   char c = get_symbol_end ();
805   char *p;
806   int type = 0;
807   symbolS *sym;
808
809   p = input_line_pointer;
810   *p = c;
811   SKIP_WHITESPACE ();
812   if (*input_line_pointer != ',')
813     {
814       as_bad ("expected comma after name in .type directive");
815     egress:
816       ignore_rest_of_line ();
817       return;
818     }
819   input_line_pointer++;
820   SKIP_WHITESPACE ();
821   if (*input_line_pointer != '#' && *input_line_pointer != '@')
822     {
823       as_bad ("expected `#' or `@' after comma in .type directive");
824       goto egress;
825     }
826   input_line_pointer++;
827   if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
828     {
829       type = BSF_FUNCTION;
830       input_line_pointer += sizeof ("function") - 1;
831     }
832   else if (!strncmp ("object", input_line_pointer, sizeof ("object") - 1))
833     {
834       input_line_pointer += sizeof ("object") - 1;
835     }
836   else
837     {
838       as_bad ("unrecognized symbol type, ignored");
839       goto egress;
840     }
841   demand_empty_rest_of_line ();
842   *p = 0;
843   sym = symbol_find_or_make (name);
844   sym->bsym->flags |= type;
845 }
846
847 static void
848 obj_elf_ident (ignore)
849      int ignore;
850 {
851   static segT comment_section;
852   segT old_section = now_seg;
853   int old_subsection = now_subseg;
854
855   if (!comment_section)
856     {
857       char *p;
858       comment_section = subseg_new (".comment", 0);
859       bfd_set_section_flags (stdoutput, comment_section,
860                              SEC_READONLY | SEC_HAS_CONTENTS);
861       p = frag_more (1);
862       *p = 0;
863     }
864   else
865     subseg_set (comment_section, 0);
866   stringer (1);
867   subseg_set (old_section, old_subsection);
868 }
869
870 /* The first entry in a .stabs section is special.  */
871
872 void
873 obj_elf_init_stab_section (seg)
874      segT seg;
875 {
876   char *file;
877   char *p;
878   char *stabstr_name;
879   unsigned int stroff;
880
881   /* Force the section to align to a longword boundary.  Without this,
882      UnixWare ar crashes.  */
883   bfd_set_section_alignment (stdoutput, seg, 2);
884
885   p = frag_more (12);
886   as_where (&file, (unsigned int *) NULL);
887   stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
888   strcpy (stabstr_name, segment_name (seg));
889   strcat (stabstr_name, "str");
890   stroff = get_stab_string_offset (file, stabstr_name);
891   know (stroff == 1);
892   md_number_to_chars (p, stroff, 4);
893   seg_info (seg)->stabu.p = p;
894 }
895
896 /* Fill in the counts in the first entry in a .stabs section.  */
897
898 static void
899 adjust_stab_sections (abfd, sec, xxx)
900      bfd *abfd;
901      asection *sec;
902      PTR xxx;
903 {
904   char *name;
905   asection *strsec;
906   char *p;
907   int strsz, nsyms;
908
909   if (strncmp (".stab", sec->name, 5))
910     return;
911   if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
912     return;
913
914   name = (char *) alloca (strlen (sec->name) + 4);
915   strcpy (name, sec->name);
916   strcat (name, "str");
917   strsec = bfd_get_section_by_name (abfd, name);
918   if (strsec)
919     strsz = bfd_section_size (abfd, strsec);
920   else
921     strsz = 0;
922   nsyms = bfd_section_size (abfd, sec) / 12 - 1;
923
924   p = seg_info (sec)->stabu.p;
925   assert (p != 0);
926
927   bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
928   bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
929 }
930
931 #ifdef ECOFF_DEBUGGING
932
933 /* This function is called by the ECOFF code.  It is supposed to
934    record the external symbol information so that the backend can
935    write it out correctly.  The ELF backend doesn't actually handle
936    this at the moment, so we do it ourselves.  We save the information
937    in the symbol.  */
938
939 void
940 obj_ecoff_set_ext (sym, ext)
941      symbolS *sym;
942      EXTR *ext;
943 {
944   sym->bsym->udata = (PTR) ext;
945 }
946
947 /* This function is called by bfd_ecoff_debug_externals.  It is
948    supposed to *EXT to the external symbol information, and return
949    whether the symbol should be used at all.  */
950
951 static boolean
952 elf_get_extr (sym, ext)
953      asymbol *sym;
954      EXTR *ext;
955 {
956   if (sym->udata == NULL)
957     return false;
958   *ext = *(EXTR *) sym->udata;
959   return true;
960 }
961
962 /* This function is called by bfd_ecoff_debug_externals.  It has
963    nothing to do for ELF.  */
964
965 /*ARGSUSED*/
966 static void
967 elf_set_index (sym, indx)
968      asymbol *sym;
969      bfd_size_type indx;
970 {
971 }
972
973 #endif /* ECOFF_DEBUGGING */
974
975 void 
976 elf_frob_file ()
977 {
978   bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
979
980 #ifdef elf_tc_symbol
981   {
982     int i;
983
984     for (i = 0; i < stdoutput->symcount; i++)
985       elf_tc_symbol (stdoutput, (PTR) (stdoutput->outsymbols[i]),
986                      i + 1);
987   }
988 #endif
989
990 #ifdef elf_tc_final_processing
991   elf_tc_final_processing ();
992 #endif
993
994   /* Finally, we must make any target-specific sections. */
995
996 #ifdef elf_tc_make_sections
997   elf_tc_make_sections (stdoutput);
998 #endif
999
1000 #ifdef ECOFF_DEBUGGING
1001   /* Generate the ECOFF debugging information.  */
1002   {
1003     const struct ecoff_debug_swap *debug_swap;
1004     struct ecoff_debug_info debug;
1005     char *buf;
1006     asection *sec;
1007
1008     debug_swap
1009       = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1010     know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1011     ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1012
1013     /* Set up the pointers in debug.  */
1014 #define SET(ptr, offset, type) \
1015     debug.ptr = (type) (buf + debug.symbolic_header.offset)
1016
1017     SET (line, cbLineOffset, unsigned char *);
1018     SET (external_dnr, cbDnOffset, PTR);
1019     SET (external_pdr, cbPdOffset, PTR);
1020     SET (external_sym, cbSymOffset, PTR);
1021     SET (external_opt, cbOptOffset, PTR);
1022     SET (external_aux, cbAuxOffset, union aux_ext *);
1023     SET (ss, cbSsOffset, char *);
1024     SET (external_fdr, cbFdOffset, PTR);
1025     SET (external_rfd, cbRfdOffset, PTR);
1026     /* ssext and external_ext are set up just below.  */
1027
1028 #undef SET    
1029
1030     /* Set up the external symbols.  */
1031     debug.ssext = debug.ssext_end = NULL;
1032     debug.external_ext = debug.external_ext_end = NULL;
1033     if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1034                                      elf_get_extr, elf_set_index))
1035       as_fatal ("Failed to set up debugging information: %s",
1036                 bfd_errmsg (bfd_error));
1037
1038     sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1039     assert (sec != NULL);
1040
1041     know (stdoutput->output_has_begun == false);
1042
1043     /* We set the size of the section, call bfd_set_section_contents
1044        to force the ELF backend to allocate a file position, and then
1045        write out the data.  FIXME: Is this really the best way to do
1046        this?  */
1047     sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1048
1049     if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
1050                                     (file_ptr) 0, (bfd_size_type) 0))
1051       as_fatal ("Can't start writing .mdebug section: %s",
1052                 bfd_errmsg (bfd_error));
1053
1054     know (stdoutput->output_has_begun == true);
1055     know (sec->filepos != 0);
1056
1057     if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1058                                  sec->filepos))
1059       as_fatal ("Could not write .mdebug section: %s",
1060                 bfd_errmsg (bfd_error));
1061   }
1062 #endif /* ECOFF_DEBUGGING */
1063 }
This page took 0.087849 seconds and 4 git commands to generate.