obj-ecoff.c revision 33965
133965Sjdp/* ECOFF object file format.
233965Sjdp   Copyright (C) 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
333965Sjdp   Contributed by Cygnus Support.
433965Sjdp   This file was put together by Ian Lance Taylor <ian@cygnus.com>.
533965Sjdp
633965Sjdp   This file is part of GAS.
733965Sjdp
833965Sjdp   GAS is free software; you can redistribute it and/or modify
933965Sjdp   it under the terms of the GNU General Public License as published by
1033965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1133965Sjdp   any later version.
1233965Sjdp
1333965Sjdp   GAS is distributed in the hope that it will be useful,
1433965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1533965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965Sjdp   GNU General Public License for more details.
1733965Sjdp
1833965Sjdp   You should have received a copy of the GNU General Public License
1933965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
2033965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2133965Sjdp   02111-1307, USA.  */
2233965Sjdp
2333965Sjdp#define OBJ_HEADER "obj-ecoff.h"
2433965Sjdp#include "as.h"
2533965Sjdp#include "coff/internal.h"
2633965Sjdp#include "bfd/libcoff.h"
2733965Sjdp#include "bfd/libecoff.h"
2833965Sjdp
2933965Sjdp/* Almost all of the ECOFF support is actually in ecoff.c in the main
3033965Sjdp   gas directory.  This file mostly just arranges to call that one at
3133965Sjdp   the right times.  */
3233965Sjdp
3333965Sjdpstatic int ecoff_sec_sym_ok_for_reloc PARAMS ((asection *));
3433965Sjdpstatic void obj_ecoff_frob_symbol PARAMS ((symbolS *, int *));
3533965Sjdpstatic void ecoff_pop_insert PARAMS ((void));
3633965Sjdp
3733965Sjdp/* These are the pseudo-ops we support in this file.  Only those
3833965Sjdp   relating to debugging information are supported here.
3933965Sjdp
4033965Sjdp   The following pseudo-ops from the Kane and Heinrich MIPS book
4133965Sjdp   should be defined here, but are currently unsupported: .aent,
4233965Sjdp   .bgnb, .endb, .verstamp, .vreg.
4333965Sjdp
4433965Sjdp   The following pseudo-ops from the Kane and Heinrich MIPS book are
4533965Sjdp   MIPS CPU specific, and should be defined by tc-mips.c: .alias,
4633965Sjdp   .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
4733965Sjdp   .rdata, .sdata, .set.
4833965Sjdp
4933965Sjdp   The following pseudo-ops from the Kane and Heinrich MIPS book are
5033965Sjdp   not MIPS CPU specific, but are also not ECOFF specific.  I have
5133965Sjdp   only listed the ones which are not already in read.c.  It's not
5233965Sjdp   completely clear where these should be defined, but tc-mips.c is
5333965Sjdp   probably the most reasonable place: .asciiz, .asm0, .endr, .err,
5433965Sjdp   .half, .lab, .repeat, .struct, .weakext.  */
5533965Sjdp
5633965Sjdpconst pseudo_typeS obj_pseudo_table[] =
5733965Sjdp{
5833965Sjdp  /* COFF style debugging information. .ln is not used; .loc is used
5933965Sjdp     instead.  */
6033965Sjdp  { "def",	ecoff_directive_def,	0 },
6133965Sjdp  { "dim",	ecoff_directive_dim,	0 },
6233965Sjdp  { "endef",	ecoff_directive_endef,	0 },
6333965Sjdp  { "file",	ecoff_directive_file,	0 },
6433965Sjdp  { "scl",	ecoff_directive_scl,	0 },
6533965Sjdp  { "size",	ecoff_directive_size,	0 },
6633965Sjdp  { "esize",	ecoff_directive_size,	0 },
6733965Sjdp  { "tag",	ecoff_directive_tag,	0 },
6833965Sjdp  { "type",	ecoff_directive_type,	0 },
6933965Sjdp  { "etype",	ecoff_directive_type,	0 },
7033965Sjdp  { "val",	ecoff_directive_val,	0 },
7133965Sjdp
7233965Sjdp  /* ECOFF specific debugging information.  */
7333965Sjdp  { "begin",	ecoff_directive_begin,	0 },
7433965Sjdp  { "bend",	ecoff_directive_bend,	0 },
7533965Sjdp  { "end",	ecoff_directive_end,	0 },
7633965Sjdp  { "ent",	ecoff_directive_ent,	0 },
7733965Sjdp  { "fmask",	ecoff_directive_fmask,	0 },
7833965Sjdp  { "frame",	ecoff_directive_frame,	0 },
7933965Sjdp  { "loc",	ecoff_directive_loc,	0 },
8033965Sjdp  { "mask",	ecoff_directive_mask,	0 },
8133965Sjdp
8233965Sjdp  /* Other ECOFF directives.  */
8333965Sjdp  { "extern",	ecoff_directive_extern,	0 },
8433965Sjdp  { "weakext",	ecoff_directive_weakext, 0 },
8533965Sjdp
8633965Sjdp  /* These are used on Irix.  I don't know how to implement them.  */
8733965Sjdp  { "bgnb",	s_ignore,		0 },
8833965Sjdp  { "endb",	s_ignore,		0 },
8933965Sjdp  { "verstamp",	s_ignore,		0 },
9033965Sjdp
9133965Sjdp  /* Sentinel.  */
9233965Sjdp  { NULL }
9333965Sjdp};
9433965Sjdp
9533965Sjdp/* Swap out the symbols and debugging information for BFD.  */
9633965Sjdp
9733965Sjdpvoid
9833965Sjdpecoff_frob_file ()
9933965Sjdp{
10033965Sjdp  const struct ecoff_debug_swap * const debug_swap
10133965Sjdp    = &ecoff_backend (stdoutput)->debug_swap;
10233965Sjdp  bfd_vma addr;
10333965Sjdp  asection *sec;
10433965Sjdp  HDRR *hdr;
10533965Sjdp  char *buf;
10633965Sjdp  char *set;
10733965Sjdp
10833965Sjdp  /* Set the section VMA values.  We force the .sdata and .sbss
10933965Sjdp     sections to the end to ensure that their VMA addresses are close
11033965Sjdp     together so that the GP register can address both of them.  We
11133965Sjdp     put the .bss section after the .sbss section.
11233965Sjdp
11333965Sjdp     Also, for the Alpha, we must sort the sections, to make sure they
11433965Sjdp     appear in the output file in the correct order.  (Actually, maybe
11533965Sjdp     this is a job for BFD.  But the VMAs computed would be out of
11633965Sjdp     whack if we computed them given our initial, random ordering.
11733965Sjdp     It's possible that that wouldn't break things; I could do some
11833965Sjdp     experimenting sometime and find out.
11933965Sjdp
12033965Sjdp     This output ordering of sections is magic, on the Alpha, at
12133965Sjdp     least.  The .lita section must come before .lit8 and .lit4,
12233965Sjdp     otherwise the OSF/1 linker may silently trash the .lit{4,8}
12333965Sjdp     section contents.  Also, .text must preceed .rdata.  These differ
12433965Sjdp     from the order described in some parts of the DEC OSF/1 Assembly
12533965Sjdp     Language Programmer's Guide, but that order doesn't seem to work
12633965Sjdp     with their linker.
12733965Sjdp
12833965Sjdp     I don't know if section ordering on the MIPS is important.  */
12933965Sjdp
13033965Sjdp  static const char *const names[] = {
13133965Sjdp    /* text segment */
13233965Sjdp    ".text", ".rdata", ".init", ".fini",
13333965Sjdp    /* data segment */
13433965Sjdp    ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
13533965Sjdp    /* bss segment */
13633965Sjdp    ".sbss", ".bss",
13733965Sjdp  };
13833965Sjdp#define n_names (sizeof (names) / sizeof (names[0]))
13933965Sjdp
14033965Sjdp  addr = 0;
14133965Sjdp  {
14233965Sjdp    /* Sections that match names, order to be straightened out later.  */
14333965Sjdp    asection *secs[n_names];
14433965Sjdp    /* Linked list of sections with non-matching names.  Random ordering.  */
14533965Sjdp    asection *other_sections = 0;
14633965Sjdp    /* Pointer to next section, since we're destroying the original
14733965Sjdp       ordering.  */
14833965Sjdp    asection *next;
14933965Sjdp
15033965Sjdp    int i;
15133965Sjdp
15233965Sjdp    for (i = 0; i < n_names; i++)
15333965Sjdp      secs[i] = 0;
15433965Sjdp    for (sec = stdoutput->sections; sec != (asection *) NULL; sec = next)
15533965Sjdp      {
15633965Sjdp	next = sec->next;
15733965Sjdp	for (i = 0; i < n_names; i++)
15833965Sjdp	  if (!strcmp (sec->name, names[i]))
15933965Sjdp	    {
16033965Sjdp	      secs[i] = sec;
16133965Sjdp	      break;
16233965Sjdp	    }
16333965Sjdp	if (i == n_names)
16433965Sjdp	  {
16533965Sjdp	    bfd_set_section_vma (stdoutput, sec, addr);
16633965Sjdp	    addr += bfd_section_size (stdoutput, sec);
16733965Sjdp	    sec->next = other_sections;
16833965Sjdp	    other_sections = sec;
16933965Sjdp	  }
17033965Sjdp      }
17133965Sjdp    for (i = 0; i < n_names; i++)
17233965Sjdp      if (secs[i])
17333965Sjdp	{
17433965Sjdp	  sec = secs[i];
17533965Sjdp	  bfd_set_section_vma (stdoutput, sec, addr);
17633965Sjdp	  addr += bfd_section_size (stdoutput, sec);
17733965Sjdp	}
17833965Sjdp    for (i = n_names - 1; i >= 0; i--)
17933965Sjdp      if (secs[i])
18033965Sjdp	{
18133965Sjdp	  sec = secs[i];
18233965Sjdp	  sec->next = other_sections;
18333965Sjdp	  other_sections = sec;
18433965Sjdp	}
18533965Sjdp    stdoutput->sections = other_sections;
18633965Sjdp  }
18733965Sjdp
18833965Sjdp  /* Build the ECOFF debugging information.  */
18933965Sjdp  assert (ecoff_data (stdoutput) != 0);
19033965Sjdp  hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
19133965Sjdp  ecoff_build_debug (hdr, &buf, debug_swap);
19233965Sjdp
19333965Sjdp  /* Finish up the ecoff_tdata structure.  */
19433965Sjdp  set = buf;
19533965Sjdp#define SET(ptr, count, type, size) \
19633965Sjdp  if (hdr->count == 0) \
19733965Sjdp    ecoff_data (stdoutput)->debug_info.ptr = (type) NULL; \
19833965Sjdp  else \
19933965Sjdp    { \
20033965Sjdp      ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
20133965Sjdp      set += hdr->count * size; \
20233965Sjdp    }
20333965Sjdp
20433965Sjdp  SET (line, cbLine, unsigned char *, sizeof (unsigned char));
20533965Sjdp  SET (external_dnr, idnMax, PTR, debug_swap->external_dnr_size);
20633965Sjdp  SET (external_pdr, ipdMax, PTR, debug_swap->external_pdr_size);
20733965Sjdp  SET (external_sym, isymMax, PTR, debug_swap->external_sym_size);
20833965Sjdp  SET (external_opt, ioptMax, PTR, debug_swap->external_opt_size);
20933965Sjdp  SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
21033965Sjdp  SET (ss, issMax, char *, sizeof (char));
21133965Sjdp  SET (ssext, issExtMax, char *, sizeof (char));
21233965Sjdp  SET (external_rfd, crfd, PTR, debug_swap->external_rfd_size);
21333965Sjdp  SET (external_fdr, ifdMax, PTR, debug_swap->external_fdr_size);
21433965Sjdp  SET (external_ext, iextMax, PTR, debug_swap->external_ext_size);
21533965Sjdp
21633965Sjdp#undef SET
21733965Sjdp
21833965Sjdp  /* Fill in the register masks.  */
21933965Sjdp  {
22033965Sjdp    unsigned long gprmask = 0;
22133965Sjdp    unsigned long fprmask = 0;
22233965Sjdp    unsigned long *cprmask = NULL;
22333965Sjdp
22433965Sjdp#ifdef TC_MIPS
22533965Sjdp    /* Fill in the MIPS register masks.  It's probably not worth
22633965Sjdp       setting up a generic interface for this.  */
22733965Sjdp    gprmask = mips_gprmask;
22833965Sjdp    cprmask = mips_cprmask;
22933965Sjdp#endif
23033965Sjdp
23133965Sjdp#ifdef TC_ALPHA
23233965Sjdp    alpha_frob_ecoff_data ();
23333965Sjdp
23433965Sjdp    if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
23533965Sjdp      as_fatal ("Can't set GP value");
23633965Sjdp
23733965Sjdp    gprmask = alpha_gprmask;
23833965Sjdp    fprmask = alpha_fprmask;
23933965Sjdp#endif
24033965Sjdp
24133965Sjdp    if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
24233965Sjdp      as_fatal ("Can't set register masks");
24333965Sjdp  }
24433965Sjdp}
24533965Sjdp
24633965Sjdp/* This is called by the ECOFF code to set the external information
24733965Sjdp   for a symbol.  We just pass it on to BFD, which expects the swapped
24833965Sjdp   information to be stored in the native field of the symbol.  */
24933965Sjdp
25033965Sjdpvoid
25133965Sjdpobj_ecoff_set_ext (sym, ext)
25233965Sjdp     symbolS *sym;
25333965Sjdp     EXTR *ext;
25433965Sjdp{
25533965Sjdp  const struct ecoff_debug_swap * const debug_swap
25633965Sjdp    = &ecoff_backend (stdoutput)->debug_swap;
25733965Sjdp  ecoff_symbol_type *esym;
25833965Sjdp
25933965Sjdp  know (bfd_asymbol_flavour (sym->bsym) == bfd_target_ecoff_flavour);
26033965Sjdp  esym = ecoffsymbol (sym->bsym);
26133965Sjdp  esym->local = false;
26233965Sjdp  esym->native = xmalloc (debug_swap->external_ext_size);
26333965Sjdp  (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
26433965Sjdp}
26533965Sjdp
26633965Sjdpstatic int
26733965Sjdpecoff_sec_sym_ok_for_reloc (sec)
26833965Sjdp     asection *sec;
26933965Sjdp{
27033965Sjdp  return 1;
27133965Sjdp}
27233965Sjdp
27333965Sjdpstatic void
27433965Sjdpobj_ecoff_frob_symbol (sym, puntp)
27533965Sjdp     symbolS *sym;
27633965Sjdp     int *puntp;
27733965Sjdp{
27833965Sjdp  ecoff_frob_symbol (sym);
27933965Sjdp}
28033965Sjdp
28133965Sjdpstatic void
28233965Sjdpecoff_pop_insert ()
28333965Sjdp{
28433965Sjdp  pop_insert (obj_pseudo_table);
28533965Sjdp}
28633965Sjdp
28733965Sjdpconst struct format_ops ecoff_format_ops =
28833965Sjdp{
28933965Sjdp  bfd_target_ecoff_flavour,
29033965Sjdp  0,
29133965Sjdp  1,
29233965Sjdp  obj_ecoff_frob_symbol,
29333965Sjdp  ecoff_frob_file,
29433965Sjdp  0,
29533965Sjdp  0, 0,
29633965Sjdp  0, 0,
29733965Sjdp  0,
29833965Sjdp  ecoff_generate_asm_lineno,
29933965Sjdp  ecoff_stab,
30033965Sjdp  ecoff_sec_sym_ok_for_reloc,
30133965Sjdp  ecoff_pop_insert,
30233965Sjdp  ecoff_set_ext,
30333965Sjdp  ecoff_read_begin_hook,
30433965Sjdp  ecoff_symbol_new_hook,
30533965Sjdp};
306