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