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