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