133965Sjdp/* ECOFF object file format.
2218822Sdim   Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
3218822Sdim   2005  Free Software Foundation, Inc.
433965Sjdp   Contributed by Cygnus Support.
533965Sjdp   This file was put together by Ian Lance Taylor <ian@cygnus.com>.
633965Sjdp
733965Sjdp   This file is part of GAS.
833965Sjdp
933965Sjdp   GAS is free software; you can redistribute it and/or modify
1033965Sjdp   it under the terms of the GNU General Public License as published by
1133965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1233965Sjdp   any later version.
1333965Sjdp
1433965Sjdp   GAS is distributed in the hope that it will be useful,
1533965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1633965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1733965Sjdp   GNU General Public License for more details.
1833965Sjdp
1933965Sjdp   You should have received a copy of the GNU General Public License
2033965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
21218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22218822Sdim   02110-1301, USA.  */
2333965Sjdp
2433965Sjdp#define OBJ_HEADER "obj-ecoff.h"
2533965Sjdp#include "as.h"
2633965Sjdp#include "coff/internal.h"
2733965Sjdp#include "bfd/libcoff.h"
2833965Sjdp#include "bfd/libecoff.h"
2933965Sjdp
3033965Sjdp/* Almost all of the ECOFF support is actually in ecoff.c in the main
3133965Sjdp   gas directory.  This file mostly just arranges to call that one at
3233965Sjdp   the right times.  */
3333965Sjdp
34130561Sobrien/* Set section VMAs and GP values before reloc processing.  */
3533965Sjdp
3633965Sjdpvoid
37218822Sdimecoff_frob_file_before_fix (void)
3833965Sjdp{
3933965Sjdp  bfd_vma addr;
40218822Sdim  asection *sec;
4133965Sjdp
4233965Sjdp  /* Set the section VMA values.  We force the .sdata and .sbss
4333965Sjdp     sections to the end to ensure that their VMA addresses are close
4433965Sjdp     together so that the GP register can address both of them.  We
4533965Sjdp     put the .bss section after the .sbss section.
4633965Sjdp
4733965Sjdp     Also, for the Alpha, we must sort the sections, to make sure they
4833965Sjdp     appear in the output file in the correct order.  (Actually, maybe
4933965Sjdp     this is a job for BFD.  But the VMAs computed would be out of
5033965Sjdp     whack if we computed them given our initial, random ordering.
5133965Sjdp     It's possible that that wouldn't break things; I could do some
5233965Sjdp     experimenting sometime and find out.
5333965Sjdp
5433965Sjdp     This output ordering of sections is magic, on the Alpha, at
5533965Sjdp     least.  The .lita section must come before .lit8 and .lit4,
5633965Sjdp     otherwise the OSF/1 linker may silently trash the .lit{4,8}
5733965Sjdp     section contents.  Also, .text must preceed .rdata.  These differ
5833965Sjdp     from the order described in some parts of the DEC OSF/1 Assembly
5933965Sjdp     Language Programmer's Guide, but that order doesn't seem to work
6033965Sjdp     with their linker.
6133965Sjdp
6233965Sjdp     I don't know if section ordering on the MIPS is important.  */
6333965Sjdp
64218822Sdim  static const char *const names[] =
65218822Sdim  {
6633965Sjdp    /* text segment */
6733965Sjdp    ".text", ".rdata", ".init", ".fini",
6833965Sjdp    /* data segment */
6933965Sjdp    ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
7033965Sjdp    /* bss segment */
7133965Sjdp    ".sbss", ".bss",
7233965Sjdp  };
7378828Sobrien#define n_names ((int) (sizeof (names) / sizeof (names[0])))
7433965Sjdp
7589857Sobrien  /* Sections that match names, order to be straightened out later.  */
7689857Sobrien  asection *secs[n_names];
7789857Sobrien  int i;
7889857Sobrien
7933965Sjdp  addr = 0;
8089857Sobrien  for (i = 0; i < n_names; i++)
81218822Sdim    secs[i] = NULL;
8233965Sjdp
83218822Sdim  for (sec = stdoutput->sections; sec != NULL; sec = sec->next)
8489857Sobrien    {
8589857Sobrien      for (i = 0; i < n_names; i++)
86218822Sdim	if (!strcmp (sec->name, names[i]))
8733965Sjdp	  {
88218822Sdim	    secs[i] = sec;
8989857Sobrien	    bfd_section_list_remove (stdoutput, sec);
9089857Sobrien	    break;
9133965Sjdp	  }
9289857Sobrien      if (i == n_names)
9333965Sjdp	{
94218822Sdim	  bfd_set_section_vma (stdoutput, sec, addr);
95218822Sdim	  addr += bfd_section_size (stdoutput, sec);
9633965Sjdp	}
9789857Sobrien    }
9889857Sobrien  for (i = 0; i < n_names; i++)
9989857Sobrien    if (secs[i])
10089857Sobrien      {
10189857Sobrien	bfd_set_section_vma (stdoutput, secs[i], addr);
10289857Sobrien	addr += bfd_section_size (stdoutput, secs[i]);
10389857Sobrien      }
10489857Sobrien  for (i = n_names - 1; i >= 0; i--)
10589857Sobrien    if (secs[i])
106218822Sdim      bfd_section_list_prepend (stdoutput, secs[i]);
10733965Sjdp
108130561Sobrien  /* Fill in the register masks.  */
109130561Sobrien  {
110130561Sobrien    unsigned long gprmask = 0;
111130561Sobrien    unsigned long fprmask = 0;
112130561Sobrien    unsigned long *cprmask = NULL;
113130561Sobrien
114130561Sobrien#ifdef TC_MIPS
115130561Sobrien    /* Fill in the MIPS register masks.  It's probably not worth
116130561Sobrien       setting up a generic interface for this.  */
117130561Sobrien    gprmask = mips_gprmask;
118130561Sobrien    cprmask = mips_cprmask;
119130561Sobrien#endif
120130561Sobrien
121130561Sobrien#ifdef TC_ALPHA
122130561Sobrien    alpha_frob_ecoff_data ();
123130561Sobrien
124130561Sobrien    if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
125130561Sobrien      as_fatal (_("Can't set GP value"));
126130561Sobrien
127130561Sobrien    gprmask = alpha_gprmask;
128130561Sobrien    fprmask = alpha_fprmask;
129130561Sobrien#endif
130130561Sobrien
131130561Sobrien    if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
132130561Sobrien      as_fatal (_("Can't set register masks"));
133130561Sobrien  }
134130561Sobrien}
135130561Sobrien
136130561Sobrien/* Swap out the symbols and debugging information for BFD.  */
137130561Sobrien
138130561Sobrienvoid
139218822Sdimecoff_frob_file (void)
140130561Sobrien{
141130561Sobrien  const struct ecoff_debug_swap * const debug_swap
142130561Sobrien    = &ecoff_backend (stdoutput)->debug_swap;
143130561Sobrien  bfd_vma addr ATTRIBUTE_UNUSED;
144130561Sobrien  HDRR *hdr;
145130561Sobrien  char *buf;
146130561Sobrien  char *set;
147130561Sobrien
14833965Sjdp  /* Build the ECOFF debugging information.  */
14933965Sjdp  assert (ecoff_data (stdoutput) != 0);
15033965Sjdp  hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
15133965Sjdp  ecoff_build_debug (hdr, &buf, debug_swap);
15233965Sjdp
15333965Sjdp  /* Finish up the ecoff_tdata structure.  */
15433965Sjdp  set = buf;
15533965Sjdp#define SET(ptr, count, type, size) \
15633965Sjdp  if (hdr->count == 0) \
157218822Sdim    ecoff_data (stdoutput)->debug_info.ptr = NULL; \
15833965Sjdp  else \
15933965Sjdp    { \
16033965Sjdp      ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
16133965Sjdp      set += hdr->count * size; \
16233965Sjdp    }
16333965Sjdp
16433965Sjdp  SET (line, cbLine, unsigned char *, sizeof (unsigned char));
165218822Sdim  SET (external_dnr, idnMax, void *, debug_swap->external_dnr_size);
166218822Sdim  SET (external_pdr, ipdMax, void *, debug_swap->external_pdr_size);
167218822Sdim  SET (external_sym, isymMax, void *, debug_swap->external_sym_size);
168218822Sdim  SET (external_opt, ioptMax, void *, debug_swap->external_opt_size);
16933965Sjdp  SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
17033965Sjdp  SET (ss, issMax, char *, sizeof (char));
17133965Sjdp  SET (ssext, issExtMax, char *, sizeof (char));
172218822Sdim  SET (external_rfd, crfd, void *, debug_swap->external_rfd_size);
173218822Sdim  SET (external_fdr, ifdMax, void *, debug_swap->external_fdr_size);
174218822Sdim  SET (external_ext, iextMax, void *, debug_swap->external_ext_size);
17533965Sjdp#undef SET
17633965Sjdp}
17733965Sjdp
17833965Sjdp/* This is called by the ECOFF code to set the external information
17933965Sjdp   for a symbol.  We just pass it on to BFD, which expects the swapped
18033965Sjdp   information to be stored in the native field of the symbol.  */
18133965Sjdp
18233965Sjdpvoid
183218822Sdimobj_ecoff_set_ext (symbolS *sym, EXTR *ext)
18433965Sjdp{
18533965Sjdp  const struct ecoff_debug_swap * const debug_swap
18633965Sjdp    = &ecoff_backend (stdoutput)->debug_swap;
18733965Sjdp  ecoff_symbol_type *esym;
18833965Sjdp
18960484Sobrien  know (bfd_asymbol_flavour (symbol_get_bfdsym (sym))
19060484Sobrien	== bfd_target_ecoff_flavour);
19160484Sobrien  esym = ecoffsymbol (symbol_get_bfdsym (sym));
192130561Sobrien  esym->local = FALSE;
19333965Sjdp  esym->native = xmalloc (debug_swap->external_ext_size);
19433965Sjdp  (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
19533965Sjdp}
19633965Sjdp
19733965Sjdpstatic int
198218822Sdimecoff_sec_sym_ok_for_reloc (asection *sec ATTRIBUTE_UNUSED)
19933965Sjdp{
20033965Sjdp  return 1;
20133965Sjdp}
20233965Sjdp
20333965Sjdpstatic void
204218822Sdimobj_ecoff_frob_symbol (symbolS *sym, int *puntp ATTRIBUTE_UNUSED)
20533965Sjdp{
20633965Sjdp  ecoff_frob_symbol (sym);
20733965Sjdp}
20833965Sjdp
20933965Sjdpstatic void
210218822Sdimecoff_pop_insert (void)
21133965Sjdp{
21233965Sjdp  pop_insert (obj_pseudo_table);
21333965Sjdp}
21433965Sjdp
21577298Sobrienstatic int
216218822Sdimecoff_separate_stab_sections (void)
21777298Sobrien{
21877298Sobrien  return 0;
21977298Sobrien}
22077298Sobrien
221218822Sdim/* These are the pseudo-ops we support in this file.  Only those
222218822Sdim   relating to debugging information are supported here.
223218822Sdim
224218822Sdim   The following pseudo-ops from the Kane and Heinrich MIPS book
225218822Sdim   should be defined here, but are currently unsupported: .aent,
226218822Sdim   .bgnb, .endb, .verstamp, .vreg.
227218822Sdim
228218822Sdim   The following pseudo-ops from the Kane and Heinrich MIPS book are
229218822Sdim   MIPS CPU specific, and should be defined by tc-mips.c: .alias,
230218822Sdim   .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
231218822Sdim   .rdata, .sdata, .set.
232218822Sdim
233218822Sdim   The following pseudo-ops from the Kane and Heinrich MIPS book are
234218822Sdim   not MIPS CPU specific, but are also not ECOFF specific.  I have
235218822Sdim   only listed the ones which are not already in read.c.  It's not
236218822Sdim   completely clear where these should be defined, but tc-mips.c is
237218822Sdim   probably the most reasonable place: .asciiz, .asm0, .endr, .err,
238218822Sdim   .half, .lab, .repeat, .struct, .weakext.  */
239218822Sdim
240218822Sdimconst pseudo_typeS obj_pseudo_table[] =
241218822Sdim{
242218822Sdim  /* COFF style debugging information. .ln is not used; .loc is used
243218822Sdim     instead.  */
244218822Sdim  { "def",	ecoff_directive_def,	0 },
245218822Sdim  { "dim",	ecoff_directive_dim,	0 },
246218822Sdim  { "endef",	ecoff_directive_endef,	0 },
247218822Sdim  { "file",	ecoff_directive_file,	0 },
248218822Sdim  { "scl",	ecoff_directive_scl,	0 },
249218822Sdim  { "size",	ecoff_directive_size,	0 },
250218822Sdim  { "esize",	ecoff_directive_size,	0 },
251218822Sdim  { "tag",	ecoff_directive_tag,	0 },
252218822Sdim  { "type",	ecoff_directive_type,	0 },
253218822Sdim  { "etype",	ecoff_directive_type,	0 },
254218822Sdim  { "val",	ecoff_directive_val,	0 },
255218822Sdim
256218822Sdim  /* ECOFF specific debugging information.  */
257218822Sdim  { "begin",	ecoff_directive_begin,	0 },
258218822Sdim  { "bend",	ecoff_directive_bend,	0 },
259218822Sdim  { "end",	ecoff_directive_end,	0 },
260218822Sdim  { "ent",	ecoff_directive_ent,	0 },
261218822Sdim  { "fmask",	ecoff_directive_fmask,	0 },
262218822Sdim  { "frame",	ecoff_directive_frame,	0 },
263218822Sdim  { "loc",	ecoff_directive_loc,	0 },
264218822Sdim  { "mask",	ecoff_directive_mask,	0 },
265218822Sdim
266218822Sdim  /* Other ECOFF directives.  */
267218822Sdim  { "extern",	ecoff_directive_extern,	0 },
268218822Sdim
269218822Sdim#ifndef TC_MIPS
270218822Sdim  /* For TC_MIPS, tc-mips.c adds this.  */
271218822Sdim  { "weakext",	ecoff_directive_weakext, 0 },
272218822Sdim#endif
273218822Sdim
274218822Sdim  /* These are used on Irix.  I don't know how to implement them.  */
275218822Sdim  { "bgnb",	s_ignore,		0 },
276218822Sdim  { "endb",	s_ignore,		0 },
277218822Sdim  { "verstamp",	s_ignore,		0 },
278218822Sdim
279218822Sdim  /* Sentinel.  */
280218822Sdim  { NULL,	s_ignore,		0 }
281218822Sdim};
282218822Sdim
28333965Sjdpconst struct format_ops ecoff_format_ops =
28433965Sjdp{
28533965Sjdp  bfd_target_ecoff_flavour,
286218822Sdim  0,	/* dfl_leading_underscore.  */
28777298Sobrien
28877298Sobrien  /* FIXME: A comment why emit_section_symbols is different here (1) from
28977298Sobrien     the single-format definition (0) would be in order.  */
290218822Sdim  1,	/* emit_section_symbols.  */
291218822Sdim  0,	/* begin.  */
29277298Sobrien  ecoff_new_file,
29333965Sjdp  obj_ecoff_frob_symbol,
29433965Sjdp  ecoff_frob_file,
295218822Sdim  0,	/* frob_file_before_adjust.  */
296130561Sobrien  ecoff_frob_file_before_fix,
297218822Sdim  0,	/* frob_file_after_relocs.  */
298218822Sdim  0,	/* s_get_size.  */
299218822Sdim  0,	/* s_set_size.  */
300218822Sdim  0,	/* s_get_align.  */
301218822Sdim  0,	/* s_set_align.  */
302218822Sdim  0,	/* s_get_other.  */
303218822Sdim  0,	/* s_set_other.  */
304218822Sdim  0,	/* s_get_desc.  */
305218822Sdim  0,	/* s_set_desc.  */
306218822Sdim  0,	/* s_get_type.  */
307218822Sdim  0,	/* s_set_type.  */
308218822Sdim  0,	/* copy_symbol_attributes.  */
30933965Sjdp  ecoff_generate_asm_lineno,
31033965Sjdp  ecoff_stab,
31177298Sobrien  ecoff_separate_stab_sections,
312218822Sdim  0,	/* init_stab_section.  */
31333965Sjdp  ecoff_sec_sym_ok_for_reloc,
31433965Sjdp  ecoff_pop_insert,
31533965Sjdp  ecoff_set_ext,
31633965Sjdp  ecoff_read_begin_hook,
31777298Sobrien  ecoff_symbol_new_hook
31833965Sjdp};
319