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