* elf-bfd.h (struct bfd_elf_section_data): Add "group" and
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
CommitLineData
252b5132 1/* ELF object file format
8fd3e36b 2 Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
fa306131 3 Free Software Foundation, Inc.
252b5132
RH
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2,
10 or (at your option) any later version.
11
12 GAS is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
bf514e21 20 02111-1307, USA. */
252b5132
RH
21
22#define OBJ_HEADER "obj-elf.h"
23#include "as.h"
3882b010 24#include "safe-ctype.h"
252b5132
RH
25#include "subsegs.h"
26#include "obstack.h"
27
28#ifndef ECOFF_DEBUGGING
29#define ECOFF_DEBUGGING 0
30#else
31#define NEED_ECOFF_DEBUG
32#endif
33
34#ifdef NEED_ECOFF_DEBUG
35#include "ecoff.h"
36#endif
37
38#ifdef TC_ALPHA
39#include "elf/alpha.h"
40#endif
41
42#ifdef TC_MIPS
43#include "elf/mips.h"
44#endif
45
46#ifdef TC_PPC
47#include "elf/ppc.h"
48#endif
49
5b93d8bb
AM
50#ifdef TC_I370
51#include "elf/i370.h"
52#endif
53
252b5132
RH
54static bfd_vma elf_s_get_size PARAMS ((symbolS *));
55static void elf_s_set_size PARAMS ((symbolS *, bfd_vma));
56static bfd_vma elf_s_get_align PARAMS ((symbolS *));
57static void elf_s_set_align PARAMS ((symbolS *, bfd_vma));
5110c57e 58static void elf_s_set_other PARAMS ((symbolS *, int));
252b5132
RH
59static int elf_sec_sym_ok_for_reloc PARAMS ((asection *));
60static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
5110c57e
HPN
61static int elf_separate_stab_sections PARAMS ((void));
62static void elf_init_stab_section PARAMS ((segT));
252b5132
RH
63
64#ifdef NEED_ECOFF_DEBUG
65static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
66static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
67#endif
68
69static void obj_elf_line PARAMS ((int));
70void obj_elf_version PARAMS ((int));
71static void obj_elf_size PARAMS ((int));
72static void obj_elf_type PARAMS ((int));
73static void obj_elf_ident PARAMS ((int));
74static void obj_elf_weak PARAMS ((int));
75static void obj_elf_local PARAMS ((int));
2e13b764 76static void obj_elf_visibility PARAMS ((int));
8d28c9d7
AM
77static void obj_elf_change_section PARAMS ((char *, int, int, int, int));
78static int obj_elf_parse_section_letters PARAMS ((char *, size_t));
79static int obj_elf_section_word PARAMS ((char *, size_t));
6ce8b369 80static char *obj_elf_section_name PARAMS ((void));
8d28c9d7 81static int obj_elf_section_type PARAMS ((char *, size_t));
252b5132 82static void obj_elf_symver PARAMS ((int));
252b5132 83static void obj_elf_subsection PARAMS ((int));
9de8d8f1 84static void obj_elf_popsection PARAMS ((int));
252b5132
RH
85
86static const pseudo_typeS elf_pseudo_table[] =
87{
88 {"comm", obj_elf_common, 0},
9be1cda6 89 {"common", obj_elf_common, 1},
252b5132
RH
90 {"ident", obj_elf_ident, 0},
91 {"local", obj_elf_local, 0},
92 {"previous", obj_elf_previous, 0},
93 {"section", obj_elf_section, 0},
94 {"section.s", obj_elf_section, 0},
95 {"sect", obj_elf_section, 0},
96 {"sect.s", obj_elf_section, 0},
9de8d8f1
RH
97 {"pushsection", obj_elf_section, 1},
98 {"popsection", obj_elf_popsection, 0},
252b5132
RH
99 {"size", obj_elf_size, 0},
100 {"type", obj_elf_type, 0},
101 {"version", obj_elf_version, 0},
102 {"weak", obj_elf_weak, 0},
103
bf514e21 104 /* These define symbol visibility. */
2e13b764
NC
105 {"internal", obj_elf_visibility, STV_INTERNAL},
106 {"hidden", obj_elf_visibility, STV_HIDDEN},
107 {"protected", obj_elf_visibility, STV_PROTECTED},
108
252b5132
RH
109 /* These are used for stabs-in-elf configurations. */
110 {"line", obj_elf_line, 0},
111
112 /* This is a GNU extension to handle symbol versions. */
113 {"symver", obj_elf_symver, 0},
114
115 /* A GNU extension to change subsection only. */
116 {"subsection", obj_elf_subsection, 0},
117
118 /* These are GNU extensions to aid in garbage collecting C++ vtables. */
904a31bf
AM
119 {"vtable_inherit", (void (*) PARAMS ((int))) &obj_elf_vtable_inherit, 0},
120 {"vtable_entry", (void (*) PARAMS ((int))) &obj_elf_vtable_entry, 0},
252b5132 121
bf514e21 122 /* These are used for dwarf. */
252b5132
RH
123 {"2byte", cons, 2},
124 {"4byte", cons, 4},
125 {"8byte", cons, 8},
126
127 /* We need to trap the section changing calls to handle .previous. */
128 {"data", obj_elf_data, 0},
129 {"text", obj_elf_text, 0},
130
131 /* End sentinel. */
ab9da554 132 {NULL, NULL, 0},
252b5132
RH
133};
134
135static const pseudo_typeS ecoff_debug_pseudo_table[] =
136{
137#ifdef NEED_ECOFF_DEBUG
138 /* COFF style debugging information for ECOFF. .ln is not used; .loc
139 is used instead. */
140 { "def", ecoff_directive_def, 0 },
141 { "dim", ecoff_directive_dim, 0 },
142 { "endef", ecoff_directive_endef, 0 },
143 { "file", ecoff_directive_file, 0 },
144 { "scl", ecoff_directive_scl, 0 },
145 { "tag", ecoff_directive_tag, 0 },
146 { "val", ecoff_directive_val, 0 },
147
148 /* COFF debugging requires pseudo-ops .size and .type, but ELF
149 already has meanings for those. We use .esize and .etype
150 instead. These are only generated by gcc anyhow. */
151 { "esize", ecoff_directive_size, 0 },
152 { "etype", ecoff_directive_type, 0 },
153
154 /* ECOFF specific debugging information. */
155 { "begin", ecoff_directive_begin, 0 },
156 { "bend", ecoff_directive_bend, 0 },
157 { "end", ecoff_directive_end, 0 },
158 { "ent", ecoff_directive_ent, 0 },
159 { "fmask", ecoff_directive_fmask, 0 },
160 { "frame", ecoff_directive_frame, 0 },
161 { "loc", ecoff_directive_loc, 0 },
162 { "mask", ecoff_directive_mask, 0 },
163
164 /* Other ECOFF directives. */
165 { "extern", ecoff_directive_extern, 0 },
166
167 /* These are used on Irix. I don't know how to implement them. */
168 { "alias", s_ignore, 0 },
169 { "bgnb", s_ignore, 0 },
170 { "endb", s_ignore, 0 },
171 { "lab", s_ignore, 0 },
172 { "noalias", s_ignore, 0 },
173 { "verstamp", s_ignore, 0 },
174 { "vreg", s_ignore, 0 },
175#endif
176
ab9da554 177 {NULL, NULL, 0} /* end sentinel */
252b5132
RH
178};
179
180#undef NO_RELOC
181#include "aout/aout64.h"
182
183/* This is called when the assembler starts. */
184
185void
186elf_begin ()
187{
188 /* Add symbols for the known sections to the symbol table. */
189 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
190 TEXT_SECTION_NAME)));
191 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
192 DATA_SECTION_NAME)));
193 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
194 BSS_SECTION_NAME)));
195}
196
197void
198elf_pop_insert ()
199{
200 pop_insert (elf_pseudo_table);
201 if (ECOFF_DEBUGGING)
202 pop_insert (ecoff_debug_pseudo_table);
203}
204
205static bfd_vma
206elf_s_get_size (sym)
207 symbolS *sym;
208{
209 return S_GET_SIZE (sym);
210}
211
212static void
213elf_s_set_size (sym, sz)
214 symbolS *sym;
215 bfd_vma sz;
216{
217 S_SET_SIZE (sym, sz);
218}
219
220static bfd_vma
221elf_s_get_align (sym)
222 symbolS *sym;
223{
224 return S_GET_ALIGN (sym);
225}
226
227static void
228elf_s_set_align (sym, align)
229 symbolS *sym;
230 bfd_vma align;
231{
232 S_SET_ALIGN (sym, align);
233}
234
4c63da97
AM
235int
236elf_s_get_other (sym)
237 symbolS *sym;
238{
239 return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
240}
241
5110c57e
HPN
242static void
243elf_s_set_other (sym, other)
244 symbolS *sym;
245 int other;
246{
247 S_SET_OTHER (sym, other);
248}
249
252b5132
RH
250static int
251elf_sec_sym_ok_for_reloc (sec)
252 asection *sec;
253{
254 return obj_sec_sym_ok_for_reloc (sec);
255}
256
257void
258elf_file_symbol (s)
5110c57e 259 const char *s;
252b5132
RH
260{
261 symbolS *sym;
262
263 sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
49309057
ILT
264 symbol_set_frag (sym, &zero_address_frag);
265 symbol_get_bfdsym (sym)->flags |= BSF_FILE;
252b5132
RH
266
267 if (symbol_rootP != sym)
268 {
269 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
270 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
271#ifdef DEBUG
272 verify_symbol_chain (symbol_rootP, symbol_lastP);
273#endif
274 }
275
276#ifdef NEED_ECOFF_DEBUG
277 ecoff_new_file (s);
278#endif
279}
280
16b93d88 281void
9be1cda6
AS
282obj_elf_common (is_common)
283 int is_common;
252b5132
RH
284{
285 char *name;
286 char c;
287 char *p;
288 int temp, size;
289 symbolS *symbolP;
290 int have_align;
291
9be1cda6
AS
292 if (flag_mri && is_common)
293 {
294 s_mri_common (0);
295 return;
296 }
297
252b5132
RH
298 name = input_line_pointer;
299 c = get_symbol_end ();
300 /* just after name is now '\0' */
301 p = input_line_pointer;
302 *p = c;
303 SKIP_WHITESPACE ();
304 if (*input_line_pointer != ',')
305 {
6ce8b369 306 as_bad (_("expected comma after symbol-name"));
252b5132
RH
307 ignore_rest_of_line ();
308 return;
309 }
310 input_line_pointer++; /* skip ',' */
311 if ((temp = get_absolute_expression ()) < 0)
312 {
313 as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
314 ignore_rest_of_line ();
315 return;
316 }
317 size = temp;
318 *p = 0;
319 symbolP = symbol_find_or_make (name);
320 *p = c;
321 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
322 {
6ce8b369 323 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
252b5132
RH
324 ignore_rest_of_line ();
325 return;
326 }
327 if (S_GET_VALUE (symbolP) != 0)
328 {
ab9da554 329 if (S_GET_VALUE (symbolP) != (valueT) size)
252b5132 330 {
6ce8b369 331 as_warn (_("length of .comm \"%s\" is already %ld; not changed to %d"),
252b5132
RH
332 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
333 }
334 }
335 know (symbolP->sy_frag == &zero_address_frag);
336 if (*input_line_pointer != ',')
337 have_align = 0;
338 else
339 {
340 have_align = 1;
341 input_line_pointer++;
342 SKIP_WHITESPACE ();
343 }
344 if (! have_align || *input_line_pointer != '"')
345 {
346 if (! have_align)
347 temp = 0;
348 else
349 {
350 temp = get_absolute_expression ();
351 if (temp < 0)
352 {
353 temp = 0;
6ce8b369 354 as_warn (_("common alignment negative; 0 assumed"));
252b5132
RH
355 }
356 }
49309057 357 if (symbol_get_obj (symbolP)->local)
252b5132
RH
358 {
359 segT old_sec;
360 int old_subsec;
361 char *pfrag;
362 int align;
363
364 /* allocate_bss: */
365 old_sec = now_seg;
366 old_subsec = now_subseg;
367 if (temp)
368 {
369 /* convert to a power of 2 alignment */
370 for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
371 if (temp != 1)
372 {
6ce8b369 373 as_bad (_("common alignment not a power of 2"));
252b5132
RH
374 ignore_rest_of_line ();
375 return;
376 }
377 }
378 else
379 align = 0;
380 record_alignment (bss_section, align);
381 subseg_set (bss_section, 0);
382 if (align)
383 frag_align (align, 0, 0);
384 if (S_GET_SEGMENT (symbolP) == bss_section)
49309057
ILT
385 symbol_get_frag (symbolP)->fr_symbol = 0;
386 symbol_set_frag (symbolP, frag_now);
252b5132
RH
387 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
388 (offsetT) size, (char *) 0);
389 *pfrag = 0;
390 S_SET_SIZE (symbolP, size);
391 S_SET_SEGMENT (symbolP, bss_section);
392 S_CLEAR_EXTERNAL (symbolP);
393 subseg_set (old_sec, old_subsec);
394 }
395 else
396 {
397 allocate_common:
398 S_SET_VALUE (symbolP, (valueT) size);
399 S_SET_ALIGN (symbolP, temp);
400 S_SET_EXTERNAL (symbolP);
401 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
402 }
403 }
404 else
405 {
406 input_line_pointer++;
407 /* @@ Some use the dot, some don't. Can we get some consistency?? */
408 if (*input_line_pointer == '.')
409 input_line_pointer++;
410 /* @@ Some say data, some say bss. */
411 if (strncmp (input_line_pointer, "bss\"", 4)
412 && strncmp (input_line_pointer, "data\"", 5))
413 {
414 while (*--input_line_pointer != '"')
415 ;
416 input_line_pointer--;
417 goto bad_common_segment;
418 }
419 while (*input_line_pointer++ != '"')
420 ;
421 goto allocate_common;
422 }
423
49309057 424 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
252b5132
RH
425
426 demand_empty_rest_of_line ();
427 return;
428
429 {
430 bad_common_segment:
431 p = input_line_pointer;
432 while (*p && *p != '\n')
433 p++;
434 c = *p;
435 *p = '\0';
436 as_bad (_("bad .common segment %s"), input_line_pointer + 1);
437 *p = c;
438 input_line_pointer = p;
439 ignore_rest_of_line ();
440 return;
441 }
442}
443
444static void
445obj_elf_local (ignore)
ab9da554 446 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
447{
448 char *name;
449 int c;
450 symbolS *symbolP;
451
452 do
453 {
454 name = input_line_pointer;
455 c = get_symbol_end ();
456 symbolP = symbol_find_or_make (name);
457 *input_line_pointer = c;
458 SKIP_WHITESPACE ();
459 S_CLEAR_EXTERNAL (symbolP);
49309057 460 symbol_get_obj (symbolP)->local = 1;
252b5132
RH
461 if (c == ',')
462 {
463 input_line_pointer++;
464 SKIP_WHITESPACE ();
465 if (*input_line_pointer == '\n')
466 c = '\n';
467 }
468 }
469 while (c == ',');
470 demand_empty_rest_of_line ();
471}
472
473static void
474obj_elf_weak (ignore)
ab9da554 475 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
476{
477 char *name;
478 int c;
479 symbolS *symbolP;
480
481 do
482 {
483 name = input_line_pointer;
484 c = get_symbol_end ();
485 symbolP = symbol_find_or_make (name);
486 *input_line_pointer = c;
487 SKIP_WHITESPACE ();
488 S_SET_WEAK (symbolP);
49309057 489 symbol_get_obj (symbolP)->local = 1;
252b5132
RH
490 if (c == ',')
491 {
492 input_line_pointer++;
493 SKIP_WHITESPACE ();
494 if (*input_line_pointer == '\n')
495 c = '\n';
496 }
497 }
498 while (c == ',');
499 demand_empty_rest_of_line ();
500}
501
2e13b764
NC
502static void
503obj_elf_visibility (visibility)
504 int visibility;
505{
506 char *name;
507 int c;
508 symbolS *symbolP;
509 asymbol *bfdsym;
510 elf_symbol_type *elfsym;
511
512 do
513 {
514 name = input_line_pointer;
515 c = get_symbol_end ();
516 symbolP = symbol_find_or_make (name);
517 *input_line_pointer = c;
fa306131 518
2e13b764 519 SKIP_WHITESPACE ();
fa306131 520
2e13b764
NC
521 bfdsym = symbol_get_bfdsym (symbolP);
522 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
fa306131 523
2e13b764 524 assert (elfsym);
fa306131 525
2e13b764 526 elfsym->internal_elf_sym.st_other = visibility;
fa306131 527
2e13b764
NC
528 if (c == ',')
529 {
530 input_line_pointer ++;
fa306131 531
2e13b764 532 SKIP_WHITESPACE ();
fa306131 533
2e13b764
NC
534 if (*input_line_pointer == '\n')
535 c = '\n';
536 }
537 }
538 while (c == ',');
fa306131 539
2e13b764
NC
540 demand_empty_rest_of_line ();
541}
542
252b5132
RH
543static segT previous_section;
544static int previous_subsection;
545
9de8d8f1
RH
546struct section_stack
547{
548 struct section_stack *next;
549 segT seg, prev_seg;
550 int subseg, prev_subseg;
551};
552
553static struct section_stack *section_stack;
554
252b5132
RH
555/* Handle the .section pseudo-op. This code supports two different
556 syntaxes.
557
558 The first is found on Solaris, and looks like
559 .section ".sec1",#alloc,#execinstr,#write
560 Here the names after '#' are the SHF_* flags to turn on for the
561 section. I'm not sure how it determines the SHT_* type (BFD
562 doesn't really give us control over the type, anyhow).
563
564 The second format is found on UnixWare, and probably most SVR4
565 machines, and looks like
566 .section .sec1,"a",@progbits
567 The quoted string may contain any combination of a, w, x, and
568 represents the SHF_* flags to turn on for the section. The string
569 beginning with '@' can be progbits or nobits. There should be
570 other possibilities, but I don't know what they are. In any case,
571 BFD doesn't really let us set the section type. */
572
573/* Certain named sections have particular defined types, listed on p.
574 4-19 of the ABI. */
575struct special_section
576{
577 const char *name;
578 int type;
579 int attributes;
580};
581
9de8d8f1 582static struct special_section const special_sections[] =
252b5132
RH
583{
584 { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
585 { ".comment", SHT_PROGBITS, 0 },
586 { ".data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
587 { ".data1", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
588 { ".debug", SHT_PROGBITS, 0 },
589 { ".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
590 { ".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
591 { ".line", SHT_PROGBITS, 0 },
592 { ".note", SHT_NOTE, 0 },
593 { ".rodata", SHT_PROGBITS, SHF_ALLOC },
594 { ".rodata1", SHT_PROGBITS, SHF_ALLOC },
595 { ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
596
597#ifdef ELF_TC_SPECIAL_SECTIONS
598 ELF_TC_SPECIAL_SECTIONS
599#endif
600
601#if 0
602 /* The following section names are special, but they can not
603 reasonably appear in assembler code. Some of the attributes are
604 processor dependent. */
605 { ".dynamic", SHT_DYNAMIC, SHF_ALLOC /* + SHF_WRITE */ },
606 { ".dynstr", SHT_STRTAB, SHF_ALLOC },
607 { ".dynsym", SHT_DYNSYM, SHF_ALLOC },
608 { ".got", SHT_PROGBITS, 0 },
609 { ".hash", SHT_HASH, SHF_ALLOC },
610 { ".interp", SHT_PROGBITS, /* SHF_ALLOC */ },
611 { ".plt", SHT_PROGBITS, 0 },
612 { ".shstrtab",SHT_STRTAB, 0 },
613 { ".strtab", SHT_STRTAB, /* SHF_ALLOC */ },
614 { ".symtab", SHT_SYMTAB, /* SHF_ALLOC */ },
615#endif
616
617 { NULL, 0, 0 }
618};
619
8d28c9d7 620static void
f5fa8ca2 621obj_elf_change_section (name, type, attr, entsize, push)
9de8d8f1 622 char *name;
f5fa8ca2 623 int type, attr, entsize, push;
252b5132 624{
742f45cf 625 asection *old_sec;
252b5132 626 segT sec;
742f45cf
AM
627 flagword flags;
628 int i;
252b5132
RH
629
630#ifdef md_flush_pending_output
631 md_flush_pending_output ();
632#endif
633
9de8d8f1
RH
634 /* Switch to the section, creating it if necessary. */
635 if (push)
636 {
637 struct section_stack *elt;
638 elt = xmalloc (sizeof (struct section_stack));
639 elt->next = section_stack;
640 elt->seg = now_seg;
641 elt->prev_seg = previous_section;
642 elt->subseg = now_subseg;
643 elt->prev_subseg = previous_subsection;
644 section_stack = elt;
645 }
646 previous_section = now_seg;
647 previous_subsection = now_subseg;
648
742f45cf 649 old_sec = bfd_get_section_by_name (stdoutput, name);
9de8d8f1
RH
650 sec = subseg_new (name, 0);
651
742f45cf
AM
652 /* See if this is one of the special sections. */
653 for (i = 0; special_sections[i].name != NULL; i++)
654 if (strcmp (name, special_sections[i].name) == 0)
655 {
656 if (type == SHT_NULL)
657 type = special_sections[i].type;
658 else if (type != special_sections[i].type)
659 {
660 if (old_sec == NULL)
9de8d8f1 661 {
6ce8b369 662 as_warn (_("setting incorrect section type for %s"), name);
742f45cf
AM
663 }
664 else
665 {
6ce8b369 666 as_warn (_("ignoring incorrect section type for %s"), name);
742f45cf 667 type = special_sections[i].type;
9de8d8f1 668 }
9de8d8f1 669 }
742f45cf
AM
670 if ((attr &~ special_sections[i].attributes) != 0
671 && old_sec == NULL)
672 {
673 /* As a GNU extension, we permit a .note section to be
674 allocatable. If the linker sees an allocateable .note
675 section, it will create a PT_NOTE segment in the output
676 file. */
677 if (strcmp (name, ".note") != 0
678 || attr != SHF_ALLOC)
6ce8b369 679 as_warn (_("setting incorrect section attributes for %s"),
742f45cf
AM
680 name);
681 }
682 attr |= special_sections[i].attributes;
683 break;
684 }
685
686 /* Convert ELF type and flags to BFD flags. */
687 flags = (SEC_RELOC
688 | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
689 | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
690 | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
f5fa8ca2
JJ
691 | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
692 | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
693 | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0));
9de8d8f1 694#ifdef md_elf_section_flags
742f45cf 695 flags = md_elf_section_flags (flags, attr, type);
9de8d8f1
RH
696#endif
697
742f45cf
AM
698 if (old_sec == NULL)
699 {
700 symbolS *secsym;
701
9de8d8f1
RH
702 /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
703 if (type == SHT_NOBITS)
704 seg_info (sec)->bss = 1;
705
706 bfd_set_section_flags (stdoutput, sec, flags);
f5fa8ca2
JJ
707 if (flags & SEC_MERGE)
708 sec->entsize = entsize;
9de8d8f1
RH
709
710 /* Add a symbol for this section to the symbol table. */
711 secsym = symbol_find (name);
712 if (secsym != NULL)
713 symbol_set_bfdsym (secsym, sec->symbol);
714 else
715 symbol_table_insert (section_symbol (sec));
716 }
742f45cf
AM
717 else if (attr != 0)
718 {
719 /* If section attributes are specified the second time we see a
720 particular section, then check that they are the same as we
721 saw the first time. */
722 if ((old_sec->flags ^ flags)
723 & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
f5fa8ca2 724 | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS))
6ce8b369 725 as_warn (_("ignoring changed section attributes for %s"), name);
0e1a166b 726 else if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
6ce8b369 727 as_warn (_("ignoring changed section entity size for %s"), name);
742f45cf 728 }
9de8d8f1
RH
729
730#ifdef md_elf_section_change_hook
742f45cf 731 md_elf_section_change_hook ();
9de8d8f1
RH
732#endif
733}
734
8d28c9d7 735static int
9de8d8f1
RH
736obj_elf_parse_section_letters (str, len)
737 char *str;
738 size_t len;
739{
740 int attr = 0;
741
742 while (len > 0)
743 {
744 switch (*str)
745 {
746 case 'a':
747 attr |= SHF_ALLOC;
748 break;
749 case 'w':
750 attr |= SHF_WRITE;
751 break;
752 case 'x':
753 attr |= SHF_EXECINSTR;
754 break;
9469ddf0 755 case 'M':
f5fa8ca2
JJ
756 attr |= SHF_MERGE;
757 break;
9469ddf0 758 case 'S':
f5fa8ca2
JJ
759 attr |= SHF_STRINGS;
760 break;
34105363
L
761 /* Compatibility. */
762 case 'm':
763 if (*(str - 1) == 'a')
764 {
765 attr |= SHF_MERGE;
766 if (len > 1 && str[1] == 's')
767 {
768 attr |= SHF_STRINGS;
769 str++, len--;
770 }
771 break;
772 }
9de8d8f1
RH
773 default:
774 {
6ce8b369 775 char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S");
9de8d8f1
RH
776#ifdef md_elf_section_letter
777 int md_attr = md_elf_section_letter (*str, &bad_msg);
778 if (md_attr >= 0)
779 attr |= md_attr;
780 else
781#endif
782 {
4c63da97 783 as_warn ("%s", bad_msg);
9de8d8f1
RH
784 attr = -1;
785 }
786 }
787 break;
788 }
789 str++, len--;
790 }
791
792 return attr;
793}
794
8d28c9d7 795static int
9de8d8f1
RH
796obj_elf_section_word (str, len)
797 char *str;
798 size_t len;
799{
800 if (len == 5 && strncmp (str, "write", 5) == 0)
801 return SHF_WRITE;
802 if (len == 5 && strncmp (str, "alloc", 5) == 0)
803 return SHF_ALLOC;
804 if (len == 9 && strncmp (str, "execinstr", 9) == 0)
805 return SHF_EXECINSTR;
806
807#ifdef md_elf_section_word
808 {
809 int md_attr = md_elf_section_word (str, len);
810 if (md_attr >= 0)
811 return md_attr;
812 }
813#endif
814
6ce8b369 815 as_warn (_("unrecognized section attribute"));
9de8d8f1
RH
816 return 0;
817}
818
8d28c9d7 819static int
9de8d8f1
RH
820obj_elf_section_type (str, len)
821 char *str;
822 size_t len;
823{
824 if (len == 8 && strncmp (str, "progbits", 8) == 0)
825 return SHT_PROGBITS;
826 if (len == 6 && strncmp (str, "nobits", 6) == 0)
827 return SHT_NOBITS;
828
829#ifdef md_elf_section_type
830 {
831 int md_type = md_elf_section_type (str, len);
832 if (md_type >= 0)
833 return md_type;
834 }
835#endif
836
6ce8b369 837 as_warn (_("unrecognized section type"));
9de8d8f1
RH
838 return 0;
839}
840
6ce8b369
AM
841/* Get name of section. */
842static char *
843obj_elf_section_name ()
844{
845 char *name;
846
847 SKIP_WHITESPACE ();
848 if (*input_line_pointer == '"')
849 {
850 int dummy;
851
852 name = demand_copy_C_string (&dummy);
853 if (name == NULL)
854 {
855 ignore_rest_of_line ();
856 return NULL;
857 }
858 }
859 else
860 {
861 char *end = input_line_pointer;
862
863 while (0 == strchr ("\n\t,; ", *end))
864 end++;
865 if (end == input_line_pointer)
866 {
867 as_warn (_("missing name"));
868 ignore_rest_of_line ();
869 return NULL;
870 }
871
872 name = xmalloc (end - input_line_pointer + 1);
873 memcpy (name, input_line_pointer, end - input_line_pointer);
874 name[end - input_line_pointer] = '\0';
875 input_line_pointer = end;
876 }
877 SKIP_WHITESPACE ();
878 return name;
879}
880
9de8d8f1
RH
881void
882obj_elf_section (push)
883 int push;
884{
6ce8b369 885 char *name, *beg;
9de8d8f1 886 int type, attr, dummy;
f5fa8ca2 887 int entsize;
9de8d8f1 888
5b93d8bb 889#ifndef TC_I370
252b5132
RH
890 if (flag_mri)
891 {
892 char mri_type;
893
9de8d8f1 894#ifdef md_flush_pending_output
60bcf0fa 895 md_flush_pending_output ();
9de8d8f1
RH
896#endif
897
252b5132
RH
898 previous_section = now_seg;
899 previous_subsection = now_subseg;
900
901 s_mri_sect (&mri_type);
902
903#ifdef md_elf_section_change_hook
904 md_elf_section_change_hook ();
905#endif
906
907 return;
908 }
5b93d8bb 909#endif /* ! defined (TC_I370) */
252b5132 910
6ce8b369
AM
911 name = obj_elf_section_name ();
912 if (name == NULL)
913 return;
252b5132
RH
914 type = SHT_NULL;
915 attr = 0;
f5fa8ca2 916 entsize = 0;
252b5132
RH
917
918 if (*input_line_pointer == ',')
919 {
920 /* Skip the comma. */
921 ++input_line_pointer;
252b5132
RH
922 SKIP_WHITESPACE ();
923
924 if (*input_line_pointer == '"')
925 {
9de8d8f1
RH
926 beg = demand_copy_C_string (&dummy);
927 if (beg == NULL)
252b5132 928 {
9de8d8f1
RH
929 ignore_rest_of_line ();
930 return;
252b5132 931 }
9de8d8f1 932 attr |= obj_elf_parse_section_letters (beg, strlen (beg));
252b5132
RH
933
934 SKIP_WHITESPACE ();
935 if (*input_line_pointer == ',')
936 {
9de8d8f1 937 char c;
252b5132
RH
938 ++input_line_pointer;
939 SKIP_WHITESPACE ();
9de8d8f1
RH
940 c = *input_line_pointer;
941 if (c == '"')
252b5132 942 {
9de8d8f1
RH
943 beg = demand_copy_C_string (&dummy);
944 if (beg == NULL)
252b5132 945 {
9de8d8f1
RH
946 ignore_rest_of_line ();
947 return;
252b5132 948 }
9de8d8f1 949 type = obj_elf_section_type (beg, strlen (beg));
9de8d8f1
RH
950 }
951 else if (c == '@' || c == '%')
952 {
953 beg = ++input_line_pointer;
954 c = get_symbol_end ();
955 *input_line_pointer = c;
956 type = obj_elf_section_type (beg, input_line_pointer - beg);
252b5132
RH
957 }
958 }
f5fa8ca2
JJ
959
960 SKIP_WHITESPACE ();
6ce8b369 961 if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
f5fa8ca2
JJ
962 {
963 ++input_line_pointer;
964 SKIP_WHITESPACE ();
965 entsize = get_absolute_expression ();
6ce8b369 966 SKIP_WHITESPACE ();
f5fa8ca2
JJ
967 if (entsize < 0)
968 {
6ce8b369 969 as_warn (_("invalid merge entity size"));
f5fa8ca2
JJ
970 attr &= ~SHF_MERGE;
971 entsize = 0;
972 }
973 }
6ce8b369
AM
974 else if ((attr & SHF_MERGE) != 0)
975 {
976 as_warn (_("entity size for SHF_MERGE not specified"));
977 attr &= ~SHF_MERGE;
978 }
252b5132
RH
979 }
980 else
981 {
982 do
983 {
9de8d8f1
RH
984 char c;
985
252b5132
RH
986 SKIP_WHITESPACE ();
987 if (*input_line_pointer != '#')
988 {
6ce8b369 989 as_warn (_("character following name is not '#'"));
252b5132
RH
990 ignore_rest_of_line ();
991 return;
992 }
9de8d8f1
RH
993 beg = ++input_line_pointer;
994 c = get_symbol_end ();
995 *input_line_pointer = c;
996
997 attr |= obj_elf_section_word (beg, input_line_pointer - beg);
998
252b5132
RH
999 SKIP_WHITESPACE ();
1000 }
1001 while (*input_line_pointer++ == ',');
1002 --input_line_pointer;
1003 }
1004 }
1005
252b5132 1006 demand_empty_rest_of_line ();
9de8d8f1 1007
f5fa8ca2 1008 obj_elf_change_section (name, type, attr, entsize, push);
252b5132
RH
1009}
1010
1011/* Change to the .data section. */
1012
16b93d88 1013void
252b5132
RH
1014obj_elf_data (i)
1015 int i;
1016{
1017#ifdef md_flush_pending_output
1018 md_flush_pending_output ();
1019#endif
1020
1021 previous_section = now_seg;
1022 previous_subsection = now_subseg;
1023 s_data (i);
1024
1025#ifdef md_elf_section_change_hook
1026 md_elf_section_change_hook ();
1027#endif
1028}
1029
1030/* Change to the .text section. */
1031
16b93d88 1032void
252b5132
RH
1033obj_elf_text (i)
1034 int i;
1035{
1036#ifdef md_flush_pending_output
1037 md_flush_pending_output ();
1038#endif
1039
1040 previous_section = now_seg;
1041 previous_subsection = now_subseg;
1042 s_text (i);
1043
1044#ifdef md_elf_section_change_hook
1045 md_elf_section_change_hook ();
1046#endif
1047}
1048
1049static void
1050obj_elf_subsection (ignore)
ab9da554 1051 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1052{
1053 register int temp;
1054
1055#ifdef md_flush_pending_output
1056 md_flush_pending_output ();
1057#endif
1058
1059 previous_section = now_seg;
1060 previous_subsection = now_subseg;
1061
1062 temp = get_absolute_expression ();
1063 subseg_set (now_seg, (subsegT) temp);
1064 demand_empty_rest_of_line ();
1065
1066#ifdef md_elf_section_change_hook
1067 md_elf_section_change_hook ();
1068#endif
1069}
1070
1071/* This can be called from the processor backends if they change
1072 sections. */
1073
1074void
1075obj_elf_section_change_hook ()
1076{
1077 previous_section = now_seg;
1078 previous_subsection = now_subseg;
1079}
1080
1081void
1082obj_elf_previous (ignore)
ab9da554 1083 int ignore ATTRIBUTE_UNUSED;
252b5132 1084{
9de8d8f1
RH
1085 segT new_section;
1086 int new_subsection;
1087
252b5132
RH
1088 if (previous_section == 0)
1089 {
6ce8b369 1090 as_warn (_(".previous without corresponding .section; ignored"));
252b5132
RH
1091 return;
1092 }
1093
1094#ifdef md_flush_pending_output
1095 md_flush_pending_output ();
1096#endif
1097
9de8d8f1
RH
1098 new_section = previous_section;
1099 new_subsection = previous_subsection;
1100 previous_section = now_seg;
1101 previous_subsection = now_subseg;
1102 subseg_set (new_section, new_subsection);
1103
1104#ifdef md_elf_section_change_hook
1105 md_elf_section_change_hook ();
1106#endif
1107}
1108
1109static void
1110obj_elf_popsection (xxx)
ab9da554 1111 int xxx ATTRIBUTE_UNUSED;
9de8d8f1
RH
1112{
1113 struct section_stack *top = section_stack;
1114
1115 if (top == NULL)
1116 {
6ce8b369 1117 as_warn (_(".popsection without corresponding .pushsection; ignored"));
9de8d8f1
RH
1118 return;
1119 }
1120
1121#ifdef md_flush_pending_output
1122 md_flush_pending_output ();
1123#endif
1124
1125 section_stack = top->next;
1126 previous_section = top->prev_seg;
1127 previous_subsection = top->prev_subseg;
1128 subseg_set (top->seg, top->subseg);
1129 free (top);
252b5132
RH
1130
1131#ifdef md_elf_section_change_hook
1132 md_elf_section_change_hook ();
1133#endif
1134}
1135
1136static void
1137obj_elf_line (ignore)
ab9da554 1138 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1139{
1140 /* Assume delimiter is part of expression. BSD4.2 as fails with
bf514e21 1141 delightful bug, so we are not being incompatible here. */
252b5132
RH
1142 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
1143 demand_empty_rest_of_line ();
1144}
1145
1146/* This handles the .symver pseudo-op, which is used to specify a
1147 symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
1148 SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
1149 pseudo-op causes the assembler to emit a symbol named SYMVERNAME
1150 with the same value as the symbol NAME. */
1151
1152static void
1153obj_elf_symver (ignore)
ab9da554 1154 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1155{
1156 char *name;
1157 char c;
468cced8 1158 char old_lexat;
252b5132
RH
1159 symbolS *sym;
1160
1161 name = input_line_pointer;
1162 c = get_symbol_end ();
1163
1164 sym = symbol_find_or_make (name);
1165
1166 *input_line_pointer = c;
1167
252b5132
RH
1168 SKIP_WHITESPACE ();
1169 if (*input_line_pointer != ',')
1170 {
1171 as_bad (_("expected comma after name in .symver"));
1172 ignore_rest_of_line ();
1173 return;
1174 }
1175
1176 ++input_line_pointer;
1177 name = input_line_pointer;
468cced8
AM
1178
1179 /* Temporarily include '@' in symbol names. */
1180 old_lexat = lex_type[(unsigned char) '@'];
1181 lex_type[(unsigned char) '@'] |= LEX_NAME;
1182 c = get_symbol_end ();
1183 lex_type[(unsigned char) '@'] = old_lexat;
252b5132 1184
339681c0
L
1185 if (symbol_get_obj (sym)->versioned_name == NULL)
1186 {
1187 symbol_get_obj (sym)->versioned_name = xstrdup (name);
252b5132 1188
339681c0 1189 *input_line_pointer = c;
252b5132 1190
6f620856
L
1191 if (strchr (symbol_get_obj (sym)->versioned_name,
1192 ELF_VER_CHR) == NULL)
339681c0
L
1193 {
1194 as_bad (_("missing version name in `%s' for symbol `%s'"),
1195 symbol_get_obj (sym)->versioned_name,
1196 S_GET_NAME (sym));
1197 ignore_rest_of_line ();
1198 return;
1199 }
1200 }
1201 else
252b5132 1202 {
339681c0
L
1203 if (strcmp (symbol_get_obj (sym)->versioned_name, name))
1204 {
1205 as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"),
1206 name, symbol_get_obj (sym)->versioned_name,
1207 S_GET_NAME (sym));
1208 ignore_rest_of_line ();
1209 return;
1210 }
1211
1212 *input_line_pointer = c;
252b5132
RH
1213 }
1214
1215 demand_empty_rest_of_line ();
1216}
1217
1218/* This handles the .vtable_inherit pseudo-op, which is used to indicate
1219 to the linker the hierarchy in which a particular table resides. The
1220 syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
1221
904a31bf 1222struct fix *
252b5132 1223obj_elf_vtable_inherit (ignore)
ab9da554 1224 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1225{
1226 char *cname, *pname;
1227 symbolS *csym, *psym;
1228 char c, bad = 0;
1229
1230 if (*input_line_pointer == '#')
1231 ++input_line_pointer;
1232
1233 cname = input_line_pointer;
1234 c = get_symbol_end ();
1235 csym = symbol_find (cname);
1236
1237 /* GCFIXME: should check that we don't have two .vtable_inherits for
1238 the same child symbol. Also, we can currently only do this if the
1239 child symbol is already exists and is placed in a fragment. */
1240
49309057 1241 if (csym == NULL || symbol_get_frag (csym) == NULL)
252b5132
RH
1242 {
1243 as_bad ("expected `%s' to have already been set for .vtable_inherit",
1244 cname);
1245 bad = 1;
1246 }
1247
1248 *input_line_pointer = c;
1249
1250 SKIP_WHITESPACE ();
1251 if (*input_line_pointer != ',')
1252 {
1253 as_bad ("expected comma after name in .vtable_inherit");
1254 ignore_rest_of_line ();
904a31bf 1255 return NULL;
252b5132
RH
1256 }
1257
1258 ++input_line_pointer;
1259 SKIP_WHITESPACE ();
1260
1261 if (*input_line_pointer == '#')
1262 ++input_line_pointer;
1263
1264 if (input_line_pointer[0] == '0'
1265 && (input_line_pointer[1] == '\0'
3882b010 1266 || ISSPACE (input_line_pointer[1])))
252b5132
RH
1267 {
1268 psym = section_symbol (absolute_section);
1269 ++input_line_pointer;
1270 }
1271 else
1272 {
1273 pname = input_line_pointer;
1274 c = get_symbol_end ();
1275 psym = symbol_find_or_make (pname);
1276 *input_line_pointer = c;
1277 }
1278
1279 demand_empty_rest_of_line ();
1280
1281 if (bad)
904a31bf 1282 return NULL;
252b5132 1283
49309057 1284 assert (symbol_get_value_expression (csym)->X_op == O_constant);
904a31bf
AM
1285 return fix_new (symbol_get_frag (csym),
1286 symbol_get_value_expression (csym)->X_add_number,
1287 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
252b5132 1288}
fa306131 1289
252b5132
RH
1290/* This handles the .vtable_entry pseudo-op, which is used to indicate
1291 to the linker that a vtable slot was used. The syntax is
1292 ".vtable_entry tablename, offset". */
1293
904a31bf 1294struct fix *
252b5132 1295obj_elf_vtable_entry (ignore)
ab9da554 1296 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1297{
1298 char *name;
1299 symbolS *sym;
1300 offsetT offset;
1301 char c;
1302
1303 if (*input_line_pointer == '#')
1304 ++input_line_pointer;
1305
1306 name = input_line_pointer;
1307 c = get_symbol_end ();
1308 sym = symbol_find_or_make (name);
1309 *input_line_pointer = c;
1310
1311 SKIP_WHITESPACE ();
1312 if (*input_line_pointer != ',')
1313 {
1314 as_bad ("expected comma after name in .vtable_entry");
1315 ignore_rest_of_line ();
904a31bf 1316 return NULL;
252b5132
RH
1317 }
1318
1319 ++input_line_pointer;
1320 if (*input_line_pointer == '#')
1321 ++input_line_pointer;
1322
1323 offset = get_absolute_expression ();
1324
252b5132 1325 demand_empty_rest_of_line ();
904a31bf
AM
1326
1327 return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
1328 BFD_RELOC_VTABLE_ENTRY);
252b5132
RH
1329}
1330
1331void
4c63da97 1332elf_obj_read_begin_hook ()
252b5132
RH
1333{
1334#ifdef NEED_ECOFF_DEBUG
1335 if (ECOFF_DEBUGGING)
1336 ecoff_read_begin_hook ();
1337#endif
1338}
1339
1340void
4c63da97 1341elf_obj_symbol_new_hook (symbolP)
252b5132
RH
1342 symbolS *symbolP;
1343{
49309057
ILT
1344 struct elf_obj_sy *sy_obj;
1345
1346 sy_obj = symbol_get_obj (symbolP);
1347 sy_obj->size = NULL;
1348 sy_obj->versioned_name = NULL;
252b5132
RH
1349
1350#ifdef NEED_ECOFF_DEBUG
1351 if (ECOFF_DEBUGGING)
1352 ecoff_symbol_new_hook (symbolP);
1353#endif
1354}
1355
8fd3e36b
AM
1356/* When setting one symbol equal to another, by default we probably
1357 want them to have the same "size", whatever it means in the current
1358 context. */
1359
1360void
1361elf_copy_symbol_attributes (dest, src)
1362 symbolS *dest, *src;
1363{
1364 struct elf_obj_sy *srcelf = symbol_get_obj (src);
1365 struct elf_obj_sy *destelf = symbol_get_obj (dest);
1366 if (srcelf->size)
1367 {
1368 if (destelf->size == NULL)
1369 destelf->size =
1370 (expressionS *) xmalloc (sizeof (expressionS));
1371 *destelf->size = *srcelf->size;
1372 }
1373 else
1374 {
1375 if (destelf->size != NULL)
1376 free (destelf->size);
1377 destelf->size = NULL;
1378 }
1379 S_SET_SIZE (dest, S_GET_SIZE (src));
1380 S_SET_OTHER (dest, S_GET_OTHER (src));
1381}
1382
252b5132
RH
1383void
1384obj_elf_version (ignore)
ab9da554 1385 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1386{
1387 char *name;
1388 unsigned int c;
1389 char ch;
1390 char *p;
1391 asection *seg = now_seg;
1392 subsegT subseg = now_subseg;
1393 Elf_Internal_Note i_note;
1394 Elf_External_Note e_note;
1395 asection *note_secp = (asection *) NULL;
1396 int i, len;
1397
1398 SKIP_WHITESPACE ();
1399 if (*input_line_pointer == '\"')
1400 {
bf514e21 1401 ++input_line_pointer; /* -> 1st char of string. */
252b5132
RH
1402 name = input_line_pointer;
1403
1404 while (is_a_char (c = next_char_of_string ()))
1405 ;
1406 c = *input_line_pointer;
1407 *input_line_pointer = '\0';
1408 *(input_line_pointer - 1) = '\0';
1409 *input_line_pointer = c;
1410
1411 /* create the .note section */
1412
1413 note_secp = subseg_new (".note", 0);
1414 bfd_set_section_flags (stdoutput,
1415 note_secp,
1416 SEC_HAS_CONTENTS | SEC_READONLY);
1417
1418 /* process the version string */
1419
1420 len = strlen (name);
1421
1422 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
1423 i_note.descsz = 0; /* no description */
1424 i_note.type = NT_VERSION;
1425 p = frag_more (sizeof (e_note.namesz));
1426 md_number_to_chars (p, (valueT) i_note.namesz, 4);
1427 p = frag_more (sizeof (e_note.descsz));
1428 md_number_to_chars (p, (valueT) i_note.descsz, 4);
1429 p = frag_more (sizeof (e_note.type));
1430 md_number_to_chars (p, (valueT) i_note.type, 4);
1431
1432 for (i = 0; i < len; i++)
1433 {
1434 ch = *(name + i);
1435 {
1436 FRAG_APPEND_1_CHAR (ch);
1437 }
1438 }
1439 frag_align (2, 0, 0);
1440
1441 subseg_set (seg, subseg);
1442 }
1443 else
1444 {
6ce8b369 1445 as_bad (_("expected quoted string"));
252b5132
RH
1446 }
1447 demand_empty_rest_of_line ();
1448}
1449
1450static void
1451obj_elf_size (ignore)
ab9da554 1452 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1453{
1454 char *name = input_line_pointer;
1455 char c = get_symbol_end ();
1456 char *p;
1457 expressionS exp;
1458 symbolS *sym;
1459
1460 p = input_line_pointer;
1461 *p = c;
1462 SKIP_WHITESPACE ();
1463 if (*input_line_pointer != ',')
1464 {
1465 *p = 0;
1466 as_bad (_("expected comma after name `%s' in .size directive"), name);
1467 *p = c;
1468 ignore_rest_of_line ();
1469 return;
1470 }
1471 input_line_pointer++;
1472 expression (&exp);
1473 if (exp.X_op == O_absent)
1474 {
1475 as_bad (_("missing expression in .size directive"));
1476 exp.X_op = O_constant;
1477 exp.X_add_number = 0;
1478 }
1479 *p = 0;
1480 sym = symbol_find_or_make (name);
1481 *p = c;
1482 if (exp.X_op == O_constant)
c538998c
JJ
1483 {
1484 S_SET_SIZE (sym, exp.X_add_number);
1485 if (symbol_get_obj (sym)->size)
1486 {
1487 xfree (symbol_get_obj (sym)->size);
1488 symbol_get_obj (sym)->size = NULL;
1489 }
1490 }
252b5132
RH
1491 else
1492 {
49309057
ILT
1493 symbol_get_obj (sym)->size =
1494 (expressionS *) xmalloc (sizeof (expressionS));
1495 *symbol_get_obj (sym)->size = exp;
252b5132
RH
1496 }
1497 demand_empty_rest_of_line ();
1498}
1499
1500/* Handle the ELF .type pseudo-op. This sets the type of a symbol.
aa8c34c3 1501 There are five syntaxes:
fa306131 1502
252b5132
RH
1503 The first (used on Solaris) is
1504 .type SYM,#function
1505 The second (used on UnixWare) is
1506 .type SYM,@function
1507 The third (reportedly to be used on Irix 6.0) is
1508 .type SYM STT_FUNC
1509 The fourth (used on NetBSD/Arm and Linux/ARM) is
1510 .type SYM,%function
aa8c34c3
JE
1511 The fifth (used on SVR4/860) is
1512 .type SYM,"function"
252b5132
RH
1513 */
1514
1515static void
1516obj_elf_type (ignore)
ab9da554 1517 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1518{
1519 char *name;
1520 char c;
1521 int type;
1522 const char *typename;
1523 symbolS *sym;
904a31bf 1524 elf_symbol_type *elfsym;
252b5132
RH
1525
1526 name = input_line_pointer;
1527 c = get_symbol_end ();
1528 sym = symbol_find_or_make (name);
904a31bf 1529 elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
252b5132
RH
1530 *input_line_pointer = c;
1531
1532 SKIP_WHITESPACE ();
1533 if (*input_line_pointer == ',')
1534 ++input_line_pointer;
1535
1536 SKIP_WHITESPACE ();
1537 if ( *input_line_pointer == '#'
1538 || *input_line_pointer == '@'
aa8c34c3 1539 || *input_line_pointer == '"'
252b5132
RH
1540 || *input_line_pointer == '%')
1541 ++input_line_pointer;
1542
1543 typename = input_line_pointer;
1544 c = get_symbol_end ();
1545
1546 type = 0;
1547 if (strcmp (typename, "function") == 0
1548 || strcmp (typename, "STT_FUNC") == 0)
1549 type = BSF_FUNCTION;
1550 else if (strcmp (typename, "object") == 0
1551 || strcmp (typename, "STT_OBJECT") == 0)
1552 type = BSF_OBJECT;
904a31bf
AM
1553#ifdef md_elf_symbol_type
1554 else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1)
1555 ;
1556#endif
252b5132 1557 else
6ce8b369 1558 as_bad (_("unrecognized symbol type \"%s\""), typename);
252b5132
RH
1559
1560 *input_line_pointer = c;
1561
aa8c34c3
JE
1562 if (*input_line_pointer == '"')
1563 ++input_line_pointer;
1564
904a31bf 1565 elfsym->symbol.flags |= type;
252b5132
RH
1566
1567 demand_empty_rest_of_line ();
1568}
1569
1570static void
1571obj_elf_ident (ignore)
ab9da554 1572 int ignore ATTRIBUTE_UNUSED;
252b5132
RH
1573{
1574 static segT comment_section;
1575 segT old_section = now_seg;
1576 int old_subsection = now_subseg;
1577
5f91fe03
ILT
1578#ifdef md_flush_pending_output
1579 md_flush_pending_output ();
1580#endif
1581
252b5132
RH
1582 if (!comment_section)
1583 {
1584 char *p;
1585 comment_section = subseg_new (".comment", 0);
1586 bfd_set_section_flags (stdoutput, comment_section,
1587 SEC_READONLY | SEC_HAS_CONTENTS);
1588 p = frag_more (1);
1589 *p = 0;
1590 }
1591 else
1592 subseg_set (comment_section, 0);
1593 stringer (1);
1594 subseg_set (old_section, old_subsection);
1595}
1596
1597#ifdef INIT_STAB_SECTION
1598
1599/* The first entry in a .stabs section is special. */
1600
1601void
1602obj_elf_init_stab_section (seg)
1603 segT seg;
1604{
1605 char *file;
1606 char *p;
1607 char *stabstr_name;
1608 unsigned int stroff;
1609
1610 /* Force the section to align to a longword boundary. Without this,
1611 UnixWare ar crashes. */
1612 bfd_set_section_alignment (stdoutput, seg, 2);
1613
bf514e21 1614 /* Make space for this first symbol. */
252b5132 1615 p = frag_more (12);
bf514e21 1616 /* Zero it out. */
252b5132
RH
1617 memset (p, 0, 12);
1618 as_where (&file, (unsigned int *) NULL);
1619 stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
1620 strcpy (stabstr_name, segment_name (seg));
1621 strcat (stabstr_name, "str");
1622 stroff = get_stab_string_offset (file, stabstr_name);
1623 know (stroff == 1);
1624 md_number_to_chars (p, stroff, 4);
1625 seg_info (seg)->stabu.p = p;
1626}
1627
1628#endif
1629
1630/* Fill in the counts in the first entry in a .stabs section. */
1631
1632static void
1633adjust_stab_sections (abfd, sec, xxx)
1634 bfd *abfd;
1635 asection *sec;
ab9da554 1636 PTR xxx ATTRIBUTE_UNUSED;
252b5132
RH
1637{
1638 char *name;
1639 asection *strsec;
1640 char *p;
1641 int strsz, nsyms;
1642
1643 if (strncmp (".stab", sec->name, 5))
1644 return;
1645 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1646 return;
1647
1648 name = (char *) alloca (strlen (sec->name) + 4);
1649 strcpy (name, sec->name);
1650 strcat (name, "str");
1651 strsec = bfd_get_section_by_name (abfd, name);
1652 if (strsec)
1653 strsz = bfd_section_size (abfd, strsec);
1654 else
1655 strsz = 0;
1656 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1657
1658 p = seg_info (sec)->stabu.p;
1659 assert (p != 0);
1660
1661 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
1662 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
1663}
1664
1665#ifdef NEED_ECOFF_DEBUG
1666
1667/* This function is called by the ECOFF code. It is supposed to
1668 record the external symbol information so that the backend can
1669 write it out correctly. The ELF backend doesn't actually handle
1670 this at the moment, so we do it ourselves. We save the information
1671 in the symbol. */
1672
1673void
1674elf_ecoff_set_ext (sym, ext)
1675 symbolS *sym;
1676 struct ecoff_extr *ext;
1677{
49309057 1678 symbol_get_bfdsym (sym)->udata.p = (PTR) ext;
252b5132
RH
1679}
1680
1681/* This function is called by bfd_ecoff_debug_externals. It is
1682 supposed to *EXT to the external symbol information, and return
1683 whether the symbol should be used at all. */
1684
1685static boolean
1686elf_get_extr (sym, ext)
1687 asymbol *sym;
1688 EXTR *ext;
1689{
1690 if (sym->udata.p == NULL)
1691 return false;
1692 *ext = *(EXTR *) sym->udata.p;
1693 return true;
1694}
1695
1696/* This function is called by bfd_ecoff_debug_externals. It has
1697 nothing to do for ELF. */
1698
1699/*ARGSUSED*/
1700static void
1701elf_set_index (sym, indx)
5f91fe03
ILT
1702 asymbol *sym ATTRIBUTE_UNUSED;
1703 bfd_size_type indx ATTRIBUTE_UNUSED;
252b5132
RH
1704{
1705}
1706
1707#endif /* NEED_ECOFF_DEBUG */
1708
1709void
1710elf_frob_symbol (symp, puntp)
1711 symbolS *symp;
1712 int *puntp;
1713{
49309057
ILT
1714 struct elf_obj_sy *sy_obj;
1715
252b5132
RH
1716#ifdef NEED_ECOFF_DEBUG
1717 if (ECOFF_DEBUGGING)
1718 ecoff_frob_symbol (symp);
1719#endif
1720
49309057
ILT
1721 sy_obj = symbol_get_obj (symp);
1722
1723 if (sy_obj->size != NULL)
252b5132 1724 {
49309057 1725 switch (sy_obj->size->X_op)
252b5132
RH
1726 {
1727 case O_subtract:
1728 S_SET_SIZE (symp,
49309057
ILT
1729 (S_GET_VALUE (sy_obj->size->X_add_symbol)
1730 + sy_obj->size->X_add_number
1731 - S_GET_VALUE (sy_obj->size->X_op_symbol)));
252b5132
RH
1732 break;
1733 case O_constant:
1734 S_SET_SIZE (symp,
49309057
ILT
1735 (S_GET_VALUE (sy_obj->size->X_add_symbol)
1736 + sy_obj->size->X_add_number));
252b5132
RH
1737 break;
1738 default:
1739 as_bad (_(".size expression too complicated to fix up"));
1740 break;
1741 }
49309057
ILT
1742 free (sy_obj->size);
1743 sy_obj->size = NULL;
252b5132
RH
1744 }
1745
49309057 1746 if (sy_obj->versioned_name != NULL)
252b5132 1747 {
79082ff0
L
1748 char *p;
1749
1750 p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
1751 know (p != NULL);
1752
252b5132
RH
1753 /* This symbol was given a new name with the .symver directive.
1754
1755 If this is an external reference, just rename the symbol to
1756 include the version string. This will make the relocs be
1757 against the correct versioned symbol.
1758
1759 If this is a definition, add an alias. FIXME: Using an alias
1760 will permit the debugging information to refer to the right
1761 symbol. However, it's not clear whether it is the best
1762 approach. */
1763
1764 if (! S_IS_DEFINED (symp))
1765 {
252b5132
RH
1766 /* Verify that the name isn't using the @@ syntax--this is
1767 reserved for definitions of the default version to link
1768 against. */
252b5132
RH
1769 if (p[1] == ELF_VER_CHR)
1770 {
1771 as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
49309057 1772 sy_obj->versioned_name);
252b5132
RH
1773 *puntp = true;
1774 }
49309057 1775 S_SET_NAME (symp, sy_obj->versioned_name);
252b5132
RH
1776 }
1777 else
1778 {
79082ff0
L
1779 if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)
1780 {
1781 size_t l;
1782
1783 /* The @@@ syntax is a special case. It renames the
1784 symbol name to versioned_name with one `@' removed. */
1785 l = strlen (&p[3]) + 1;
1786 memmove (&p [2], &p[3], l);
1787 S_SET_NAME (symp, sy_obj->versioned_name);
1788 }
1789 else
1790 {
1791 symbolS *symp2;
252b5132 1792
79082ff0
L
1793 /* FIXME: Creating a new symbol here is risky. We're
1794 in the final loop over the symbol table. We can
1795 get away with it only because the symbol goes to
1796 the end of the list, where the loop will still see
1797 it. It would probably be better to do this in
1798 obj_frob_file_before_adjust. */
252b5132 1799
79082ff0 1800 symp2 = symbol_find_or_make (sy_obj->versioned_name);
252b5132 1801
79082ff0 1802 /* Now we act as though we saw symp2 = sym. */
252b5132 1803
79082ff0 1804 S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
252b5132 1805
79082ff0
L
1806 /* Subtracting out the frag address here is a hack
1807 because we are in the middle of the final loop. */
1808 S_SET_VALUE (symp2,
1809 (S_GET_VALUE (symp)
1810 - symbol_get_frag (symp)->fr_address));
252b5132 1811
79082ff0 1812 symbol_set_frag (symp2, symbol_get_frag (symp));
252b5132 1813
79082ff0
L
1814 /* This will copy over the size information. */
1815 copy_symbol_attributes (symp2, symp);
252b5132 1816
79082ff0
L
1817 if (S_IS_WEAK (symp))
1818 S_SET_WEAK (symp2);
252b5132 1819
79082ff0
L
1820 if (S_IS_EXTERNAL (symp))
1821 S_SET_EXTERNAL (symp2);
1822 }
252b5132
RH
1823 }
1824 }
1825
1826 /* Double check weak symbols. */
49309057 1827 if (S_IS_WEAK (symp))
252b5132
RH
1828 {
1829 if (S_IS_COMMON (symp))
6ce8b369 1830 as_bad (_("symbol `%s' can not be both weak and common"),
252b5132
RH
1831 S_GET_NAME (symp));
1832 }
1833
1834#ifdef TC_MIPS
1835 /* The Irix 5 and 6 assemblers set the type of any common symbol and
1836 any undefined non-function symbol to STT_OBJECT. We try to be
1837 compatible, since newer Irix 5 and 6 linkers care. However, we
1838 only set undefined symbols to be STT_OBJECT if we are on Irix,
1839 because that is the only time gcc will generate the necessary
1840 .global directives to mark functions. */
1841
1842 if (S_IS_COMMON (symp))
49309057 1843 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1844
1845 if (strstr (TARGET_OS, "irix") != NULL
49309057
ILT
1846 && ! S_IS_DEFINED (symp)
1847 && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
1848 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1849#endif
1850
c5e54cc2
ILT
1851#if 0 /* TC_PPC */
1852 /* If TC_PPC is defined, we used to force the type of a symbol to be
1853 BSF_OBJECT if it was otherwise unset. This was required by some
1854 version of VxWorks. Thomas de Lellis <tdel@windriver.com> says
1855 that this is no longer needed, so it is now commented out. */
49309057
ILT
1856 if ((symbol_get_bfdsym (symp)->flags
1857 & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
252b5132 1858 && S_IS_DEFINED (symp))
49309057 1859 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
252b5132
RH
1860#endif
1861}
1862
1863void
1864elf_frob_file ()
1865{
1866 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1867
1868#ifdef elf_tc_final_processing
1869 elf_tc_final_processing ();
1870#endif
1871}
1872
4a1805b1 1873/* It removes any unneeded versioned symbols from the symbol table. */
339681c0
L
1874
1875void
1876elf_frob_file_before_adjust ()
1877{
1878 if (symbol_rootP)
1879 {
1880 symbolS *symp;
1881
1882 for (symp = symbol_rootP; symp; symp = symbol_next (symp))
79082ff0
L
1883 if (symbol_get_obj (symp)->versioned_name)
1884 {
1885 if (!S_IS_DEFINED (symp))
1886 {
1887 char *p;
1888
1889 /* The @@@ syntax is a special case. If the symbol is
1890 not defined, 2 `@'s will be removed from the
1891 versioned_name. */
1892
1893 p = strchr (symbol_get_obj (symp)->versioned_name,
1894 ELF_VER_CHR);
1895 know (p != NULL);
1896 if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)
1897 {
1898 size_t l = strlen (&p[3]) + 1;
1899 memmove (&p [1], &p[3], l);
1900 }
1901 if (symbol_used_p (symp) == 0
1902 && symbol_used_in_reloc_p (symp) == 0)
1903 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
1904 }
1905 }
339681c0
L
1906 }
1907}
1908
252b5132
RH
1909/* It is required that we let write_relocs have the opportunity to
1910 optimize away fixups before output has begun, since it is possible
1911 to eliminate all fixups for a section and thus we never should
1912 have generated the relocation section. */
1913
1914void
1915elf_frob_file_after_relocs ()
1916{
1917#ifdef NEED_ECOFF_DEBUG
1918 if (ECOFF_DEBUGGING)
1919 /* Generate the ECOFF debugging information. */
1920 {
1921 const struct ecoff_debug_swap *debug_swap;
1922 struct ecoff_debug_info debug;
1923 char *buf;
1924 asection *sec;
1925
1926 debug_swap
1927 = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1928 know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1929 ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1930
1931 /* Set up the pointers in debug. */
1932#define SET(ptr, offset, type) \
1933 debug.ptr = (type) (buf + debug.symbolic_header.offset)
1934
1935 SET (line, cbLineOffset, unsigned char *);
1936 SET (external_dnr, cbDnOffset, PTR);
1937 SET (external_pdr, cbPdOffset, PTR);
1938 SET (external_sym, cbSymOffset, PTR);
1939 SET (external_opt, cbOptOffset, PTR);
1940 SET (external_aux, cbAuxOffset, union aux_ext *);
1941 SET (ss, cbSsOffset, char *);
1942 SET (external_fdr, cbFdOffset, PTR);
1943 SET (external_rfd, cbRfdOffset, PTR);
1944 /* ssext and external_ext are set up just below. */
1945
1946#undef SET
1947
1948 /* Set up the external symbols. */
1949 debug.ssext = debug.ssext_end = NULL;
1950 debug.external_ext = debug.external_ext_end = NULL;
1951 if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1952 elf_get_extr, elf_set_index))
6ce8b369 1953 as_fatal (_("failed to set up debugging information: %s"),
252b5132
RH
1954 bfd_errmsg (bfd_get_error ()));
1955
1956 sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1957 assert (sec != NULL);
1958
1959 know (stdoutput->output_has_begun == false);
1960
1961 /* We set the size of the section, call bfd_set_section_contents
1962 to force the ELF backend to allocate a file position, and then
1963 write out the data. FIXME: Is this really the best way to do
1964 this? */
1965 sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1966
5f91fe03
ILT
1967 /* Pass BUF to bfd_set_section_contents because this will
1968 eventually become a call to fwrite, and ISO C prohibits
1969 passing a NULL pointer to a stdio function even if the
1970 pointer will not be used. */
1971 if (! bfd_set_section_contents (stdoutput, sec, (PTR) buf,
252b5132 1972 (file_ptr) 0, (bfd_size_type) 0))
6ce8b369 1973 as_fatal (_("can't start writing .mdebug section: %s"),
252b5132
RH
1974 bfd_errmsg (bfd_get_error ()));
1975
1976 know (stdoutput->output_has_begun == true);
1977 know (sec->filepos != 0);
1978
1979 if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1980 sec->filepos))
6ce8b369 1981 as_fatal (_("could not write .mdebug section: %s"),
252b5132
RH
1982 bfd_errmsg (bfd_get_error ()));
1983 }
1984#endif /* NEED_ECOFF_DEBUG */
1985}
1986
1987#ifdef SCO_ELF
1988
1989/* Heavily plagarized from obj_elf_version. The idea is to emit the
1990 SCO specific identifier in the .notes section to satisfy the SCO
1991 linker.
1992
1993 This looks more complicated than it really is. As opposed to the
1994 "obvious" solution, this should handle the cross dev cases
1995 correctly. (i.e, hosting on a 64 bit big endian processor, but
1996 generating SCO Elf code) Efficiency isn't a concern, as there
1997 should be exactly one of these sections per object module.
1998
1999 SCO OpenServer 5 identifies it's ELF modules with a standard ELF
2000 .note section.
2001
fa306131
AM
2002 int_32 namesz = 4 ; Name size
2003 int_32 descsz = 12 ; Descriptive information
2004 int_32 type = 1 ;
2005 char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
252b5132
RH
2006 int_32 version = (major ver # << 16) | version of tools ;
2007 int_32 source = (tool_id << 16 ) | 1 ;
2008 int_32 info = 0 ; These are set by the SCO tools, but we
fa306131 2009 don't know enough about the source
252b5132
RH
2010 environment to set them. SCO ld currently
2011 ignores them, and recommends we set them
2012 to zero. */
2013
2014#define SCO_MAJOR_VERSION 0x1
2015#define SCO_MINOR_VERSION 0x1
2016
2017void
2018sco_id ()
2019{
2020
2021 char *name;
2022 unsigned int c;
2023 char ch;
2024 char *p;
2025 asection *seg = now_seg;
2026 subsegT subseg = now_subseg;
2027 Elf_Internal_Note i_note;
2028 Elf_External_Note e_note;
2029 asection *note_secp = (asection *) NULL;
2030 int i, len;
2031
2032 /* create the .note section */
2033
2034 note_secp = subseg_new (".note", 0);
2035 bfd_set_section_flags (stdoutput,
2036 note_secp,
2037 SEC_HAS_CONTENTS | SEC_READONLY);
2038
2039 /* process the version string */
2040
fa306131 2041 i_note.namesz = 4;
252b5132
RH
2042 i_note.descsz = 12; /* 12 descriptive bytes */
2043 i_note.type = NT_VERSION; /* Contains a version string */
2044
2045 p = frag_more (sizeof (i_note.namesz));
2046 md_number_to_chars (p, (valueT) i_note.namesz, 4);
2047
2048 p = frag_more (sizeof (i_note.descsz));
2049 md_number_to_chars (p, (valueT) i_note.descsz, 4);
2050
2051 p = frag_more (sizeof (i_note.type));
2052 md_number_to_chars (p, (valueT) i_note.type, 4);
2053
2054 p = frag_more (4);
fa306131 2055 strcpy (p, "SCO");
252b5132
RH
2056
2057 /* Note: this is the version number of the ELF we're representing */
2058 p = frag_more (4);
2059 md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
2060
2061 /* Here, we pick a magic number for ourselves (yes, I "registered"
2062 it with SCO. The bottom bit shows that we are compat with the
2063 SCO ABI. */
2064 p = frag_more (4);
2065 md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
2066
2067 /* If we knew (or cared) what the source language options were, we'd
2068 fill them in here. SCO has given us permission to ignore these
2069 and just set them to zero. */
2070 p = frag_more (4);
2071 md_number_to_chars (p, 0x0000, 4);
fa306131 2072
252b5132
RH
2073 frag_align (2, 0, 0);
2074
2075 /* We probably can't restore the current segment, for there likely
2076 isn't one yet... */
2077 if (seg && subseg)
2078 subseg_set (seg, subseg);
2079
2080}
2081
2082#endif /* SCO_ELF */
2083
5110c57e
HPN
2084static int
2085elf_separate_stab_sections ()
2086{
2087#ifdef NEED_ECOFF_DEBUG
2088 return (!ECOFF_DEBUGGING);
2089#else
2090 return 1;
2091#endif
2092}
2093
2094static void
2095elf_init_stab_section (seg)
2096 segT seg;
2097{
2098#ifdef NEED_ECOFF_DEBUG
2099 if (!ECOFF_DEBUGGING)
2100#endif
2101 obj_elf_init_stab_section (seg);
2102}
2103
252b5132
RH
2104const struct format_ops elf_format_ops =
2105{
2106 bfd_target_elf_flavour,
4c63da97
AM
2107 0, /* dfl_leading_underscore */
2108 1, /* emit_section_symbols */
5110c57e
HPN
2109 elf_begin,
2110 elf_file_symbol,
252b5132
RH
2111 elf_frob_symbol,
2112 elf_frob_file,
339681c0 2113 elf_frob_file_before_adjust,
252b5132
RH
2114 elf_frob_file_after_relocs,
2115 elf_s_get_size, elf_s_set_size,
2116 elf_s_get_align, elf_s_set_align,
4c63da97 2117 elf_s_get_other,
5110c57e 2118 elf_s_set_other,
4c63da97 2119 0, /* s_get_desc */
5110c57e
HPN
2120 0, /* s_set_desc */
2121 0, /* s_get_type */
2122 0, /* s_set_type */
252b5132
RH
2123 elf_copy_symbol_attributes,
2124#ifdef NEED_ECOFF_DEBUG
2125 ecoff_generate_asm_lineno,
2126 ecoff_stab,
2127#else
4c63da97
AM
2128 0, /* generate_asm_lineno */
2129 0, /* process_stab */
252b5132 2130#endif
5110c57e
HPN
2131 elf_separate_stab_sections,
2132 elf_init_stab_section,
252b5132
RH
2133 elf_sec_sym_ok_for_reloc,
2134 elf_pop_insert,
2135#ifdef NEED_ECOFF_DEBUG
2136 elf_ecoff_set_ext,
2137#else
4c63da97 2138 0, /* ecoff_set_ext */
252b5132 2139#endif
4c63da97 2140 elf_obj_read_begin_hook,
5110c57e 2141 elf_obj_symbol_new_hook
252b5132 2142};
This page took 0.197144 seconds and 4 git commands to generate.