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