a0cf0acfe33f78702e7f094930406f84c8c25a66
[binutils-gdb.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 }