Back to index

cell-binutils  2.17cvs20070401
obj-ecoff.c
Go to the documentation of this file.
00001 /* ECOFF object file format.
00002    Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
00003    2005  Free Software Foundation, Inc.
00004    Contributed by Cygnus Support.
00005    This file was put together by Ian Lance Taylor <ian@cygnus.com>.
00006 
00007    This file is part of GAS.
00008 
00009    GAS is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2, or (at your option)
00012    any later version.
00013 
00014    GAS is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with GAS; see the file COPYING.  If not, write to the Free
00021    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00022    02110-1301, USA.  */
00023 
00024 #define OBJ_HEADER "obj-ecoff.h"
00025 #include "as.h"
00026 #include "coff/internal.h"
00027 #include "bfd/libcoff.h"
00028 #include "bfd/libecoff.h"
00029 
00030 /* Almost all of the ECOFF support is actually in ecoff.c in the main
00031    gas directory.  This file mostly just arranges to call that one at
00032    the right times.  */
00033 
00034 /* Set section VMAs and GP values before reloc processing.  */
00035 
00036 void
00037 ecoff_frob_file_before_fix (void)
00038 {
00039   bfd_vma addr;
00040   asection *sec;
00041 
00042   /* Set the section VMA values.  We force the .sdata and .sbss
00043      sections to the end to ensure that their VMA addresses are close
00044      together so that the GP register can address both of them.  We
00045      put the .bss section after the .sbss section.
00046 
00047      Also, for the Alpha, we must sort the sections, to make sure they
00048      appear in the output file in the correct order.  (Actually, maybe
00049      this is a job for BFD.  But the VMAs computed would be out of
00050      whack if we computed them given our initial, random ordering.
00051      It's possible that that wouldn't break things; I could do some
00052      experimenting sometime and find out.
00053 
00054      This output ordering of sections is magic, on the Alpha, at
00055      least.  The .lita section must come before .lit8 and .lit4,
00056      otherwise the OSF/1 linker may silently trash the .lit{4,8}
00057      section contents.  Also, .text must preceed .rdata.  These differ
00058      from the order described in some parts of the DEC OSF/1 Assembly
00059      Language Programmer's Guide, but that order doesn't seem to work
00060      with their linker.
00061 
00062      I don't know if section ordering on the MIPS is important.  */
00063 
00064   static const char *const names[] =
00065   {
00066     /* text segment */
00067     ".text", ".rdata", ".init", ".fini",
00068     /* data segment */
00069     ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
00070     /* bss segment */
00071     ".sbss", ".bss",
00072   };
00073 #define n_names ((int) (sizeof (names) / sizeof (names[0])))
00074 
00075   /* Sections that match names, order to be straightened out later.  */
00076   asection *secs[n_names];
00077   int i;
00078 
00079   addr = 0;
00080   for (i = 0; i < n_names; i++)
00081     secs[i] = NULL;
00082 
00083   for (sec = stdoutput->sections; sec != NULL; sec = sec->next)
00084     {
00085       for (i = 0; i < n_names; i++)
00086        if (!strcmp (sec->name, names[i]))
00087          {
00088            secs[i] = sec;
00089            bfd_section_list_remove (stdoutput, sec);
00090            break;
00091          }
00092       if (i == n_names)
00093        {
00094          bfd_set_section_vma (stdoutput, sec, addr);
00095          addr += bfd_section_size (stdoutput, sec);
00096        }
00097     }
00098   for (i = 0; i < n_names; i++)
00099     if (secs[i])
00100       {
00101        bfd_set_section_vma (stdoutput, secs[i], addr);
00102        addr += bfd_section_size (stdoutput, secs[i]);
00103       }
00104   for (i = n_names - 1; i >= 0; i--)
00105     if (secs[i])
00106       bfd_section_list_prepend (stdoutput, secs[i]);
00107 
00108   /* Fill in the register masks.  */
00109   {
00110     unsigned long gprmask = 0;
00111     unsigned long fprmask = 0;
00112     unsigned long *cprmask = NULL;
00113 
00114 #ifdef TC_MIPS
00115     /* Fill in the MIPS register masks.  It's probably not worth
00116        setting up a generic interface for this.  */
00117     gprmask = mips_gprmask;
00118     cprmask = mips_cprmask;
00119 #endif
00120 
00121 #ifdef TC_ALPHA
00122     alpha_frob_ecoff_data ();
00123 
00124     if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
00125       as_fatal (_("Can't set GP value"));
00126 
00127     gprmask = alpha_gprmask;
00128     fprmask = alpha_fprmask;
00129 #endif
00130 
00131     if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
00132       as_fatal (_("Can't set register masks"));
00133   }
00134 }
00135 
00136 /* Swap out the symbols and debugging information for BFD.  */
00137 
00138 void
00139 ecoff_frob_file (void)
00140 {
00141   const struct ecoff_debug_swap * const debug_swap
00142     = &ecoff_backend (stdoutput)->debug_swap;
00143   bfd_vma addr ATTRIBUTE_UNUSED;
00144   HDRR *hdr;
00145   char *buf;
00146   char *set;
00147 
00148   /* Build the ECOFF debugging information.  */
00149   assert (ecoff_data (stdoutput) != 0);
00150   hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
00151   ecoff_build_debug (hdr, &buf, debug_swap);
00152 
00153   /* Finish up the ecoff_tdata structure.  */
00154   set = buf;
00155 #define SET(ptr, count, type, size) \
00156   if (hdr->count == 0) \
00157     ecoff_data (stdoutput)->debug_info.ptr = NULL; \
00158   else \
00159     { \
00160       ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
00161       set += hdr->count * size; \
00162     }
00163 
00164   SET (line, cbLine, unsigned char *, sizeof (unsigned char));
00165   SET (external_dnr, idnMax, void *, debug_swap->external_dnr_size);
00166   SET (external_pdr, ipdMax, void *, debug_swap->external_pdr_size);
00167   SET (external_sym, isymMax, void *, debug_swap->external_sym_size);
00168   SET (external_opt, ioptMax, void *, debug_swap->external_opt_size);
00169   SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
00170   SET (ss, issMax, char *, sizeof (char));
00171   SET (ssext, issExtMax, char *, sizeof (char));
00172   SET (external_rfd, crfd, void *, debug_swap->external_rfd_size);
00173   SET (external_fdr, ifdMax, void *, debug_swap->external_fdr_size);
00174   SET (external_ext, iextMax, void *, debug_swap->external_ext_size);
00175 #undef SET
00176 }
00177 
00178 /* This is called by the ECOFF code to set the external information
00179    for a symbol.  We just pass it on to BFD, which expects the swapped
00180    information to be stored in the native field of the symbol.  */
00181 
00182 void
00183 obj_ecoff_set_ext (symbolS *sym, EXTR *ext)
00184 {
00185   const struct ecoff_debug_swap * const debug_swap
00186     = &ecoff_backend (stdoutput)->debug_swap;
00187   ecoff_symbol_type *esym;
00188 
00189   know (bfd_asymbol_flavour (symbol_get_bfdsym (sym))
00190        == bfd_target_ecoff_flavour);
00191   esym = ecoffsymbol (symbol_get_bfdsym (sym));
00192   esym->local = FALSE;
00193   esym->native = xmalloc (debug_swap->external_ext_size);
00194   (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
00195 }
00196 
00197 static int
00198 ecoff_sec_sym_ok_for_reloc (asection *sec ATTRIBUTE_UNUSED)
00199 {
00200   return 1;
00201 }
00202 
00203 static void
00204 obj_ecoff_frob_symbol (symbolS *sym, int *puntp ATTRIBUTE_UNUSED)
00205 {
00206   ecoff_frob_symbol (sym);
00207 }
00208 
00209 static void
00210 ecoff_pop_insert (void)
00211 {
00212   pop_insert (obj_pseudo_table);
00213 }
00214 
00215 static int
00216 ecoff_separate_stab_sections (void)
00217 {
00218   return 0;
00219 }
00220 
00221 /* These are the pseudo-ops we support in this file.  Only those
00222    relating to debugging information are supported here.
00223 
00224    The following pseudo-ops from the Kane and Heinrich MIPS book
00225    should be defined here, but are currently unsupported: .aent,
00226    .bgnb, .endb, .verstamp, .vreg.
00227 
00228    The following pseudo-ops from the Kane and Heinrich MIPS book are
00229    MIPS CPU specific, and should be defined by tc-mips.c: .alias,
00230    .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
00231    .rdata, .sdata, .set.
00232 
00233    The following pseudo-ops from the Kane and Heinrich MIPS book are
00234    not MIPS CPU specific, but are also not ECOFF specific.  I have
00235    only listed the ones which are not already in read.c.  It's not
00236    completely clear where these should be defined, but tc-mips.c is
00237    probably the most reasonable place: .asciiz, .asm0, .endr, .err,
00238    .half, .lab, .repeat, .struct, .weakext.  */
00239 
00240 const pseudo_typeS obj_pseudo_table[] =
00241 {
00242   /* COFF style debugging information. .ln is not used; .loc is used
00243      instead.  */
00244   { "def",    ecoff_directive_def, 0 },
00245   { "dim",    ecoff_directive_dim, 0 },
00246   { "endef",  ecoff_directive_endef,      0 },
00247   { "file",   ecoff_directive_file,       0 },
00248   { "scl",    ecoff_directive_scl, 0 },
00249   { "size",   ecoff_directive_size,       0 },
00250   { "esize",  ecoff_directive_size,       0 },
00251   { "tag",    ecoff_directive_tag, 0 },
00252   { "type",   ecoff_directive_type,       0 },
00253   { "etype",  ecoff_directive_type,       0 },
00254   { "val",    ecoff_directive_val, 0 },
00255 
00256   /* ECOFF specific debugging information.  */
00257   { "begin",  ecoff_directive_begin,      0 },
00258   { "bend",   ecoff_directive_bend,       0 },
00259   { "end",    ecoff_directive_end, 0 },
00260   { "ent",    ecoff_directive_ent, 0 },
00261   { "fmask",  ecoff_directive_fmask,      0 },
00262   { "frame",  ecoff_directive_frame,      0 },
00263   { "loc",    ecoff_directive_loc, 0 },
00264   { "mask",   ecoff_directive_mask,       0 },
00265 
00266   /* Other ECOFF directives.  */
00267   { "extern", ecoff_directive_extern,     0 },
00268 
00269 #ifndef TC_MIPS
00270   /* For TC_MIPS, tc-mips.c adds this.  */
00271   { "weakext",       ecoff_directive_weakext, 0 },
00272 #endif
00273 
00274   /* These are used on Irix.  I don't know how to implement them.  */
00275   { "bgnb",   s_ignore,            0 },
00276   { "endb",   s_ignore,            0 },
00277   { "verstamp",      s_ignore,            0 },
00278 
00279   /* Sentinel.  */
00280   { NULL,     s_ignore,            0 }
00281 };
00282 
00283 const struct format_ops ecoff_format_ops =
00284 {
00285   bfd_target_ecoff_flavour,
00286   0,   /* dfl_leading_underscore.  */
00287 
00288   /* FIXME: A comment why emit_section_symbols is different here (1) from
00289      the single-format definition (0) would be in order.  */
00290   1,   /* emit_section_symbols.  */
00291   0,   /* begin.  */
00292   ecoff_new_file,
00293   obj_ecoff_frob_symbol,
00294   ecoff_frob_file,
00295   0,   /* frob_file_before_adjust.  */
00296   ecoff_frob_file_before_fix,
00297   0,   /* frob_file_after_relocs.  */
00298   0,   /* s_get_size.  */
00299   0,   /* s_set_size.  */
00300   0,   /* s_get_align.  */
00301   0,   /* s_set_align.  */
00302   0,   /* s_get_other.  */
00303   0,   /* s_set_other.  */
00304   0,   /* s_get_desc.  */
00305   0,   /* s_set_desc.  */
00306   0,   /* s_get_type.  */
00307   0,   /* s_set_type.  */
00308   0,   /* copy_symbol_attributes.  */
00309   ecoff_generate_asm_lineno,
00310   ecoff_stab,
00311   ecoff_separate_stab_sections,
00312   0,   /* init_stab_section.  */
00313   ecoff_sec_sym_ok_for_reloc,
00314   ecoff_pop_insert,
00315   ecoff_set_ext,
00316   ecoff_read_begin_hook,
00317   ecoff_symbol_new_hook
00318 };