obj-ecoff.c revision 77298
133965Sjdp/* ECOFF object file format.
260484Sobrien   Copyright (C) 1993, 94, 95, 96, 97, 98, 99, 2000
360484Sobrien   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
2133965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2233965Sjdp   02111-1307, 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
3433965Sjdpstatic int ecoff_sec_sym_ok_for_reloc PARAMS ((asection *));
3533965Sjdpstatic void obj_ecoff_frob_symbol PARAMS ((symbolS *, int *));
3633965Sjdpstatic void ecoff_pop_insert PARAMS ((void));
3777298Sobrienstatic int ecoff_separate_stab_sections PARAMS ((void));
3833965Sjdp
3933965Sjdp/* These are the pseudo-ops we support in this file.  Only those
4033965Sjdp   relating to debugging information are supported here.
4133965Sjdp
4233965Sjdp   The following pseudo-ops from the Kane and Heinrich MIPS book
4333965Sjdp   should be defined here, but are currently unsupported: .aent,
4433965Sjdp   .bgnb, .endb, .verstamp, .vreg.
4533965Sjdp
4633965Sjdp   The following pseudo-ops from the Kane and Heinrich MIPS book are
4733965Sjdp   MIPS CPU specific, and should be defined by tc-mips.c: .alias,
4833965Sjdp   .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
4933965Sjdp   .rdata, .sdata, .set.
5033965Sjdp
5133965Sjdp   The following pseudo-ops from the Kane and Heinrich MIPS book are
5233965Sjdp   not MIPS CPU specific, but are also not ECOFF specific.  I have
5333965Sjdp   only listed the ones which are not already in read.c.  It's not
5433965Sjdp   completely clear where these should be defined, but tc-mips.c is
5533965Sjdp   probably the most reasonable place: .asciiz, .asm0, .endr, .err,
5633965Sjdp   .half, .lab, .repeat, .struct, .weakext.  */
5733965Sjdp
5833965Sjdpconst pseudo_typeS obj_pseudo_table[] =
5933965Sjdp{
6033965Sjdp  /* COFF style debugging information. .ln is not used; .loc is used
6133965Sjdp     instead.  */
6233965Sjdp  { "def",	ecoff_directive_def,	0 },
6333965Sjdp  { "dim",	ecoff_directive_dim,	0 },
6433965Sjdp  { "endef",	ecoff_directive_endef,	0 },
6533965Sjdp  { "file",	ecoff_directive_file,	0 },
6633965Sjdp  { "scl",	ecoff_directive_scl,	0 },
6733965Sjdp  { "size",	ecoff_directive_size,	0 },
6833965Sjdp  { "esize",	ecoff_directive_size,	0 },
6933965Sjdp  { "tag",	ecoff_directive_tag,	0 },
7033965Sjdp  { "type",	ecoff_directive_type,	0 },
7133965Sjdp  { "etype",	ecoff_directive_type,	0 },
7233965Sjdp  { "val",	ecoff_directive_val,	0 },
7333965Sjdp
7433965Sjdp  /* ECOFF specific debugging information.  */
7533965Sjdp  { "begin",	ecoff_directive_begin,	0 },
7633965Sjdp  { "bend",	ecoff_directive_bend,	0 },
7733965Sjdp  { "end",	ecoff_directive_end,	0 },
7833965Sjdp  { "ent",	ecoff_directive_ent,	0 },
7933965Sjdp  { "fmask",	ecoff_directive_fmask,	0 },
8033965Sjdp  { "frame",	ecoff_directive_frame,	0 },
8133965Sjdp  { "loc",	ecoff_directive_loc,	0 },
8233965Sjdp  { "mask",	ecoff_directive_mask,	0 },
8333965Sjdp
8433965Sjdp  /* Other ECOFF directives.  */
8533965Sjdp  { "extern",	ecoff_directive_extern,	0 },
8660484Sobrien
8760484Sobrien#ifndef TC_MIPS
8877298Sobrien  /* For TC_MIPS, tc-mips.c adds this.  */
8933965Sjdp  { "weakext",	ecoff_directive_weakext, 0 },
9060484Sobrien#endif
9133965Sjdp
9233965Sjdp  /* These are used on Irix.  I don't know how to implement them.  */
9333965Sjdp  { "bgnb",	s_ignore,		0 },
9433965Sjdp  { "endb",	s_ignore,		0 },
9533965Sjdp  { "verstamp",	s_ignore,		0 },
9633965Sjdp
9733965Sjdp  /* Sentinel.  */
9833965Sjdp  { NULL }
9933965Sjdp};
10033965Sjdp
10133965Sjdp/* Swap out the symbols and debugging information for BFD.  */
10233965Sjdp
10333965Sjdpvoid
10433965Sjdpecoff_frob_file ()
10533965Sjdp{
10633965Sjdp  const struct ecoff_debug_swap * const debug_swap
10733965Sjdp    = &ecoff_backend (stdoutput)->debug_swap;
10833965Sjdp  bfd_vma addr;
10933965Sjdp  asection *sec;
11033965Sjdp  HDRR *hdr;
11133965Sjdp  char *buf;
11233965Sjdp  char *set;
11333965Sjdp
11433965Sjdp  /* Set the section VMA values.  We force the .sdata and .sbss
11533965Sjdp     sections to the end to ensure that their VMA addresses are close
11633965Sjdp     together so that the GP register can address both of them.  We
11733965Sjdp     put the .bss section after the .sbss section.
11833965Sjdp
11933965Sjdp     Also, for the Alpha, we must sort the sections, to make sure they
12033965Sjdp     appear in the output file in the correct order.  (Actually, maybe
12133965Sjdp     this is a job for BFD.  But the VMAs computed would be out of
12233965Sjdp     whack if we computed them given our initial, random ordering.
12333965Sjdp     It's possible that that wouldn't break things; I could do some
12433965Sjdp     experimenting sometime and find out.
12533965Sjdp
12633965Sjdp     This output ordering of sections is magic, on the Alpha, at
12733965Sjdp     least.  The .lita section must come before .lit8 and .lit4,
12833965Sjdp     otherwise the OSF/1 linker may silently trash the .lit{4,8}
12933965Sjdp     section contents.  Also, .text must preceed .rdata.  These differ
13033965Sjdp     from the order described in some parts of the DEC OSF/1 Assembly
13133965Sjdp     Language Programmer's Guide, but that order doesn't seem to work
13233965Sjdp     with their linker.
13333965Sjdp
13433965Sjdp     I don't know if section ordering on the MIPS is important.  */
13533965Sjdp
13633965Sjdp  static const char *const names[] = {
13733965Sjdp    /* text segment */
13833965Sjdp    ".text", ".rdata", ".init", ".fini",
13933965Sjdp    /* data segment */
14033965Sjdp    ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
14133965Sjdp    /* bss segment */
14233965Sjdp    ".sbss", ".bss",
14333965Sjdp  };
14433965Sjdp#define n_names (sizeof (names) / sizeof (names[0]))
14533965Sjdp
14633965Sjdp  addr = 0;
14733965Sjdp  {
14833965Sjdp    /* Sections that match names, order to be straightened out later.  */
14933965Sjdp    asection *secs[n_names];
15033965Sjdp    /* Linked list of sections with non-matching names.  Random ordering.  */
15133965Sjdp    asection *other_sections = 0;
15233965Sjdp    /* Pointer to next section, since we're destroying the original
15333965Sjdp       ordering.  */
15433965Sjdp    asection *next;
15533965Sjdp
15633965Sjdp    int i;
15733965Sjdp
15833965Sjdp    for (i = 0; i < n_names; i++)
15933965Sjdp      secs[i] = 0;
16033965Sjdp    for (sec = stdoutput->sections; sec != (asection *) NULL; sec = next)
16133965Sjdp      {
16233965Sjdp	next = sec->next;
16333965Sjdp	for (i = 0; i < n_names; i++)
16433965Sjdp	  if (!strcmp (sec->name, names[i]))
16533965Sjdp	    {
16633965Sjdp	      secs[i] = sec;
16733965Sjdp	      break;
16833965Sjdp	    }
16933965Sjdp	if (i == n_names)
17033965Sjdp	  {
17133965Sjdp	    bfd_set_section_vma (stdoutput, sec, addr);
17233965Sjdp	    addr += bfd_section_size (stdoutput, sec);
17333965Sjdp	    sec->next = other_sections;
17433965Sjdp	    other_sections = sec;
17533965Sjdp	  }
17633965Sjdp      }
17733965Sjdp    for (i = 0; i < n_names; i++)
17833965Sjdp      if (secs[i])
17933965Sjdp	{
18033965Sjdp	  sec = secs[i];
18133965Sjdp	  bfd_set_section_vma (stdoutput, sec, addr);
18233965Sjdp	  addr += bfd_section_size (stdoutput, sec);
18333965Sjdp	}
18433965Sjdp    for (i = n_names - 1; i >= 0; i--)
18533965Sjdp      if (secs[i])
18633965Sjdp	{
18733965Sjdp	  sec = secs[i];
18833965Sjdp	  sec->next = other_sections;
18933965Sjdp	  other_sections = sec;
19033965Sjdp	}
19133965Sjdp    stdoutput->sections = other_sections;
19233965Sjdp  }
19333965Sjdp
19433965Sjdp  /* Build the ECOFF debugging information.  */
19533965Sjdp  assert (ecoff_data (stdoutput) != 0);
19633965Sjdp  hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
19733965Sjdp  ecoff_build_debug (hdr, &buf, debug_swap);
19833965Sjdp
19933965Sjdp  /* Finish up the ecoff_tdata structure.  */
20033965Sjdp  set = buf;
20133965Sjdp#define SET(ptr, count, type, size) \
20233965Sjdp  if (hdr->count == 0) \
20333965Sjdp    ecoff_data (stdoutput)->debug_info.ptr = (type) NULL; \
20433965Sjdp  else \
20533965Sjdp    { \
20633965Sjdp      ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
20733965Sjdp      set += hdr->count * size; \
20833965Sjdp    }
20933965Sjdp
21033965Sjdp  SET (line, cbLine, unsigned char *, sizeof (unsigned char));
21133965Sjdp  SET (external_dnr, idnMax, PTR, debug_swap->external_dnr_size);
21233965Sjdp  SET (external_pdr, ipdMax, PTR, debug_swap->external_pdr_size);
21333965Sjdp  SET (external_sym, isymMax, PTR, debug_swap->external_sym_size);
21433965Sjdp  SET (external_opt, ioptMax, PTR, debug_swap->external_opt_size);
21533965Sjdp  SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
21633965Sjdp  SET (ss, issMax, char *, sizeof (char));
21733965Sjdp  SET (ssext, issExtMax, char *, sizeof (char));
21833965Sjdp  SET (external_rfd, crfd, PTR, debug_swap->external_rfd_size);
21933965Sjdp  SET (external_fdr, ifdMax, PTR, debug_swap->external_fdr_size);
22033965Sjdp  SET (external_ext, iextMax, PTR, debug_swap->external_ext_size);
22133965Sjdp
22233965Sjdp#undef SET
22333965Sjdp
22433965Sjdp  /* Fill in the register masks.  */
22533965Sjdp  {
22633965Sjdp    unsigned long gprmask = 0;
22733965Sjdp    unsigned long fprmask = 0;
22833965Sjdp    unsigned long *cprmask = NULL;
22933965Sjdp
23033965Sjdp#ifdef TC_MIPS
23133965Sjdp    /* Fill in the MIPS register masks.  It's probably not worth
23233965Sjdp       setting up a generic interface for this.  */
23333965Sjdp    gprmask = mips_gprmask;
23433965Sjdp    cprmask = mips_cprmask;
23533965Sjdp#endif
23633965Sjdp
23733965Sjdp#ifdef TC_ALPHA
23833965Sjdp    alpha_frob_ecoff_data ();
23933965Sjdp
24033965Sjdp    if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
24160484Sobrien      as_fatal (_("Can't set GP value"));
24233965Sjdp
24333965Sjdp    gprmask = alpha_gprmask;
24433965Sjdp    fprmask = alpha_fprmask;
24533965Sjdp#endif
24633965Sjdp
24733965Sjdp    if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
24860484Sobrien      as_fatal (_("Can't set register masks"));
24933965Sjdp  }
25033965Sjdp}
25133965Sjdp
25233965Sjdp/* This is called by the ECOFF code to set the external information
25333965Sjdp   for a symbol.  We just pass it on to BFD, which expects the swapped
25433965Sjdp   information to be stored in the native field of the symbol.  */
25533965Sjdp
25633965Sjdpvoid
25733965Sjdpobj_ecoff_set_ext (sym, ext)
25833965Sjdp     symbolS *sym;
25933965Sjdp     EXTR *ext;
26033965Sjdp{
26133965Sjdp  const struct ecoff_debug_swap * const debug_swap
26233965Sjdp    = &ecoff_backend (stdoutput)->debug_swap;
26333965Sjdp  ecoff_symbol_type *esym;
26433965Sjdp
26560484Sobrien  know (bfd_asymbol_flavour (symbol_get_bfdsym (sym))
26660484Sobrien	== bfd_target_ecoff_flavour);
26760484Sobrien  esym = ecoffsymbol (symbol_get_bfdsym (sym));
26833965Sjdp  esym->local = false;
26933965Sjdp  esym->native = xmalloc (debug_swap->external_ext_size);
27033965Sjdp  (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
27133965Sjdp}
27233965Sjdp
27333965Sjdpstatic int
27433965Sjdpecoff_sec_sym_ok_for_reloc (sec)
27533965Sjdp     asection *sec;
27633965Sjdp{
27733965Sjdp  return 1;
27833965Sjdp}
27933965Sjdp
28033965Sjdpstatic void
28133965Sjdpobj_ecoff_frob_symbol (sym, puntp)
28233965Sjdp     symbolS *sym;
28333965Sjdp     int *puntp;
28433965Sjdp{
28533965Sjdp  ecoff_frob_symbol (sym);
28633965Sjdp}
28733965Sjdp
28833965Sjdpstatic void
28933965Sjdpecoff_pop_insert ()
29033965Sjdp{
29133965Sjdp  pop_insert (obj_pseudo_table);
29233965Sjdp}
29333965Sjdp
29477298Sobrienstatic int
29577298Sobrienecoff_separate_stab_sections ()
29677298Sobrien{
29777298Sobrien  return 0;
29877298Sobrien}
29977298Sobrien
30033965Sjdpconst struct format_ops ecoff_format_ops =
30133965Sjdp{
30233965Sjdp  bfd_target_ecoff_flavour,
30360484Sobrien  0,	/* dfl_leading_underscore */
30477298Sobrien
30577298Sobrien  /* FIXME: A comment why emit_section_symbols is different here (1) from
30677298Sobrien     the single-format definition (0) would be in order.  */
30760484Sobrien  1,	/* emit_section_symbols */
30877298Sobrien  0,	/* begin */
30977298Sobrien  ecoff_new_file,
31033965Sjdp  obj_ecoff_frob_symbol,
31133965Sjdp  ecoff_frob_file,
31277298Sobrien  0,	/* frob_file_before_adjust */
31360484Sobrien  0,	/* frob_file_after_relocs */
31460484Sobrien  0,	/* s_get_size */
31560484Sobrien  0,	/* s_set_size */
31660484Sobrien  0,	/* s_get_align */
31760484Sobrien  0,	/* s_set_align */
31860484Sobrien  0,	/* s_get_other */
31977298Sobrien  0,	/* s_set_other */
32060484Sobrien  0,	/* s_get_desc */
32177298Sobrien  0,	/* s_set_desc */
32277298Sobrien  0,	/* s_get_type */
32377298Sobrien  0,	/* s_set_type */
32460484Sobrien  0,	/* copy_symbol_attributes */
32533965Sjdp  ecoff_generate_asm_lineno,
32633965Sjdp  ecoff_stab,
32777298Sobrien  ecoff_separate_stab_sections,
32877298Sobrien  0,	/* init_stab_section */
32933965Sjdp  ecoff_sec_sym_ok_for_reloc,
33033965Sjdp  ecoff_pop_insert,
33133965Sjdp  ecoff_set_ext,
33233965Sjdp  ecoff_read_begin_hook,
33377298Sobrien  ecoff_symbol_new_hook
33433965Sjdp};
335