* config/obj-elf.c (obj_elf_type): Set BSF_OBJECT flag for a type
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
1 /* ELF object file format
2 Copyright (C) 1992, 1993, 1994, 1995, 1996 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 License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #define OBJ_HEADER "obj-elf.h"
22 #include "as.h"
23 #include "subsegs.h"
24 #include "obstack.h"
25
26 #ifndef ECOFF_DEBUGGING
27 #define ECOFF_DEBUGGING 0
28 #else
29 #define NEED_ECOFF_DEBUG
30 #endif
31
32 #ifdef NEED_ECOFF_DEBUG
33 #include "ecoff.h"
34 #endif
35
36 #ifdef TC_MIPS
37 #include "elf/mips.h"
38 #endif
39
40 #ifdef TC_PPC
41 #include "elf/ppc.h"
42 #endif
43
44 #ifdef NEED_ECOFF_DEBUG
45 static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
46 static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
47 #endif
48
49 static void obj_elf_line PARAMS ((int));
50 void obj_elf_version PARAMS ((int));
51 static void obj_elf_size PARAMS ((int));
52 static void obj_elf_type PARAMS ((int));
53 static void obj_elf_ident PARAMS ((int));
54 static void obj_elf_weak PARAMS ((int));
55 static void obj_elf_local PARAMS ((int));
56 static void obj_elf_common PARAMS ((int));
57 static void obj_elf_data PARAMS ((int));
58 static void obj_elf_text PARAMS ((int));
59
60 static const pseudo_typeS elf_pseudo_table[] =
61 {
62 {"comm", obj_elf_common, 0},
63 {"ident", obj_elf_ident, 0},
64 {"local", obj_elf_local, 0},
65 {"previous", obj_elf_previous, 0},
66 {"section", obj_elf_section, 0},
67 {"section.s", obj_elf_section, 0},
68 {"sect", obj_elf_section, 0},
69 {"sect.s", obj_elf_section, 0},
70 {"size", obj_elf_size, 0},
71 {"type", obj_elf_type, 0},
72 {"version", obj_elf_version, 0},
73 {"weak", obj_elf_weak, 0},
74
75 /* These are used for stabs-in-elf configurations. */
76 {"line", obj_elf_line, 0},
77
78 /* These are used for dwarf. */
79 {"2byte", cons, 2},
80 {"4byte", cons, 4},
81 {"8byte", cons, 8},
82
83 /* We need to trap the section changing calls to handle .previous. */
84 {"data", obj_elf_data, 0},
85 {"text", obj_elf_text, 0},
86
87 /* End sentinel. */
88 {NULL},
89 };
90
91 static const pseudo_typeS ecoff_debug_pseudo_table[] =
92 {
93 #ifdef NEED_ECOFF_DEBUG
94 /* COFF style debugging information for ECOFF. .ln is not used; .loc
95 is used instead. */
96 { "def", ecoff_directive_def, 0 },
97 { "dim", ecoff_directive_dim, 0 },
98 { "endef", ecoff_directive_endef, 0 },
99 { "file", ecoff_directive_file, 0 },
100 { "scl", ecoff_directive_scl, 0 },
101 { "tag", ecoff_directive_tag, 0 },
102 { "val", ecoff_directive_val, 0 },
103
104 /* COFF debugging requires pseudo-ops .size and .type, but ELF
105 already has meanings for those. We use .esize and .etype
106 instead. These are only generated by gcc anyhow. */
107 { "esize", ecoff_directive_size, 0 },
108 { "etype", ecoff_directive_type, 0 },
109
110 /* ECOFF specific debugging information. */
111 { "begin", ecoff_directive_begin, 0 },
112 { "bend", ecoff_directive_bend, 0 },
113 { "end", ecoff_directive_end, 0 },
114 { "ent", ecoff_directive_ent, 0 },
115 { "fmask", ecoff_directive_fmask, 0 },
116 { "frame", ecoff_directive_frame, 0 },
117 { "loc", ecoff_directive_loc, 0 },
118 { "mask", ecoff_directive_mask, 0 },
119
120 /* Other ECOFF directives. */
121 { "extern", ecoff_directive_extern, 0 },
122
123 /* These are used on Irix. I don't know how to implement them. */
124 { "alias", s_ignore, 0 },
125 { "bgnb", s_ignore, 0 },
126 { "endb", s_ignore, 0 },
127 { "lab", s_ignore, 0 },
128 { "noalias", s_ignore, 0 },
129 { "verstamp", s_ignore, 0 },
130 { "vreg", s_ignore, 0 },
131 #endif
132
133 {NULL} /* end sentinel */
134 };
135
136 #undef NO_RELOC
137 #include "aout/aout64.h"
138
139 void
140 elf_pop_insert ()
141 {
142 pop_insert (elf_pseudo_table);
143 if (ECOFF_DEBUGGING)
144 pop_insert (ecoff_debug_pseudo_table);
145 }
146
147 static bfd_vma
148 elf_s_get_size (sym)
149 symbolS *sym;
150 {
151 return S_GET_SIZE (sym);
152 }
153
154 static void
155 elf_s_set_size (sym, sz)
156 symbolS *sym;
157 bfd_vma sz;
158 {
159 S_SET_SIZE (sym, sz);
160 }
161
162 static bfd_vma
163 elf_s_get_align (sym)
164 symbolS *sym;
165 {
166 return S_GET_ALIGN (sym);
167 }
168
169 static void
170 elf_s_set_align (sym, align)
171 symbolS *sym;
172 bfd_vma align;
173 {
174 S_SET_ALIGN (sym, align);
175 }
176
177 static void
178 elf_copy_symbol_attributes (dest, src)
179 symbolS *dest, *src;
180 {
181 OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
182 }
183
184 static int
185 elf_sec_sym_ok_for_reloc (sec)
186 asection *sec;
187 {
188 return obj_sec_sym_ok_for_reloc (sec);
189 }
190
191 void
192 elf_file_symbol (s)
193 char *s;
194 {
195 symbolS *sym;
196
197 sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
198 sym->sy_frag = &zero_address_frag;
199 sym->bsym->flags |= BSF_FILE;
200
201 if (symbol_rootP != sym)
202 {
203 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
204 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
205 #ifdef DEBUG
206 verify_symbol_chain (symbol_rootP, symbol_lastP);
207 #endif
208 }
209 }
210
211 static void
212 obj_elf_common (ignore)
213 int ignore;
214 {
215 char *name;
216 char c;
217 char *p;
218 int temp, size;
219 symbolS *symbolP;
220 int have_align;
221
222 name = input_line_pointer;
223 c = get_symbol_end ();
224 /* just after name is now '\0' */
225 p = input_line_pointer;
226 *p = c;
227 SKIP_WHITESPACE ();
228 if (*input_line_pointer != ',')
229 {
230 as_bad ("Expected comma after symbol-name");
231 ignore_rest_of_line ();
232 return;
233 }
234 input_line_pointer++; /* skip ',' */
235 if ((temp = get_absolute_expression ()) < 0)
236 {
237 as_bad (".COMMon length (%d.) <0! Ignored.", temp);
238 ignore_rest_of_line ();
239 return;
240 }
241 size = temp;
242 *p = 0;
243 symbolP = symbol_find_or_make (name);
244 *p = c;
245 if (S_IS_DEFINED (symbolP))
246 {
247 as_bad ("Ignoring attempt to re-define symbol");
248 ignore_rest_of_line ();
249 return;
250 }
251 if (S_GET_VALUE (symbolP) != 0)
252 {
253 if (S_GET_VALUE (symbolP) != size)
254 {
255 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
256 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
257 }
258 }
259 know (symbolP->sy_frag == &zero_address_frag);
260 if (*input_line_pointer != ',')
261 have_align = 0;
262 else
263 {
264 have_align = 1;
265 input_line_pointer++;
266 SKIP_WHITESPACE ();
267 }
268 if (! have_align || *input_line_pointer != '"')
269 {
270 if (! have_align)
271 temp = 0;
272 else
273 {
274 temp = get_absolute_expression ();
275 if (temp < 0)
276 {
277 temp = 0;
278 as_warn ("Common alignment negative; 0 assumed");
279 }
280 }
281 if (symbolP->local)
282 {
283 segT old_sec;
284 int old_subsec;
285 char *pfrag;
286 int align;
287
288 /* allocate_bss: */
289 old_sec = now_seg;
290 old_subsec = now_subseg;
291 if (temp)
292 {
293 /* convert to a power of 2 alignment */
294 for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
295 if (temp != 1)
296 {
297 as_bad ("Common alignment not a power of 2");
298 ignore_rest_of_line ();
299 return;
300 }
301 }
302 else
303 align = 0;
304 record_alignment (bss_section, align);
305 subseg_set (bss_section, 0);
306 if (align)
307 frag_align (align, 0);
308 if (S_GET_SEGMENT (symbolP) == bss_section)
309 symbolP->sy_frag->fr_symbol = 0;
310 symbolP->sy_frag = frag_now;
311 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
312 (char *) 0);
313 *pfrag = 0;
314 S_SET_SIZE (symbolP, size);
315 S_SET_SEGMENT (symbolP, bss_section);
316 S_CLEAR_EXTERNAL (symbolP);
317 subseg_set (old_sec, old_subsec);
318 }
319 else
320 {
321 allocate_common:
322 S_SET_VALUE (symbolP, (valueT) size);
323 S_SET_ALIGN (symbolP, temp);
324 S_SET_EXTERNAL (symbolP);
325 /* should be common, but this is how gas does it for now */
326 S_SET_SEGMENT (symbolP, bfd_und_section_ptr);
327 }
328 }
329 else
330 {
331 input_line_pointer++;
332 /* @@ Some use the dot, some don't. Can we get some consistency?? */
333 if (*input_line_pointer == '.')
334 input_line_pointer++;
335 /* @@ Some say data, some say bss. */
336 if (strncmp (input_line_pointer, "bss\"", 4)
337 && strncmp (input_line_pointer, "data\"", 5))
338 {
339 while (*--input_line_pointer != '"')
340 ;
341 input_line_pointer--;
342 goto bad_common_segment;
343 }
344 while (*input_line_pointer++ != '"')
345 ;
346 goto allocate_common;
347 }
348 demand_empty_rest_of_line ();
349 return;
350
351 {
352 bad_common_segment:
353 p = input_line_pointer;
354 while (*p && *p != '\n')
355 p++;
356 c = *p;
357 *p = '\0';
358 as_bad ("bad .common segment %s", input_line_pointer + 1);
359 *p = c;
360 input_line_pointer = p;
361 ignore_rest_of_line ();
362 return;
363 }
364 }
365
366 static void
367 obj_elf_local (ignore)
368 int ignore;
369 {
370 char *name;
371 int c;
372 symbolS *symbolP;
373
374 do
375 {
376 name = input_line_pointer;
377 c = get_symbol_end ();
378 symbolP = symbol_find_or_make (name);
379 *input_line_pointer = c;
380 SKIP_WHITESPACE ();
381 S_CLEAR_EXTERNAL (symbolP);
382 symbolP->local = 1;
383 if (c == ',')
384 {
385 input_line_pointer++;
386 SKIP_WHITESPACE ();
387 if (*input_line_pointer == '\n')
388 c = '\n';
389 }
390 }
391 while (c == ',');
392 demand_empty_rest_of_line ();
393 }
394
395 static void
396 obj_elf_weak (ignore)
397 int ignore;
398 {
399 char *name;
400 int c;
401 symbolS *symbolP;
402
403 do
404 {
405 name = input_line_pointer;
406 c = get_symbol_end ();
407 symbolP = symbol_find_or_make (name);
408 *input_line_pointer = c;
409 SKIP_WHITESPACE ();
410 S_SET_WEAK (symbolP);
411 symbolP->local = 1;
412 if (c == ',')
413 {
414 input_line_pointer++;
415 SKIP_WHITESPACE ();
416 if (*input_line_pointer == '\n')
417 c = '\n';
418 }
419 }
420 while (c == ',');
421 demand_empty_rest_of_line ();
422 }
423
424 static segT previous_section;
425 static int previous_subsection;
426
427 /* Handle the .section pseudo-op. This code supports two different
428 syntaxes.
429
430 The first is found on Solaris, and looks like
431 .section ".sec1",#alloc,#execinstr,#write
432 Here the names after '#' are the SHF_* flags to turn on for the
433 section. I'm not sure how it determines the SHT_* type (BFD
434 doesn't really give us control over the type, anyhow).
435
436 The second format is found on UnixWare, and probably most SVR4
437 machines, and looks like
438 .section .sec1,"a",@progbits
439 The quoted string may contain any combination of a, w, x, and
440 represents the SHF_* flags to turn on for the section. The string
441 beginning with '@' can be progbits or nobits. There should be
442 other possibilities, but I don't know what they are. In any case,
443 BFD doesn't really let us set the section type. */
444
445 /* Certain named sections have particular defined types, listed on p.
446 4-19 of the ABI. */
447 struct special_section
448 {
449 const char *name;
450 int type;
451 int attributes;
452 };
453
454 static struct special_section special_sections[] =
455 {
456 { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
457 { ".comment", SHT_PROGBITS, 0 },
458 { ".data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
459 { ".data1", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
460 { ".debug", SHT_PROGBITS, 0 },
461 { ".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
462 { ".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
463 { ".line", SHT_PROGBITS, 0 },
464 { ".note", SHT_NOTE, 0 },
465 { ".rodata", SHT_PROGBITS, SHF_ALLOC },
466 { ".rodata1", SHT_PROGBITS, SHF_ALLOC },
467 { ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
468
469 #ifdef ELF_TC_SPECIAL_SECTIONS
470 ELF_TC_SPECIAL_SECTIONS
471 #endif
472
473 #if 0
474 /* The following section names are special, but they can not
475 reasonably appear in assembler code. Some of the attributes are
476 processor dependent. */
477 { ".dynamic", SHT_DYNAMIC, SHF_ALLOC /* + SHF_WRITE */ },
478 { ".dynstr", SHT_STRTAB, SHF_ALLOC },
479 { ".dynsym", SHT_DYNSYM, SHF_ALLOC },
480 { ".got", SHT_PROGBITS, 0 },
481 { ".hash", SHT_HASH, SHF_ALLOC },
482 { ".interp", SHT_PROGBITS, /* SHF_ALLOC */ },
483 { ".plt", SHT_PROGBITS, 0 },
484 { ".shstrtab",SHT_STRTAB, 0 },
485 { ".strtab", SHT_STRTAB, /* SHF_ALLOC */ },
486 { ".symtab", SHT_SYMTAB, /* SHF_ALLOC */ },
487 #endif
488
489 { NULL, 0, 0 }
490 };
491
492 void
493 obj_elf_section (xxx)
494 int xxx;
495 {
496 char *string;
497 int new_sec;
498 segT sec;
499 int type, attr;
500 int i;
501 flagword flags;
502
503 #ifdef md_flush_pending_output
504 md_flush_pending_output ();
505 #endif
506
507 if (flag_mri)
508 {
509 char type;
510
511 previous_section = now_seg;
512 previous_subsection = now_subseg;
513
514 s_mri_sect (&type);
515
516 #ifdef md_elf_section_change_hook
517 md_elf_section_change_hook ();
518 #endif
519
520 return;
521 }
522
523 /* Get name of section. */
524 SKIP_WHITESPACE ();
525 if (*input_line_pointer == '"')
526 {
527 string = demand_copy_C_string (&xxx);
528 if (string == NULL)
529 {
530 ignore_rest_of_line ();
531 return;
532 }
533 }
534 else
535 {
536 char *p = input_line_pointer;
537 char c;
538 while (0 == strchr ("\n\t,; ", *p))
539 p++;
540 if (p == input_line_pointer)
541 {
542 as_warn ("Missing section name");
543 ignore_rest_of_line ();
544 return;
545 }
546 c = *p;
547 *p = 0;
548 string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
549 strcpy (string, input_line_pointer);
550 *p = c;
551 input_line_pointer = p;
552 }
553
554 /* Switch to the section, creating it if necessary. */
555 previous_section = now_seg;
556 previous_subsection = now_subseg;
557
558 new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
559 sec = subseg_new (string, 0);
560
561 /* If this section already existed, we don't bother to change the
562 flag values. */
563 if (! new_sec)
564 {
565 while (! is_end_of_line[(unsigned char) *input_line_pointer])
566 ++input_line_pointer;
567 ++input_line_pointer;
568
569 #ifdef md_elf_section_change_hook
570 md_elf_section_change_hook ();
571 #endif
572
573 return;
574 }
575
576 SKIP_WHITESPACE ();
577
578 type = SHT_NULL;
579 attr = 0;
580
581 if (*input_line_pointer == ',')
582 {
583 /* Skip the comma. */
584 ++input_line_pointer;
585
586 SKIP_WHITESPACE ();
587 if (*input_line_pointer == '"')
588 {
589 /* Pick up a string with a combination of a, w, x. */
590 ++input_line_pointer;
591 while (*input_line_pointer != '"')
592 {
593 switch (*input_line_pointer)
594 {
595 case 'a':
596 attr |= SHF_ALLOC;
597 break;
598 case 'w':
599 attr |= SHF_WRITE;
600 break;
601 case 'x':
602 attr |= SHF_EXECINSTR;
603 break;
604 default:
605 {
606 char *bad_msg = "Bad .section directive: want a,w,x in string";
607 #ifdef md_elf_section_letter
608 int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
609 if (md_attr)
610 attr |= md_attr;
611 else
612 #endif
613 {
614 as_warn (bad_msg);
615 ignore_rest_of_line ();
616 return;
617 }
618 }
619 }
620 ++input_line_pointer;
621 }
622
623 /* Skip the closing quote. */
624 ++input_line_pointer;
625
626 SKIP_WHITESPACE ();
627 if (*input_line_pointer == ',')
628 {
629 ++input_line_pointer;
630 SKIP_WHITESPACE ();
631 if (*input_line_pointer == '@')
632 {
633 ++input_line_pointer;
634 if (strncmp (input_line_pointer, "progbits",
635 sizeof "progbits" - 1) == 0)
636 {
637 type = SHT_PROGBITS;
638 input_line_pointer += sizeof "progbits" - 1;
639 }
640 else if (strncmp (input_line_pointer, "nobits",
641 sizeof "nobits" - 1) == 0)
642 {
643 type = SHT_NOBITS;
644 input_line_pointer += sizeof "nobits" - 1;
645 }
646 else
647 {
648 #ifdef md_elf_section_type
649 int md_type = md_elf_section_type (&input_line_pointer);
650 if (md_type)
651 type = md_type;
652 else
653 #endif
654 {
655 as_warn ("Unrecognized section type");
656 ignore_rest_of_line ();
657 }
658 }
659 }
660 }
661 }
662 else
663 {
664 do
665 {
666 SKIP_WHITESPACE ();
667 if (*input_line_pointer != '#')
668 {
669 as_warn ("Bad .section directive");
670 ignore_rest_of_line ();
671 return;
672 }
673 ++input_line_pointer;
674 if (strncmp (input_line_pointer, "write",
675 sizeof "write" - 1) == 0)
676 {
677 attr |= SHF_WRITE;
678 input_line_pointer += sizeof "write" - 1;
679 }
680 else if (strncmp (input_line_pointer, "alloc",
681 sizeof "alloc" - 1) == 0)
682 {
683 attr |= SHF_ALLOC;
684 input_line_pointer += sizeof "alloc" - 1;
685 }
686 else if (strncmp (input_line_pointer, "execinstr",
687 sizeof "execinstr" - 1) == 0)
688 {
689 attr |= SHF_EXECINSTR;
690 input_line_pointer += sizeof "execinstr" - 1;
691 }
692 else
693 {
694 #ifdef md_elf_section_word
695 int md_attr = md_elf_section_word (&input_line_pointer);
696 if (md_attr)
697 attr |= md_attr;
698 else
699 #endif
700 {
701 as_warn ("Unrecognized section attribute");
702 ignore_rest_of_line ();
703 return;
704 }
705 }
706 SKIP_WHITESPACE ();
707 }
708 while (*input_line_pointer++ == ',');
709 --input_line_pointer;
710 }
711 }
712
713 /* See if this is one of the special sections. */
714 for (i = 0; special_sections[i].name != NULL; i++)
715 {
716 if (string[1] == special_sections[i].name[1]
717 && strcmp (string, special_sections[i].name) == 0)
718 {
719 if (type == SHT_NULL)
720 type = special_sections[i].type;
721 else if (type != special_sections[i].type)
722 as_warn ("Setting incorrect section type for %s", string);
723
724 if ((attr &~ special_sections[i].attributes) != 0)
725 as_warn ("Setting incorrect section attributes for %s", string);
726 attr |= special_sections[i].attributes;
727
728 break;
729 }
730 }
731
732 flags = (SEC_RELOC
733 | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
734 | ((attr & SHF_ALLOC) ? SEC_ALLOC | SEC_LOAD : 0)
735 | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
736 if (special_sections[i].name == NULL)
737 {
738 if (type == SHT_PROGBITS)
739 flags |= SEC_ALLOC | SEC_LOAD;
740 else if (type == SHT_NOBITS)
741 {
742 flags |= SEC_ALLOC;
743 flags &=~ SEC_LOAD;
744 }
745
746 #ifdef md_elf_section_flags
747 flags = md_elf_section_flags (flags, attr, type);
748 #endif
749 }
750
751 bfd_set_section_flags (stdoutput, sec, flags);
752
753 #ifdef md_elf_section_change_hook
754 md_elf_section_change_hook ();
755 #endif
756
757 demand_empty_rest_of_line ();
758 }
759
760 /* Change to the .data section. */
761
762 static void
763 obj_elf_data (i)
764 int i;
765 {
766 previous_section = now_seg;
767 previous_subsection = now_subseg;
768 s_data (i);
769 }
770
771 /* Change to the .text section. */
772
773 static void
774 obj_elf_text (i)
775 int i;
776 {
777 previous_section = now_seg;
778 previous_subsection = now_subseg;
779 s_text (i);
780 }
781
782 void
783 obj_elf_previous (ignore)
784 int ignore;
785 {
786 if (previous_section == 0)
787 {
788 as_bad (".previous without corresponding .section; ignored");
789 return;
790 }
791 subseg_set (previous_section, previous_subsection);
792 previous_section = 0;
793 }
794
795 static void
796 obj_elf_line (ignore)
797 int ignore;
798 {
799 /* Assume delimiter is part of expression. BSD4.2 as fails with
800 delightful bug, so we are not being incompatible here. */
801 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
802 demand_empty_rest_of_line ();
803 }
804
805 void
806 obj_read_begin_hook ()
807 {
808 #ifdef NEED_ECOFF_DEBUG
809 if (ECOFF_DEBUGGING)
810 ecoff_read_begin_hook ();
811 #endif
812 }
813
814 void
815 obj_symbol_new_hook (symbolP)
816 symbolS *symbolP;
817 {
818 symbolP->sy_obj = 0;
819
820 #ifdef NEED_ECOFF_DEBUG
821 if (ECOFF_DEBUGGING)
822 ecoff_symbol_new_hook (symbolP);
823 #endif
824 }
825
826 void
827 obj_elf_version (ignore)
828 int ignore;
829 {
830 char *name;
831 unsigned int c;
832 char ch;
833 char *p;
834 asection *seg = now_seg;
835 subsegT subseg = now_subseg;
836 Elf_Internal_Note i_note;
837 Elf_External_Note e_note;
838 asection *note_secp = (asection *) NULL;
839 int i, len;
840
841 SKIP_WHITESPACE ();
842 if (*input_line_pointer == '\"')
843 {
844 ++input_line_pointer; /* -> 1st char of string. */
845 name = input_line_pointer;
846
847 while (is_a_char (c = next_char_of_string ()))
848 ;
849 c = *input_line_pointer;
850 *input_line_pointer = '\0';
851 *(input_line_pointer - 1) = '\0';
852 *input_line_pointer = c;
853
854 /* create the .note section */
855
856 note_secp = subseg_new (".note", 0);
857 bfd_set_section_flags (stdoutput,
858 note_secp,
859 SEC_HAS_CONTENTS | SEC_READONLY);
860
861 /* process the version string */
862
863 len = strlen (name);
864
865 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
866 i_note.descsz = 0; /* no description */
867 i_note.type = NT_VERSION;
868 p = frag_more (sizeof (e_note.namesz));
869 md_number_to_chars (p, (valueT) i_note.namesz, 4);
870 p = frag_more (sizeof (e_note.descsz));
871 md_number_to_chars (p, (valueT) i_note.descsz, 4);
872 p = frag_more (sizeof (e_note.type));
873 md_number_to_chars (p, (valueT) i_note.type, 4);
874
875 for (i = 0; i < len; i++)
876 {
877 ch = *(name + i);
878 {
879 FRAG_APPEND_1_CHAR (ch);
880 }
881 }
882 frag_align (2, 0);
883
884 subseg_set (seg, subseg);
885 }
886 else
887 {
888 as_bad ("Expected quoted string");
889 }
890 demand_empty_rest_of_line ();
891 }
892
893 static void
894 obj_elf_size (ignore)
895 int ignore;
896 {
897 char *name = input_line_pointer;
898 char c = get_symbol_end ();
899 char *p;
900 expressionS exp;
901 symbolS *sym;
902
903 p = input_line_pointer;
904 *p = c;
905 SKIP_WHITESPACE ();
906 if (*input_line_pointer != ',')
907 {
908 *p = 0;
909 as_bad ("expected comma after name `%s' in .size directive", name);
910 *p = c;
911 ignore_rest_of_line ();
912 return;
913 }
914 input_line_pointer++;
915 expression (&exp);
916 if (exp.X_op == O_absent)
917 {
918 as_bad ("missing expression in .size directive");
919 exp.X_op = O_constant;
920 exp.X_add_number = 0;
921 }
922 *p = 0;
923 sym = symbol_find_or_make (name);
924 *p = c;
925 if (exp.X_op == O_constant)
926 S_SET_SIZE (sym, exp.X_add_number);
927 else
928 {
929 sym->sy_obj = (expressionS *) xmalloc (sizeof (expressionS));
930 *sym->sy_obj = exp;
931 }
932 demand_empty_rest_of_line ();
933 }
934
935 /* Handle the ELF .type pseudo-op. This sets the type of a symbol.
936 There are three syntaxes. The first (used on Solaris) is
937 .type SYM,#function
938 The second (used on UnixWare) is
939 .type SYM,@function
940 The third (reportedly to be used on Irix 6.0) is
941 .type SYM STT_FUNC
942 */
943
944 static void
945 obj_elf_type (ignore)
946 int ignore;
947 {
948 char *name;
949 char c;
950 int type;
951 const char *typename;
952 symbolS *sym;
953
954 name = input_line_pointer;
955 c = get_symbol_end ();
956 sym = symbol_find_or_make (name);
957 *input_line_pointer = c;
958
959 SKIP_WHITESPACE ();
960 if (*input_line_pointer == ',')
961 ++input_line_pointer;
962
963 SKIP_WHITESPACE ();
964 if (*input_line_pointer == '#' || *input_line_pointer == '@')
965 ++input_line_pointer;
966
967 typename = input_line_pointer;
968 c = get_symbol_end ();
969
970 type = 0;
971 if (strcmp (typename, "function") == 0
972 || strcmp (typename, "STT_FUNC") == 0)
973 type = BSF_FUNCTION;
974 else if (strcmp (typename, "object") == 0
975 || strcmp (typename, "STT_OBJECT") == 0)
976 type = BSF_OBJECT;
977 else
978 as_bad ("ignoring unrecognized symbol type \"%s\"", typename);
979
980 *input_line_pointer = c;
981
982 sym->bsym->flags |= type;
983
984 demand_empty_rest_of_line ();
985 }
986
987 static void
988 obj_elf_ident (ignore)
989 int ignore;
990 {
991 static segT comment_section;
992 segT old_section = now_seg;
993 int old_subsection = now_subseg;
994
995 if (!comment_section)
996 {
997 char *p;
998 comment_section = subseg_new (".comment", 0);
999 bfd_set_section_flags (stdoutput, comment_section,
1000 SEC_READONLY | SEC_HAS_CONTENTS);
1001 p = frag_more (1);
1002 *p = 0;
1003 }
1004 else
1005 subseg_set (comment_section, 0);
1006 stringer (1);
1007 subseg_set (old_section, old_subsection);
1008 }
1009
1010 #ifdef INIT_STAB_SECTION
1011
1012 /* The first entry in a .stabs section is special. */
1013
1014 void
1015 obj_elf_init_stab_section (seg)
1016 segT seg;
1017 {
1018 char *file;
1019 char *p;
1020 char *stabstr_name;
1021 unsigned int stroff;
1022
1023 /* Force the section to align to a longword boundary. Without this,
1024 UnixWare ar crashes. */
1025 bfd_set_section_alignment (stdoutput, seg, 2);
1026
1027 /* Make space for this first symbol. */
1028 p = frag_more (12);
1029 /* Zero it out. */
1030 memset (p, 0, 12);
1031 as_where (&file, (unsigned int *) NULL);
1032 stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
1033 strcpy (stabstr_name, segment_name (seg));
1034 strcat (stabstr_name, "str");
1035 stroff = get_stab_string_offset (file, stabstr_name);
1036 know (stroff == 1);
1037 md_number_to_chars (p, stroff, 4);
1038 seg_info (seg)->stabu.p = p;
1039 }
1040
1041 #endif
1042
1043 /* Fill in the counts in the first entry in a .stabs section. */
1044
1045 static void
1046 adjust_stab_sections (abfd, sec, xxx)
1047 bfd *abfd;
1048 asection *sec;
1049 PTR xxx;
1050 {
1051 char *name;
1052 asection *strsec;
1053 char *p;
1054 int strsz, nsyms;
1055
1056 if (strncmp (".stab", sec->name, 5))
1057 return;
1058 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1059 return;
1060
1061 name = (char *) alloca (strlen (sec->name) + 4);
1062 strcpy (name, sec->name);
1063 strcat (name, "str");
1064 strsec = bfd_get_section_by_name (abfd, name);
1065 if (strsec)
1066 strsz = bfd_section_size (abfd, strsec);
1067 else
1068 strsz = 0;
1069 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1070
1071 p = seg_info (sec)->stabu.p;
1072 assert (p != 0);
1073
1074 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
1075 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
1076 }
1077
1078 #ifdef NEED_ECOFF_DEBUG
1079
1080 /* This function is called by the ECOFF code. It is supposed to
1081 record the external symbol information so that the backend can
1082 write it out correctly. The ELF backend doesn't actually handle
1083 this at the moment, so we do it ourselves. We save the information
1084 in the symbol. */
1085
1086 void
1087 elf_ecoff_set_ext (sym, ext)
1088 symbolS *sym;
1089 struct ecoff_extr *ext;
1090 {
1091 sym->bsym->udata.p = (PTR) ext;
1092 }
1093
1094 /* This function is called by bfd_ecoff_debug_externals. It is
1095 supposed to *EXT to the external symbol information, and return
1096 whether the symbol should be used at all. */
1097
1098 static boolean
1099 elf_get_extr (sym, ext)
1100 asymbol *sym;
1101 EXTR *ext;
1102 {
1103 if (sym->udata.p == NULL)
1104 return false;
1105 *ext = *(EXTR *) sym->udata.p;
1106 return true;
1107 }
1108
1109 /* This function is called by bfd_ecoff_debug_externals. It has
1110 nothing to do for ELF. */
1111
1112 /*ARGSUSED*/
1113 static void
1114 elf_set_index (sym, indx)
1115 asymbol *sym;
1116 bfd_size_type indx;
1117 {
1118 }
1119
1120 #endif /* NEED_ECOFF_DEBUG */
1121
1122 void
1123 elf_frob_symbol (symp, puntp)
1124 symbolS *symp;
1125 int *puntp;
1126 {
1127 #ifdef NEED_ECOFF_DEBUG
1128 if (ECOFF_DEBUGGING)
1129 ecoff_frob_symbol (symp);
1130 #endif
1131
1132 if (symp->sy_obj)
1133 {
1134 switch (symp->sy_obj->X_op)
1135 {
1136 case O_subtract:
1137 S_SET_SIZE (symp,
1138 (S_GET_VALUE (symp->sy_obj->X_add_symbol)
1139 + symp->sy_obj->X_add_number
1140 - S_GET_VALUE (symp->sy_obj->X_op_symbol)));
1141 break;
1142 case O_constant:
1143 S_SET_SIZE (symp,
1144 (S_GET_VALUE (symp->sy_obj->X_add_symbol)
1145 + symp->sy_obj->X_add_number));
1146 break;
1147 default:
1148 as_bad (".size expression too complicated to fix up");
1149 break;
1150 }
1151 free (symp->sy_obj);
1152 symp->sy_obj = 0;
1153 }
1154
1155 /* Double check weak symbols. */
1156 if (symp->bsym->flags & BSF_WEAK)
1157 {
1158 if (S_IS_COMMON (symp))
1159 as_bad ("Symbol `%s' can not be both weak and common",
1160 S_GET_NAME (symp));
1161 }
1162 }
1163
1164 void
1165 elf_frob_file ()
1166 {
1167 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1168
1169 #ifdef elf_tc_final_processing
1170 elf_tc_final_processing ();
1171 #endif
1172
1173 #ifdef NEED_ECOFF_DEBUG
1174 if (ECOFF_DEBUGGING)
1175 /* Generate the ECOFF debugging information. */
1176 {
1177 const struct ecoff_debug_swap *debug_swap;
1178 struct ecoff_debug_info debug;
1179 char *buf;
1180 asection *sec;
1181
1182 debug_swap
1183 = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1184 know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1185 ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1186
1187 /* Set up the pointers in debug. */
1188 #define SET(ptr, offset, type) \
1189 debug.ptr = (type) (buf + debug.symbolic_header.offset)
1190
1191 SET (line, cbLineOffset, unsigned char *);
1192 SET (external_dnr, cbDnOffset, PTR);
1193 SET (external_pdr, cbPdOffset, PTR);
1194 SET (external_sym, cbSymOffset, PTR);
1195 SET (external_opt, cbOptOffset, PTR);
1196 SET (external_aux, cbAuxOffset, union aux_ext *);
1197 SET (ss, cbSsOffset, char *);
1198 SET (external_fdr, cbFdOffset, PTR);
1199 SET (external_rfd, cbRfdOffset, PTR);
1200 /* ssext and external_ext are set up just below. */
1201
1202 #undef SET
1203
1204 /* Set up the external symbols. */
1205 debug.ssext = debug.ssext_end = NULL;
1206 debug.external_ext = debug.external_ext_end = NULL;
1207 if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1208 elf_get_extr, elf_set_index))
1209 as_fatal ("Failed to set up debugging information: %s",
1210 bfd_errmsg (bfd_get_error ()));
1211
1212 sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1213 assert (sec != NULL);
1214
1215 know (stdoutput->output_has_begun == false);
1216
1217 /* We set the size of the section, call bfd_set_section_contents
1218 to force the ELF backend to allocate a file position, and then
1219 write out the data. FIXME: Is this really the best way to do
1220 this? */
1221 sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1222
1223 if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
1224 (file_ptr) 0, (bfd_size_type) 0))
1225 as_fatal ("Can't start writing .mdebug section: %s",
1226 bfd_errmsg (bfd_get_error ()));
1227
1228 know (stdoutput->output_has_begun == true);
1229 know (sec->filepos != 0);
1230
1231 if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1232 sec->filepos))
1233 as_fatal ("Could not write .mdebug section: %s",
1234 bfd_errmsg (bfd_get_error ()));
1235 }
1236 #endif /* NEED_ECOFF_DEBUG */
1237 }
1238
1239 const struct format_ops elf_format_ops =
1240 {
1241 bfd_target_elf_flavour,
1242 0,
1243 1,
1244 elf_frob_symbol,
1245 elf_frob_file,
1246 elf_s_get_size, elf_s_set_size,
1247 elf_s_get_align, elf_s_set_align,
1248 elf_copy_symbol_attributes,
1249 #ifdef NEED_ECOFF_DEBUG
1250 ecoff_generate_asm_lineno,
1251 ecoff_stab,
1252 #else
1253 0,
1254 0, /* process_stab */
1255 #endif
1256 elf_sec_sym_ok_for_reloc,
1257 elf_pop_insert,
1258 #ifdef NEED_ECOFF_DEBUG
1259 elf_ecoff_set_ext,
1260 #else
1261 0,
1262 #endif
1263 obj_read_begin_hook,
1264 obj_symbol_new_hook,
1265 };
This page took 0.058737 seconds and 5 git commands to generate.