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