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