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