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
elf_begin(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
elf_pop_insert(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
elf_s_get_size(symbolS * sym)200 elf_s_get_size (symbolS *sym)
201 {
202   return S_GET_SIZE (sym);
203 }
204 
205 static void
elf_s_set_size(symbolS * sym,bfd_vma sz)206 elf_s_set_size (symbolS *sym, bfd_vma sz)
207 {
208   S_SET_SIZE (sym, sz);
209 }
210 
211 static bfd_vma
elf_s_get_align(symbolS * sym)212 elf_s_get_align (symbolS *sym)
213 {
214   return S_GET_ALIGN (sym);
215 }
216 
217 static void
elf_s_set_align(symbolS * sym,bfd_vma align)218 elf_s_set_align (symbolS *sym, bfd_vma align)
219 {
220   S_SET_ALIGN (sym, align);
221 }
222 
223 int
elf_s_get_other(symbolS * sym)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
elf_s_set_other(symbolS * sym,int other)230 elf_s_set_other (symbolS *sym, int other)
231 {
232   S_SET_OTHER (sym, other);
233 }
234 
235 static int
elf_sec_sym_ok_for_reloc(asection * sec)236 elf_sec_sym_ok_for_reloc (asection *sec)
237 {
238   return obj_sec_sym_ok_for_reloc (sec);
239 }
240 
241 void
elf_file_symbol(const char * s,int appfile)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 *
elf_common_parse(int ignore ATTRIBUTE_UNUSED,symbolS * symbolP,addressT size)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
obj_elf_common(int is_common)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
obj_elf_tls_common(int ignore ATTRIBUTE_UNUSED)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
obj_elf_lcomm(int ignore ATTRIBUTE_UNUSED)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
obj_elf_local(int ignore ATTRIBUTE_UNUSED)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
obj_elf_weak(int ignore ATTRIBUTE_UNUSED)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
obj_elf_visibility(int visibility)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
get_section(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,void * inf)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
obj_elf_change_section(const char * name,int type,int attr,int entsize,const char * group_name,int linkonce,int push)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
obj_elf_parse_section_letters(char * str,size_t len)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
obj_elf_section_word(char * str,size_t len)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
obj_elf_section_type(char * str,size_t len)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 *
obj_elf_section_name(void)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
obj_elf_section(int push)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
obj_elf_data(int i)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
obj_elf_text(int i)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
obj_elf_struct(int i)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
obj_elf_subsection(int ignore ATTRIBUTE_UNUSED)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
obj_elf_section_change_hook(void)1087 obj_elf_section_change_hook (void)
1088 {
1089   previous_section = now_seg;
1090   previous_subsection = now_subseg;
1091 }
1092 
1093 void
obj_elf_previous(int ignore ATTRIBUTE_UNUSED)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
obj_elf_popsection(int xxx ATTRIBUTE_UNUSED)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
obj_elf_line(int ignore ATTRIBUTE_UNUSED)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
obj_elf_symver(int ignore ATTRIBUTE_UNUSED)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 *
obj_elf_vtable_inherit(int ignore ATTRIBUTE_UNUSED)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 *
obj_elf_vtable_entry(int ignore ATTRIBUTE_UNUSED)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
elf_obj_read_begin_hook(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
elf_obj_symbol_new_hook(symbolS * symbolP)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
elf_copy_symbol_attributes(symbolS * dest,symbolS * src)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
obj_elf_version(int ignore ATTRIBUTE_UNUSED)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
obj_elf_size(int ignore ATTRIBUTE_UNUSED)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
obj_elf_type(int ignore ATTRIBUTE_UNUSED)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
obj_elf_ident(int ignore ATTRIBUTE_UNUSED)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
obj_elf_init_stab_section(segT seg)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
adjust_stab_sections(bfd * abfd,asection * sec,void * xxx ATTRIBUTE_UNUSED)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
elf_ecoff_set_ext(symbolS * sym,struct ecoff_extr * ext)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
elf_get_extr(asymbol * sym,EXTR * ext)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
elf_set_index(asymbol * sym ATTRIBUTE_UNUSED,bfd_size_type indx ATTRIBUTE_UNUSED)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
elf_frob_symbol(symbolS * symp,int * puntp)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
build_group_lists(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,void * inf)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
elf_frob_file(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
elf_frob_file_before_adjust(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
elf_frob_file_after_relocs(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
sco_id(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
elf_separate_stab_sections(void)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
elf_init_stab_section(segT seg)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 };
2249