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