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