obj-elf.c revision 33965
1/* ELF object file format
2   Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3
4   This file is part of GAS, the GNU Assembler.
5
6   GAS is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as
8   published by the Free Software Foundation; either version 2,
9   or (at your option) any later version.
10
11   GAS is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14   the GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with GAS; see the file COPYING.  If not, write to the Free
18   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA. */
20
21#define OBJ_HEADER "obj-elf.h"
22#include "as.h"
23#include "subsegs.h"
24#include "obstack.h"
25
26#ifndef ECOFF_DEBUGGING
27#define ECOFF_DEBUGGING 0
28#else
29#define NEED_ECOFF_DEBUG
30#endif
31
32#ifdef NEED_ECOFF_DEBUG
33#include "ecoff.h"
34#endif
35
36#ifdef TC_MIPS
37#include "elf/mips.h"
38#endif
39
40#ifdef TC_PPC
41#include "elf/ppc.h"
42#endif
43
44static bfd_vma elf_s_get_size PARAMS ((symbolS *));
45static void elf_s_set_size PARAMS ((symbolS *, bfd_vma));
46static bfd_vma elf_s_get_align PARAMS ((symbolS *));
47static void elf_s_set_align PARAMS ((symbolS *, bfd_vma));
48static void elf_copy_symbol_attributes PARAMS ((symbolS *, symbolS *));
49static int elf_sec_sym_ok_for_reloc PARAMS ((asection *));
50static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
51
52#ifdef NEED_ECOFF_DEBUG
53static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
54static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
55#endif
56
57static void obj_elf_line PARAMS ((int));
58void obj_elf_version PARAMS ((int));
59static void obj_elf_size PARAMS ((int));
60static void obj_elf_type PARAMS ((int));
61static void obj_elf_ident PARAMS ((int));
62static void obj_elf_weak PARAMS ((int));
63static void obj_elf_local PARAMS ((int));
64static void obj_elf_common PARAMS ((int));
65static void obj_elf_symver PARAMS ((int));
66static void obj_elf_data PARAMS ((int));
67static void obj_elf_text PARAMS ((int));
68
69static const pseudo_typeS elf_pseudo_table[] =
70{
71  {"comm", obj_elf_common, 0},
72  {"ident", obj_elf_ident, 0},
73  {"local", obj_elf_local, 0},
74  {"previous", obj_elf_previous, 0},
75  {"section", obj_elf_section, 0},
76  {"section.s", obj_elf_section, 0},
77  {"sect", obj_elf_section, 0},
78  {"sect.s", obj_elf_section, 0},
79  {"size", obj_elf_size, 0},
80  {"type", obj_elf_type, 0},
81  {"version", obj_elf_version, 0},
82  {"weak", obj_elf_weak, 0},
83
84  /* These are used for stabs-in-elf configurations.  */
85  {"line", obj_elf_line, 0},
86
87  /* This is a GNU extension to handle symbol versions.  */
88  {"symver", obj_elf_symver, 0},
89
90  /* These are used for dwarf. */
91  {"2byte", cons, 2},
92  {"4byte", cons, 4},
93  {"8byte", cons, 8},
94
95  /* We need to trap the section changing calls to handle .previous.  */
96  {"data", obj_elf_data, 0},
97  {"text", obj_elf_text, 0},
98
99  /* End sentinel.  */
100  {NULL},
101};
102
103static const pseudo_typeS ecoff_debug_pseudo_table[] =
104{
105#ifdef NEED_ECOFF_DEBUG
106  /* COFF style debugging information for ECOFF. .ln is not used; .loc
107     is used instead.  */
108  { "def",	ecoff_directive_def,	0 },
109  { "dim",	ecoff_directive_dim,	0 },
110  { "endef",	ecoff_directive_endef,	0 },
111  { "file",	ecoff_directive_file,	0 },
112  { "scl",	ecoff_directive_scl,	0 },
113  { "tag",	ecoff_directive_tag,	0 },
114  { "val",	ecoff_directive_val,	0 },
115
116  /* COFF debugging requires pseudo-ops .size and .type, but ELF
117     already has meanings for those.  We use .esize and .etype
118     instead.  These are only generated by gcc anyhow.  */
119  { "esize",	ecoff_directive_size,	0 },
120  { "etype",	ecoff_directive_type,	0 },
121
122  /* ECOFF specific debugging information.  */
123  { "begin",	ecoff_directive_begin,	0 },
124  { "bend",	ecoff_directive_bend,	0 },
125  { "end",	ecoff_directive_end,	0 },
126  { "ent",	ecoff_directive_ent,	0 },
127  { "fmask",	ecoff_directive_fmask,	0 },
128  { "frame",	ecoff_directive_frame,	0 },
129  { "loc",	ecoff_directive_loc,	0 },
130  { "mask",	ecoff_directive_mask,	0 },
131
132  /* Other ECOFF directives.  */
133  { "extern",	ecoff_directive_extern,	0 },
134
135  /* These are used on Irix.  I don't know how to implement them.  */
136  { "alias",	s_ignore,		0 },
137  { "bgnb",	s_ignore,		0 },
138  { "endb",	s_ignore,		0 },
139  { "lab",	s_ignore,		0 },
140  { "noalias",	s_ignore,		0 },
141  { "verstamp",	s_ignore,		0 },
142  { "vreg",	s_ignore,		0 },
143#endif
144
145  {NULL}			/* end sentinel */
146};
147
148#undef NO_RELOC
149#include "aout/aout64.h"
150
151/* This is called when the assembler starts.  */
152
153void
154elf_begin ()
155{
156  /* Add symbols for the known sections to the symbol table.  */
157  symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
158								".text")));
159  symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
160								".data")));
161  symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
162								".bss")));
163}
164
165void
166elf_pop_insert ()
167{
168  pop_insert (elf_pseudo_table);
169  if (ECOFF_DEBUGGING)
170    pop_insert (ecoff_debug_pseudo_table);
171}
172
173static bfd_vma
174elf_s_get_size (sym)
175     symbolS *sym;
176{
177  return S_GET_SIZE (sym);
178}
179
180static void
181elf_s_set_size (sym, sz)
182     symbolS *sym;
183     bfd_vma sz;
184{
185  S_SET_SIZE (sym, sz);
186}
187
188static bfd_vma
189elf_s_get_align (sym)
190     symbolS *sym;
191{
192  return S_GET_ALIGN (sym);
193}
194
195static void
196elf_s_set_align (sym, align)
197     symbolS *sym;
198     bfd_vma align;
199{
200  S_SET_ALIGN (sym, align);
201}
202
203static void
204elf_copy_symbol_attributes (dest, src)
205     symbolS *dest, *src;
206{
207  OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
208}
209
210static int
211elf_sec_sym_ok_for_reloc (sec)
212     asection *sec;
213{
214  return obj_sec_sym_ok_for_reloc (sec);
215}
216
217void
218elf_file_symbol (s)
219     char *s;
220{
221  symbolS *sym;
222
223  sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
224  sym->sy_frag = &zero_address_frag;
225  sym->bsym->flags |= BSF_FILE;
226
227  if (symbol_rootP != sym)
228    {
229      symbol_remove (sym, &symbol_rootP, &symbol_lastP);
230      symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
231#ifdef DEBUG
232      verify_symbol_chain (symbol_rootP, symbol_lastP);
233#endif
234    }
235
236#ifdef NEED_ECOFF_DEBUG
237  ecoff_new_file (s);
238#endif
239}
240
241static void
242obj_elf_common (ignore)
243     int ignore;
244{
245  char *name;
246  char c;
247  char *p;
248  int temp, size;
249  symbolS *symbolP;
250  int have_align;
251
252  name = input_line_pointer;
253  c = get_symbol_end ();
254  /* just after name is now '\0' */
255  p = input_line_pointer;
256  *p = c;
257  SKIP_WHITESPACE ();
258  if (*input_line_pointer != ',')
259    {
260      as_bad ("Expected comma after symbol-name");
261      ignore_rest_of_line ();
262      return;
263    }
264  input_line_pointer++;		/* skip ',' */
265  if ((temp = get_absolute_expression ()) < 0)
266    {
267      as_bad (".COMMon length (%d.) <0! Ignored.", temp);
268      ignore_rest_of_line ();
269      return;
270    }
271  size = temp;
272  *p = 0;
273  symbolP = symbol_find_or_make (name);
274  *p = c;
275  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
276    {
277      as_bad ("Ignoring attempt to re-define symbol");
278      ignore_rest_of_line ();
279      return;
280    }
281  if (S_GET_VALUE (symbolP) != 0)
282    {
283      if (S_GET_VALUE (symbolP) != size)
284	{
285	  as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
286		   S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
287	}
288    }
289  know (symbolP->sy_frag == &zero_address_frag);
290  if (*input_line_pointer != ',')
291    have_align = 0;
292  else
293    {
294      have_align = 1;
295      input_line_pointer++;
296      SKIP_WHITESPACE ();
297    }
298  if (! have_align || *input_line_pointer != '"')
299    {
300      if (! have_align)
301	temp = 0;
302      else
303	{
304	  temp = get_absolute_expression ();
305	  if (temp < 0)
306	    {
307	      temp = 0;
308	      as_warn ("Common alignment negative; 0 assumed");
309	    }
310	}
311      if (symbolP->local)
312	{
313	  segT old_sec;
314	  int old_subsec;
315	  char *pfrag;
316	  int align;
317
318	/* allocate_bss: */
319	  old_sec = now_seg;
320	  old_subsec = now_subseg;
321	  if (temp)
322	    {
323	      /* convert to a power of 2 alignment */
324	      for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
325	      if (temp != 1)
326		{
327		  as_bad ("Common alignment not a power of 2");
328		  ignore_rest_of_line ();
329		  return;
330		}
331	    }
332	  else
333	    align = 0;
334	  record_alignment (bss_section, align);
335	  subseg_set (bss_section, 0);
336	  if (align)
337	    frag_align (align, 0, 0);
338	  if (S_GET_SEGMENT (symbolP) == bss_section)
339	    symbolP->sy_frag->fr_symbol = 0;
340	  symbolP->sy_frag = frag_now;
341	  pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
342			    (offsetT) size, (char *) 0);
343	  *pfrag = 0;
344	  S_SET_SIZE (symbolP, size);
345	  S_SET_SEGMENT (symbolP, bss_section);
346	  S_CLEAR_EXTERNAL (symbolP);
347	  subseg_set (old_sec, old_subsec);
348	}
349      else
350	{
351	allocate_common:
352	  S_SET_VALUE (symbolP, (valueT) size);
353	  S_SET_ALIGN (symbolP, temp);
354	  S_SET_EXTERNAL (symbolP);
355	  S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
356	}
357    }
358  else
359    {
360      input_line_pointer++;
361      /* @@ Some use the dot, some don't.  Can we get some consistency??  */
362      if (*input_line_pointer == '.')
363	input_line_pointer++;
364      /* @@ Some say data, some say bss.  */
365      if (strncmp (input_line_pointer, "bss\"", 4)
366	  && strncmp (input_line_pointer, "data\"", 5))
367	{
368	  while (*--input_line_pointer != '"')
369	    ;
370	  input_line_pointer--;
371	  goto bad_common_segment;
372	}
373      while (*input_line_pointer++ != '"')
374	;
375      goto allocate_common;
376    }
377
378  symbolP->bsym->flags |= BSF_OBJECT;
379
380  demand_empty_rest_of_line ();
381  return;
382
383  {
384  bad_common_segment:
385    p = input_line_pointer;
386    while (*p && *p != '\n')
387      p++;
388    c = *p;
389    *p = '\0';
390    as_bad ("bad .common segment %s", input_line_pointer + 1);
391    *p = c;
392    input_line_pointer = p;
393    ignore_rest_of_line ();
394    return;
395  }
396}
397
398static void
399obj_elf_local (ignore)
400     int ignore;
401{
402  char *name;
403  int c;
404  symbolS *symbolP;
405
406  do
407    {
408      name = input_line_pointer;
409      c = get_symbol_end ();
410      symbolP = symbol_find_or_make (name);
411      *input_line_pointer = c;
412      SKIP_WHITESPACE ();
413      S_CLEAR_EXTERNAL (symbolP);
414      symbolP->local = 1;
415      if (c == ',')
416	{
417	  input_line_pointer++;
418	  SKIP_WHITESPACE ();
419	  if (*input_line_pointer == '\n')
420	    c = '\n';
421	}
422    }
423  while (c == ',');
424  demand_empty_rest_of_line ();
425}
426
427static void
428obj_elf_weak (ignore)
429     int ignore;
430{
431  char *name;
432  int c;
433  symbolS *symbolP;
434
435  do
436    {
437      name = input_line_pointer;
438      c = get_symbol_end ();
439      symbolP = symbol_find_or_make (name);
440      *input_line_pointer = c;
441      SKIP_WHITESPACE ();
442      S_SET_WEAK (symbolP);
443      symbolP->local = 1;
444      if (c == ',')
445	{
446	  input_line_pointer++;
447	  SKIP_WHITESPACE ();
448	  if (*input_line_pointer == '\n')
449	    c = '\n';
450	}
451    }
452  while (c == ',');
453  demand_empty_rest_of_line ();
454}
455
456static segT previous_section;
457static int previous_subsection;
458
459/* Handle the .section pseudo-op.  This code supports two different
460   syntaxes.
461
462   The first is found on Solaris, and looks like
463       .section ".sec1",#alloc,#execinstr,#write
464   Here the names after '#' are the SHF_* flags to turn on for the
465   section.  I'm not sure how it determines the SHT_* type (BFD
466   doesn't really give us control over the type, anyhow).
467
468   The second format is found on UnixWare, and probably most SVR4
469   machines, and looks like
470       .section .sec1,"a",@progbits
471   The quoted string may contain any combination of a, w, x, and
472   represents the SHF_* flags to turn on for the section.  The string
473   beginning with '@' can be progbits or nobits.  There should be
474   other possibilities, but I don't know what they are.  In any case,
475   BFD doesn't really let us set the section type.  */
476
477/* Certain named sections have particular defined types, listed on p.
478   4-19 of the ABI.  */
479struct special_section
480{
481  const char *name;
482  int type;
483  int attributes;
484};
485
486static struct special_section special_sections[] =
487{
488  { ".bss",	SHT_NOBITS,	SHF_ALLOC + SHF_WRITE		},
489  { ".comment",	SHT_PROGBITS,	0				},
490  { ".data",	SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE		},
491  { ".data1",	SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE		},
492  { ".debug",	SHT_PROGBITS,	0				},
493  { ".fini",	SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR	},
494  { ".init",	SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR	},
495  { ".line",	SHT_PROGBITS,	0				},
496  { ".note",	SHT_NOTE,	0				},
497  { ".rodata",	SHT_PROGBITS,	SHF_ALLOC			},
498  { ".rodata1",	SHT_PROGBITS,	SHF_ALLOC			},
499  { ".text",	SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR	},
500
501#ifdef ELF_TC_SPECIAL_SECTIONS
502  ELF_TC_SPECIAL_SECTIONS
503#endif
504
505#if 0
506  /* The following section names are special, but they can not
507     reasonably appear in assembler code.  Some of the attributes are
508     processor dependent.  */
509  { ".dynamic",	SHT_DYNAMIC,	SHF_ALLOC /* + SHF_WRITE */ 	},
510  { ".dynstr",	SHT_STRTAB,	SHF_ALLOC			},
511  { ".dynsym",	SHT_DYNSYM,	SHF_ALLOC			},
512  { ".got",	SHT_PROGBITS,	0				},
513  { ".hash",	SHT_HASH,	SHF_ALLOC			},
514  { ".interp",	SHT_PROGBITS,	/* SHF_ALLOC */			},
515  { ".plt",	SHT_PROGBITS,	0				},
516  { ".shstrtab",SHT_STRTAB,	0				},
517  { ".strtab",	SHT_STRTAB,	/* SHF_ALLOC */			},
518  { ".symtab",	SHT_SYMTAB,	/* SHF_ALLOC */			},
519#endif
520
521  { NULL,	0,		0				}
522};
523
524void
525obj_elf_section (xxx)
526     int xxx;
527{
528  char *string;
529  int new_sec;
530  segT sec;
531  int type, attr;
532  int i;
533  flagword flags;
534  symbolS *secsym;
535
536#ifdef md_flush_pending_output
537  md_flush_pending_output ();
538#endif
539
540  if (flag_mri)
541    {
542      char mri_type;
543
544      previous_section = now_seg;
545      previous_subsection = now_subseg;
546
547      s_mri_sect (&mri_type);
548
549#ifdef md_elf_section_change_hook
550      md_elf_section_change_hook ();
551#endif
552
553      return;
554    }
555
556  /* Get name of section.  */
557  SKIP_WHITESPACE ();
558  if (*input_line_pointer == '"')
559    {
560      string = demand_copy_C_string (&xxx);
561      if (string == NULL)
562	{
563	  ignore_rest_of_line ();
564	  return;
565	}
566    }
567  else
568    {
569      char *p = input_line_pointer;
570      char c;
571      while (0 == strchr ("\n\t,; ", *p))
572	p++;
573      if (p == input_line_pointer)
574	{
575	  as_warn ("Missing section name");
576	  ignore_rest_of_line ();
577	  return;
578	}
579      c = *p;
580      *p = 0;
581      string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
582      strcpy (string, input_line_pointer);
583      *p = c;
584      input_line_pointer = p;
585    }
586
587  /* Switch to the section, creating it if necessary.  */
588  previous_section = now_seg;
589  previous_subsection = now_subseg;
590
591  new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
592  sec = subseg_new (string, 0);
593
594  /* If this section already existed, we don't bother to change the
595     flag values.  */
596  if (! new_sec)
597    {
598      while (! is_end_of_line[(unsigned char) *input_line_pointer])
599	++input_line_pointer;
600      ++input_line_pointer;
601
602#ifdef md_elf_section_change_hook
603      md_elf_section_change_hook ();
604#endif
605
606      return;
607    }
608
609  SKIP_WHITESPACE ();
610
611  type = SHT_NULL;
612  attr = 0;
613
614  if (*input_line_pointer == ',')
615    {
616      /* Skip the comma.  */
617      ++input_line_pointer;
618
619      SKIP_WHITESPACE ();
620      if (*input_line_pointer == '"')
621	{
622	  /* Pick up a string with a combination of a, w, x.  */
623	  ++input_line_pointer;
624	  while (*input_line_pointer != '"')
625	    {
626	      switch (*input_line_pointer)
627		{
628		case 'a':
629		  attr |= SHF_ALLOC;
630		  break;
631		case 'w':
632		  attr |= SHF_WRITE;
633		  break;
634		case 'x':
635		  attr |= SHF_EXECINSTR;
636		  break;
637		default:
638		  {
639		    char *bad_msg = "Bad .section directive: want a,w,x in string";
640#ifdef md_elf_section_letter
641		    int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
642		    if (md_attr)
643		      attr |= md_attr;
644		    else
645#endif
646		      {
647			as_warn (bad_msg);
648			ignore_rest_of_line ();
649			return;
650		      }
651		  }
652		}
653	      ++input_line_pointer;
654	    }
655
656	  /* Skip the closing quote.  */
657	  ++input_line_pointer;
658
659	  SKIP_WHITESPACE ();
660	  if (*input_line_pointer == ',')
661	    {
662	      ++input_line_pointer;
663	      SKIP_WHITESPACE ();
664	      if (*input_line_pointer == '@')
665		{
666		  ++input_line_pointer;
667		  if (strncmp (input_line_pointer, "progbits",
668			       sizeof "progbits" - 1) == 0)
669		    {
670		      type = SHT_PROGBITS;
671		      input_line_pointer += sizeof "progbits" - 1;
672		    }
673		  else if (strncmp (input_line_pointer, "nobits",
674				    sizeof "nobits" - 1) == 0)
675		    {
676		      type = SHT_NOBITS;
677		      input_line_pointer += sizeof "nobits" - 1;
678		    }
679		  else
680		    {
681#ifdef md_elf_section_type
682		    int md_type = md_elf_section_type (&input_line_pointer);
683		    if (md_type)
684		      type = md_type;
685		    else
686#endif
687		      {
688			as_warn ("Unrecognized section type");
689			ignore_rest_of_line ();
690		      }
691		    }
692		}
693	    }
694	}
695      else
696	{
697	  do
698	    {
699	      SKIP_WHITESPACE ();
700	      if (*input_line_pointer != '#')
701		{
702		  as_warn ("Bad .section directive");
703		  ignore_rest_of_line ();
704		  return;
705		}
706	      ++input_line_pointer;
707	      if (strncmp (input_line_pointer, "write",
708			   sizeof "write" - 1) == 0)
709		{
710		  attr |= SHF_WRITE;
711		  input_line_pointer += sizeof "write" - 1;
712		}
713	      else if (strncmp (input_line_pointer, "alloc",
714				sizeof "alloc" - 1) == 0)
715		{
716		  attr |= SHF_ALLOC;
717		  input_line_pointer += sizeof "alloc" - 1;
718		}
719	      else if (strncmp (input_line_pointer, "execinstr",
720				sizeof "execinstr" - 1) == 0)
721		{
722		  attr |= SHF_EXECINSTR;
723		  input_line_pointer += sizeof "execinstr" - 1;
724		}
725	      else
726		{
727#ifdef md_elf_section_word
728		  int md_attr = md_elf_section_word (&input_line_pointer);
729		  if (md_attr)
730		    attr |= md_attr;
731		  else
732#endif
733		    {
734		      as_warn ("Unrecognized section attribute");
735		      ignore_rest_of_line ();
736		      return;
737		    }
738		}
739	      SKIP_WHITESPACE ();
740	    }
741	  while (*input_line_pointer++ == ',');
742	  --input_line_pointer;
743	}
744    }
745
746  /* See if this is one of the special sections.  */
747  for (i = 0; special_sections[i].name != NULL; i++)
748    {
749      if (string[1] == special_sections[i].name[1]
750	  && strcmp (string, special_sections[i].name) == 0)
751	{
752	  if (type == SHT_NULL)
753	    type = special_sections[i].type;
754	  else if (type != special_sections[i].type)
755	    as_warn ("Setting incorrect section type for %s", string);
756
757	  if ((attr &~ special_sections[i].attributes) != 0)
758	    {
759	      /* As a GNU extension, we permit a .note section to be
760                 allocatable.  If the linker sees an allocateable
761                 .note section, it will create a PT_NOTE segment in
762                 the output file.  */
763	      if (strcmp (string, ".note") != 0
764		  || attr != SHF_ALLOC)
765		as_warn ("Setting incorrect section attributes for %s",
766			 string);
767	    }
768	  attr |= special_sections[i].attributes;
769
770	  break;
771	}
772    }
773
774  flags = (SEC_RELOC
775	   | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
776	   | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
777	   | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
778	   | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
779  if (special_sections[i].name == NULL)
780    {
781      if (type == SHT_PROGBITS)
782	flags |= SEC_ALLOC | SEC_LOAD;
783      else if (type == SHT_NOBITS)
784	{
785	  flags |= SEC_ALLOC;
786	  flags &=~ SEC_LOAD;
787	}
788
789#ifdef md_elf_section_flags
790      flags = md_elf_section_flags (flags, attr, type);
791#endif
792    }
793
794  bfd_set_section_flags (stdoutput, sec, flags);
795
796  /* Add a symbol for this section to the symbol table.  */
797  secsym = symbol_find (string);
798  if (secsym != NULL)
799    secsym->bsym = sec->symbol;
800  else
801    symbol_table_insert (section_symbol (sec));
802
803#ifdef md_elf_section_change_hook
804  md_elf_section_change_hook ();
805#endif
806
807  demand_empty_rest_of_line ();
808}
809
810/* Change to the .data section.  */
811
812static void
813obj_elf_data (i)
814     int i;
815{
816#ifdef md_flush_pending_output
817  md_flush_pending_output ();
818#endif
819
820  previous_section = now_seg;
821  previous_subsection = now_subseg;
822  s_data (i);
823
824#ifdef md_elf_section_change_hook
825  md_elf_section_change_hook ();
826#endif
827}
828
829/* Change to the .text section.  */
830
831static void
832obj_elf_text (i)
833     int i;
834{
835#ifdef md_flush_pending_output
836  md_flush_pending_output ();
837#endif
838
839  previous_section = now_seg;
840  previous_subsection = now_subseg;
841  s_text (i);
842
843#ifdef md_elf_section_change_hook
844  md_elf_section_change_hook ();
845#endif
846}
847
848/* This can be called from the processor backends if they change
849   sections.  */
850
851void
852obj_elf_section_change_hook ()
853{
854  previous_section = now_seg;
855  previous_subsection = now_subseg;
856}
857
858void
859obj_elf_previous (ignore)
860     int ignore;
861{
862  if (previous_section == 0)
863    {
864      as_bad (".previous without corresponding .section; ignored");
865      return;
866    }
867
868#ifdef md_flush_pending_output
869  md_flush_pending_output ();
870#endif
871
872  subseg_set (previous_section, previous_subsection);
873  previous_section = 0;
874
875#ifdef md_elf_section_change_hook
876  md_elf_section_change_hook ();
877#endif
878}
879
880static void
881obj_elf_line (ignore)
882     int ignore;
883{
884  /* Assume delimiter is part of expression.  BSD4.2 as fails with
885     delightful bug, so we are not being incompatible here. */
886  new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
887  demand_empty_rest_of_line ();
888}
889
890/* This handle the .symver pseudo-op, which is used to specify a
891   symbol version.  The syntax is ``.symver NAME,SYMVERNAME''.
892   SYMVERNAME may contain ELF_VER_CHR ('@') characters.  This
893   pseudo-op causes the assembler to emit a symbol named SYMVERNAME
894   with the same value as the symbol NAME.  */
895
896static void
897obj_elf_symver (ignore)
898     int ignore;
899{
900  char *name;
901  char c;
902  symbolS *sym;
903
904  name = input_line_pointer;
905  c = get_symbol_end ();
906
907  sym = symbol_find_or_make (name);
908
909  *input_line_pointer = c;
910
911  if (sym->sy_obj.versioned_name != NULL)
912    {
913      as_bad ("multiple .symver directives for symbol `%s'",
914	      S_GET_NAME (sym));
915      ignore_rest_of_line ();
916      return;
917    }
918
919  SKIP_WHITESPACE ();
920  if (*input_line_pointer != ',')
921    {
922      as_bad ("expected comma after name in .symver");
923      ignore_rest_of_line ();
924      return;
925    }
926
927  ++input_line_pointer;
928  name = input_line_pointer;
929  while (1)
930    {
931      c = get_symbol_end ();
932      if (c != ELF_VER_CHR)
933	break;
934      *input_line_pointer++ = c;
935    }
936
937  sym->sy_obj.versioned_name = xstrdup (name);
938
939  *input_line_pointer = c;
940
941  if (strchr (sym->sy_obj.versioned_name, ELF_VER_CHR) == NULL)
942    {
943      as_bad ("missing version name in `%s' for symbol `%s'",
944	      sym->sy_obj.versioned_name, S_GET_NAME (sym));
945      ignore_rest_of_line ();
946      return;
947    }
948
949  demand_empty_rest_of_line ();
950}
951
952void
953obj_read_begin_hook ()
954{
955#ifdef NEED_ECOFF_DEBUG
956  if (ECOFF_DEBUGGING)
957    ecoff_read_begin_hook ();
958#endif
959}
960
961void
962obj_symbol_new_hook (symbolP)
963     symbolS *symbolP;
964{
965  symbolP->sy_obj.size = NULL;
966  symbolP->sy_obj.versioned_name = NULL;
967
968#ifdef NEED_ECOFF_DEBUG
969  if (ECOFF_DEBUGGING)
970    ecoff_symbol_new_hook (symbolP);
971#endif
972}
973
974void
975obj_elf_version (ignore)
976     int ignore;
977{
978  char *name;
979  unsigned int c;
980  char ch;
981  char *p;
982  asection *seg = now_seg;
983  subsegT subseg = now_subseg;
984  Elf_Internal_Note i_note;
985  Elf_External_Note e_note;
986  asection *note_secp = (asection *) NULL;
987  int i, len;
988
989  SKIP_WHITESPACE ();
990  if (*input_line_pointer == '\"')
991    {
992      ++input_line_pointer;	/* -> 1st char of string. */
993      name = input_line_pointer;
994
995      while (is_a_char (c = next_char_of_string ()))
996	;
997      c = *input_line_pointer;
998      *input_line_pointer = '\0';
999      *(input_line_pointer - 1) = '\0';
1000      *input_line_pointer = c;
1001
1002      /* create the .note section */
1003
1004      note_secp = subseg_new (".note", 0);
1005      bfd_set_section_flags (stdoutput,
1006			     note_secp,
1007			     SEC_HAS_CONTENTS | SEC_READONLY);
1008
1009      /* process the version string */
1010
1011      len = strlen (name);
1012
1013      i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
1014      i_note.descsz = 0;	/* no description */
1015      i_note.type = NT_VERSION;
1016      p = frag_more (sizeof (e_note.namesz));
1017      md_number_to_chars (p, (valueT) i_note.namesz, 4);
1018      p = frag_more (sizeof (e_note.descsz));
1019      md_number_to_chars (p, (valueT) i_note.descsz, 4);
1020      p = frag_more (sizeof (e_note.type));
1021      md_number_to_chars (p, (valueT) i_note.type, 4);
1022
1023      for (i = 0; i < len; i++)
1024	{
1025	  ch = *(name + i);
1026	  {
1027	    FRAG_APPEND_1_CHAR (ch);
1028	  }
1029	}
1030      frag_align (2, 0, 0);
1031
1032      subseg_set (seg, subseg);
1033    }
1034  else
1035    {
1036      as_bad ("Expected quoted string");
1037    }
1038  demand_empty_rest_of_line ();
1039}
1040
1041static void
1042obj_elf_size (ignore)
1043     int ignore;
1044{
1045  char *name = input_line_pointer;
1046  char c = get_symbol_end ();
1047  char *p;
1048  expressionS exp;
1049  symbolS *sym;
1050
1051  p = input_line_pointer;
1052  *p = c;
1053  SKIP_WHITESPACE ();
1054  if (*input_line_pointer != ',')
1055    {
1056      *p = 0;
1057      as_bad ("expected comma after name `%s' in .size directive", name);
1058      *p = c;
1059      ignore_rest_of_line ();
1060      return;
1061    }
1062  input_line_pointer++;
1063  expression (&exp);
1064  if (exp.X_op == O_absent)
1065    {
1066      as_bad ("missing expression in .size directive");
1067      exp.X_op = O_constant;
1068      exp.X_add_number = 0;
1069    }
1070  *p = 0;
1071  sym = symbol_find_or_make (name);
1072  *p = c;
1073  if (exp.X_op == O_constant)
1074    S_SET_SIZE (sym, exp.X_add_number);
1075  else
1076    {
1077      sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS));
1078      *sym->sy_obj.size = exp;
1079    }
1080  demand_empty_rest_of_line ();
1081}
1082
1083/* Handle the ELF .type pseudo-op.  This sets the type of a symbol.
1084   There are three syntaxes.  The first (used on Solaris) is
1085       .type SYM,#function
1086   The second (used on UnixWare) is
1087       .type SYM,@function
1088   The third (reportedly to be used on Irix 6.0) is
1089       .type SYM STT_FUNC
1090   */
1091
1092static void
1093obj_elf_type (ignore)
1094     int ignore;
1095{
1096  char *name;
1097  char c;
1098  int type;
1099  const char *typename;
1100  symbolS *sym;
1101
1102  name = input_line_pointer;
1103  c = get_symbol_end ();
1104  sym = symbol_find_or_make (name);
1105  *input_line_pointer = c;
1106
1107  SKIP_WHITESPACE ();
1108  if (*input_line_pointer == ',')
1109    ++input_line_pointer;
1110
1111  SKIP_WHITESPACE ();
1112  if (*input_line_pointer == '#' || *input_line_pointer == '@')
1113    ++input_line_pointer;
1114
1115  typename = input_line_pointer;
1116  c = get_symbol_end ();
1117
1118  type = 0;
1119  if (strcmp (typename, "function") == 0
1120      || strcmp (typename, "STT_FUNC") == 0)
1121    type = BSF_FUNCTION;
1122  else if (strcmp (typename, "object") == 0
1123	   || strcmp (typename, "STT_OBJECT") == 0)
1124    type = BSF_OBJECT;
1125  else
1126    as_bad ("ignoring unrecognized symbol type \"%s\"", typename);
1127
1128  *input_line_pointer = c;
1129
1130  sym->bsym->flags |= type;
1131
1132  demand_empty_rest_of_line ();
1133}
1134
1135static void
1136obj_elf_ident (ignore)
1137     int ignore;
1138{
1139  static segT comment_section;
1140  segT old_section = now_seg;
1141  int old_subsection = now_subseg;
1142
1143  if (!comment_section)
1144    {
1145      char *p;
1146      comment_section = subseg_new (".comment", 0);
1147      bfd_set_section_flags (stdoutput, comment_section,
1148			     SEC_READONLY | SEC_HAS_CONTENTS);
1149      p = frag_more (1);
1150      *p = 0;
1151    }
1152  else
1153    subseg_set (comment_section, 0);
1154  stringer (1);
1155  subseg_set (old_section, old_subsection);
1156}
1157
1158#ifdef INIT_STAB_SECTION
1159
1160/* The first entry in a .stabs section is special.  */
1161
1162void
1163obj_elf_init_stab_section (seg)
1164     segT seg;
1165{
1166  char *file;
1167  char *p;
1168  char *stabstr_name;
1169  unsigned int stroff;
1170
1171  /* Force the section to align to a longword boundary.  Without this,
1172     UnixWare ar crashes.  */
1173  bfd_set_section_alignment (stdoutput, seg, 2);
1174
1175  /* Make space for this first symbol. */
1176  p = frag_more (12);
1177  /* Zero it out. */
1178  memset (p, 0, 12);
1179  as_where (&file, (unsigned int *) NULL);
1180  stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
1181  strcpy (stabstr_name, segment_name (seg));
1182  strcat (stabstr_name, "str");
1183  stroff = get_stab_string_offset (file, stabstr_name);
1184  know (stroff == 1);
1185  md_number_to_chars (p, stroff, 4);
1186  seg_info (seg)->stabu.p = p;
1187}
1188
1189#endif
1190
1191/* Fill in the counts in the first entry in a .stabs section.  */
1192
1193static void
1194adjust_stab_sections (abfd, sec, xxx)
1195     bfd *abfd;
1196     asection *sec;
1197     PTR xxx;
1198{
1199  char *name;
1200  asection *strsec;
1201  char *p;
1202  int strsz, nsyms;
1203
1204  if (strncmp (".stab", sec->name, 5))
1205    return;
1206  if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
1207    return;
1208
1209  name = (char *) alloca (strlen (sec->name) + 4);
1210  strcpy (name, sec->name);
1211  strcat (name, "str");
1212  strsec = bfd_get_section_by_name (abfd, name);
1213  if (strsec)
1214    strsz = bfd_section_size (abfd, strsec);
1215  else
1216    strsz = 0;
1217  nsyms = bfd_section_size (abfd, sec) / 12 - 1;
1218
1219  p = seg_info (sec)->stabu.p;
1220  assert (p != 0);
1221
1222  bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
1223  bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
1224}
1225
1226#ifdef NEED_ECOFF_DEBUG
1227
1228/* This function is called by the ECOFF code.  It is supposed to
1229   record the external symbol information so that the backend can
1230   write it out correctly.  The ELF backend doesn't actually handle
1231   this at the moment, so we do it ourselves.  We save the information
1232   in the symbol.  */
1233
1234void
1235elf_ecoff_set_ext (sym, ext)
1236     symbolS *sym;
1237     struct ecoff_extr *ext;
1238{
1239  sym->bsym->udata.p = (PTR) ext;
1240}
1241
1242/* This function is called by bfd_ecoff_debug_externals.  It is
1243   supposed to *EXT to the external symbol information, and return
1244   whether the symbol should be used at all.  */
1245
1246static boolean
1247elf_get_extr (sym, ext)
1248     asymbol *sym;
1249     EXTR *ext;
1250{
1251  if (sym->udata.p == NULL)
1252    return false;
1253  *ext = *(EXTR *) sym->udata.p;
1254  return true;
1255}
1256
1257/* This function is called by bfd_ecoff_debug_externals.  It has
1258   nothing to do for ELF.  */
1259
1260/*ARGSUSED*/
1261static void
1262elf_set_index (sym, indx)
1263     asymbol *sym;
1264     bfd_size_type indx;
1265{
1266}
1267
1268#endif /* NEED_ECOFF_DEBUG */
1269
1270void
1271elf_frob_symbol (symp, puntp)
1272     symbolS *symp;
1273     int *puntp;
1274{
1275#ifdef NEED_ECOFF_DEBUG
1276  if (ECOFF_DEBUGGING)
1277    ecoff_frob_symbol (symp);
1278#endif
1279
1280  if (symp->sy_obj.size != NULL)
1281    {
1282      switch (symp->sy_obj.size->X_op)
1283	{
1284	case O_subtract:
1285	  S_SET_SIZE (symp,
1286		      (S_GET_VALUE (symp->sy_obj.size->X_add_symbol)
1287		       + symp->sy_obj.size->X_add_number
1288		       - S_GET_VALUE (symp->sy_obj.size->X_op_symbol)));
1289	  break;
1290	case O_constant:
1291	  S_SET_SIZE (symp,
1292		      (S_GET_VALUE (symp->sy_obj.size->X_add_symbol)
1293		       + symp->sy_obj.size->X_add_number));
1294	  break;
1295	default:
1296	  as_bad (".size expression too complicated to fix up");
1297	  break;
1298	}
1299      free (symp->sy_obj.size);
1300      symp->sy_obj.size = NULL;
1301    }
1302
1303  if (symp->sy_obj.versioned_name != NULL)
1304    {
1305      /* This symbol was given a new name with the .symver directive.
1306
1307         If this is an external reference, just rename the symbol to
1308         include the version string.  This will make the relocs be
1309         against the correct versioned symbol.
1310
1311	 If this is a definition, add an alias.  FIXME: Using an alias
1312	 will permit the debugging information to refer to the right
1313	 symbol.  However, it's not clear whether it is the best
1314	 approach.  */
1315
1316      if (! S_IS_DEFINED (symp))
1317	{
1318	  char *p;
1319
1320	  /* Verify that the name isn't using the @@ syntax--this is
1321             reserved for definitions of the default version to link
1322             against.  */
1323	  p = strchr (symp->sy_obj.versioned_name, ELF_VER_CHR);
1324	  know (p != NULL);
1325	  if (p[1] == ELF_VER_CHR)
1326	    {
1327	      as_bad ("invalid attempt to declare external version name as default in symbol `%s'",
1328		      symp->sy_obj.versioned_name);
1329	      *puntp = true;
1330	    }
1331	  S_SET_NAME (symp, symp->sy_obj.versioned_name);
1332	}
1333      else
1334	{
1335	  symbolS *symp2;
1336
1337	  /* FIXME: Creating a new symbol here is risky.  We're in the
1338             final loop over the symbol table.  We can get away with
1339             it only because the symbol goes to the end of the list,
1340             where the loop will still see it.  It would probably be
1341             better to do this in obj_frob_file_before_adjust. */
1342
1343	  symp2 = symbol_find_or_make (symp->sy_obj.versioned_name);
1344
1345	  /* Now we act as though we saw symp2 = sym.  */
1346
1347	  S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
1348
1349	  /* Subtracting out the frag address here is a hack because
1350             we are in the middle of the final loop.  */
1351	  S_SET_VALUE (symp2, S_GET_VALUE (symp) - symp->sy_frag->fr_address);
1352
1353	  symp2->sy_frag = symp->sy_frag;
1354
1355	  /* This will copy over the size information.  */
1356	  copy_symbol_attributes (symp2, symp);
1357
1358	  if (S_IS_WEAK (symp))
1359	    S_SET_WEAK (symp2);
1360
1361	  if (S_IS_EXTERNAL (symp))
1362	    S_SET_EXTERNAL (symp2);
1363	}
1364    }
1365
1366  /* Double check weak symbols.  */
1367  if (symp->bsym->flags & BSF_WEAK)
1368    {
1369      if (S_IS_COMMON (symp))
1370	as_bad ("Symbol `%s' can not be both weak and common",
1371		S_GET_NAME (symp));
1372    }
1373
1374#ifdef TC_MIPS
1375  /* The Irix 5 and 6 assemblers set the type of any common symbol and
1376     any undefined non-function symbol to STT_OBJECT.  We try to be compatible,
1377     since newer Irix 5 and 6 linkers care.  */
1378  if (S_IS_COMMON (symp)
1379      || (! S_IS_DEFINED (symp) && ((symp->bsym->flags & BSF_FUNCTION) == 0)))
1380    symp->bsym->flags |= BSF_OBJECT;
1381#endif
1382
1383#ifdef TC_PPC
1384  /* Frob the PowerPC, so that the symbol always has object type
1385     if it is not some other type.  VxWorks needs this.  */
1386  if ((symp->bsym->flags & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
1387      && S_IS_DEFINED (symp))
1388    symp->bsym->flags |= BSF_OBJECT;
1389#endif
1390}
1391
1392void
1393elf_frob_file ()
1394{
1395  bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
1396
1397#ifdef elf_tc_final_processing
1398  elf_tc_final_processing ();
1399#endif
1400}
1401
1402/* It is required that we let write_relocs have the opportunity to
1403   optimize away fixups before output has begun, since it is possible
1404   to eliminate all fixups for a section and thus we never should
1405   have generated the relocation section.  */
1406
1407void
1408elf_frob_file_after_relocs ()
1409{
1410#ifdef NEED_ECOFF_DEBUG
1411  if (ECOFF_DEBUGGING)
1412    /* Generate the ECOFF debugging information.  */
1413    {
1414      const struct ecoff_debug_swap *debug_swap;
1415      struct ecoff_debug_info debug;
1416      char *buf;
1417      asection *sec;
1418
1419      debug_swap
1420	= get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1421      know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1422      ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1423
1424      /* Set up the pointers in debug.  */
1425#define SET(ptr, offset, type) \
1426    debug.ptr = (type) (buf + debug.symbolic_header.offset)
1427
1428      SET (line, cbLineOffset, unsigned char *);
1429      SET (external_dnr, cbDnOffset, PTR);
1430      SET (external_pdr, cbPdOffset, PTR);
1431      SET (external_sym, cbSymOffset, PTR);
1432      SET (external_opt, cbOptOffset, PTR);
1433      SET (external_aux, cbAuxOffset, union aux_ext *);
1434      SET (ss, cbSsOffset, char *);
1435      SET (external_fdr, cbFdOffset, PTR);
1436      SET (external_rfd, cbRfdOffset, PTR);
1437      /* ssext and external_ext are set up just below.  */
1438
1439#undef SET
1440
1441      /* Set up the external symbols.  */
1442      debug.ssext = debug.ssext_end = NULL;
1443      debug.external_ext = debug.external_ext_end = NULL;
1444      if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1445				       elf_get_extr, elf_set_index))
1446	as_fatal ("Failed to set up debugging information: %s",
1447		  bfd_errmsg (bfd_get_error ()));
1448
1449      sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1450      assert (sec != NULL);
1451
1452      know (stdoutput->output_has_begun == false);
1453
1454      /* We set the size of the section, call bfd_set_section_contents
1455	 to force the ELF backend to allocate a file position, and then
1456	 write out the data.  FIXME: Is this really the best way to do
1457	 this?  */
1458      sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1459
1460      if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
1461				      (file_ptr) 0, (bfd_size_type) 0))
1462	as_fatal ("Can't start writing .mdebug section: %s",
1463		  bfd_errmsg (bfd_get_error ()));
1464
1465      know (stdoutput->output_has_begun == true);
1466      know (sec->filepos != 0);
1467
1468      if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1469				   sec->filepos))
1470	as_fatal ("Could not write .mdebug section: %s",
1471		  bfd_errmsg (bfd_get_error ()));
1472    }
1473#endif /* NEED_ECOFF_DEBUG */
1474}
1475
1476#ifdef SCO_ELF
1477
1478/* Heavily plagarized from obj_elf_version.  The idea is to emit the
1479   SCO specific identifier in the .notes section to satisfy the SCO
1480   linker.
1481
1482   This looks more complicated than it really is.  As opposed to the
1483   "obvious" solution, this should handle the cross dev cases
1484   correctly.  (i.e, hosting on a 64 bit big endian processor, but
1485   generating SCO Elf code) Efficiency isn't a concern, as there
1486   should be exactly one of these sections per object module.
1487
1488   SCO OpenServer 5 identifies it's ELF modules with a standard ELF
1489   .note section.
1490
1491   int_32 namesz  = 4 ;  Name size
1492   int_32 descsz  = 12 ; Descriptive information
1493   int_32 type    = 1 ;
1494   char   name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
1495   int_32 version = (major ver # << 16)  | version of tools ;
1496   int_32 source  = (tool_id << 16 ) | 1 ;
1497   int_32 info    = 0 ;    These are set by the SCO tools, but we
1498                           don't know enough about the source
1499			   environment to set them.  SCO ld currently
1500			   ignores them, and recommends we set them
1501			   to zero.  */
1502
1503#define SCO_MAJOR_VERSION 0x1
1504#define SCO_MINOR_VERSION 0x1
1505
1506void
1507sco_id ()
1508{
1509
1510  char *name;
1511  unsigned int c;
1512  char ch;
1513  char *p;
1514  asection *seg = now_seg;
1515  subsegT subseg = now_subseg;
1516  Elf_Internal_Note i_note;
1517  Elf_External_Note e_note;
1518  asection *note_secp = (asection *) NULL;
1519  int i, len;
1520
1521  /* create the .note section */
1522
1523  note_secp = subseg_new (".note", 0);
1524  bfd_set_section_flags (stdoutput,
1525			 note_secp,
1526			 SEC_HAS_CONTENTS | SEC_READONLY);
1527
1528  /* process the version string */
1529
1530  i_note.namesz = 4;
1531  i_note.descsz = 12;		/* 12 descriptive bytes */
1532  i_note.type = NT_VERSION;	/* Contains a version string */
1533
1534  p = frag_more (sizeof (i_note.namesz));
1535  md_number_to_chars (p, (valueT) i_note.namesz, 4);
1536
1537  p = frag_more (sizeof (i_note.descsz));
1538  md_number_to_chars (p, (valueT) i_note.descsz, 4);
1539
1540  p = frag_more (sizeof (i_note.type));
1541  md_number_to_chars (p, (valueT) i_note.type, 4);
1542
1543  p = frag_more (4);
1544  strcpy (p, "SCO");
1545
1546  /* Note: this is the version number of the ELF we're representing */
1547  p = frag_more (4);
1548  md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
1549
1550  /* Here, we pick a magic number for ourselves (yes, I "registered"
1551     it with SCO.  The bottom bit shows that we are compat with the
1552     SCO ABI.  */
1553  p = frag_more (4);
1554  md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
1555
1556  /* If we knew (or cared) what the source language options were, we'd
1557     fill them in here.  SCO has given us permission to ignore these
1558     and just set them to zero.  */
1559  p = frag_more (4);
1560  md_number_to_chars (p, 0x0000, 4);
1561
1562  frag_align (2, 0, 0);
1563
1564  /* We probably can't restore the current segment, for there likely
1565     isn't one yet...  */
1566  if (seg && subseg)
1567    subseg_set (seg, subseg);
1568
1569}
1570
1571#endif /* SCO_ELF */
1572
1573const struct format_ops elf_format_ops =
1574{
1575  bfd_target_elf_flavour,
1576  0,
1577  1,
1578  elf_frob_symbol,
1579  elf_frob_file,
1580  elf_frob_file_after_relocs,
1581  elf_s_get_size, elf_s_set_size,
1582  elf_s_get_align, elf_s_set_align,
1583  elf_copy_symbol_attributes,
1584#ifdef NEED_ECOFF_DEBUG
1585  ecoff_generate_asm_lineno,
1586  ecoff_stab,
1587#else
1588  0,
1589  0,				/* process_stab */
1590#endif
1591  elf_sec_sym_ok_for_reloc,
1592  elf_pop_insert,
1593#ifdef NEED_ECOFF_DEBUG
1594  elf_ecoff_set_ext,
1595#else
1596  0,
1597#endif
1598  obj_read_begin_hook,
1599  obj_symbol_new_hook,
1600};
1601