* tc-sparc.c (s_local): Function moved and renamed...
[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, SEC_READONLY | SEC_ALLOC);
549 }
550 /* free (newsecname);*/
551 }
552 subseg_new ((char *) seg->name, save_subseg);
553 old_gdb_string_index = gdb_string_index;
554 i = 0;
555 while ((c = *string++))
556 {
557 i++;
558 gdb_string_index++;
559 FRAG_APPEND_1_CHAR (c);
560 }
561 {
562 FRAG_APPEND_1_CHAR ((char) 0);
563 i++;
564 gdb_string_index++;
565 }
566 while (i % 4 != 0)
567 {
568 FRAG_APPEND_1_CHAR ((char) 0);
569 i++;
570 gdb_string_index++;
571 }
572 subseg_new ((char *) save_seg->name, save_subseg);
573 }
574
575 return old_gdb_string_index;
576 }
577
578 static void
579 DEFUN (elf_stab_symbol, (symbolP, stab_type),
580 symbolS *symbolP AND
581 int stab_type)
582 {
583 char *toP;
584
585 toP = frag_more (8);
586 /* the string index portion of the stab */
587 md_number_to_chars (toP, (valueT) symbolP->sy_name_offset, 4);
588 md_number_to_chars (toP + 4, (valueT) S_GET_TYPE (symbolP), 1);
589 md_number_to_chars (toP + 5, (valueT) S_GET_OTHER (symbolP), 1);
590 md_number_to_chars (toP + 6, (valueT) S_GET_DESC (symbolP), 2);
591 /* The n_value field doesn't get written here, it gets done below. It
592 may be an expression needing relocating. */
593 }
594
595 static void
596 obj_elf_stab_generic (what, secname)
597 int what;
598 char *secname;
599 {
600 extern int listing;
601
602 symbolS *symbolP = 0;
603 char *string;
604 int saved_type = 0;
605 int length;
606 int goof = 0;
607 int seg_is_new = 0;
608 long longint;
609 asection *saved_seg = now_seg;
610 asection *seg;
611 subsegT subseg = now_subseg;
612
613 #if 1
614 /* This function doesn't work yet.
615
616 Actually, this function is okay, but some finalizations are
617 needed before writing the object file; that's not done yet, and
618 the Solaris linker chokes without it.
619
620 In any case, this should effectively disable it for now. */
621 if (what == 's')
622 demand_copy_C_string (&length);
623 s_ignore (69);
624 return;
625 #endif
626
627 seg = bfd_get_section_by_name (stdoutput, secname);
628 if (seg == 0)
629 {
630 seg = subseg_new (secname, 0);
631 bfd_set_section_flags (stdoutput, seg,
632 SEC_READONLY | SEC_ALLOC | SEC_RELOC);
633 subseg_set (saved_seg, subseg);
634 seg_is_new = 1;
635 }
636
637 /*
638 * Enter with input_line_pointer pointing past .stabX and any following
639 * whitespace.
640 */
641 if (what == 's')
642 {
643 string = demand_copy_C_string (&length);
644 SKIP_WHITESPACE ();
645 if (*input_line_pointer == ',')
646 input_line_pointer++;
647 else
648 {
649 as_bad ("I need a comma after symbol's name");
650 goof = 1;
651 }
652 }
653 else
654 string = "";
655
656 /*
657 * Input_line_pointer->after ','. String->symbol name.
658 */
659 if (!goof)
660 {
661 symbolP = symbol_new (string, &bfd_und_section, (valueT) 0, (struct frag *) 0);
662
663 /* enter the string in the .stab string table (section .stabstr) */
664 symbolP->sy_name_offset = elf_stab_symbol_string (string, secname);
665
666 switch (what)
667 {
668 case 'd':
669 S_SET_NAME (symbolP, NULL); /* .stabd feature. */
670 S_SET_VALUE (symbolP,
671 (valueT) ((char*) obstack_next_free (&frags) - frag_now->fr_literal));
672 S_SET_SEGMENT (symbolP, now_seg);
673 symbolP->sy_frag = frag_now;
674 break;
675
676 case 'n':
677 symbolP->sy_frag = &zero_address_frag;
678 break;
679
680 case 's':
681 symbolP->sy_frag = &zero_address_frag;
682 break;
683
684 default:
685 BAD_CASE (what);
686 break;
687 }
688
689 if (get_absolute_expression_and_terminator (&longint) == ',')
690 {
691 saved_type = longint;
692 S_SET_TYPE (symbolP, saved_type);
693 }
694 else
695 {
696 as_bad ("I want a comma after the n_type expression");
697 goof = 1;
698 input_line_pointer--; /* Backup over a non-',' char. */
699 }
700 }
701
702 if (!goof)
703 {
704 if (get_absolute_expression_and_terminator (&longint) == ',')
705 S_SET_OTHER (symbolP, longint);
706 else
707 {
708 as_bad ("I want a comma after the n_other expression");
709 goof = 1;
710 input_line_pointer--; /* Backup over a non-',' char. */
711 }
712 }
713
714 if (!goof)
715 {
716 S_SET_DESC (symbolP, get_absolute_expression ());
717 if (what == 's' || what == 'n')
718 {
719 if (*input_line_pointer != ',')
720 {
721 as_bad ("I want a comma after the n_desc expression");
722 goof = 1;
723 }
724 else
725 {
726 input_line_pointer++;
727 }
728 }
729 }
730
731 if (goof)
732 {
733 ignore_rest_of_line ();
734 return;
735 }
736
737 subseg_new ((char *) seg->name, subseg);
738
739 if (seg_is_new)
740 /* allocate and discard -- filled in later */
741 (void) frag_more (12);
742
743 /* Emit the stab symbol. */
744 elf_stab_symbol (symbolP, what);
745
746 if (what == 's' || what == 'n')
747 {
748 cons (4);
749 input_line_pointer--;
750 }
751 else
752 {
753 char *p = frag_more (4);
754 md_number_to_chars (p, 0, 0);
755 }
756
757 subseg_new ((char *) saved_seg->name, subseg);
758
759 if ((what == 's' || what == 'n')
760 && symbolP->sy_value.X_op == O_constant)
761 {
762 /* symbol is not needed in the regular symbol table */
763 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
764 }
765
766 if (what == 's' && S_GET_TYPE (symbolP) == N_SO)
767 {
768 fragS *fragp = seg_info (seg)->frchainP->frch_root;
769 while (fragp
770 && fragp->fr_address + fragp->fr_fix < 12)
771 fragp = fragp->fr_next;
772 assert (fragp != 0);
773 assert (fragp->fr_type == rs_fill);
774 assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
775 md_number_to_chars (fragp->fr_literal, (valueT) symbolP->sy_name_offset,
776 4);
777 }
778
779 if (listing)
780 switch (S_GET_TYPE (symbolP))
781 {
782 case N_SLINE:
783 listing_source_line (S_GET_DESC (symbolP));
784 break;
785 case N_SO:
786 case N_SOL:
787 listing_source_file (string);
788 break;
789 }
790
791 demand_empty_rest_of_line ();
792 }
793
794 static void
795 obj_elf_stab (what)
796 int what;
797 {
798 obj_elf_stab_generic (what, ".stab");
799 }
800
801 static void
802 obj_elf_xstab (what)
803 int what;
804 {
805 int length;
806 char *secname;
807
808 secname = demand_copy_C_string (&length);
809 SKIP_WHITESPACE ();
810 if (*input_line_pointer == ',')
811 input_line_pointer++;
812 else
813 {
814 as_bad ("comma missing in .xstabs");
815 ignore_rest_of_line ();
816 return;
817 }
818 obj_elf_stab_generic (what, secname);
819 }
820
821 void
822 obj_elf_desc ()
823 {
824 char *name;
825 char c;
826 char *p;
827 symbolS *symbolP;
828 int temp;
829
830 /* Frob invented at RMS' request. Set the n_desc of a symbol. */
831 name = input_line_pointer;
832 c = get_symbol_end ();
833 p = input_line_pointer;
834 *p = c;
835 SKIP_WHITESPACE ();
836 if (*input_line_pointer != ',')
837 {
838 *p = 0;
839 as_bad ("Expected comma after name \"%s\"", name);
840 *p = c;
841 ignore_rest_of_line ();
842 }
843 else
844 {
845 input_line_pointer++;
846 temp = get_absolute_expression ();
847 *p = 0;
848 symbolP = symbol_find_or_make (name);
849 *p = c;
850 S_SET_DESC (symbolP, temp);
851 }
852 demand_empty_rest_of_line ();
853 } /* obj_elf_desc() */
854
855 void
856 obj_read_begin_hook ()
857 {
858 }
859
860 void
861 obj_symbol_new_hook (symbolP)
862 symbolS *symbolP;
863 {
864 #if 0 /* BFD already takes care of this */
865 elf32_symbol_type *esym = (elf32_symbol_type *) symbolP;
866
867 /* There is an Elf_Internal_Sym and an Elf_External_Sym. For now,
868 just zero them out. */
869
870 bzero ((char *) &esym->internal_elf_sym, sizeof (esym->internal_elf_sym));
871 bzero ((char *) &esym->native_elf_sym, sizeof (esym->native_elf_sym));
872 bzero ((char *) &esym->tc_data, sizeof (esym->tc_data));
873 #endif
874 }
875
876 void
877 obj_elf_version ()
878 {
879 char *name;
880 unsigned int c;
881 char ch;
882 char *p;
883 asection *seg = now_seg;
884 subsegT subseg = now_subseg;
885 Elf_Internal_Note i_note;
886 Elf_External_Note e_note;
887 asection *note_secp = (asection *) NULL;
888 int i, len;
889
890 SKIP_WHITESPACE ();
891 if (*input_line_pointer == '\"')
892 {
893 ++input_line_pointer; /* -> 1st char of string. */
894 name = input_line_pointer;
895
896 while (is_a_char (c = next_char_of_string ()))
897 ;
898 c = *input_line_pointer;
899 *input_line_pointer = '\0';
900 *(input_line_pointer - 1) = '\0';
901 *input_line_pointer = c;
902
903 /* create the .note section if this is the first version string */
904
905 note_secp = bfd_get_section_by_name (stdoutput, ".note");
906 if (note_secp == (asection *) NULL)
907 {
908 note_secp = bfd_make_section_old_way (stdoutput, ".note");
909 bfd_set_section_flags (stdoutput,
910 note_secp,
911 SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
912 }
913
914 /* process the version string */
915
916 subseg_new ((char *) note_secp->name, 0);
917 len = strlen (name);
918
919 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
920 i_note.descsz = 0; /* no description */
921 i_note.type = NT_VERSION;
922 p = frag_more (sizeof (e_note.namesz));
923 md_number_to_chars (p, (valueT) i_note.namesz, 4);
924 p = frag_more (sizeof (e_note.descsz));
925 md_number_to_chars (p, (valueT) i_note.descsz, 4);
926 p = frag_more (sizeof (e_note.type));
927 md_number_to_chars (p, (valueT) i_note.type, 4);
928
929 for (i = 0; i < len; i++)
930 {
931 ch = *(name + i);
932 {
933 FRAG_APPEND_1_CHAR (ch);
934 }
935 }
936 frag_align (2, 0);
937
938 subseg_new ((char *) seg->name, subseg);
939 }
940 else
941 {
942 as_bad ("Expected quoted string");
943 }
944 demand_empty_rest_of_line ();
945 }
946
947 static void
948 obj_elf_size ()
949 {
950 char *name = input_line_pointer;
951 char c = get_symbol_end ();
952 char *p;
953 expressionS exp;
954 symbolS *sym;
955
956 p = input_line_pointer;
957 *p = c;
958 SKIP_WHITESPACE ();
959 if (*input_line_pointer != ',')
960 {
961 *p = 0;
962 as_bad ("expected comma after name `%s' in .size directive", name);
963 *p = c;
964 ignore_rest_of_line ();
965 return;
966 }
967 input_line_pointer++;
968 expression (&exp);
969 if (exp.X_op == O_absent)
970 {
971 as_bad ("missing expression in .size directive");
972 exp.X_op = O_constant;
973 exp.X_add_number = 0;
974 }
975 *p = 0;
976 sym = symbol_find_or_make (name);
977 *p = c;
978 if (exp.X_op == O_constant)
979 S_SET_SIZE (sym, exp.X_add_number);
980 else
981 {
982 #if 0
983 static int warned;
984 if (!warned)
985 {
986 as_tsktsk (".size expressions not yet supported, ignored");
987 warned++;
988 }
989 #endif
990 }
991 demand_empty_rest_of_line ();
992 }
993
994 static void
995 obj_elf_type ()
996 {
997 char *name = input_line_pointer;
998 char c = get_symbol_end ();
999 char *p;
1000 int type = 0;
1001 symbolS *sym;
1002
1003 p = input_line_pointer;
1004 *p = c;
1005 SKIP_WHITESPACE ();
1006 if (*input_line_pointer != ',')
1007 {
1008 as_bad ("expected comma after name in .type directive");
1009 egress:
1010 ignore_rest_of_line ();
1011 return;
1012 }
1013 input_line_pointer++;
1014 SKIP_WHITESPACE ();
1015 if (*input_line_pointer != '#' && *input_line_pointer != '@')
1016 {
1017 as_bad ("expected `#' or `@' after comma in .type directive");
1018 goto egress;
1019 }
1020 input_line_pointer++;
1021 if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
1022 {
1023 type = BSF_FUNCTION;
1024 input_line_pointer += sizeof ("function") - 1;
1025 }
1026 else if (!strncmp ("object", input_line_pointer, sizeof ("object") - 1))
1027 {
1028 input_line_pointer += sizeof ("object") - 1;
1029 }
1030 else
1031 {
1032 as_bad ("unrecognized symbol type, ignored");
1033 goto egress;
1034 }
1035 demand_empty_rest_of_line ();
1036 *p = 0;
1037 sym = symbol_find_or_make (name);
1038 sym->bsym->flags |= type;
1039 }
1040
1041 static void
1042 obj_elf_ident ()
1043 {
1044 static segT comment_section;
1045 segT old_section = now_seg;
1046 int old_subsection = now_subseg;
1047
1048 if (!comment_section)
1049 {
1050 char *p;
1051 comment_section = subseg_new (".comment", 0);
1052 bfd_set_section_flags (stdoutput, comment_section, SEC_HAS_CONTENTS);
1053 p = frag_more (1);
1054 *p = 0;
1055 }
1056 else
1057 subseg_set (comment_section, 0);
1058 stringer (1);
1059 subseg_set (old_section, old_subsection);
1060 }
1061
1062 static void
1063 adjust_stab_sections (abfd, sec, xxx)
1064 bfd *abfd;
1065 asection *sec;
1066 PTR xxx;
1067 {
1068 char *name;
1069 asection *strsec;
1070 fragS *fragp;
1071 int strsz, nsyms;
1072
1073 if (strncmp (".stab", sec->name, 5))
1074 return;
1075 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1076 return;
1077
1078 name = (char *) alloca (strlen (sec->name) + 4);
1079 strcpy (name, sec->name);
1080 strcat (name, "str");
1081 strsec = bfd_get_section_by_name (abfd, name);
1082 if (strsec)
1083 strsz = bfd_section_size (abfd, strsec);
1084 else
1085 strsz = 0;
1086 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1087
1088 fragp = seg_info (sec)->frchainP->frch_root;
1089 while (fragp
1090 && fragp->fr_address + fragp->fr_fix < 12)
1091 fragp = fragp->fr_next;
1092 assert (fragp != 0);
1093 assert (fragp->fr_type == rs_fill);
1094 assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
1095
1096 bfd_h_put_16 (abfd, nsyms, fragp->fr_literal + 6);
1097 bfd_h_put_32 (abfd, strsz, fragp->fr_literal + 8);
1098 }
1099
1100 void
1101 elf_frob_file ()
1102 {
1103 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1104
1105 #ifdef elf_tc_symbol
1106 {
1107 int i;
1108
1109 for (i = 0; i < stdoutput->symcount; i++)
1110 elf_tc_symbol (stdoutput, (elf_symbol_type *) (stdoutput->outsymbols[i]),
1111 i + 1);
1112 }
1113 #endif
1114
1115 #ifdef elf_tc_final_processing
1116 elf_tc_final_processing_hook ();
1117 #endif
1118
1119 /* Finally, we must make any target-specific sections. */
1120
1121 #ifdef elf_tc_make_sections
1122 elf_tc_make_sections (stdoutput, NULL);
1123 #endif
1124 }