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