more Utah changes, some cleanup of mine
[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 "aout/stab_gnu.h"
23 #include "obstack.h"
24
25 static void obj_elf_stab PARAMS ((int what));
26 static void obj_elf_xstab PARAMS ((int what));
27 static void obj_elf_line PARAMS ((void));
28 void obj_elf_desc PARAMS ((void));
29 void obj_elf_version PARAMS ((void));
30 static void obj_elf_size PARAMS ((void));
31 static void obj_elf_type PARAMS ((void));
32 static void obj_elf_ident PARAMS ((void));
33 static void obj_elf_weak PARAMS ((void));
34 static void obj_elf_local PARAMS ((void));
35 static void obj_elf_common PARAMS ((void));
36
37 const pseudo_typeS obj_pseudo_table[] =
38 {
39 {"comm", obj_elf_common, 0},
40 {"ident", obj_elf_ident, 0},
41 {"local", obj_elf_local, 0},
42 {"previous", obj_elf_previous, 0},
43 {"section", obj_elf_section, 0},
44 {"size", obj_elf_size, 0},
45 {"type", obj_elf_type, 0},
46 {"version", obj_elf_version, 0},
47 {"weak", obj_elf_weak, 0},
48
49 /* These are used for stabs-in-elf configurations. */
50 {"desc", obj_elf_desc, 0},
51 {"line", obj_elf_line, 0},
52 {"stabd", obj_elf_stab, 'd'},
53 {"stabn", obj_elf_stab, 'n'},
54 {"stabs", obj_elf_stab, 's'},
55 /* This is used on Solaris 2.x on SPARC, but not supported yet. */
56 {"xstabs", obj_elf_xstab, 's'},
57
58 /* These are used for dwarf. */
59 {"2byte", cons, 2},
60 {"4byte", cons, 4},
61 {"8byte", cons, 8},
62
63 {NULL} /* end sentinel */
64 };
65
66 #undef NO_RELOC
67 #include "aout/aout64.h"
68
69 void
70 elf_file_symbol (s)
71 char *s;
72 {
73 symbolS *sym;
74
75 sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
76 sym->sy_frag = &zero_address_frag;
77 sym->bsym->flags |= BSF_FILE;
78
79 if (symbol_rootP != sym)
80 {
81 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
82 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
83 #ifdef DEBUG
84 verify_symbol_chain (symbol_rootP, symbol_lastP);
85 #endif
86 }
87 }
88
89 static void
90 obj_elf_common ()
91 {
92 char *name;
93 char c;
94 char *p;
95 int temp, size;
96 symbolS *symbolP;
97
98 name = input_line_pointer;
99 c = get_symbol_end ();
100 /* just after name is now '\0' */
101 p = input_line_pointer;
102 *p = c;
103 SKIP_WHITESPACE ();
104 if (*input_line_pointer != ',')
105 {
106 as_bad ("Expected comma after symbol-name");
107 ignore_rest_of_line ();
108 return;
109 }
110 input_line_pointer++; /* skip ',' */
111 if ((temp = get_absolute_expression ()) < 0)
112 {
113 as_bad (".COMMon length (%d.) <0! Ignored.", temp);
114 ignore_rest_of_line ();
115 return;
116 }
117 size = temp;
118 *p = 0;
119 symbolP = symbol_find_or_make (name);
120 *p = c;
121 if (S_IS_DEFINED (symbolP))
122 {
123 as_bad ("Ignoring attempt to re-define symbol");
124 ignore_rest_of_line ();
125 return;
126 }
127 if (S_GET_VALUE (symbolP) != 0)
128 {
129 if (S_GET_VALUE (symbolP) != size)
130 {
131 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
132 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
133 }
134 }
135 know (symbolP->sy_frag == &zero_address_frag);
136 if (*input_line_pointer != ',')
137 {
138 as_bad ("Expected comma after common length");
139 ignore_rest_of_line ();
140 return;
141 }
142 input_line_pointer++;
143 SKIP_WHITESPACE ();
144 if (*input_line_pointer != '"')
145 {
146 temp = get_absolute_expression ();
147 if (temp < 0)
148 {
149 temp = 0;
150 as_warn ("Common alignment negative; 0 assumed");
151 }
152 if (symbolP->local)
153 {
154 segT old_sec;
155 int old_subsec;
156 char *p;
157 int align;
158
159 allocate_bss:
160 old_sec = now_seg;
161 old_subsec = now_subseg;
162 align = temp;
163 record_alignment (bss_section, align);
164 subseg_set (bss_section, 0);
165 if (align)
166 frag_align (align, 0);
167 if (S_GET_SEGMENT (symbolP) == bss_section)
168 symbolP->sy_frag->fr_symbol = 0;
169 symbolP->sy_frag = frag_now;
170 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
171 (char *) 0);
172 *p = 0;
173 S_SET_SEGMENT (symbolP, bss_section);
174 S_CLEAR_EXTERNAL (symbolP);
175 subseg_set (old_sec, old_subsec);
176 }
177 else
178 {
179 allocate_common:
180 S_SET_VALUE (symbolP, size);
181 S_SET_EXTERNAL (symbolP);
182 /* should be common, but this is how gas does it for now */
183 S_SET_SEGMENT (symbolP, &bfd_und_section);
184 }
185 }
186 else
187 {
188 input_line_pointer++;
189 /* @@ Some use the dot, some don't. Can we get some consistency?? */
190 if (*input_line_pointer == '.')
191 input_line_pointer++;
192 /* @@ Some say data, some say bss. */
193 if (strncmp (input_line_pointer, "bss\"", 4)
194 && strncmp (input_line_pointer, "data\"", 5))
195 {
196 while (*--input_line_pointer != '"')
197 ;
198 input_line_pointer--;
199 goto bad_common_segment;
200 }
201 while (*input_line_pointer++ != '"')
202 ;
203 goto allocate_common;
204 }
205 demand_empty_rest_of_line ();
206 return;
207
208 {
209 bad_common_segment:
210 p = input_line_pointer;
211 while (*p && *p != '\n')
212 p++;
213 c = *p;
214 *p = '\0';
215 as_bad ("bad .common segment %s", input_line_pointer + 1);
216 *p = c;
217 input_line_pointer = p;
218 ignore_rest_of_line ();
219 return;
220 }
221 }
222
223 static void
224 obj_elf_local ()
225 {
226 char *name;
227 int c;
228 symbolS *symbolP;
229
230 do
231 {
232 name = input_line_pointer;
233 c = get_symbol_end ();
234 symbolP = symbol_find_or_make (name);
235 *input_line_pointer = c;
236 SKIP_WHITESPACE ();
237 S_CLEAR_EXTERNAL (symbolP);
238 symbolP->local = 1;
239 if (c == ',')
240 {
241 input_line_pointer++;
242 SKIP_WHITESPACE ();
243 if (*input_line_pointer == '\n')
244 c = '\n';
245 }
246 }
247 while (c == ',');
248 demand_empty_rest_of_line ();
249 }
250
251 static void
252 obj_elf_weak ()
253 {
254 char *name;
255 int c;
256 symbolS *symbolP;
257
258 do
259 {
260 name = input_line_pointer;
261 c = get_symbol_end ();
262 symbolP = symbol_find_or_make (name);
263 *input_line_pointer = c;
264 SKIP_WHITESPACE ();
265 S_SET_WEAK (symbolP);
266 symbolP->local = 1;
267 if (c == ',')
268 {
269 input_line_pointer++;
270 SKIP_WHITESPACE ();
271 if (*input_line_pointer == '\n')
272 c = '\n';
273 }
274 }
275 while (c == ',');
276 demand_empty_rest_of_line ();
277 }
278
279 static segT previous_section;
280 static int previous_subsection;
281
282 void
283 obj_elf_section (xxx)
284 int xxx;
285 {
286 char *string;
287 asection *sec;
288
289 /* Initialize this with inclusive-or of all flags that can be cleared
290 by attributes, but not set by them. Also include flags that won't
291 get set properly in the assembler, but which the user/compiler
292 shouldn't be expected to set. */
293 flagword flags = SEC_READONLY | SEC_ALLOC | SEC_RELOC;
294 /* Initialize this with the default flags to be used if none are
295 specified. */
296 flagword default_flags = 0;
297
298 SKIP_WHITESPACE ();
299 /* Get name of section. */
300 if (*input_line_pointer == '"')
301 string = demand_copy_C_string (&xxx);
302 else
303 {
304 char *p = input_line_pointer;
305 char c;
306 while (0 == strchr ("\n\t,; ", *p))
307 p++;
308 c = *p;
309 *p = 0;
310 string = xmalloc (p - input_line_pointer + 1);
311 strcpy (string, input_line_pointer);
312 *p = c;
313 input_line_pointer = p;
314 }
315 if (!strcmp (string, ".rodata"))
316 default_flags = SEC_ALLOC | SEC_READONLY | SEC_RELOC;
317 else if (!strcmp (string, ".init")
318 || !strcmp (string, ".fini"))
319 default_flags = SEC_ALLOC | SEC_READONLY | SEC_RELOC | SEC_CODE;
320
321 SKIP_WHITESPACE ();
322 if (*input_line_pointer != ',')
323 flags = default_flags;
324 while (*input_line_pointer == ',')
325 {
326 flagword bit;
327 int len, inv;
328 char *p, oldp;
329
330 input_line_pointer++;
331
332 /* Under i386-svr4, gcc emits a string here. I don't know what this
333 string is supposed to signify or how to handle it. Ignore it for
334 now, unless it becomes a problem. */
335 if (*input_line_pointer == '"')
336 {
337 demand_copy_C_string (&xxx);
338 SKIP_WHITESPACE ();
339 continue;
340 }
341
342 if (*input_line_pointer != '#' && *input_line_pointer != '@')
343 {
344 as_bad ("unrecognized syntax in .section command");
345 ignore_rest_of_line ();
346 break;
347 }
348 input_line_pointer++;
349
350 #define CHECK(X,BIT,NEG) \
351 if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
352 bit = BIT; inv = NEG; goto match; }
353
354 CHECK ("write", SEC_READONLY, 1);
355 CHECK ("alloc", SEC_ALLOC, 0);
356 CHECK ("execinstr", SEC_CODE, 1);
357 CHECK ("progbits", SEC_LOAD, 1);
358 #undef CHECK
359
360 p = input_line_pointer;
361 while (!is_end_of_line[*p] && *p != 0 && *p != ',')
362 p++;
363 *p = 0;
364 oldp = *p;
365 as_bad ("unrecognized section attribute `%s' ignored",
366 input_line_pointer);
367 *p = oldp;
368 continue;
369
370 match:
371 if (inv)
372 flags &= ~bit;
373 else
374 flags |= bit;
375 input_line_pointer += len;
376 }
377 demand_empty_rest_of_line ();
378
379 /* If the C string wasn't valid, `string' could be null. */
380 if (!string)
381 return;
382
383 sec = bfd_get_section_by_name (stdoutput, string);
384 if (sec == 0)
385 {
386 sec = subseg_new (string, 0);
387 bfd_set_section_flags (stdoutput, sec, flags);
388 sec->output_section = sec;
389 }
390 previous_section = now_seg;
391 previous_subsection = now_subseg;
392 subseg_set (sec, 0);
393 }
394
395 void
396 obj_elf_previous ()
397 {
398 if (previous_section == 0)
399 {
400 as_bad (".previous without corresponding .section; ignored");
401 return;
402 }
403 subseg_set (previous_section, previous_subsection);
404 previous_section = 0;
405 }
406
407 int
408 obj_elf_write_symbol_p (sym)
409 symbolS *sym;
410 {
411 /* If this is a local symbol, are there any relocations for which
412 need this symbol? */
413
414 /* To find this out, we examine all relocations in all bfd sections
415 that have relocations. If there is one that references this
416 symbol, we need to keep this symbol. In this case, we return a
417 true status. In all other cases, we return a false status. */
418
419 if (S_IS_LOCAL (sym))
420 {
421 asymbol *bsym = sym->bsym;
422 bfd *abfd = bsym->the_bfd;
423 asection *bsec;
424
425 for (bsec = abfd->sections; bsec; bsec = bsec->next)
426 {
427 struct reloc_cache_entry **rlocs = bsec->orelocation;
428 int rcnt = bsec->reloc_count;
429
430 if (rlocs)
431 {
432 int i;
433
434 for (i = 0; i < rcnt; i++)
435 if (rlocs[i]->sym_ptr_ptr
436 && rlocs[i]->sym_ptr_ptr[0] == bsym)
437 return 1;
438 }
439 else
440 {
441 /* No relocations for this section. Check the seg_info
442 structure to see if there are any fixups for this
443 section. */
444 segment_info_type *seginfo = seg_info (bsec);
445 fixS *fixp;
446
447 for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
448 if ((fixp->fx_addsy && fixp->fx_addsy->bsym == bsym)
449 || (fixp->fx_subsy && fixp->fx_subsy->bsym == bsym))
450 return 1;
451 }
452 }
453 }
454 return 0;
455 }
456
457 int
458 obj_elf_write_symbol (sym)
459 symbolS *sym;
460 {
461 return /* obj_elf_write_symbol_p (sym) || */ !S_IS_LOCAL (sym);
462 }
463
464 int
465 obj_elf_frob_symbol (sym, punt)
466 symbolS *sym;
467 int *punt;
468 {
469 #if 0 /* ?? The return value is ignored. Only the value of *punt is
470 relevant. */
471 return obj_elf_write_symbol_p (sym);
472 #endif
473 }
474
475 static void
476 obj_elf_line ()
477 {
478 /* Assume delimiter is part of expression. BSD4.2 as fails with
479 delightful bug, so we are not being incompatible here. */
480 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
481 demand_empty_rest_of_line ();
482 }
483
484 /*
485 * stab()
486 *
487 * Handle .stabX directives, which used to be open-coded.
488 * So much creeping featurism overloaded the semantics that we decided
489 * to put all .stabX thinking in one place. Here.
490 *
491 * We try to make any .stabX directive legal. Other people's AS will often
492 * do assembly-time consistency checks: eg assigning meaning to n_type bits
493 * and "protecting" you from setting them to certain values. (They also zero
494 * certain bits before emitting symbols. Tut tut.)
495 *
496 * If an expression is not absolute we either gripe or use the relocation
497 * information. Other people's assemblers silently forget information they
498 * don't need and invent information they need that you didn't supply.
499 *
500 * .stabX directives always make a symbol table entry. It may be junk if
501 * the rest of your .stabX directive is malformed.
502 */
503
504 /*
505 * elf_stab_symbol_string()
506 *
507 * Build a string dictionary entry for a .stabX symbol.
508 * The symbol is added to the .stabstr section.
509 *
510 */
511
512 static unsigned int
513 elf_stab_symbol_string (string, secname)
514 char *string, *secname;
515 {
516 asection *save_seg;
517 asection *seg;
518 subsegT save_subseg;
519 unsigned int length;
520 unsigned int old_gdb_string_index;
521 char *clengthP;
522 int i;
523 char c;
524 /* @@FIXME -- there should be no static data here!
525 This also has the effect of making all stab string tables large enough
526 to contain all the contents written to any of them. This only matters
527 with the Solaris native compiler for the moment, but it should be fixed
528 anyways. */
529 static unsigned int gdb_string_index = 0;
530
531 old_gdb_string_index = 0;
532 length = strlen (string);
533 clengthP = (char *) &length;
534 if (length > 0)
535 { /* Ordinary case. */
536 save_seg = now_seg;
537 save_subseg = now_subseg;
538
539 /* Create the stab sections, if they are not already created. */
540 {
541 char *newsecname = xmalloc (strlen (secname) + 4);
542 strcpy (newsecname, secname);
543 strcat (newsecname, "str");
544 seg = bfd_get_section_by_name (stdoutput, newsecname);
545 if (seg == 0)
546 {
547 seg = bfd_make_section_old_way (stdoutput, newsecname);
548 bfd_set_section_flags (stdoutput, seg,
549 SEC_LOAD | SEC_READONLY | SEC_ALLOC);
550 }
551 /* free (newsecname);*/
552 }
553 subseg_new ((char *) seg->name, save_subseg);
554 old_gdb_string_index = gdb_string_index;
555 i = 0;
556 while ((c = *string++))
557 {
558 i++;
559 gdb_string_index++;
560 FRAG_APPEND_1_CHAR (c);
561 }
562 {
563 FRAG_APPEND_1_CHAR ((char) 0);
564 i++;
565 gdb_string_index++;
566 }
567 while (i % 4 != 0)
568 {
569 FRAG_APPEND_1_CHAR ((char) 0);
570 i++;
571 gdb_string_index++;
572 }
573 subseg_new ((char *) save_seg->name, save_subseg);
574 }
575
576 return old_gdb_string_index;
577 }
578
579 static void
580 DEFUN (elf_stab_symbol, (symbolP, stab_type),
581 symbolS *symbolP AND
582 int stab_type)
583 {
584 char *toP;
585
586 toP = frag_more (8);
587 /* the string index portion of the stab */
588 md_number_to_chars (toP, (valueT) symbolP->sy_name_offset, 4);
589 md_number_to_chars (toP + 4, (valueT) S_GET_TYPE (symbolP), 1);
590 md_number_to_chars (toP + 5, (valueT) S_GET_OTHER (symbolP), 1);
591 md_number_to_chars (toP + 6, (valueT) S_GET_DESC (symbolP), 2);
592 /* The n_value field doesn't get written here, it gets done below. It
593 may be an expression needing relocating. */
594 }
595
596 static void
597 obj_elf_stab_generic (what, secname)
598 int what;
599 char *secname;
600 {
601 extern int listing;
602
603 symbolS *symbolP = 0;
604 char *string;
605 int saved_type = 0;
606 int length;
607 int goof = 0;
608 int seg_is_new = 0;
609 long longint;
610 asection *saved_seg = now_seg;
611 asection *seg;
612 subsegT subseg = now_subseg;
613
614 #if 0
615 /* This function doesn't work yet.
616
617 Actually, this function is okay, but some finalizations are
618 needed before writing the object file; that's not done yet, and
619 the Solaris linker chokes without it.
620
621 In any case, this should effectively disable it for now. */
622 if (what == 's')
623 demand_copy_C_string (&length);
624 s_ignore (69);
625 return;
626 #endif
627
628 seg = bfd_get_section_by_name (stdoutput, secname);
629 if (seg == 0)
630 {
631 seg = subseg_new (secname, 0);
632 bfd_set_section_flags (stdoutput, seg,
633 SEC_LOAD | SEC_READONLY | SEC_ALLOC | SEC_RELOC);
634 subseg_set (saved_seg, subseg);
635 seg_is_new = 1;
636 }
637
638 /*
639 * Enter with input_line_pointer pointing past .stabX and any following
640 * whitespace.
641 */
642 if (what == 's')
643 {
644 string = demand_copy_C_string (&length);
645 SKIP_WHITESPACE ();
646 if (*input_line_pointer == ',')
647 input_line_pointer++;
648 else
649 {
650 as_bad ("I need a comma after symbol's name");
651 goof = 1;
652 }
653 }
654 else
655 string = "";
656
657 /*
658 * Input_line_pointer->after ','. String->symbol name.
659 */
660 if (!goof)
661 {
662 symbolP = symbol_new (string, &bfd_und_section, (valueT) 0, (struct frag *) 0);
663
664 /* enter the string in the .stab string table (section .stabstr) */
665 symbolP->sy_name_offset = elf_stab_symbol_string (string, secname);
666
667 switch (what)
668 {
669 case 'd':
670 S_SET_NAME (symbolP, NULL); /* .stabd feature. */
671 S_SET_VALUE (symbolP,
672 (valueT) ((char*) obstack_next_free (&frags) - frag_now->fr_literal));
673 S_SET_SEGMENT (symbolP, now_seg);
674 symbolP->sy_frag = frag_now;
675 break;
676
677 case 'n':
678 symbolP->sy_frag = &zero_address_frag;
679 break;
680
681 case 's':
682 symbolP->sy_frag = &zero_address_frag;
683 break;
684
685 default:
686 BAD_CASE (what);
687 break;
688 }
689
690 if (get_absolute_expression_and_terminator (&longint) == ',')
691 {
692 saved_type = longint;
693 S_SET_TYPE (symbolP, saved_type);
694 }
695 else
696 {
697 as_bad ("I want a comma after the n_type expression");
698 goof = 1;
699 input_line_pointer--; /* Backup over a non-',' char. */
700 }
701 }
702
703 if (!goof)
704 {
705 if (get_absolute_expression_and_terminator (&longint) == ',')
706 S_SET_OTHER (symbolP, longint);
707 else
708 {
709 as_bad ("I want a comma after the n_other expression");
710 goof = 1;
711 input_line_pointer--; /* Backup over a non-',' char. */
712 }
713 }
714
715 if (!goof)
716 {
717 S_SET_DESC (symbolP, get_absolute_expression ());
718 if (what == 's' || what == 'n')
719 {
720 if (*input_line_pointer != ',')
721 {
722 as_bad ("I want a comma after the n_desc expression");
723 goof = 1;
724 }
725 else
726 {
727 input_line_pointer++;
728 }
729 }
730 }
731
732 if (goof)
733 {
734 ignore_rest_of_line ();
735 return;
736 }
737
738 subseg_new ((char *) seg->name, subseg);
739
740 if (seg_is_new)
741 /* allocate and discard -- filled in later */
742 (void) frag_more (12);
743
744 /* Emit the stab symbol. */
745 elf_stab_symbol (symbolP, what);
746
747 if (what == 's' || what == 'n')
748 {
749 cons (4);
750 input_line_pointer--;
751 }
752 else
753 {
754 char *p = frag_more (4);
755 md_number_to_chars (p, 0, 4);
756 }
757
758 subseg_new ((char *) saved_seg->name, subseg);
759
760 if ((what == 's' || what == 'n')
761 && symbolP->sy_value.X_op == O_constant)
762 {
763 /* symbol is not needed in the regular symbol table */
764 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
765 }
766
767 if (what == 's' && S_GET_TYPE (symbolP) == N_SO)
768 {
769 fragS *fragp = seg_info (seg)->frchainP->frch_root;
770 while (fragp
771 && fragp->fr_address + fragp->fr_fix < 12)
772 fragp = fragp->fr_next;
773 assert (fragp != 0);
774 assert (fragp->fr_type == rs_fill);
775 assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
776 md_number_to_chars (fragp->fr_literal, (valueT) symbolP->sy_name_offset,
777 4);
778 }
779
780 if (listing)
781 switch (S_GET_TYPE (symbolP))
782 {
783 case N_SLINE:
784 listing_source_line (S_GET_DESC (symbolP));
785 break;
786 case N_SO:
787 case N_SOL:
788 listing_source_file (string);
789 break;
790 }
791
792 demand_empty_rest_of_line ();
793 }
794
795 static void
796 obj_elf_stab (what)
797 int what;
798 {
799 obj_elf_stab_generic (what, ".stab");
800 }
801
802 static void
803 obj_elf_xstab (what)
804 int what;
805 {
806 int length;
807 char *secname;
808
809 secname = demand_copy_C_string (&length);
810 SKIP_WHITESPACE ();
811 if (*input_line_pointer == ',')
812 input_line_pointer++;
813 else
814 {
815 as_bad ("comma missing in .xstabs");
816 ignore_rest_of_line ();
817 return;
818 }
819 obj_elf_stab_generic (what, secname);
820 }
821
822 void
823 obj_elf_desc ()
824 {
825 char *name;
826 char c;
827 char *p;
828 symbolS *symbolP;
829 int temp;
830
831 /* Frob invented at RMS' request. Set the n_desc of a symbol. */
832 name = input_line_pointer;
833 c = get_symbol_end ();
834 p = input_line_pointer;
835 *p = c;
836 SKIP_WHITESPACE ();
837 if (*input_line_pointer != ',')
838 {
839 *p = 0;
840 as_bad ("Expected comma after name \"%s\"", name);
841 *p = c;
842 ignore_rest_of_line ();
843 }
844 else
845 {
846 input_line_pointer++;
847 temp = get_absolute_expression ();
848 *p = 0;
849 symbolP = symbol_find_or_make (name);
850 *p = c;
851 S_SET_DESC (symbolP, temp);
852 }
853 demand_empty_rest_of_line ();
854 } /* obj_elf_desc() */
855
856 void
857 obj_read_begin_hook ()
858 {
859 }
860
861 void
862 obj_symbol_new_hook (symbolP)
863 symbolS *symbolP;
864 {
865 #if 0 /* BFD already takes care of this */
866 elf32_symbol_type *esym = (elf32_symbol_type *) symbolP;
867
868 /* There is an Elf_Internal_Sym and an Elf_External_Sym. For now,
869 just zero them out. */
870
871 bzero ((char *) &esym->internal_elf_sym, sizeof (esym->internal_elf_sym));
872 bzero ((char *) &esym->native_elf_sym, sizeof (esym->native_elf_sym));
873 bzero ((char *) &esym->tc_data, sizeof (esym->tc_data));
874 #endif
875 }
876
877 void
878 obj_elf_version ()
879 {
880 char *name;
881 unsigned int c;
882 char ch;
883 char *p;
884 asection *seg = now_seg;
885 subsegT subseg = now_subseg;
886 Elf_Internal_Note i_note;
887 Elf_External_Note e_note;
888 asection *note_secp = (asection *) NULL;
889 int i, len;
890
891 SKIP_WHITESPACE ();
892 if (*input_line_pointer == '\"')
893 {
894 ++input_line_pointer; /* -> 1st char of string. */
895 name = input_line_pointer;
896
897 while (is_a_char (c = next_char_of_string ()))
898 ;
899 c = *input_line_pointer;
900 *input_line_pointer = '\0';
901 *(input_line_pointer - 1) = '\0';
902 *input_line_pointer = c;
903
904 /* create the .note section if this is the first version string */
905
906 note_secp = bfd_get_section_by_name (stdoutput, ".note");
907 if (note_secp == (asection *) NULL)
908 {
909 note_secp = bfd_make_section_old_way (stdoutput, ".note");
910 bfd_set_section_flags (stdoutput,
911 note_secp,
912 SEC_LOAD | SEC_HAS_CONTENTS | SEC_READONLY);
913 }
914
915 /* process the version string */
916
917 subseg_new ((char *) note_secp->name, 0);
918 len = strlen (name);
919
920 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
921 i_note.descsz = 0; /* no description */
922 i_note.type = NT_VERSION;
923 p = frag_more (sizeof (e_note.namesz));
924 md_number_to_chars (p, (valueT) i_note.namesz, 4);
925 p = frag_more (sizeof (e_note.descsz));
926 md_number_to_chars (p, (valueT) i_note.descsz, 4);
927 p = frag_more (sizeof (e_note.type));
928 md_number_to_chars (p, (valueT) i_note.type, 4);
929
930 for (i = 0; i < len; i++)
931 {
932 ch = *(name + i);
933 {
934 FRAG_APPEND_1_CHAR (ch);
935 }
936 }
937 frag_align (2, 0);
938
939 subseg_new ((char *) seg->name, subseg);
940 }
941 else
942 {
943 as_bad ("Expected quoted string");
944 }
945 demand_empty_rest_of_line ();
946 }
947
948 static void
949 obj_elf_size ()
950 {
951 char *name = input_line_pointer;
952 char c = get_symbol_end ();
953 char *p;
954 expressionS exp;
955 symbolS *sym;
956
957 p = input_line_pointer;
958 *p = c;
959 SKIP_WHITESPACE ();
960 if (*input_line_pointer != ',')
961 {
962 *p = 0;
963 as_bad ("expected comma after name `%s' in .size directive", name);
964 *p = c;
965 ignore_rest_of_line ();
966 return;
967 }
968 input_line_pointer++;
969 expression (&exp);
970 if (exp.X_op == O_absent)
971 {
972 as_bad ("missing expression in .size directive");
973 exp.X_op = O_constant;
974 exp.X_add_number = 0;
975 }
976 *p = 0;
977 sym = symbol_find_or_make (name);
978 *p = c;
979 if (exp.X_op == O_constant)
980 S_SET_SIZE (sym, exp.X_add_number);
981 else
982 {
983 #if 0
984 static int warned;
985 if (!warned)
986 {
987 as_tsktsk (".size expressions not yet supported, ignored");
988 warned++;
989 }
990 #endif
991 }
992 demand_empty_rest_of_line ();
993 }
994
995 static void
996 obj_elf_type ()
997 {
998 char *name = input_line_pointer;
999 char c = get_symbol_end ();
1000 char *p;
1001 int type = 0;
1002 symbolS *sym;
1003
1004 p = input_line_pointer;
1005 *p = c;
1006 SKIP_WHITESPACE ();
1007 if (*input_line_pointer != ',')
1008 {
1009 as_bad ("expected comma after name in .type directive");
1010 egress:
1011 ignore_rest_of_line ();
1012 return;
1013 }
1014 input_line_pointer++;
1015 SKIP_WHITESPACE ();
1016 if (*input_line_pointer != '#' && *input_line_pointer != '@')
1017 {
1018 as_bad ("expected `#' or `@' after comma in .type directive");
1019 goto egress;
1020 }
1021 input_line_pointer++;
1022 if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
1023 {
1024 type = BSF_FUNCTION;
1025 input_line_pointer += sizeof ("function") - 1;
1026 }
1027 else if (!strncmp ("object", input_line_pointer, sizeof ("object") - 1))
1028 {
1029 input_line_pointer += sizeof ("object") - 1;
1030 }
1031 else
1032 {
1033 as_bad ("unrecognized symbol type, ignored");
1034 goto egress;
1035 }
1036 demand_empty_rest_of_line ();
1037 *p = 0;
1038 sym = symbol_find_or_make (name);
1039 sym->bsym->flags |= type;
1040 }
1041
1042 static void
1043 obj_elf_ident ()
1044 {
1045 static segT comment_section;
1046 segT old_section = now_seg;
1047 int old_subsection = now_subseg;
1048
1049 if (!comment_section)
1050 {
1051 char *p;
1052 comment_section = subseg_new (".comment", 0);
1053 bfd_set_section_flags (stdoutput, comment_section, SEC_HAS_CONTENTS);
1054 p = frag_more (1);
1055 *p = 0;
1056 }
1057 else
1058 subseg_set (comment_section, 0);
1059 stringer (1);
1060 subseg_set (old_section, old_subsection);
1061 }
1062
1063 static void
1064 adjust_stab_sections (abfd, sec, xxx)
1065 bfd *abfd;
1066 asection *sec;
1067 PTR xxx;
1068 {
1069 char *name;
1070 asection *strsec;
1071 fragS *fragp;
1072 int strsz, nsyms;
1073
1074 if (strncmp (".stab", sec->name, 5))
1075 return;
1076 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1077 return;
1078
1079 name = (char *) alloca (strlen (sec->name) + 4);
1080 strcpy (name, sec->name);
1081 strcat (name, "str");
1082 strsec = bfd_get_section_by_name (abfd, name);
1083 if (strsec)
1084 strsz = bfd_section_size (abfd, strsec);
1085 else
1086 strsz = 0;
1087 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1088
1089 fragp = seg_info (sec)->frchainP->frch_root;
1090 while (fragp
1091 && fragp->fr_address + fragp->fr_fix < 12)
1092 fragp = fragp->fr_next;
1093 assert (fragp != 0);
1094 assert (fragp->fr_type == rs_fill);
1095 assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
1096
1097 bfd_h_put_16 (abfd, nsyms, fragp->fr_literal + 6);
1098 bfd_h_put_32 (abfd, strsz, fragp->fr_literal + 8);
1099 }
1100
1101 void
1102 elf_frob_file ()
1103 {
1104 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1105
1106 #ifdef elf_tc_symbol
1107 {
1108 int i;
1109
1110 for (i = 0; i < stdoutput->symcount; i++)
1111 elf_tc_symbol (stdoutput, (PTR) (stdoutput->outsymbols[i]),
1112 i + 1);
1113 }
1114 #endif
1115
1116 #ifdef elf_tc_final_processing
1117 elf_tc_final_processing ();
1118 #endif
1119
1120 /* Finally, we must make any target-specific sections. */
1121
1122 #ifdef elf_tc_make_sections
1123 elf_tc_make_sections (stdoutput);
1124 #endif
1125 }