133965Sjdp/* Generic ECOFF (Extended-COFF) routines. 2130561Sobrien Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 3218822Sdim 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 433965Sjdp Original version by Per Bothner. 533965Sjdp Full support added by Ian Lance Taylor, ian@cygnus.com. 633965Sjdp 7104834Sobrien This file is part of BFD, the Binary File Descriptor library. 833965Sjdp 9104834Sobrien This program is free software; you can redistribute it and/or modify 10104834Sobrien it under the terms of the GNU General Public License as published by 11104834Sobrien the Free Software Foundation; either version 2 of the License, or 12104834Sobrien (at your option) any later version. 1333965Sjdp 14104834Sobrien This program is distributed in the hope that it will be useful, 15104834Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 16104834Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17104834Sobrien GNU General Public License for more details. 1833965Sjdp 19104834Sobrien You should have received a copy of the GNU General Public License 20104834Sobrien along with this program; if not, write to the Free Software 21218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2233965Sjdp 23218822Sdim#include "sysdep.h" 2433965Sjdp#include "bfd.h" 2533965Sjdp#include "bfdlink.h" 2633965Sjdp#include "libbfd.h" 2733965Sjdp#include "aout/ar.h" 2833965Sjdp#include "aout/ranlib.h" 2933965Sjdp#include "aout/stab_gnu.h" 3033965Sjdp 3133965Sjdp/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines 3233965Sjdp some other stuff which we don't want and which conflicts with stuff 3333965Sjdp we do want. */ 3433965Sjdp#include "libaout.h" 3533965Sjdp#include "aout/aout64.h" 3633965Sjdp#undef N_ABS 3733965Sjdp#undef exec_hdr 3833965Sjdp#undef obj_sym_filepos 3933965Sjdp 4033965Sjdp#include "coff/internal.h" 4133965Sjdp#include "coff/sym.h" 4233965Sjdp#include "coff/symconst.h" 4333965Sjdp#include "coff/ecoff.h" 4433965Sjdp#include "libcoff.h" 4533965Sjdp#include "libecoff.h" 46218822Sdim#include "libiberty.h" 4733965Sjdp 48218822Sdim#define streq(a, b) (strcmp ((a), (b)) == 0) 49218822Sdim#define strneq(a, b, n) (strncmp ((a), (b), (n)) == 0) 50218822Sdim 5133965Sjdp 5233965Sjdp/* This stuff is somewhat copied from coffcode.h. */ 5360484Sobrienstatic asection bfd_debug_section = 5460484Sobrien{ 55218822Sdim /* name, id, index, next, prev, flags, user_set_vma, */ 56218822Sdim "*DEBUG*", 0, 0, NULL, NULL, 0, 0, 57218822Sdim /* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh, */ 58218822Sdim 0, 0, 1, 0, 59218822Sdim /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */ 60218822Sdim 0, 0, 0, 0, 61218822Sdim /* has_gp_reloc, need_finalize_relax, reloc_done, */ 62218822Sdim 0, 0, 0, 63218822Sdim /* vma, lma, size, rawsize, */ 64218822Sdim 0, 0, 0, 0, 6578828Sobrien /* output_offset, output_section, alignment_power, */ 6678828Sobrien 0, NULL, 0, 6778828Sobrien /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ 6878828Sobrien NULL, NULL, 0, 0, 0, 6978828Sobrien /* line_filepos, userdata, contents, lineno, lineno_count, */ 7078828Sobrien 0, NULL, NULL, NULL, 0, 71218822Sdim /* entsize, kept_section, moving_line_filepos, */ 72218822Sdim 0, NULL, 0, 7378828Sobrien /* target_index, used_by_bfd, constructor_chain, owner, */ 7478828Sobrien 0, NULL, NULL, NULL, 7578828Sobrien /* symbol, */ 76218822Sdim NULL, 7778828Sobrien /* symbol_ptr_ptr, */ 78218822Sdim NULL, 79218822Sdim /* map_head, map_tail */ 80218822Sdim { NULL }, { NULL } 8160484Sobrien}; 8233965Sjdp 8333965Sjdp/* Create an ECOFF object. */ 8433965Sjdp 85130561Sobrienbfd_boolean 86218822Sdim_bfd_ecoff_mkobject (bfd *abfd) 8733965Sjdp{ 8889857Sobrien bfd_size_type amt = sizeof (ecoff_data_type); 89104834Sobrien 90218822Sdim abfd->tdata.ecoff_obj_data = bfd_zalloc (abfd, amt); 9133965Sjdp if (abfd->tdata.ecoff_obj_data == NULL) 92130561Sobrien return FALSE; 9333965Sjdp 94130561Sobrien return TRUE; 9533965Sjdp} 9633965Sjdp 9733965Sjdp/* This is a hook called by coff_real_object_p to create any backend 9833965Sjdp specific information. */ 9933965Sjdp 100218822Sdimvoid * 101218822Sdim_bfd_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr) 10233965Sjdp{ 10333965Sjdp struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; 10433965Sjdp struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr; 10533965Sjdp ecoff_data_type *ecoff; 10633965Sjdp 107104834Sobrien if (! _bfd_ecoff_mkobject (abfd)) 10833965Sjdp return NULL; 10933965Sjdp 11033965Sjdp ecoff = ecoff_data (abfd); 11133965Sjdp ecoff->gp_size = 8; 11233965Sjdp ecoff->sym_filepos = internal_f->f_symptr; 11333965Sjdp 114218822Sdim if (internal_a != NULL) 11533965Sjdp { 11633965Sjdp int i; 11733965Sjdp 11833965Sjdp ecoff->text_start = internal_a->text_start; 11933965Sjdp ecoff->text_end = internal_a->text_start + internal_a->tsize; 12033965Sjdp ecoff->gp = internal_a->gp_value; 12133965Sjdp ecoff->gprmask = internal_a->gprmask; 12233965Sjdp for (i = 0; i < 4; i++) 12333965Sjdp ecoff->cprmask[i] = internal_a->cprmask[i]; 12433965Sjdp ecoff->fprmask = internal_a->fprmask; 12533965Sjdp if (internal_a->magic == ECOFF_AOUT_ZMAGIC) 12633965Sjdp abfd->flags |= D_PAGED; 12733965Sjdp else 12833965Sjdp abfd->flags &=~ D_PAGED; 12933965Sjdp } 13033965Sjdp 13133965Sjdp /* It turns out that no special action is required by the MIPS or 13233965Sjdp Alpha ECOFF backends. They have different information in the 13333965Sjdp a.out header, but we just copy it all (e.g., gprmask, cprmask and 13433965Sjdp fprmask) and let the swapping routines ensure that only relevant 13533965Sjdp information is written out. */ 13633965Sjdp 137218822Sdim return (void *) ecoff; 13833965Sjdp} 13933965Sjdp 14033965Sjdp/* Initialize a new section. */ 14133965Sjdp 142130561Sobrienbfd_boolean 143218822Sdim_bfd_ecoff_new_section_hook (bfd *abfd, asection *section) 14433965Sjdp{ 145218822Sdim unsigned int i; 146218822Sdim static struct 147218822Sdim { 148218822Sdim const char * name; 149218822Sdim flagword flags; 150218822Sdim } 151218822Sdim section_flags [] = 152218822Sdim { 153218822Sdim { _TEXT, SEC_ALLOC | SEC_CODE | SEC_LOAD }, 154218822Sdim { _INIT, SEC_ALLOC | SEC_CODE | SEC_LOAD }, 155218822Sdim { _FINI, SEC_ALLOC | SEC_CODE | SEC_LOAD }, 156218822Sdim { _DATA, SEC_ALLOC | SEC_DATA | SEC_LOAD }, 157218822Sdim { _SDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD }, 158218822Sdim { _RDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, 159218822Sdim { _LIT8, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, 160218822Sdim { _LIT4, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, 161218822Sdim { _RCONST, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, 162218822Sdim { _PDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY}, 163218822Sdim { _BSS, SEC_ALLOC}, 164218822Sdim { _SBSS, SEC_ALLOC}, 165218822Sdim /* An Irix 4 shared libary. */ 166218822Sdim { _LIB, SEC_COFF_SHARED_LIBRARY} 167218822Sdim }; 168218822Sdim 16933965Sjdp section->alignment_power = 4; 17033965Sjdp 171218822Sdim for (i = 0; i < ARRAY_SIZE (section_flags); i++) 172218822Sdim if (streq (section->name, section_flags[i].name)) 173218822Sdim { 174218822Sdim section->flags |= section_flags[i].flags; 175218822Sdim break; 176218822Sdim } 17733965Sjdp 178218822Sdim 17933965Sjdp /* Probably any other section name is SEC_NEVER_LOAD, but I'm 18033965Sjdp uncertain about .init on some systems and I don't know how shared 18133965Sjdp libraries work. */ 18233965Sjdp 183218822Sdim return _bfd_generic_new_section_hook (abfd, section); 18433965Sjdp} 18533965Sjdp 18633965Sjdp/* Determine the machine architecture and type. This is called from 18733965Sjdp the generic COFF routines. It is the inverse of ecoff_get_magic, 18833965Sjdp below. This could be an ECOFF backend routine, with one version 18933965Sjdp for each target, but there aren't all that many ECOFF targets. */ 19033965Sjdp 191130561Sobrienbfd_boolean 192218822Sdim_bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr) 19333965Sjdp{ 194218822Sdim struct internal_filehdr *internal_f = filehdr; 19533965Sjdp enum bfd_architecture arch; 19633965Sjdp unsigned long mach; 19733965Sjdp 19833965Sjdp switch (internal_f->f_magic) 19933965Sjdp { 20033965Sjdp case MIPS_MAGIC_1: 20133965Sjdp case MIPS_MAGIC_LITTLE: 20233965Sjdp case MIPS_MAGIC_BIG: 20333965Sjdp arch = bfd_arch_mips; 204130561Sobrien mach = bfd_mach_mips3000; 20533965Sjdp break; 20633965Sjdp 20733965Sjdp case MIPS_MAGIC_LITTLE2: 20833965Sjdp case MIPS_MAGIC_BIG2: 209104834Sobrien /* MIPS ISA level 2: the r6000. */ 21033965Sjdp arch = bfd_arch_mips; 211130561Sobrien mach = bfd_mach_mips6000; 21233965Sjdp break; 21333965Sjdp 21433965Sjdp case MIPS_MAGIC_LITTLE3: 21533965Sjdp case MIPS_MAGIC_BIG3: 216104834Sobrien /* MIPS ISA level 3: the r4000. */ 21733965Sjdp arch = bfd_arch_mips; 218130561Sobrien mach = bfd_mach_mips4000; 21933965Sjdp break; 22033965Sjdp 22133965Sjdp case ALPHA_MAGIC: 22233965Sjdp arch = bfd_arch_alpha; 22333965Sjdp mach = 0; 22433965Sjdp break; 22533965Sjdp 22633965Sjdp default: 22733965Sjdp arch = bfd_arch_obscure; 22833965Sjdp mach = 0; 22933965Sjdp break; 23033965Sjdp } 23133965Sjdp 23233965Sjdp return bfd_default_set_arch_mach (abfd, arch, mach); 23333965Sjdp} 23433965Sjdp 23533965Sjdp/* Get the magic number to use based on the architecture and machine. 23633965Sjdp This is the inverse of _bfd_ecoff_set_arch_mach_hook, above. */ 23733965Sjdp 23833965Sjdpstatic int 239218822Sdimecoff_get_magic (bfd *abfd) 24033965Sjdp{ 24133965Sjdp int big, little; 24233965Sjdp 24333965Sjdp switch (bfd_get_arch (abfd)) 24433965Sjdp { 24533965Sjdp case bfd_arch_mips: 24633965Sjdp switch (bfd_get_mach (abfd)) 24733965Sjdp { 24833965Sjdp default: 24933965Sjdp case 0: 250130561Sobrien case bfd_mach_mips3000: 25133965Sjdp big = MIPS_MAGIC_BIG; 25233965Sjdp little = MIPS_MAGIC_LITTLE; 25333965Sjdp break; 25433965Sjdp 255130561Sobrien case bfd_mach_mips6000: 25633965Sjdp big = MIPS_MAGIC_BIG2; 25733965Sjdp little = MIPS_MAGIC_LITTLE2; 25833965Sjdp break; 25933965Sjdp 260130561Sobrien case bfd_mach_mips4000: 26133965Sjdp big = MIPS_MAGIC_BIG3; 26233965Sjdp little = MIPS_MAGIC_LITTLE3; 26333965Sjdp break; 26433965Sjdp } 26533965Sjdp 26633965Sjdp return bfd_big_endian (abfd) ? big : little; 26733965Sjdp 26833965Sjdp case bfd_arch_alpha: 26933965Sjdp return ALPHA_MAGIC; 27033965Sjdp 27133965Sjdp default: 27233965Sjdp abort (); 27333965Sjdp return 0; 27433965Sjdp } 27533965Sjdp} 27633965Sjdp 27733965Sjdp/* Get the section s_flags to use for a section. */ 27833965Sjdp 27933965Sjdpstatic long 280218822Sdimecoff_sec_to_styp_flags (const char *name, flagword flags) 28133965Sjdp{ 282218822Sdim unsigned int i; 283218822Sdim static struct 284218822Sdim { 285218822Sdim const char * name; 286218822Sdim long flags; 287218822Sdim } 288218822Sdim styp_flags [] = 289218822Sdim { 290218822Sdim { _TEXT, STYP_TEXT }, 291218822Sdim { _DATA, STYP_DATA }, 292218822Sdim { _SDATA, STYP_SDATA }, 293218822Sdim { _RDATA, STYP_RDATA }, 294218822Sdim { _LITA, STYP_LITA }, 295218822Sdim { _LIT8, STYP_LIT8 }, 296218822Sdim { _LIT4, STYP_LIT4 }, 297218822Sdim { _BSS, STYP_BSS }, 298218822Sdim { _SBSS, STYP_SBSS }, 299218822Sdim { _INIT, STYP_ECOFF_INIT }, 300218822Sdim { _FINI, STYP_ECOFF_FINI }, 301218822Sdim { _PDATA, STYP_PDATA }, 302218822Sdim { _XDATA, STYP_XDATA }, 303218822Sdim { _LIB, STYP_ECOFF_LIB }, 304218822Sdim { _GOT, STYP_GOT }, 305218822Sdim { _HASH, STYP_HASH }, 306218822Sdim { _DYNAMIC, STYP_DYNAMIC }, 307218822Sdim { _LIBLIST, STYP_LIBLIST }, 308218822Sdim { _RELDYN, STYP_RELDYN }, 309218822Sdim { _CONFLIC, STYP_CONFLIC }, 310218822Sdim { _DYNSTR, STYP_DYNSTR }, 311218822Sdim { _DYNSYM, STYP_DYNSYM }, 312218822Sdim { _RCONST, STYP_RCONST } 313218822Sdim }; 314218822Sdim long styp = 0; 31533965Sjdp 316218822Sdim for (i = 0; i < ARRAY_SIZE (styp_flags); i++) 317218822Sdim if (streq (name, styp_flags[i].name)) 318218822Sdim { 319218822Sdim styp = styp_flags[i].flags; 320218822Sdim break; 321218822Sdim } 32233965Sjdp 323218822Sdim if (styp == 0) 32433965Sjdp { 325218822Sdim if (streq (name, _COMMENT)) 326218822Sdim { 327218822Sdim styp = STYP_COMMENT; 328218822Sdim flags &=~ SEC_NEVER_LOAD; 329218822Sdim } 330218822Sdim else if (flags & SEC_CODE) 331218822Sdim styp = STYP_TEXT; 332218822Sdim else if (flags & SEC_DATA) 333218822Sdim styp = STYP_DATA; 334218822Sdim else if (flags & SEC_READONLY) 335218822Sdim styp = STYP_RDATA; 336218822Sdim else if (flags & SEC_LOAD) 337218822Sdim styp = STYP_REG; 338218822Sdim else 339218822Sdim styp = STYP_BSS; 34033965Sjdp } 34133965Sjdp 34233965Sjdp if (flags & SEC_NEVER_LOAD) 34333965Sjdp styp |= STYP_NOLOAD; 34433965Sjdp 34533965Sjdp return styp; 34633965Sjdp} 34733965Sjdp 34833965Sjdp/* Get the BFD flags to use for a section. */ 34933965Sjdp 350130561Sobrienbfd_boolean 351218822Sdim_bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED, 352218822Sdim void * hdr, 353218822Sdim const char *name ATTRIBUTE_UNUSED, 354218822Sdim asection *section ATTRIBUTE_UNUSED, 355218822Sdim flagword * flags_ptr) 35633965Sjdp{ 357218822Sdim struct internal_scnhdr *internal_s = hdr; 35833965Sjdp long styp_flags = internal_s->s_flags; 35989857Sobrien flagword sec_flags = 0; 36033965Sjdp 36133965Sjdp if (styp_flags & STYP_NOLOAD) 36233965Sjdp sec_flags |= SEC_NEVER_LOAD; 36333965Sjdp 36433965Sjdp /* For 386 COFF, at least, an unloadable text or data section is 36533965Sjdp actually a shared library section. */ 36633965Sjdp if ((styp_flags & STYP_TEXT) 36733965Sjdp || (styp_flags & STYP_ECOFF_INIT) 36833965Sjdp || (styp_flags & STYP_ECOFF_FINI) 36933965Sjdp || (styp_flags & STYP_DYNAMIC) 37033965Sjdp || (styp_flags & STYP_LIBLIST) 37133965Sjdp || (styp_flags & STYP_RELDYN) 37233965Sjdp || styp_flags == STYP_CONFLIC 37333965Sjdp || (styp_flags & STYP_DYNSTR) 37433965Sjdp || (styp_flags & STYP_DYNSYM) 37533965Sjdp || (styp_flags & STYP_HASH)) 37633965Sjdp { 37733965Sjdp if (sec_flags & SEC_NEVER_LOAD) 37833965Sjdp sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; 37933965Sjdp else 38033965Sjdp sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; 38133965Sjdp } 38233965Sjdp else if ((styp_flags & STYP_DATA) 38333965Sjdp || (styp_flags & STYP_RDATA) 38433965Sjdp || (styp_flags & STYP_SDATA) 38533965Sjdp || styp_flags == STYP_PDATA 38633965Sjdp || styp_flags == STYP_XDATA 38733965Sjdp || (styp_flags & STYP_GOT) 38833965Sjdp || styp_flags == STYP_RCONST) 38933965Sjdp { 39033965Sjdp if (sec_flags & SEC_NEVER_LOAD) 39133965Sjdp sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; 39233965Sjdp else 39333965Sjdp sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; 39433965Sjdp if ((styp_flags & STYP_RDATA) 39533965Sjdp || styp_flags == STYP_PDATA 39633965Sjdp || styp_flags == STYP_RCONST) 39733965Sjdp sec_flags |= SEC_READONLY; 39833965Sjdp } 39933965Sjdp else if ((styp_flags & STYP_BSS) 40033965Sjdp || (styp_flags & STYP_SBSS)) 40189857Sobrien sec_flags |= SEC_ALLOC; 40233965Sjdp else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT) 40389857Sobrien sec_flags |= SEC_NEVER_LOAD; 40433965Sjdp else if ((styp_flags & STYP_LITA) 40533965Sjdp || (styp_flags & STYP_LIT8) 40633965Sjdp || (styp_flags & STYP_LIT4)) 40789857Sobrien sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; 40833965Sjdp else if (styp_flags & STYP_ECOFF_LIB) 40989857Sobrien sec_flags |= SEC_COFF_SHARED_LIBRARY; 41033965Sjdp else 41189857Sobrien sec_flags |= SEC_ALLOC | SEC_LOAD; 41233965Sjdp 41389857Sobrien * flags_ptr = sec_flags; 414130561Sobrien return TRUE; 41533965Sjdp} 41633965Sjdp 41733965Sjdp/* Read in the symbolic header for an ECOFF object file. */ 41833965Sjdp 419130561Sobrienstatic bfd_boolean 420218822Sdimecoff_slurp_symbolic_header (bfd *abfd) 42133965Sjdp{ 42233965Sjdp const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 42333965Sjdp bfd_size_type external_hdr_size; 424218822Sdim void * raw = NULL; 42533965Sjdp HDRR *internal_symhdr; 42633965Sjdp 42733965Sjdp /* See if we've already read it in. */ 42877298Sobrien if (ecoff_data (abfd)->debug_info.symbolic_header.magic == 42933965Sjdp backend->debug_swap.sym_magic) 430130561Sobrien return TRUE; 43133965Sjdp 43233965Sjdp /* See whether there is a symbolic header. */ 43333965Sjdp if (ecoff_data (abfd)->sym_filepos == 0) 43433965Sjdp { 43533965Sjdp bfd_get_symcount (abfd) = 0; 436130561Sobrien return TRUE; 43733965Sjdp } 43833965Sjdp 43933965Sjdp /* At this point bfd_get_symcount (abfd) holds the number of symbols 44033965Sjdp as read from the file header, but on ECOFF this is always the 44133965Sjdp size of the symbolic information header. It would be cleaner to 44233965Sjdp handle this when we first read the file in coffgen.c. */ 44333965Sjdp external_hdr_size = backend->debug_swap.external_hdr_size; 44433965Sjdp if (bfd_get_symcount (abfd) != external_hdr_size) 44533965Sjdp { 44633965Sjdp bfd_set_error (bfd_error_bad_value); 447130561Sobrien return FALSE; 44833965Sjdp } 44933965Sjdp 45033965Sjdp /* Read the symbolic information header. */ 451218822Sdim raw = bfd_malloc (external_hdr_size); 45233965Sjdp if (raw == NULL) 45333965Sjdp goto error_return; 45433965Sjdp 45589857Sobrien if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0 45689857Sobrien || bfd_bread (raw, external_hdr_size, abfd) != external_hdr_size) 45733965Sjdp goto error_return; 45833965Sjdp internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; 45933965Sjdp (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr); 46033965Sjdp 46133965Sjdp if (internal_symhdr->magic != backend->debug_swap.sym_magic) 46233965Sjdp { 46333965Sjdp bfd_set_error (bfd_error_bad_value); 46433965Sjdp goto error_return; 46533965Sjdp } 46633965Sjdp 46733965Sjdp /* Now we can get the correct number of symbols. */ 46833965Sjdp bfd_get_symcount (abfd) = (internal_symhdr->isymMax 46933965Sjdp + internal_symhdr->iextMax); 47033965Sjdp 47133965Sjdp if (raw != NULL) 47233965Sjdp free (raw); 473130561Sobrien return TRUE; 47433965Sjdp error_return: 47533965Sjdp if (raw != NULL) 47633965Sjdp free (raw); 477130561Sobrien return FALSE; 47833965Sjdp} 47933965Sjdp 48033965Sjdp/* Read in and swap the important symbolic information for an ECOFF 48133965Sjdp object file. This is called by gdb via the read_debug_info entry 48233965Sjdp point in the backend structure. */ 48333965Sjdp 484130561Sobrienbfd_boolean 485218822Sdim_bfd_ecoff_slurp_symbolic_info (bfd *abfd, 486218822Sdim asection *ignore ATTRIBUTE_UNUSED, 487218822Sdim struct ecoff_debug_info *debug) 48833965Sjdp{ 48933965Sjdp const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 49033965Sjdp HDRR *internal_symhdr; 49133965Sjdp bfd_size_type raw_base; 49233965Sjdp bfd_size_type raw_size; 493218822Sdim void * raw; 49433965Sjdp bfd_size_type external_fdr_size; 49533965Sjdp char *fraw_src; 49633965Sjdp char *fraw_end; 49733965Sjdp struct fdr *fdr_ptr; 49833965Sjdp bfd_size_type raw_end; 49933965Sjdp bfd_size_type cb_end; 50089857Sobrien bfd_size_type amt; 50189857Sobrien file_ptr pos; 50233965Sjdp 50333965Sjdp BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info); 50433965Sjdp 50533965Sjdp /* Check whether we've already gotten it, and whether there's any to 50633965Sjdp get. */ 507218822Sdim if (ecoff_data (abfd)->raw_syments != NULL) 508130561Sobrien return TRUE; 50933965Sjdp if (ecoff_data (abfd)->sym_filepos == 0) 51033965Sjdp { 51133965Sjdp bfd_get_symcount (abfd) = 0; 512130561Sobrien return TRUE; 51333965Sjdp } 51433965Sjdp 51533965Sjdp if (! ecoff_slurp_symbolic_header (abfd)) 516130561Sobrien return FALSE; 51733965Sjdp 51833965Sjdp internal_symhdr = &debug->symbolic_header; 51933965Sjdp 52033965Sjdp /* Read all the symbolic information at once. */ 52133965Sjdp raw_base = (ecoff_data (abfd)->sym_filepos 52233965Sjdp + backend->debug_swap.external_hdr_size); 52333965Sjdp 52433965Sjdp /* Alpha ecoff makes the determination of raw_size difficult. It has 52533965Sjdp an undocumented debug data section between the symhdr and the first 52633965Sjdp documented section. And the ordering of the sections varies between 52733965Sjdp statically and dynamically linked executables. 52833965Sjdp If bfd supports SEEK_END someday, this code could be simplified. */ 52933965Sjdp raw_end = 0; 53033965Sjdp 53133965Sjdp#define UPDATE_RAW_END(start, count, size) \ 53233965Sjdp cb_end = internal_symhdr->start + internal_symhdr->count * (size); \ 53333965Sjdp if (cb_end > raw_end) \ 53433965Sjdp raw_end = cb_end 53533965Sjdp 53633965Sjdp UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char)); 53733965Sjdp UPDATE_RAW_END (cbDnOffset, idnMax, backend->debug_swap.external_dnr_size); 53833965Sjdp UPDATE_RAW_END (cbPdOffset, ipdMax, backend->debug_swap.external_pdr_size); 53933965Sjdp UPDATE_RAW_END (cbSymOffset, isymMax, backend->debug_swap.external_sym_size); 540104834Sobrien /* eraxxon@alumni.rice.edu: ioptMax refers to the size of the 541218822Sdim optimization symtab, not the number of entries. */ 542104834Sobrien UPDATE_RAW_END (cbOptOffset, ioptMax, sizeof (char)); 54333965Sjdp UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext)); 54433965Sjdp UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char)); 54533965Sjdp UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char)); 54633965Sjdp UPDATE_RAW_END (cbFdOffset, ifdMax, backend->debug_swap.external_fdr_size); 54733965Sjdp UPDATE_RAW_END (cbRfdOffset, crfd, backend->debug_swap.external_rfd_size); 54833965Sjdp UPDATE_RAW_END (cbExtOffset, iextMax, backend->debug_swap.external_ext_size); 54933965Sjdp 55033965Sjdp#undef UPDATE_RAW_END 55133965Sjdp 55233965Sjdp raw_size = raw_end - raw_base; 55333965Sjdp if (raw_size == 0) 55433965Sjdp { 55533965Sjdp ecoff_data (abfd)->sym_filepos = 0; 556130561Sobrien return TRUE; 55733965Sjdp } 558218822Sdim raw = bfd_alloc (abfd, raw_size); 55933965Sjdp if (raw == NULL) 560130561Sobrien return FALSE; 56189857Sobrien 56289857Sobrien pos = ecoff_data (abfd)->sym_filepos; 56389857Sobrien pos += backend->debug_swap.external_hdr_size; 56489857Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0 56589857Sobrien || bfd_bread (raw, raw_size, abfd) != raw_size) 56633965Sjdp { 56733965Sjdp bfd_release (abfd, raw); 568130561Sobrien return FALSE; 56933965Sjdp } 57033965Sjdp 57133965Sjdp ecoff_data (abfd)->raw_syments = raw; 57233965Sjdp 57333965Sjdp /* Get pointers for the numeric offsets in the HDRR structure. */ 574218822Sdim#define FIX(off1, off2, type) \ 575218822Sdim if (internal_symhdr->off1 == 0) \ 576218822Sdim debug->off2 = NULL; \ 577218822Sdim else \ 578218822Sdim debug->off2 = (type) ((char *) raw \ 579218822Sdim + (internal_symhdr->off1 \ 58033965Sjdp - raw_base)) 581104834Sobrien 58233965Sjdp FIX (cbLineOffset, line, unsigned char *); 583218822Sdim FIX (cbDnOffset, external_dnr, void *); 584218822Sdim FIX (cbPdOffset, external_pdr, void *); 585218822Sdim FIX (cbSymOffset, external_sym, void *); 586218822Sdim FIX (cbOptOffset, external_opt, void *); 58733965Sjdp FIX (cbAuxOffset, external_aux, union aux_ext *); 58833965Sjdp FIX (cbSsOffset, ss, char *); 58933965Sjdp FIX (cbSsExtOffset, ssext, char *); 590218822Sdim FIX (cbFdOffset, external_fdr, void *); 591218822Sdim FIX (cbRfdOffset, external_rfd, void *); 592218822Sdim FIX (cbExtOffset, external_ext, void *); 59333965Sjdp#undef FIX 59433965Sjdp 59533965Sjdp /* I don't want to always swap all the data, because it will just 59633965Sjdp waste time and most programs will never look at it. The only 59733965Sjdp time the linker needs most of the debugging information swapped 59833965Sjdp is when linking big-endian and little-endian MIPS object files 59933965Sjdp together, which is not a common occurrence. 60033965Sjdp 60133965Sjdp We need to look at the fdr to deal with a lot of information in 60233965Sjdp the symbols, so we swap them here. */ 60389857Sobrien amt = internal_symhdr->ifdMax; 60489857Sobrien amt *= sizeof (struct fdr); 605218822Sdim debug->fdr = bfd_alloc (abfd, amt); 60633965Sjdp if (debug->fdr == NULL) 607130561Sobrien return FALSE; 60833965Sjdp external_fdr_size = backend->debug_swap.external_fdr_size; 60933965Sjdp fdr_ptr = debug->fdr; 61033965Sjdp fraw_src = (char *) debug->external_fdr; 61133965Sjdp fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size; 61233965Sjdp for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) 613218822Sdim (*backend->debug_swap.swap_fdr_in) (abfd, (void *) fraw_src, fdr_ptr); 61433965Sjdp 615130561Sobrien return TRUE; 61633965Sjdp} 61733965Sjdp 61833965Sjdp/* ECOFF symbol table routines. The ECOFF symbol table is described 61933965Sjdp in gcc/mips-tfile.c. */ 62033965Sjdp 62133965Sjdp/* ECOFF uses two common sections. One is the usual one, and the 62233965Sjdp other is for small objects. All the small objects are kept 62333965Sjdp together, and then referenced via the gp pointer, which yields 62433965Sjdp faster assembler code. This is what we use for the small common 62533965Sjdp section. */ 62633965Sjdpstatic asection ecoff_scom_section; 62733965Sjdpstatic asymbol ecoff_scom_symbol; 62833965Sjdpstatic asymbol *ecoff_scom_symbol_ptr; 62933965Sjdp 63033965Sjdp/* Create an empty symbol. */ 63133965Sjdp 63233965Sjdpasymbol * 633218822Sdim_bfd_ecoff_make_empty_symbol (bfd *abfd) 63433965Sjdp{ 63533965Sjdp ecoff_symbol_type *new; 63689857Sobrien bfd_size_type amt = sizeof (ecoff_symbol_type); 63733965Sjdp 638218822Sdim new = bfd_zalloc (abfd, amt); 639218822Sdim if (new == NULL) 640218822Sdim return NULL; 641218822Sdim new->symbol.section = NULL; 642218822Sdim new->fdr = NULL; 643130561Sobrien new->local = FALSE; 64433965Sjdp new->native = NULL; 64533965Sjdp new->symbol.the_bfd = abfd; 64633965Sjdp return &new->symbol; 64733965Sjdp} 64833965Sjdp 64933965Sjdp/* Set the BFD flags and section for an ECOFF symbol. */ 65033965Sjdp 651130561Sobrienstatic bfd_boolean 652218822Sdimecoff_set_symbol_info (bfd *abfd, 653218822Sdim SYMR *ecoff_sym, 654218822Sdim asymbol *asym, 655218822Sdim int ext, 656218822Sdim int weak) 65733965Sjdp{ 65833965Sjdp asym->the_bfd = abfd; 65933965Sjdp asym->value = ecoff_sym->value; 66033965Sjdp asym->section = &bfd_debug_section; 66133965Sjdp asym->udata.i = 0; 66233965Sjdp 66333965Sjdp /* Most symbol types are just for debugging. */ 66433965Sjdp switch (ecoff_sym->st) 66533965Sjdp { 66633965Sjdp case stGlobal: 66733965Sjdp case stStatic: 66833965Sjdp case stLabel: 66933965Sjdp case stProc: 67033965Sjdp case stStaticProc: 67133965Sjdp break; 67233965Sjdp case stNil: 67333965Sjdp if (ECOFF_IS_STAB (ecoff_sym)) 67433965Sjdp { 67533965Sjdp asym->flags = BSF_DEBUGGING; 676130561Sobrien return TRUE; 67733965Sjdp } 67833965Sjdp break; 67933965Sjdp default: 68033965Sjdp asym->flags = BSF_DEBUGGING; 681130561Sobrien return TRUE; 68233965Sjdp } 68333965Sjdp 68433965Sjdp if (weak) 68533965Sjdp asym->flags = BSF_EXPORT | BSF_WEAK; 68633965Sjdp else if (ext) 68733965Sjdp asym->flags = BSF_EXPORT | BSF_GLOBAL; 68833965Sjdp else 68933965Sjdp { 69033965Sjdp asym->flags = BSF_LOCAL; 69133965Sjdp /* Normally, a local stProc symbol will have a corresponding 69233965Sjdp external symbol. We mark the local symbol as a debugging 69333965Sjdp symbol, in order to prevent nm from printing both out. 69433965Sjdp Similarly, we mark stLabel and stabs symbols as debugging 69533965Sjdp symbols. In both cases, we do want to set the value 69633965Sjdp correctly based on the symbol class. */ 69733965Sjdp if (ecoff_sym->st == stProc 69833965Sjdp || ecoff_sym->st == stLabel 69933965Sjdp || ECOFF_IS_STAB (ecoff_sym)) 70033965Sjdp asym->flags |= BSF_DEBUGGING; 70133965Sjdp } 702104834Sobrien 703104834Sobrien if (ecoff_sym->st == stProc || ecoff_sym->st == stStaticProc) 704104834Sobrien asym->flags |= BSF_FUNCTION; 705104834Sobrien 70633965Sjdp switch (ecoff_sym->sc) 70733965Sjdp { 70833965Sjdp case scNil: 70933965Sjdp /* Used for compiler generated labels. Leave them in the 71033965Sjdp debugging section, and mark them as local. If BSF_DEBUGGING 71133965Sjdp is set, then nm does not display them for some reason. If no 71233965Sjdp flags are set then the linker whines about them. */ 71333965Sjdp asym->flags = BSF_LOCAL; 71433965Sjdp break; 71533965Sjdp case scText: 716218822Sdim asym->section = bfd_make_section_old_way (abfd, _TEXT); 71733965Sjdp asym->value -= asym->section->vma; 71833965Sjdp break; 71933965Sjdp case scData: 720218822Sdim asym->section = bfd_make_section_old_way (abfd, _DATA); 72133965Sjdp asym->value -= asym->section->vma; 72233965Sjdp break; 72333965Sjdp case scBss: 724218822Sdim asym->section = bfd_make_section_old_way (abfd, _BSS); 72533965Sjdp asym->value -= asym->section->vma; 72633965Sjdp break; 72733965Sjdp case scRegister: 72833965Sjdp asym->flags = BSF_DEBUGGING; 72933965Sjdp break; 73033965Sjdp case scAbs: 73133965Sjdp asym->section = bfd_abs_section_ptr; 73233965Sjdp break; 73333965Sjdp case scUndefined: 73433965Sjdp asym->section = bfd_und_section_ptr; 73533965Sjdp asym->flags = 0; 73633965Sjdp asym->value = 0; 73733965Sjdp break; 73833965Sjdp case scCdbLocal: 73933965Sjdp case scBits: 74033965Sjdp case scCdbSystem: 74133965Sjdp case scRegImage: 74233965Sjdp case scInfo: 74333965Sjdp case scUserStruct: 74433965Sjdp asym->flags = BSF_DEBUGGING; 74533965Sjdp break; 74633965Sjdp case scSData: 74733965Sjdp asym->section = bfd_make_section_old_way (abfd, ".sdata"); 74833965Sjdp asym->value -= asym->section->vma; 74933965Sjdp break; 75033965Sjdp case scSBss: 75133965Sjdp asym->section = bfd_make_section_old_way (abfd, ".sbss"); 75233965Sjdp asym->value -= asym->section->vma; 75333965Sjdp break; 75433965Sjdp case scRData: 75533965Sjdp asym->section = bfd_make_section_old_way (abfd, ".rdata"); 75633965Sjdp asym->value -= asym->section->vma; 75733965Sjdp break; 75833965Sjdp case scVar: 75933965Sjdp asym->flags = BSF_DEBUGGING; 76033965Sjdp break; 76133965Sjdp case scCommon: 76233965Sjdp if (asym->value > ecoff_data (abfd)->gp_size) 76333965Sjdp { 76433965Sjdp asym->section = bfd_com_section_ptr; 76533965Sjdp asym->flags = 0; 76633965Sjdp break; 76733965Sjdp } 76833965Sjdp /* Fall through. */ 76933965Sjdp case scSCommon: 77033965Sjdp if (ecoff_scom_section.name == NULL) 77133965Sjdp { 77233965Sjdp /* Initialize the small common section. */ 77333965Sjdp ecoff_scom_section.name = SCOMMON; 77433965Sjdp ecoff_scom_section.flags = SEC_IS_COMMON; 77533965Sjdp ecoff_scom_section.output_section = &ecoff_scom_section; 77633965Sjdp ecoff_scom_section.symbol = &ecoff_scom_symbol; 77733965Sjdp ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr; 77833965Sjdp ecoff_scom_symbol.name = SCOMMON; 77933965Sjdp ecoff_scom_symbol.flags = BSF_SECTION_SYM; 78033965Sjdp ecoff_scom_symbol.section = &ecoff_scom_section; 78133965Sjdp ecoff_scom_symbol_ptr = &ecoff_scom_symbol; 78233965Sjdp } 78333965Sjdp asym->section = &ecoff_scom_section; 78433965Sjdp asym->flags = 0; 78533965Sjdp break; 78633965Sjdp case scVarRegister: 78733965Sjdp case scVariant: 78833965Sjdp asym->flags = BSF_DEBUGGING; 78933965Sjdp break; 79033965Sjdp case scSUndefined: 79133965Sjdp asym->section = bfd_und_section_ptr; 79233965Sjdp asym->flags = 0; 79333965Sjdp asym->value = 0; 79433965Sjdp break; 79533965Sjdp case scInit: 79633965Sjdp asym->section = bfd_make_section_old_way (abfd, ".init"); 79733965Sjdp asym->value -= asym->section->vma; 79833965Sjdp break; 79933965Sjdp case scBasedVar: 80033965Sjdp case scXData: 80133965Sjdp case scPData: 80233965Sjdp asym->flags = BSF_DEBUGGING; 80333965Sjdp break; 80433965Sjdp case scFini: 80533965Sjdp asym->section = bfd_make_section_old_way (abfd, ".fini"); 80633965Sjdp asym->value -= asym->section->vma; 80733965Sjdp break; 80833965Sjdp case scRConst: 80933965Sjdp asym->section = bfd_make_section_old_way (abfd, ".rconst"); 81033965Sjdp asym->value -= asym->section->vma; 81133965Sjdp break; 81233965Sjdp default: 81333965Sjdp break; 81433965Sjdp } 81533965Sjdp 81633965Sjdp /* Look for special constructors symbols and make relocation entries 81733965Sjdp in a special construction section. These are produced by the 81833965Sjdp -fgnu-linker argument to g++. */ 81933965Sjdp if (ECOFF_IS_STAB (ecoff_sym)) 82033965Sjdp { 82133965Sjdp switch (ECOFF_UNMARK_STAB (ecoff_sym->index)) 82233965Sjdp { 82333965Sjdp default: 82433965Sjdp break; 82533965Sjdp 82633965Sjdp case N_SETA: 82733965Sjdp case N_SETT: 82833965Sjdp case N_SETD: 82933965Sjdp case N_SETB: 830218822Sdim /* Mark the symbol as a constructor. */ 831218822Sdim asym->flags |= BSF_CONSTRUCTOR; 83233965Sjdp break; 83333965Sjdp } 83433965Sjdp } 835130561Sobrien return TRUE; 83633965Sjdp} 83733965Sjdp 83833965Sjdp/* Read an ECOFF symbol table. */ 83933965Sjdp 840130561Sobrienbfd_boolean 841218822Sdim_bfd_ecoff_slurp_symbol_table (bfd *abfd) 84233965Sjdp{ 84333965Sjdp const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 84433965Sjdp const bfd_size_type external_ext_size 84533965Sjdp = backend->debug_swap.external_ext_size; 84633965Sjdp const bfd_size_type external_sym_size 84733965Sjdp = backend->debug_swap.external_sym_size; 848218822Sdim void (* const swap_ext_in) (bfd *, void *, EXTR *) 84933965Sjdp = backend->debug_swap.swap_ext_in; 850218822Sdim void (* const swap_sym_in) (bfd *, void *, SYMR *) 85133965Sjdp = backend->debug_swap.swap_sym_in; 85233965Sjdp bfd_size_type internal_size; 85333965Sjdp ecoff_symbol_type *internal; 85433965Sjdp ecoff_symbol_type *internal_ptr; 85533965Sjdp char *eraw_src; 85633965Sjdp char *eraw_end; 85733965Sjdp FDR *fdr_ptr; 85833965Sjdp FDR *fdr_end; 85933965Sjdp 86033965Sjdp /* If we've already read in the symbol table, do nothing. */ 86133965Sjdp if (ecoff_data (abfd)->canonical_symbols != NULL) 862130561Sobrien return TRUE; 86333965Sjdp 86433965Sjdp /* Get the symbolic information. */ 865218822Sdim if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL, 86633965Sjdp &ecoff_data (abfd)->debug_info)) 867130561Sobrien return FALSE; 86833965Sjdp if (bfd_get_symcount (abfd) == 0) 869130561Sobrien return TRUE; 87033965Sjdp 87189857Sobrien internal_size = bfd_get_symcount (abfd); 87289857Sobrien internal_size *= sizeof (ecoff_symbol_type); 873218822Sdim internal = bfd_alloc (abfd, internal_size); 87433965Sjdp if (internal == NULL) 875130561Sobrien return FALSE; 87633965Sjdp 87733965Sjdp internal_ptr = internal; 87833965Sjdp eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext; 87933965Sjdp eraw_end = (eraw_src 88033965Sjdp + (ecoff_data (abfd)->debug_info.symbolic_header.iextMax 88133965Sjdp * external_ext_size)); 88233965Sjdp for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++) 88333965Sjdp { 88433965Sjdp EXTR internal_esym; 88533965Sjdp 886218822Sdim (*swap_ext_in) (abfd, (void *) eraw_src, &internal_esym); 88733965Sjdp internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext 88833965Sjdp + internal_esym.asym.iss); 88933965Sjdp if (!ecoff_set_symbol_info (abfd, &internal_esym.asym, 89033965Sjdp &internal_ptr->symbol, 1, 89133965Sjdp internal_esym.weakext)) 892130561Sobrien return FALSE; 89333965Sjdp /* The alpha uses a negative ifd field for section symbols. */ 89433965Sjdp if (internal_esym.ifd >= 0) 89533965Sjdp internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr 89633965Sjdp + internal_esym.ifd); 89733965Sjdp else 89833965Sjdp internal_ptr->fdr = NULL; 899130561Sobrien internal_ptr->local = FALSE; 900218822Sdim internal_ptr->native = (void *) eraw_src; 90133965Sjdp } 90233965Sjdp 90333965Sjdp /* The local symbols must be accessed via the fdr's, because the 90433965Sjdp string and aux indices are relative to the fdr information. */ 90533965Sjdp fdr_ptr = ecoff_data (abfd)->debug_info.fdr; 90633965Sjdp fdr_end = fdr_ptr + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax; 90733965Sjdp for (; fdr_ptr < fdr_end; fdr_ptr++) 90833965Sjdp { 90933965Sjdp char *lraw_src; 91033965Sjdp char *lraw_end; 91133965Sjdp 91233965Sjdp lraw_src = ((char *) ecoff_data (abfd)->debug_info.external_sym 91333965Sjdp + fdr_ptr->isymBase * external_sym_size); 91433965Sjdp lraw_end = lraw_src + fdr_ptr->csym * external_sym_size; 91533965Sjdp for (; 91633965Sjdp lraw_src < lraw_end; 91733965Sjdp lraw_src += external_sym_size, internal_ptr++) 91833965Sjdp { 91933965Sjdp SYMR internal_sym; 92033965Sjdp 921218822Sdim (*swap_sym_in) (abfd, (void *) lraw_src, &internal_sym); 92233965Sjdp internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ss 92333965Sjdp + fdr_ptr->issBase 92433965Sjdp + internal_sym.iss); 92533965Sjdp if (!ecoff_set_symbol_info (abfd, &internal_sym, 92633965Sjdp &internal_ptr->symbol, 0, 0)) 927130561Sobrien return FALSE; 92833965Sjdp internal_ptr->fdr = fdr_ptr; 929130561Sobrien internal_ptr->local = TRUE; 930218822Sdim internal_ptr->native = (void *) lraw_src; 93133965Sjdp } 93233965Sjdp } 93333965Sjdp 93433965Sjdp ecoff_data (abfd)->canonical_symbols = internal; 93533965Sjdp 936130561Sobrien return TRUE; 93733965Sjdp} 93833965Sjdp 93933965Sjdp/* Return the amount of space needed for the canonical symbols. */ 94033965Sjdp 94133965Sjdplong 942218822Sdim_bfd_ecoff_get_symtab_upper_bound (bfd *abfd) 94333965Sjdp{ 944218822Sdim if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL, 94533965Sjdp &ecoff_data (abfd)->debug_info)) 94633965Sjdp return -1; 94733965Sjdp 94833965Sjdp if (bfd_get_symcount (abfd) == 0) 94933965Sjdp return 0; 95033965Sjdp 95133965Sjdp return (bfd_get_symcount (abfd) + 1) * (sizeof (ecoff_symbol_type *)); 95233965Sjdp} 95333965Sjdp 95433965Sjdp/* Get the canonical symbols. */ 95533965Sjdp 95633965Sjdplong 957218822Sdim_bfd_ecoff_canonicalize_symtab (bfd *abfd, asymbol **alocation) 95833965Sjdp{ 95933965Sjdp unsigned int counter = 0; 96033965Sjdp ecoff_symbol_type *symbase; 96133965Sjdp ecoff_symbol_type **location = (ecoff_symbol_type **) alocation; 96233965Sjdp 963104834Sobrien if (! _bfd_ecoff_slurp_symbol_table (abfd)) 96433965Sjdp return -1; 96533965Sjdp if (bfd_get_symcount (abfd) == 0) 96633965Sjdp return 0; 96733965Sjdp 96833965Sjdp symbase = ecoff_data (abfd)->canonical_symbols; 96933965Sjdp while (counter < bfd_get_symcount (abfd)) 97033965Sjdp { 97133965Sjdp *(location++) = symbase++; 97233965Sjdp counter++; 97333965Sjdp } 974218822Sdim *location++ = NULL; 97533965Sjdp return bfd_get_symcount (abfd); 97633965Sjdp} 97733965Sjdp 97833965Sjdp/* Turn ECOFF type information into a printable string. 97933965Sjdp ecoff_emit_aggregate and ecoff_type_to_string are from 98033965Sjdp gcc/mips-tdump.c, with swapping added and used_ptr removed. */ 98133965Sjdp 98233965Sjdp/* Write aggregate information to a string. */ 98333965Sjdp 98433965Sjdpstatic void 985218822Sdimecoff_emit_aggregate (bfd *abfd, 986218822Sdim FDR *fdr, 987218822Sdim char *string, 988218822Sdim RNDXR *rndx, 989218822Sdim long isym, 990218822Sdim const char *which) 99133965Sjdp{ 99233965Sjdp const struct ecoff_debug_swap * const debug_swap = 99333965Sjdp &ecoff_backend (abfd)->debug_swap; 99433965Sjdp struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info; 99533965Sjdp unsigned int ifd = rndx->rfd; 99633965Sjdp unsigned int indx = rndx->index; 99733965Sjdp const char *name; 99877298Sobrien 99933965Sjdp if (ifd == 0xfff) 100033965Sjdp ifd = isym; 100133965Sjdp 100233965Sjdp /* An ifd of -1 is an opaque type. An escaped index of 0 is a 100333965Sjdp struct return type of a procedure compiled without -g. */ 100433965Sjdp if (ifd == 0xffffffff 100533965Sjdp || (rndx->rfd == 0xfff && indx == 0)) 100633965Sjdp name = "<undefined>"; 100733965Sjdp else if (indx == indexNil) 100833965Sjdp name = "<no name>"; 100933965Sjdp else 101033965Sjdp { 101133965Sjdp SYMR sym; 101233965Sjdp 101333965Sjdp if (debug_info->external_rfd == NULL) 101433965Sjdp fdr = debug_info->fdr + ifd; 101533965Sjdp else 101633965Sjdp { 101733965Sjdp RFDT rfd; 101833965Sjdp 101933965Sjdp (*debug_swap->swap_rfd_in) (abfd, 102033965Sjdp ((char *) debug_info->external_rfd 102133965Sjdp + ((fdr->rfdBase + ifd) 102233965Sjdp * debug_swap->external_rfd_size)), 102333965Sjdp &rfd); 102433965Sjdp fdr = debug_info->fdr + rfd; 102533965Sjdp } 102633965Sjdp 102733965Sjdp indx += fdr->isymBase; 102833965Sjdp 102933965Sjdp (*debug_swap->swap_sym_in) (abfd, 103033965Sjdp ((char *) debug_info->external_sym 103133965Sjdp + indx * debug_swap->external_sym_size), 103233965Sjdp &sym); 103333965Sjdp 103433965Sjdp name = debug_info->ss + fdr->issBase + sym.iss; 103533965Sjdp } 103633965Sjdp 103733965Sjdp sprintf (string, 103833965Sjdp "%s %s { ifd = %u, index = %lu }", 103933965Sjdp which, name, ifd, 104033965Sjdp ((long) indx 104133965Sjdp + debug_info->symbolic_header.iextMax)); 104233965Sjdp} 104333965Sjdp 104433965Sjdp/* Convert the type information to string format. */ 104533965Sjdp 104633965Sjdpstatic char * 1047218822Sdimecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx) 104833965Sjdp{ 104933965Sjdp union aux_ext *aux_ptr; 105033965Sjdp int bigendian; 105133965Sjdp AUXU u; 1052218822Sdim struct qual 1053218822Sdim { 105433965Sjdp unsigned int type; 105533965Sjdp int low_bound; 105633965Sjdp int high_bound; 105733965Sjdp int stride; 105833965Sjdp } qualifiers[7]; 105933965Sjdp unsigned int basic_type; 106033965Sjdp int i; 106133965Sjdp char buffer1[1024]; 106233965Sjdp static char buffer2[1024]; 106333965Sjdp char *p1 = buffer1; 106433965Sjdp char *p2 = buffer2; 106533965Sjdp RNDXR rndx; 106633965Sjdp 106733965Sjdp aux_ptr = ecoff_data (abfd)->debug_info.external_aux + fdr->iauxBase; 106833965Sjdp bigendian = fdr->fBigendian; 106933965Sjdp 107033965Sjdp for (i = 0; i < 7; i++) 107133965Sjdp { 107233965Sjdp qualifiers[i].low_bound = 0; 107333965Sjdp qualifiers[i].high_bound = 0; 107433965Sjdp qualifiers[i].stride = 0; 107533965Sjdp } 107633965Sjdp 107733965Sjdp if (AUX_GET_ISYM (bigendian, &aux_ptr[indx]) == (bfd_vma) -1) 107833965Sjdp return "-1 (no type)"; 107933965Sjdp _bfd_ecoff_swap_tir_in (bigendian, &aux_ptr[indx++].a_ti, &u.ti); 108033965Sjdp 108133965Sjdp basic_type = u.ti.bt; 108233965Sjdp qualifiers[0].type = u.ti.tq0; 108333965Sjdp qualifiers[1].type = u.ti.tq1; 108433965Sjdp qualifiers[2].type = u.ti.tq2; 108533965Sjdp qualifiers[3].type = u.ti.tq3; 108633965Sjdp qualifiers[4].type = u.ti.tq4; 108733965Sjdp qualifiers[5].type = u.ti.tq5; 108833965Sjdp qualifiers[6].type = tqNil; 108933965Sjdp 1090104834Sobrien /* Go get the basic type. */ 109133965Sjdp switch (basic_type) 109233965Sjdp { 1093104834Sobrien case btNil: /* Undefined. */ 109433965Sjdp strcpy (p1, "nil"); 109533965Sjdp break; 109633965Sjdp 1097104834Sobrien case btAdr: /* Address - integer same size as pointer. */ 109833965Sjdp strcpy (p1, "address"); 109933965Sjdp break; 110033965Sjdp 1101104834Sobrien case btChar: /* Character. */ 110233965Sjdp strcpy (p1, "char"); 110333965Sjdp break; 110433965Sjdp 1105104834Sobrien case btUChar: /* Unsigned character. */ 110633965Sjdp strcpy (p1, "unsigned char"); 110733965Sjdp break; 110833965Sjdp 1109104834Sobrien case btShort: /* Short. */ 111033965Sjdp strcpy (p1, "short"); 111133965Sjdp break; 111233965Sjdp 1113104834Sobrien case btUShort: /* Unsigned short. */ 111433965Sjdp strcpy (p1, "unsigned short"); 111533965Sjdp break; 111633965Sjdp 1117104834Sobrien case btInt: /* Int. */ 111833965Sjdp strcpy (p1, "int"); 111933965Sjdp break; 112033965Sjdp 1121104834Sobrien case btUInt: /* Unsigned int. */ 112233965Sjdp strcpy (p1, "unsigned int"); 112333965Sjdp break; 112433965Sjdp 1125104834Sobrien case btLong: /* Long. */ 112633965Sjdp strcpy (p1, "long"); 112733965Sjdp break; 112833965Sjdp 1129104834Sobrien case btULong: /* Unsigned long. */ 113033965Sjdp strcpy (p1, "unsigned long"); 113133965Sjdp break; 113233965Sjdp 1133104834Sobrien case btFloat: /* Float (real). */ 113433965Sjdp strcpy (p1, "float"); 113533965Sjdp break; 113633965Sjdp 1137104834Sobrien case btDouble: /* Double (real). */ 113833965Sjdp strcpy (p1, "double"); 113933965Sjdp break; 114033965Sjdp 114133965Sjdp /* Structures add 1-2 aux words: 114233965Sjdp 1st word is [ST_RFDESCAPE, offset] pointer to struct def; 114333965Sjdp 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ 114433965Sjdp 1145104834Sobrien case btStruct: /* Structure (Record). */ 114633965Sjdp _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); 114733965Sjdp ecoff_emit_aggregate (abfd, fdr, p1, &rndx, 114833965Sjdp (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), 114933965Sjdp "struct"); 1150104834Sobrien indx++; /* Skip aux words. */ 115133965Sjdp break; 115233965Sjdp 115333965Sjdp /* Unions add 1-2 aux words: 115433965Sjdp 1st word is [ST_RFDESCAPE, offset] pointer to union def; 115533965Sjdp 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ 115633965Sjdp 1157104834Sobrien case btUnion: /* Union. */ 115833965Sjdp _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); 115933965Sjdp ecoff_emit_aggregate (abfd, fdr, p1, &rndx, 116033965Sjdp (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), 116133965Sjdp "union"); 1162104834Sobrien indx++; /* Skip aux words. */ 116333965Sjdp break; 116433965Sjdp 116533965Sjdp /* Enumerations add 1-2 aux words: 116633965Sjdp 1st word is [ST_RFDESCAPE, offset] pointer to enum def; 116733965Sjdp 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ 116833965Sjdp 1169104834Sobrien case btEnum: /* Enumeration. */ 117033965Sjdp _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); 117133965Sjdp ecoff_emit_aggregate (abfd, fdr, p1, &rndx, 117233965Sjdp (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), 117333965Sjdp "enum"); 1174104834Sobrien indx++; /* Skip aux words. */ 117533965Sjdp break; 117633965Sjdp 1177104834Sobrien case btTypedef: /* Defined via a typedef, isymRef points. */ 117833965Sjdp strcpy (p1, "typedef"); 117933965Sjdp break; 118033965Sjdp 1181104834Sobrien case btRange: /* Subrange of int. */ 118233965Sjdp strcpy (p1, "subrange"); 118333965Sjdp break; 118433965Sjdp 1185104834Sobrien case btSet: /* Pascal sets. */ 118633965Sjdp strcpy (p1, "set"); 118733965Sjdp break; 118833965Sjdp 1189104834Sobrien case btComplex: /* Fortran complex. */ 119033965Sjdp strcpy (p1, "complex"); 119133965Sjdp break; 119233965Sjdp 1193104834Sobrien case btDComplex: /* Fortran double complex. */ 119433965Sjdp strcpy (p1, "double complex"); 119533965Sjdp break; 119633965Sjdp 1197104834Sobrien case btIndirect: /* Forward or unnamed typedef. */ 119833965Sjdp strcpy (p1, "forward/unamed typedef"); 119933965Sjdp break; 120033965Sjdp 1201104834Sobrien case btFixedDec: /* Fixed Decimal. */ 120233965Sjdp strcpy (p1, "fixed decimal"); 120333965Sjdp break; 120433965Sjdp 1205104834Sobrien case btFloatDec: /* Float Decimal. */ 120633965Sjdp strcpy (p1, "float decimal"); 120733965Sjdp break; 120833965Sjdp 1209104834Sobrien case btString: /* Varying Length Character String. */ 121033965Sjdp strcpy (p1, "string"); 121133965Sjdp break; 121233965Sjdp 1213104834Sobrien case btBit: /* Aligned Bit String. */ 121433965Sjdp strcpy (p1, "bit"); 121533965Sjdp break; 121633965Sjdp 1217104834Sobrien case btPicture: /* Picture. */ 121833965Sjdp strcpy (p1, "picture"); 121933965Sjdp break; 122033965Sjdp 1221104834Sobrien case btVoid: /* Void. */ 122233965Sjdp strcpy (p1, "void"); 122333965Sjdp break; 122433965Sjdp 122533965Sjdp default: 122660484Sobrien sprintf (p1, _("Unknown basic type %d"), (int) basic_type); 122733965Sjdp break; 122833965Sjdp } 122933965Sjdp 123033965Sjdp p1 += strlen (buffer1); 123133965Sjdp 1232104834Sobrien /* If this is a bitfield, get the bitsize. */ 123333965Sjdp if (u.ti.fBitfield) 123433965Sjdp { 123533965Sjdp int bitsize; 123633965Sjdp 123733965Sjdp bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]); 123833965Sjdp sprintf (p1, " : %d", bitsize); 123933965Sjdp p1 += strlen (buffer1); 124033965Sjdp } 124133965Sjdp 1242104834Sobrien /* Deal with any qualifiers. */ 124333965Sjdp if (qualifiers[0].type != tqNil) 124433965Sjdp { 1245104834Sobrien /* Snarf up any array bounds in the correct order. Arrays 1246104834Sobrien store 5 successive words in the aux. table: 1247104834Sobrien word 0 RNDXR to type of the bounds (ie, int) 1248104834Sobrien word 1 Current file descriptor index 1249104834Sobrien word 2 low bound 1250104834Sobrien word 3 high bound (or -1 if []) 1251104834Sobrien word 4 stride size in bits. */ 125233965Sjdp for (i = 0; i < 7; i++) 125333965Sjdp { 125433965Sjdp if (qualifiers[i].type == tqArray) 125533965Sjdp { 125633965Sjdp qualifiers[i].low_bound = 125733965Sjdp AUX_GET_DNLOW (bigendian, &aux_ptr[indx+2]); 125833965Sjdp qualifiers[i].high_bound = 125933965Sjdp AUX_GET_DNHIGH (bigendian, &aux_ptr[indx+3]); 126033965Sjdp qualifiers[i].stride = 126133965Sjdp AUX_GET_WIDTH (bigendian, &aux_ptr[indx+4]); 126233965Sjdp indx += 5; 126333965Sjdp } 126433965Sjdp } 126533965Sjdp 1266104834Sobrien /* Now print out the qualifiers. */ 126733965Sjdp for (i = 0; i < 6; i++) 126833965Sjdp { 126933965Sjdp switch (qualifiers[i].type) 127033965Sjdp { 127133965Sjdp case tqNil: 127233965Sjdp case tqMax: 127333965Sjdp break; 127433965Sjdp 127533965Sjdp case tqPtr: 127633965Sjdp strcpy (p2, "ptr to "); 127733965Sjdp p2 += sizeof ("ptr to ")-1; 127833965Sjdp break; 127933965Sjdp 128033965Sjdp case tqVol: 128133965Sjdp strcpy (p2, "volatile "); 128233965Sjdp p2 += sizeof ("volatile ")-1; 128333965Sjdp break; 128433965Sjdp 128533965Sjdp case tqFar: 128633965Sjdp strcpy (p2, "far "); 128733965Sjdp p2 += sizeof ("far ")-1; 128833965Sjdp break; 128933965Sjdp 129033965Sjdp case tqProc: 129133965Sjdp strcpy (p2, "func. ret. "); 129233965Sjdp p2 += sizeof ("func. ret. "); 129333965Sjdp break; 129433965Sjdp 129533965Sjdp case tqArray: 129633965Sjdp { 129733965Sjdp int first_array = i; 129833965Sjdp int j; 129933965Sjdp 130033965Sjdp /* Print array bounds reversed (ie, in the order the C 130177298Sobrien programmer writes them). C is such a fun language.... */ 130233965Sjdp while (i < 5 && qualifiers[i+1].type == tqArray) 130333965Sjdp i++; 130433965Sjdp 130533965Sjdp for (j = i; j >= first_array; j--) 130633965Sjdp { 130733965Sjdp strcpy (p2, "array ["); 130833965Sjdp p2 += sizeof ("array [")-1; 130933965Sjdp if (qualifiers[j].low_bound != 0) 131033965Sjdp sprintf (p2, 131133965Sjdp "%ld:%ld {%ld bits}", 131233965Sjdp (long) qualifiers[j].low_bound, 131333965Sjdp (long) qualifiers[j].high_bound, 131433965Sjdp (long) qualifiers[j].stride); 131533965Sjdp 131633965Sjdp else if (qualifiers[j].high_bound != -1) 131733965Sjdp sprintf (p2, 131833965Sjdp "%ld {%ld bits}", 131933965Sjdp (long) (qualifiers[j].high_bound + 1), 132033965Sjdp (long) (qualifiers[j].stride)); 132133965Sjdp 132233965Sjdp else 132333965Sjdp sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride)); 132433965Sjdp 132533965Sjdp p2 += strlen (p2); 132633965Sjdp strcpy (p2, "] of "); 132733965Sjdp p2 += sizeof ("] of ")-1; 132833965Sjdp } 132933965Sjdp } 133033965Sjdp break; 133133965Sjdp } 133233965Sjdp } 133333965Sjdp } 133433965Sjdp 133533965Sjdp strcpy (p2, buffer1); 133633965Sjdp return buffer2; 133733965Sjdp} 133833965Sjdp 133933965Sjdp/* Return information about ECOFF symbol SYMBOL in RET. */ 134033965Sjdp 134133965Sjdpvoid 1342218822Sdim_bfd_ecoff_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, 1343218822Sdim asymbol *symbol, 1344218822Sdim symbol_info *ret) 134533965Sjdp{ 134633965Sjdp bfd_symbol_info (symbol, ret); 134733965Sjdp} 134833965Sjdp 134933965Sjdp/* Return whether this is a local label. */ 135033965Sjdp 1351130561Sobrienbfd_boolean 1352218822Sdim_bfd_ecoff_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, 1353218822Sdim const char *name) 135433965Sjdp{ 135533965Sjdp return name[0] == '$'; 135633965Sjdp} 135733965Sjdp 135833965Sjdp/* Print information about an ECOFF symbol. */ 135933965Sjdp 136033965Sjdpvoid 1361218822Sdim_bfd_ecoff_print_symbol (bfd *abfd, 1362218822Sdim void * filep, 1363218822Sdim asymbol *symbol, 1364218822Sdim bfd_print_symbol_type how) 136533965Sjdp{ 136633965Sjdp const struct ecoff_debug_swap * const debug_swap 136733965Sjdp = &ecoff_backend (abfd)->debug_swap; 136833965Sjdp FILE *file = (FILE *)filep; 136933965Sjdp 137033965Sjdp switch (how) 137133965Sjdp { 137233965Sjdp case bfd_print_symbol_name: 137333965Sjdp fprintf (file, "%s", symbol->name); 137433965Sjdp break; 137533965Sjdp case bfd_print_symbol_more: 137633965Sjdp if (ecoffsymbol (symbol)->local) 137733965Sjdp { 137833965Sjdp SYMR ecoff_sym; 137977298Sobrien 138033965Sjdp (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, 138133965Sjdp &ecoff_sym); 138233965Sjdp fprintf (file, "ecoff local "); 138333965Sjdp fprintf_vma (file, (bfd_vma) ecoff_sym.value); 138433965Sjdp fprintf (file, " %x %x", (unsigned) ecoff_sym.st, 138533965Sjdp (unsigned) ecoff_sym.sc); 138633965Sjdp } 138733965Sjdp else 138833965Sjdp { 138933965Sjdp EXTR ecoff_ext; 139033965Sjdp 139133965Sjdp (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, 139233965Sjdp &ecoff_ext); 139333965Sjdp fprintf (file, "ecoff extern "); 139433965Sjdp fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value); 139533965Sjdp fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st, 139633965Sjdp (unsigned) ecoff_ext.asym.sc); 139733965Sjdp } 139833965Sjdp break; 139933965Sjdp case bfd_print_symbol_all: 1400104834Sobrien /* Print out the symbols in a reasonable way. */ 140133965Sjdp { 140233965Sjdp char type; 140333965Sjdp int pos; 140433965Sjdp EXTR ecoff_ext; 140533965Sjdp char jmptbl; 140633965Sjdp char cobol_main; 140733965Sjdp char weakext; 140833965Sjdp 140933965Sjdp if (ecoffsymbol (symbol)->local) 141033965Sjdp { 141133965Sjdp (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, 141233965Sjdp &ecoff_ext.asym); 141333965Sjdp type = 'l'; 141433965Sjdp pos = ((((char *) ecoffsymbol (symbol)->native 141533965Sjdp - (char *) ecoff_data (abfd)->debug_info.external_sym) 141633965Sjdp / debug_swap->external_sym_size) 141733965Sjdp + ecoff_data (abfd)->debug_info.symbolic_header.iextMax); 141833965Sjdp jmptbl = ' '; 141933965Sjdp cobol_main = ' '; 142033965Sjdp weakext = ' '; 142133965Sjdp } 142233965Sjdp else 142333965Sjdp { 142433965Sjdp (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, 142533965Sjdp &ecoff_ext); 142633965Sjdp type = 'e'; 142733965Sjdp pos = (((char *) ecoffsymbol (symbol)->native 142833965Sjdp - (char *) ecoff_data (abfd)->debug_info.external_ext) 142933965Sjdp / debug_swap->external_ext_size); 143033965Sjdp jmptbl = ecoff_ext.jmptbl ? 'j' : ' '; 143133965Sjdp cobol_main = ecoff_ext.cobol_main ? 'c' : ' '; 143233965Sjdp weakext = ecoff_ext.weakext ? 'w' : ' '; 143333965Sjdp } 143433965Sjdp 143533965Sjdp fprintf (file, "[%3d] %c ", 143633965Sjdp pos, type); 143733965Sjdp fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value); 143833965Sjdp fprintf (file, " st %x sc %x indx %x %c%c%c %s", 143933965Sjdp (unsigned) ecoff_ext.asym.st, 144033965Sjdp (unsigned) ecoff_ext.asym.sc, 144133965Sjdp (unsigned) ecoff_ext.asym.index, 144233965Sjdp jmptbl, cobol_main, weakext, 144333965Sjdp symbol->name); 144433965Sjdp 144533965Sjdp if (ecoffsymbol (symbol)->fdr != NULL 144633965Sjdp && ecoff_ext.asym.index != indexNil) 144733965Sjdp { 144833965Sjdp FDR *fdr; 144933965Sjdp unsigned int indx; 145033965Sjdp int bigendian; 145133965Sjdp bfd_size_type sym_base; 145233965Sjdp union aux_ext *aux_base; 145333965Sjdp 145433965Sjdp fdr = ecoffsymbol (symbol)->fdr; 145533965Sjdp indx = ecoff_ext.asym.index; 145633965Sjdp 145733965Sjdp /* sym_base is used to map the fdr relative indices which 145833965Sjdp appear in the file to the position number which we are 145933965Sjdp using. */ 146033965Sjdp sym_base = fdr->isymBase; 146133965Sjdp if (ecoffsymbol (symbol)->local) 146233965Sjdp sym_base += 146333965Sjdp ecoff_data (abfd)->debug_info.symbolic_header.iextMax; 146433965Sjdp 146533965Sjdp /* aux_base is the start of the aux entries for this file; 146633965Sjdp asym.index is an offset from this. */ 146733965Sjdp aux_base = (ecoff_data (abfd)->debug_info.external_aux 146833965Sjdp + fdr->iauxBase); 146933965Sjdp 147033965Sjdp /* The aux entries are stored in host byte order; the 147133965Sjdp order is indicated by a bit in the fdr. */ 147233965Sjdp bigendian = fdr->fBigendian; 147333965Sjdp 1474104834Sobrien /* This switch is basically from gcc/mips-tdump.c. */ 147533965Sjdp switch (ecoff_ext.asym.st) 147633965Sjdp { 147733965Sjdp case stNil: 147833965Sjdp case stLabel: 147933965Sjdp break; 148033965Sjdp 148133965Sjdp case stFile: 148233965Sjdp case stBlock: 148360484Sobrien fprintf (file, _("\n End+1 symbol: %ld"), 148433965Sjdp (long) (indx + sym_base)); 148533965Sjdp break; 148633965Sjdp 148733965Sjdp case stEnd: 148833965Sjdp if (ecoff_ext.asym.sc == scText 148933965Sjdp || ecoff_ext.asym.sc == scInfo) 149060484Sobrien fprintf (file, _("\n First symbol: %ld"), 149133965Sjdp (long) (indx + sym_base)); 149233965Sjdp else 149377298Sobrien fprintf (file, _("\n First symbol: %ld"), 149433965Sjdp ((long) 149533965Sjdp (AUX_GET_ISYM (bigendian, 149633965Sjdp &aux_base[ecoff_ext.asym.index]) 149733965Sjdp + sym_base))); 149833965Sjdp break; 149933965Sjdp 150033965Sjdp case stProc: 150133965Sjdp case stStaticProc: 150233965Sjdp if (ECOFF_IS_STAB (&ecoff_ext.asym)) 150333965Sjdp ; 150433965Sjdp else if (ecoffsymbol (symbol)->local) 150560484Sobrien fprintf (file, _("\n End+1 symbol: %-7ld Type: %s"), 150633965Sjdp ((long) 150733965Sjdp (AUX_GET_ISYM (bigendian, 150833965Sjdp &aux_base[ecoff_ext.asym.index]) 150933965Sjdp + sym_base)), 151033965Sjdp ecoff_type_to_string (abfd, fdr, indx + 1)); 151133965Sjdp else 151260484Sobrien fprintf (file, _("\n Local symbol: %ld"), 151333965Sjdp ((long) indx 151433965Sjdp + (long) sym_base 151533965Sjdp + (ecoff_data (abfd) 151633965Sjdp ->debug_info.symbolic_header.iextMax))); 151733965Sjdp break; 151833965Sjdp 151933965Sjdp case stStruct: 152060484Sobrien fprintf (file, _("\n struct; End+1 symbol: %ld"), 152133965Sjdp (long) (indx + sym_base)); 152233965Sjdp break; 152333965Sjdp 152433965Sjdp case stUnion: 152560484Sobrien fprintf (file, _("\n union; End+1 symbol: %ld"), 152633965Sjdp (long) (indx + sym_base)); 152733965Sjdp break; 152833965Sjdp 152933965Sjdp case stEnum: 153060484Sobrien fprintf (file, _("\n enum; End+1 symbol: %ld"), 153133965Sjdp (long) (indx + sym_base)); 153233965Sjdp break; 153333965Sjdp 153433965Sjdp default: 153533965Sjdp if (! ECOFF_IS_STAB (&ecoff_ext.asym)) 153660484Sobrien fprintf (file, _("\n Type: %s"), 153733965Sjdp ecoff_type_to_string (abfd, fdr, indx)); 153833965Sjdp break; 153933965Sjdp } 154033965Sjdp } 154133965Sjdp } 154233965Sjdp break; 154333965Sjdp } 154433965Sjdp} 154533965Sjdp 154633965Sjdp/* Read in the relocs for a section. */ 154733965Sjdp 1548130561Sobrienstatic bfd_boolean 1549218822Sdimecoff_slurp_reloc_table (bfd *abfd, 1550218822Sdim asection *section, 1551218822Sdim asymbol **symbols) 155233965Sjdp{ 155333965Sjdp const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 155433965Sjdp arelent *internal_relocs; 155533965Sjdp bfd_size_type external_reloc_size; 155689857Sobrien bfd_size_type amt; 155733965Sjdp char *external_relocs; 155833965Sjdp arelent *rptr; 155933965Sjdp unsigned int i; 156033965Sjdp 1561218822Sdim if (section->relocation != NULL 156233965Sjdp || section->reloc_count == 0 156333965Sjdp || (section->flags & SEC_CONSTRUCTOR) != 0) 1564130561Sobrien return TRUE; 156533965Sjdp 1566104834Sobrien if (! _bfd_ecoff_slurp_symbol_table (abfd)) 1567130561Sobrien return FALSE; 156877298Sobrien 156989857Sobrien amt = section->reloc_count; 157089857Sobrien amt *= sizeof (arelent); 1571218822Sdim internal_relocs = bfd_alloc (abfd, amt); 157289857Sobrien 157333965Sjdp external_reloc_size = backend->external_reloc_size; 157489857Sobrien amt = external_reloc_size * section->reloc_count; 1575218822Sdim external_relocs = bfd_alloc (abfd, amt); 1576218822Sdim if (internal_relocs == NULL || external_relocs == NULL) 1577130561Sobrien return FALSE; 157833965Sjdp if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0) 1579130561Sobrien return FALSE; 158089857Sobrien if (bfd_bread (external_relocs, amt, abfd) != amt) 1581130561Sobrien return FALSE; 158233965Sjdp 158333965Sjdp for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++) 158433965Sjdp { 158533965Sjdp struct internal_reloc intern; 158633965Sjdp 158733965Sjdp (*backend->swap_reloc_in) (abfd, 158833965Sjdp external_relocs + i * external_reloc_size, 158933965Sjdp &intern); 159033965Sjdp 159133965Sjdp if (intern.r_extern) 159233965Sjdp { 159333965Sjdp /* r_symndx is an index into the external symbols. */ 159433965Sjdp BFD_ASSERT (intern.r_symndx >= 0 159533965Sjdp && (intern.r_symndx 159633965Sjdp < (ecoff_data (abfd) 159733965Sjdp ->debug_info.symbolic_header.iextMax))); 159833965Sjdp rptr->sym_ptr_ptr = symbols + intern.r_symndx; 159933965Sjdp rptr->addend = 0; 160033965Sjdp } 160133965Sjdp else if (intern.r_symndx == RELOC_SECTION_NONE 160233965Sjdp || intern.r_symndx == RELOC_SECTION_ABS) 160333965Sjdp { 160433965Sjdp rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 160533965Sjdp rptr->addend = 0; 160633965Sjdp } 160733965Sjdp else 160833965Sjdp { 160989857Sobrien const char *sec_name; 161033965Sjdp asection *sec; 161133965Sjdp 161233965Sjdp /* r_symndx is a section key. */ 161333965Sjdp switch (intern.r_symndx) 161433965Sjdp { 1615218822Sdim case RELOC_SECTION_TEXT: sec_name = _TEXT; break; 1616218822Sdim case RELOC_SECTION_RDATA: sec_name = _RDATA; break; 1617218822Sdim case RELOC_SECTION_DATA: sec_name = _DATA; break; 1618218822Sdim case RELOC_SECTION_SDATA: sec_name = _SDATA; break; 1619218822Sdim case RELOC_SECTION_SBSS: sec_name = _SBSS; break; 1620218822Sdim case RELOC_SECTION_BSS: sec_name = _BSS; break; 1621218822Sdim case RELOC_SECTION_INIT: sec_name = _INIT; break; 1622218822Sdim case RELOC_SECTION_LIT8: sec_name = _LIT8; break; 1623218822Sdim case RELOC_SECTION_LIT4: sec_name = _LIT4; break; 1624218822Sdim case RELOC_SECTION_XDATA: sec_name = _XDATA; break; 1625218822Sdim case RELOC_SECTION_PDATA: sec_name = _PDATA; break; 1626218822Sdim case RELOC_SECTION_FINI: sec_name = _FINI; break; 1627218822Sdim case RELOC_SECTION_LITA: sec_name = _LITA; break; 1628218822Sdim case RELOC_SECTION_RCONST: sec_name = _RCONST; break; 162933965Sjdp default: abort (); 163033965Sjdp } 163133965Sjdp 163233965Sjdp sec = bfd_get_section_by_name (abfd, sec_name); 1633218822Sdim if (sec == NULL) 163433965Sjdp abort (); 163533965Sjdp rptr->sym_ptr_ptr = sec->symbol_ptr_ptr; 163633965Sjdp 163733965Sjdp rptr->addend = - bfd_get_section_vma (abfd, sec); 163833965Sjdp } 163933965Sjdp 164033965Sjdp rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section); 164133965Sjdp 164233965Sjdp /* Let the backend select the howto field and do any other 164333965Sjdp required processing. */ 164433965Sjdp (*backend->adjust_reloc_in) (abfd, &intern, rptr); 164533965Sjdp } 164633965Sjdp 164733965Sjdp bfd_release (abfd, external_relocs); 164833965Sjdp 164933965Sjdp section->relocation = internal_relocs; 165033965Sjdp 1651130561Sobrien return TRUE; 165233965Sjdp} 165333965Sjdp 165433965Sjdp/* Get a canonical list of relocs. */ 165533965Sjdp 165633965Sjdplong 1657218822Sdim_bfd_ecoff_canonicalize_reloc (bfd *abfd, 1658218822Sdim asection *section, 1659218822Sdim arelent **relptr, 1660218822Sdim asymbol **symbols) 166133965Sjdp{ 166233965Sjdp unsigned int count; 166333965Sjdp 166477298Sobrien if (section->flags & SEC_CONSTRUCTOR) 166533965Sjdp { 166633965Sjdp arelent_chain *chain; 166733965Sjdp 166833965Sjdp /* This section has relocs made up by us, not the file, so take 166933965Sjdp them out of their chain and place them into the data area 167033965Sjdp provided. */ 167133965Sjdp for (count = 0, chain = section->constructor_chain; 167233965Sjdp count < section->reloc_count; 167333965Sjdp count++, chain = chain->next) 167433965Sjdp *relptr++ = &chain->relent; 167533965Sjdp } 167633965Sjdp else 167777298Sobrien { 167833965Sjdp arelent *tblptr; 167933965Sjdp 1680104834Sobrien if (! ecoff_slurp_reloc_table (abfd, section, symbols)) 168133965Sjdp return -1; 168233965Sjdp 168333965Sjdp tblptr = section->relocation; 168433965Sjdp 168533965Sjdp for (count = 0; count < section->reloc_count; count++) 168633965Sjdp *relptr++ = tblptr++; 168733965Sjdp } 168833965Sjdp 1689218822Sdim *relptr = NULL; 169033965Sjdp 169133965Sjdp return section->reloc_count; 169233965Sjdp} 169333965Sjdp 169433965Sjdp/* Provided a BFD, a section and an offset into the section, calculate 169533965Sjdp and return the name of the source file and the line nearest to the 169633965Sjdp wanted location. */ 169733965Sjdp 1698130561Sobrienbfd_boolean 1699218822Sdim_bfd_ecoff_find_nearest_line (bfd *abfd, 1700218822Sdim asection *section, 1701218822Sdim asymbol **ignore_symbols ATTRIBUTE_UNUSED, 1702218822Sdim bfd_vma offset, 1703218822Sdim const char **filename_ptr, 1704218822Sdim const char **functionname_ptr, 1705218822Sdim unsigned int *retline_ptr) 170633965Sjdp{ 170733965Sjdp const struct ecoff_debug_swap * const debug_swap 170833965Sjdp = &ecoff_backend (abfd)->debug_swap; 170933965Sjdp struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info; 171033965Sjdp struct ecoff_find_line *line_info; 171133965Sjdp 171233965Sjdp /* Make sure we have the FDR's. */ 1713218822Sdim if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL, debug_info) 171433965Sjdp || bfd_get_symcount (abfd) == 0) 1715130561Sobrien return FALSE; 171633965Sjdp 171733965Sjdp if (ecoff_data (abfd)->find_line_info == NULL) 171833965Sjdp { 171989857Sobrien bfd_size_type amt = sizeof (struct ecoff_find_line); 1720218822Sdim 1721218822Sdim ecoff_data (abfd)->find_line_info = bfd_zalloc (abfd, amt); 172233965Sjdp if (ecoff_data (abfd)->find_line_info == NULL) 1723130561Sobrien return FALSE; 172433965Sjdp } 172533965Sjdp line_info = ecoff_data (abfd)->find_line_info; 172633965Sjdp 172733965Sjdp return _bfd_ecoff_locate_line (abfd, section, offset, debug_info, 172833965Sjdp debug_swap, line_info, filename_ptr, 172933965Sjdp functionname_ptr, retline_ptr); 173033965Sjdp} 173133965Sjdp 173233965Sjdp/* Copy private BFD data. This is called by objcopy and strip. We 173333965Sjdp use it to copy the ECOFF debugging information from one BFD to the 173433965Sjdp other. It would be theoretically possible to represent the ECOFF 173533965Sjdp debugging information in the symbol table. However, it would be a 173633965Sjdp lot of work, and there would be little gain (gas, gdb, and ld 173733965Sjdp already access the ECOFF debugging information via the 173833965Sjdp ecoff_debug_info structure, and that structure would have to be 173933965Sjdp retained in order to support ECOFF debugging in MIPS ELF). 174033965Sjdp 174133965Sjdp The debugging information for the ECOFF external symbols comes from 174233965Sjdp the symbol table, so this function only handles the other debugging 174333965Sjdp information. */ 174433965Sjdp 1745130561Sobrienbfd_boolean 1746218822Sdim_bfd_ecoff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) 174733965Sjdp{ 174833965Sjdp struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info; 174933965Sjdp struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info; 1750218822Sdim int i; 175133965Sjdp asymbol **sym_ptr_ptr; 175233965Sjdp size_t c; 1753130561Sobrien bfd_boolean local; 175433965Sjdp 175533965Sjdp /* We only want to copy information over if both BFD's use ECOFF 175633965Sjdp format. */ 175733965Sjdp if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour 175833965Sjdp || bfd_get_flavour (obfd) != bfd_target_ecoff_flavour) 1759130561Sobrien return TRUE; 176033965Sjdp 176133965Sjdp /* Copy the GP value and the register masks. */ 176233965Sjdp ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp; 176333965Sjdp ecoff_data (obfd)->gprmask = ecoff_data (ibfd)->gprmask; 176433965Sjdp ecoff_data (obfd)->fprmask = ecoff_data (ibfd)->fprmask; 176533965Sjdp for (i = 0; i < 3; i++) 176633965Sjdp ecoff_data (obfd)->cprmask[i] = ecoff_data (ibfd)->cprmask[i]; 176733965Sjdp 176833965Sjdp /* Copy the version stamp. */ 176933965Sjdp oinfo->symbolic_header.vstamp = iinfo->symbolic_header.vstamp; 177033965Sjdp 177133965Sjdp /* If there are no symbols, don't copy any debugging information. */ 177233965Sjdp c = bfd_get_symcount (obfd); 177333965Sjdp sym_ptr_ptr = bfd_get_outsymbols (obfd); 1774218822Sdim if (c == 0 || sym_ptr_ptr == NULL) 1775130561Sobrien return TRUE; 177633965Sjdp 177733965Sjdp /* See if there are any local symbols. */ 1778130561Sobrien local = FALSE; 177933965Sjdp for (; c > 0; c--, sym_ptr_ptr++) 178033965Sjdp { 178133965Sjdp if (ecoffsymbol (*sym_ptr_ptr)->local) 178233965Sjdp { 1783130561Sobrien local = TRUE; 178433965Sjdp break; 178533965Sjdp } 178633965Sjdp } 178733965Sjdp 178833965Sjdp if (local) 178933965Sjdp { 179033965Sjdp /* There are some local symbols. We just bring over all the 179133965Sjdp debugging information. FIXME: This is not quite the right 179233965Sjdp thing to do. If the user has asked us to discard all 179333965Sjdp debugging information, then we are probably going to wind up 179433965Sjdp keeping it because there will probably be some local symbol 179533965Sjdp which objcopy did not discard. We should actually break 179633965Sjdp apart the debugging information and only keep that which 179733965Sjdp applies to the symbols we want to keep. */ 179833965Sjdp oinfo->symbolic_header.ilineMax = iinfo->symbolic_header.ilineMax; 179933965Sjdp oinfo->symbolic_header.cbLine = iinfo->symbolic_header.cbLine; 180033965Sjdp oinfo->line = iinfo->line; 180133965Sjdp 180233965Sjdp oinfo->symbolic_header.idnMax = iinfo->symbolic_header.idnMax; 180333965Sjdp oinfo->external_dnr = iinfo->external_dnr; 180433965Sjdp 180533965Sjdp oinfo->symbolic_header.ipdMax = iinfo->symbolic_header.ipdMax; 180633965Sjdp oinfo->external_pdr = iinfo->external_pdr; 180733965Sjdp 180833965Sjdp oinfo->symbolic_header.isymMax = iinfo->symbolic_header.isymMax; 180933965Sjdp oinfo->external_sym = iinfo->external_sym; 181033965Sjdp 181133965Sjdp oinfo->symbolic_header.ioptMax = iinfo->symbolic_header.ioptMax; 181233965Sjdp oinfo->external_opt = iinfo->external_opt; 181333965Sjdp 181433965Sjdp oinfo->symbolic_header.iauxMax = iinfo->symbolic_header.iauxMax; 181533965Sjdp oinfo->external_aux = iinfo->external_aux; 181633965Sjdp 181733965Sjdp oinfo->symbolic_header.issMax = iinfo->symbolic_header.issMax; 181833965Sjdp oinfo->ss = iinfo->ss; 181933965Sjdp 182033965Sjdp oinfo->symbolic_header.ifdMax = iinfo->symbolic_header.ifdMax; 182133965Sjdp oinfo->external_fdr = iinfo->external_fdr; 182233965Sjdp 182333965Sjdp oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd; 182433965Sjdp oinfo->external_rfd = iinfo->external_rfd; 182533965Sjdp } 182633965Sjdp else 182733965Sjdp { 182833965Sjdp /* We are discarding all the local symbol information. Look 182933965Sjdp through the external symbols and remove all references to FDR 183033965Sjdp or aux information. */ 183133965Sjdp c = bfd_get_symcount (obfd); 183233965Sjdp sym_ptr_ptr = bfd_get_outsymbols (obfd); 183333965Sjdp for (; c > 0; c--, sym_ptr_ptr++) 183433965Sjdp { 183533965Sjdp EXTR esym; 183633965Sjdp 183733965Sjdp (*(ecoff_backend (obfd)->debug_swap.swap_ext_in)) 183833965Sjdp (obfd, ecoffsymbol (*sym_ptr_ptr)->native, &esym); 183933965Sjdp esym.ifd = ifdNil; 184033965Sjdp esym.asym.index = indexNil; 184133965Sjdp (*(ecoff_backend (obfd)->debug_swap.swap_ext_out)) 184233965Sjdp (obfd, &esym, ecoffsymbol (*sym_ptr_ptr)->native); 184333965Sjdp } 184433965Sjdp } 184533965Sjdp 1846130561Sobrien return TRUE; 184733965Sjdp} 184833965Sjdp 184933965Sjdp/* Set the architecture. The supported architecture is stored in the 185033965Sjdp backend pointer. We always set the architecture anyhow, since many 185133965Sjdp callers ignore the return value. */ 185233965Sjdp 1853130561Sobrienbfd_boolean 1854218822Sdim_bfd_ecoff_set_arch_mach (bfd *abfd, 1855218822Sdim enum bfd_architecture arch, 1856218822Sdim unsigned long machine) 185733965Sjdp{ 185833965Sjdp bfd_default_set_arch_mach (abfd, arch, machine); 185933965Sjdp return arch == ecoff_backend (abfd)->arch; 186033965Sjdp} 186133965Sjdp 186233965Sjdp/* Get the size of the section headers. */ 186333965Sjdp 186433965Sjdpint 1865218822Sdim_bfd_ecoff_sizeof_headers (bfd *abfd, 1866218822Sdim struct bfd_link_info *info ATTRIBUTE_UNUSED) 186733965Sjdp{ 186833965Sjdp asection *current; 186933965Sjdp int c; 187033965Sjdp int ret; 187133965Sjdp 187233965Sjdp c = 0; 187333965Sjdp for (current = abfd->sections; 1874218822Sdim current != NULL; 187577298Sobrien current = current->next) 187633965Sjdp ++c; 187733965Sjdp 187833965Sjdp ret = (bfd_coff_filhsz (abfd) 187933965Sjdp + bfd_coff_aoutsz (abfd) 188033965Sjdp + c * bfd_coff_scnhsz (abfd)); 188133965Sjdp return BFD_ALIGN (ret, 16); 188233965Sjdp} 188333965Sjdp 188433965Sjdp/* Get the contents of a section. */ 188533965Sjdp 1886130561Sobrienbfd_boolean 1887218822Sdim_bfd_ecoff_get_section_contents (bfd *abfd, 1888218822Sdim asection *section, 1889218822Sdim void * location, 1890218822Sdim file_ptr offset, 1891218822Sdim bfd_size_type count) 189233965Sjdp{ 189333965Sjdp return _bfd_generic_get_section_contents (abfd, section, location, 189433965Sjdp offset, count); 189533965Sjdp} 189633965Sjdp 189733965Sjdp/* Sort sections by VMA, but put SEC_ALLOC sections first. This is 189833965Sjdp called via qsort. */ 189933965Sjdp 190033965Sjdpstatic int 1901218822Sdimecoff_sort_hdrs (const void * arg1, const void * arg2) 190233965Sjdp{ 190333965Sjdp const asection *hdr1 = *(const asection **) arg1; 190433965Sjdp const asection *hdr2 = *(const asection **) arg2; 190533965Sjdp 190633965Sjdp if ((hdr1->flags & SEC_ALLOC) != 0) 190733965Sjdp { 190833965Sjdp if ((hdr2->flags & SEC_ALLOC) == 0) 190933965Sjdp return -1; 191033965Sjdp } 191133965Sjdp else 191233965Sjdp { 191333965Sjdp if ((hdr2->flags & SEC_ALLOC) != 0) 191433965Sjdp return 1; 191533965Sjdp } 191633965Sjdp if (hdr1->vma < hdr2->vma) 191733965Sjdp return -1; 191833965Sjdp else if (hdr1->vma > hdr2->vma) 191933965Sjdp return 1; 192033965Sjdp else 192133965Sjdp return 0; 192233965Sjdp} 192333965Sjdp 192433965Sjdp/* Calculate the file position for each section, and set 192533965Sjdp reloc_filepos. */ 192633965Sjdp 1927130561Sobrienstatic bfd_boolean 1928218822Sdimecoff_compute_section_file_positions (bfd *abfd) 192933965Sjdp{ 193033965Sjdp file_ptr sofar, file_sofar; 193133965Sjdp asection **sorted_hdrs; 193233965Sjdp asection *current; 193333965Sjdp unsigned int i; 193433965Sjdp file_ptr old_sofar; 1935130561Sobrien bfd_boolean rdata_in_text; 1936130561Sobrien bfd_boolean first_data, first_nonalloc; 193733965Sjdp const bfd_vma round = ecoff_backend (abfd)->round; 193889857Sobrien bfd_size_type amt; 193933965Sjdp 1940218822Sdim sofar = _bfd_ecoff_sizeof_headers (abfd, NULL); 194133965Sjdp file_sofar = sofar; 194233965Sjdp 194333965Sjdp /* Sort the sections by VMA. */ 194489857Sobrien amt = abfd->section_count; 194589857Sobrien amt *= sizeof (asection *); 1946218822Sdim sorted_hdrs = bfd_malloc (amt); 194733965Sjdp if (sorted_hdrs == NULL) 1948130561Sobrien return FALSE; 194933965Sjdp for (current = abfd->sections, i = 0; 195033965Sjdp current != NULL; 195133965Sjdp current = current->next, i++) 195233965Sjdp sorted_hdrs[i] = current; 195333965Sjdp BFD_ASSERT (i == abfd->section_count); 195433965Sjdp 195533965Sjdp qsort (sorted_hdrs, abfd->section_count, sizeof (asection *), 195633965Sjdp ecoff_sort_hdrs); 195733965Sjdp 195833965Sjdp /* Some versions of the OSF linker put the .rdata section in the 195933965Sjdp text segment, and some do not. */ 196033965Sjdp rdata_in_text = ecoff_backend (abfd)->rdata_in_text; 196133965Sjdp if (rdata_in_text) 196233965Sjdp { 196333965Sjdp for (i = 0; i < abfd->section_count; i++) 196433965Sjdp { 196533965Sjdp current = sorted_hdrs[i]; 1966218822Sdim if (streq (current->name, _RDATA)) 196733965Sjdp break; 196833965Sjdp if ((current->flags & SEC_CODE) == 0 1969218822Sdim && ! streq (current->name, _PDATA) 1970218822Sdim && ! streq (current->name, _RCONST)) 197133965Sjdp { 1972130561Sobrien rdata_in_text = FALSE; 197333965Sjdp break; 197433965Sjdp } 197533965Sjdp } 197633965Sjdp } 197733965Sjdp ecoff_data (abfd)->rdata_in_text = rdata_in_text; 197833965Sjdp 1979130561Sobrien first_data = TRUE; 1980130561Sobrien first_nonalloc = TRUE; 198133965Sjdp for (i = 0; i < abfd->section_count; i++) 198233965Sjdp { 198333965Sjdp unsigned int alignment_power; 198433965Sjdp 198533965Sjdp current = sorted_hdrs[i]; 198633965Sjdp 198733965Sjdp /* For the Alpha ECOFF .pdata section the lnnoptr field is 198833965Sjdp supposed to indicate the number of .pdata entries that are 198933965Sjdp really in the section. Each entry is 8 bytes. We store this 199033965Sjdp away in line_filepos before increasing the section size. */ 1991218822Sdim if (streq (current->name, _PDATA)) 1992218822Sdim current->line_filepos = current->size / 8; 199333965Sjdp 199433965Sjdp alignment_power = current->alignment_power; 199533965Sjdp 199633965Sjdp /* On Ultrix, the data sections in an executable file must be 199733965Sjdp aligned to a page boundary within the file. This does not 199833965Sjdp affect the section size, though. FIXME: Does this work for 199933965Sjdp other platforms? It requires some modification for the 200033965Sjdp Alpha, because .rdata on the Alpha goes with the text, not 200133965Sjdp the data. */ 200233965Sjdp if ((abfd->flags & EXEC_P) != 0 200333965Sjdp && (abfd->flags & D_PAGED) != 0 200433965Sjdp && ! first_data 200533965Sjdp && (current->flags & SEC_CODE) == 0 200633965Sjdp && (! rdata_in_text 2007218822Sdim || ! streq (current->name, _RDATA)) 2008218822Sdim && ! streq (current->name, _PDATA) 2009218822Sdim && ! streq (current->name, _RCONST)) 201033965Sjdp { 201133965Sjdp sofar = (sofar + round - 1) &~ (round - 1); 201233965Sjdp file_sofar = (file_sofar + round - 1) &~ (round - 1); 2013130561Sobrien first_data = FALSE; 201433965Sjdp } 2015218822Sdim else if (streq (current->name, _LIB)) 201633965Sjdp { 201733965Sjdp /* On Irix 4, the location of contents of the .lib section 201833965Sjdp from a shared library section is also rounded up to a 201933965Sjdp page boundary. */ 202033965Sjdp 202133965Sjdp sofar = (sofar + round - 1) &~ (round - 1); 202233965Sjdp file_sofar = (file_sofar + round - 1) &~ (round - 1); 202333965Sjdp } 202433965Sjdp else if (first_nonalloc 202533965Sjdp && (current->flags & SEC_ALLOC) == 0 202633965Sjdp && (abfd->flags & D_PAGED) != 0) 202733965Sjdp { 202833965Sjdp /* Skip up to the next page for an unallocated section, such 202933965Sjdp as the .comment section on the Alpha. This leaves room 203033965Sjdp for the .bss section. */ 2031130561Sobrien first_nonalloc = FALSE; 203233965Sjdp sofar = (sofar + round - 1) &~ (round - 1); 203333965Sjdp file_sofar = (file_sofar + round - 1) &~ (round - 1); 203433965Sjdp } 203533965Sjdp 203633965Sjdp /* Align the sections in the file to the same boundary on 203733965Sjdp which they are aligned in virtual memory. */ 203833965Sjdp sofar = BFD_ALIGN (sofar, 1 << alignment_power); 203933965Sjdp if ((current->flags & SEC_HAS_CONTENTS) != 0) 204033965Sjdp file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power); 204133965Sjdp 204233965Sjdp if ((abfd->flags & D_PAGED) != 0 204333965Sjdp && (current->flags & SEC_ALLOC) != 0) 204433965Sjdp { 204533965Sjdp sofar += (current->vma - sofar) % round; 204633965Sjdp if ((current->flags & SEC_HAS_CONTENTS) != 0) 204733965Sjdp file_sofar += (current->vma - file_sofar) % round; 204833965Sjdp } 204933965Sjdp 205033965Sjdp if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) != 0) 205133965Sjdp current->filepos = file_sofar; 205233965Sjdp 2053218822Sdim sofar += current->size; 205433965Sjdp if ((current->flags & SEC_HAS_CONTENTS) != 0) 2055218822Sdim file_sofar += current->size; 205633965Sjdp 2057104834Sobrien /* Make sure that this section is of the right size too. */ 205833965Sjdp old_sofar = sofar; 205933965Sjdp sofar = BFD_ALIGN (sofar, 1 << alignment_power); 206033965Sjdp if ((current->flags & SEC_HAS_CONTENTS) != 0) 206133965Sjdp file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power); 2062218822Sdim current->size += sofar - old_sofar; 206333965Sjdp } 206433965Sjdp 206533965Sjdp free (sorted_hdrs); 206633965Sjdp sorted_hdrs = NULL; 206733965Sjdp 206833965Sjdp ecoff_data (abfd)->reloc_filepos = file_sofar; 206933965Sjdp 2070130561Sobrien return TRUE; 207133965Sjdp} 207233965Sjdp 207333965Sjdp/* Determine the location of the relocs for all the sections in the 207433965Sjdp output file, as well as the location of the symbolic debugging 207533965Sjdp information. */ 207633965Sjdp 207733965Sjdpstatic bfd_size_type 2078218822Sdimecoff_compute_reloc_file_positions (bfd *abfd) 207933965Sjdp{ 208033965Sjdp const bfd_size_type external_reloc_size = 208133965Sjdp ecoff_backend (abfd)->external_reloc_size; 208233965Sjdp file_ptr reloc_base; 208333965Sjdp bfd_size_type reloc_size; 208433965Sjdp asection *current; 208533965Sjdp file_ptr sym_base; 208633965Sjdp 208733965Sjdp if (! abfd->output_has_begun) 208833965Sjdp { 208933965Sjdp if (! ecoff_compute_section_file_positions (abfd)) 209033965Sjdp abort (); 2091130561Sobrien abfd->output_has_begun = TRUE; 209233965Sjdp } 209377298Sobrien 209433965Sjdp reloc_base = ecoff_data (abfd)->reloc_filepos; 209533965Sjdp 209633965Sjdp reloc_size = 0; 209733965Sjdp for (current = abfd->sections; 2098218822Sdim current != NULL; 209977298Sobrien current = current->next) 210033965Sjdp { 210133965Sjdp if (current->reloc_count == 0) 210233965Sjdp current->rel_filepos = 0; 210333965Sjdp else 210433965Sjdp { 210533965Sjdp bfd_size_type relsize; 210633965Sjdp 210733965Sjdp current->rel_filepos = reloc_base; 210833965Sjdp relsize = current->reloc_count * external_reloc_size; 210933965Sjdp reloc_size += relsize; 211033965Sjdp reloc_base += relsize; 211133965Sjdp } 211233965Sjdp } 211333965Sjdp 211433965Sjdp sym_base = ecoff_data (abfd)->reloc_filepos + reloc_size; 211533965Sjdp 211633965Sjdp /* At least on Ultrix, the symbol table of an executable file must 211733965Sjdp be aligned to a page boundary. FIXME: Is this true on other 211833965Sjdp platforms? */ 211933965Sjdp if ((abfd->flags & EXEC_P) != 0 212033965Sjdp && (abfd->flags & D_PAGED) != 0) 212133965Sjdp sym_base = ((sym_base + ecoff_backend (abfd)->round - 1) 212233965Sjdp &~ (ecoff_backend (abfd)->round - 1)); 212333965Sjdp 212433965Sjdp ecoff_data (abfd)->sym_filepos = sym_base; 212533965Sjdp 212633965Sjdp return reloc_size; 212733965Sjdp} 212833965Sjdp 212933965Sjdp/* Set the contents of a section. */ 213033965Sjdp 2131130561Sobrienbfd_boolean 2132218822Sdim_bfd_ecoff_set_section_contents (bfd *abfd, 2133218822Sdim asection *section, 2134218822Sdim const void * location, 2135218822Sdim file_ptr offset, 2136218822Sdim bfd_size_type count) 213733965Sjdp{ 213889857Sobrien file_ptr pos; 213989857Sobrien 214033965Sjdp /* This must be done first, because bfd_set_section_contents is 2141130561Sobrien going to set output_has_begun to TRUE. */ 2142218822Sdim if (! abfd->output_has_begun 2143218822Sdim && ! ecoff_compute_section_file_positions (abfd)) 2144218822Sdim return FALSE; 214533965Sjdp 214633965Sjdp /* Handle the .lib section specially so that Irix 4 shared libraries 214733965Sjdp work out. See coff_set_section_contents in coffcode.h. */ 2148218822Sdim if (streq (section->name, _LIB)) 214933965Sjdp { 215033965Sjdp bfd_byte *rec, *recend; 215133965Sjdp 215233965Sjdp rec = (bfd_byte *) location; 215333965Sjdp recend = rec + count; 215433965Sjdp while (rec < recend) 215533965Sjdp { 215633965Sjdp ++section->lma; 215733965Sjdp rec += bfd_get_32 (abfd, rec) * 4; 215833965Sjdp } 215933965Sjdp 216033965Sjdp BFD_ASSERT (rec == recend); 216133965Sjdp } 216233965Sjdp 216333965Sjdp if (count == 0) 2164130561Sobrien return TRUE; 216533965Sjdp 216689857Sobrien pos = section->filepos + offset; 216789857Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0 216889857Sobrien || bfd_bwrite (location, count, abfd) != count) 2169130561Sobrien return FALSE; 217033965Sjdp 2171130561Sobrien return TRUE; 217233965Sjdp} 217333965Sjdp 217433965Sjdp/* Get the GP value for an ECOFF file. This is a hook used by 217533965Sjdp nlmconv. */ 217633965Sjdp 217733965Sjdpbfd_vma 2178218822Sdimbfd_ecoff_get_gp_value (bfd *abfd) 217933965Sjdp{ 218033965Sjdp if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour 218133965Sjdp || bfd_get_format (abfd) != bfd_object) 218233965Sjdp { 218333965Sjdp bfd_set_error (bfd_error_invalid_operation); 218433965Sjdp return 0; 218533965Sjdp } 218677298Sobrien 218733965Sjdp return ecoff_data (abfd)->gp; 218833965Sjdp} 218933965Sjdp 219033965Sjdp/* Set the GP value for an ECOFF file. This is a hook used by the 219133965Sjdp assembler. */ 219233965Sjdp 2193130561Sobrienbfd_boolean 2194218822Sdimbfd_ecoff_set_gp_value (bfd *abfd, bfd_vma gp_value) 219533965Sjdp{ 219633965Sjdp if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour 219733965Sjdp || bfd_get_format (abfd) != bfd_object) 219833965Sjdp { 219933965Sjdp bfd_set_error (bfd_error_invalid_operation); 2200130561Sobrien return FALSE; 220133965Sjdp } 220233965Sjdp 220333965Sjdp ecoff_data (abfd)->gp = gp_value; 220433965Sjdp 2205130561Sobrien return TRUE; 220633965Sjdp} 220733965Sjdp 220833965Sjdp/* Set the register masks for an ECOFF file. This is a hook used by 220933965Sjdp the assembler. */ 221033965Sjdp 2211130561Sobrienbfd_boolean 2212218822Sdimbfd_ecoff_set_regmasks (bfd *abfd, 2213218822Sdim unsigned long gprmask, 2214218822Sdim unsigned long fprmask, 2215218822Sdim unsigned long *cprmask) 221633965Sjdp{ 221733965Sjdp ecoff_data_type *tdata; 221833965Sjdp 221933965Sjdp if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour 222033965Sjdp || bfd_get_format (abfd) != bfd_object) 222133965Sjdp { 222233965Sjdp bfd_set_error (bfd_error_invalid_operation); 2223130561Sobrien return FALSE; 222433965Sjdp } 222533965Sjdp 222633965Sjdp tdata = ecoff_data (abfd); 222733965Sjdp tdata->gprmask = gprmask; 222833965Sjdp tdata->fprmask = fprmask; 2229218822Sdim if (cprmask != NULL) 223033965Sjdp { 2231104834Sobrien int i; 223233965Sjdp 223333965Sjdp for (i = 0; i < 3; i++) 223433965Sjdp tdata->cprmask[i] = cprmask[i]; 223533965Sjdp } 223633965Sjdp 2237130561Sobrien return TRUE; 223833965Sjdp} 223933965Sjdp 224033965Sjdp/* Get ECOFF EXTR information for an external symbol. This function 224133965Sjdp is passed to bfd_ecoff_debug_externals. */ 224233965Sjdp 2243130561Sobrienstatic bfd_boolean 2244218822Sdimecoff_get_extr (asymbol *sym, EXTR *esym) 224533965Sjdp{ 224633965Sjdp ecoff_symbol_type *ecoff_sym_ptr; 224733965Sjdp bfd *input_bfd; 224833965Sjdp 224933965Sjdp if (bfd_asymbol_flavour (sym) != bfd_target_ecoff_flavour 225033965Sjdp || ecoffsymbol (sym)->native == NULL) 225133965Sjdp { 225233965Sjdp /* Don't include debugging, local, or section symbols. */ 225333965Sjdp if ((sym->flags & BSF_DEBUGGING) != 0 225433965Sjdp || (sym->flags & BSF_LOCAL) != 0 225533965Sjdp || (sym->flags & BSF_SECTION_SYM) != 0) 2256130561Sobrien return FALSE; 225733965Sjdp 225833965Sjdp esym->jmptbl = 0; 225933965Sjdp esym->cobol_main = 0; 226033965Sjdp esym->weakext = (sym->flags & BSF_WEAK) != 0; 226133965Sjdp esym->reserved = 0; 226233965Sjdp esym->ifd = ifdNil; 226333965Sjdp /* FIXME: we can do better than this for st and sc. */ 226433965Sjdp esym->asym.st = stGlobal; 226533965Sjdp esym->asym.sc = scAbs; 226633965Sjdp esym->asym.reserved = 0; 226733965Sjdp esym->asym.index = indexNil; 2268130561Sobrien return TRUE; 226933965Sjdp } 227033965Sjdp 227133965Sjdp ecoff_sym_ptr = ecoffsymbol (sym); 227233965Sjdp 227333965Sjdp if (ecoff_sym_ptr->local) 2274130561Sobrien return FALSE; 227533965Sjdp 227633965Sjdp input_bfd = bfd_asymbol_bfd (sym); 227733965Sjdp (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in)) 227833965Sjdp (input_bfd, ecoff_sym_ptr->native, esym); 227933965Sjdp 228033965Sjdp /* If the symbol was defined by the linker, then esym will be 228133965Sjdp undefined but sym will not be. Get a better class for such a 228233965Sjdp symbol. */ 228333965Sjdp if ((esym->asym.sc == scUndefined 228433965Sjdp || esym->asym.sc == scSUndefined) 228533965Sjdp && ! bfd_is_und_section (bfd_get_section (sym))) 228633965Sjdp esym->asym.sc = scAbs; 228733965Sjdp 228833965Sjdp /* Adjust the FDR index for the symbol by that used for the input 228933965Sjdp BFD. */ 229033965Sjdp if (esym->ifd != -1) 229133965Sjdp { 229233965Sjdp struct ecoff_debug_info *input_debug; 229333965Sjdp 229433965Sjdp input_debug = &ecoff_data (input_bfd)->debug_info; 229533965Sjdp BFD_ASSERT (esym->ifd < input_debug->symbolic_header.ifdMax); 2296218822Sdim if (input_debug->ifdmap != NULL) 229733965Sjdp esym->ifd = input_debug->ifdmap[esym->ifd]; 229833965Sjdp } 229933965Sjdp 2300130561Sobrien return TRUE; 230133965Sjdp} 230233965Sjdp 230333965Sjdp/* Set the external symbol index. This routine is passed to 230433965Sjdp bfd_ecoff_debug_externals. */ 230533965Sjdp 230633965Sjdpstatic void 2307218822Sdimecoff_set_index (asymbol *sym, bfd_size_type indx) 230833965Sjdp{ 230933965Sjdp ecoff_set_sym_index (sym, indx); 231033965Sjdp} 231133965Sjdp 231233965Sjdp/* Write out an ECOFF file. */ 231333965Sjdp 2314130561Sobrienbfd_boolean 2315218822Sdim_bfd_ecoff_write_object_contents (bfd *abfd) 231633965Sjdp{ 231733965Sjdp const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 231833965Sjdp const bfd_vma round = backend->round; 231933965Sjdp const bfd_size_type filhsz = bfd_coff_filhsz (abfd); 232033965Sjdp const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd); 232133965Sjdp const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd); 232233965Sjdp const bfd_size_type external_hdr_size 232333965Sjdp = backend->debug_swap.external_hdr_size; 232433965Sjdp const bfd_size_type external_reloc_size = backend->external_reloc_size; 2325218822Sdim void (* const adjust_reloc_out) (bfd *, const arelent *, struct internal_reloc *) 232633965Sjdp = backend->adjust_reloc_out; 2327218822Sdim void (* const swap_reloc_out) (bfd *, const struct internal_reloc *, void *) 232833965Sjdp = backend->swap_reloc_out; 232933965Sjdp struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info; 233033965Sjdp HDRR * const symhdr = &debug->symbolic_header; 233133965Sjdp asection *current; 233233965Sjdp unsigned int count; 233333965Sjdp bfd_size_type reloc_size; 233433965Sjdp bfd_size_type text_size; 233533965Sjdp bfd_vma text_start; 2336130561Sobrien bfd_boolean set_text_start; 233733965Sjdp bfd_size_type data_size; 233833965Sjdp bfd_vma data_start; 2339130561Sobrien bfd_boolean set_data_start; 234033965Sjdp bfd_size_type bss_size; 2341218822Sdim void * buff = NULL; 2342218822Sdim void * reloc_buff = NULL; 234333965Sjdp struct internal_filehdr internal_f; 234433965Sjdp struct internal_aouthdr internal_a; 234533965Sjdp int i; 234633965Sjdp 234733965Sjdp /* Determine where the sections and relocs will go in the output 234833965Sjdp file. */ 234933965Sjdp reloc_size = ecoff_compute_reloc_file_positions (abfd); 235033965Sjdp 235133965Sjdp count = 1; 235233965Sjdp for (current = abfd->sections; 2353218822Sdim current != NULL; 235477298Sobrien current = current->next) 235533965Sjdp { 235633965Sjdp current->target_index = count; 235733965Sjdp ++count; 235833965Sjdp } 235933965Sjdp 236033965Sjdp if ((abfd->flags & D_PAGED) != 0) 2361218822Sdim text_size = _bfd_ecoff_sizeof_headers (abfd, NULL); 236233965Sjdp else 236333965Sjdp text_size = 0; 236433965Sjdp text_start = 0; 2365130561Sobrien set_text_start = FALSE; 236633965Sjdp data_size = 0; 236733965Sjdp data_start = 0; 2368130561Sobrien set_data_start = FALSE; 236933965Sjdp bss_size = 0; 237033965Sjdp 237133965Sjdp /* Write section headers to the file. */ 237233965Sjdp 237333965Sjdp /* Allocate buff big enough to hold a section header, 237433965Sjdp file header, or a.out header. */ 237533965Sjdp { 237633965Sjdp bfd_size_type siz; 2377218822Sdim 237833965Sjdp siz = scnhsz; 237933965Sjdp if (siz < filhsz) 238033965Sjdp siz = filhsz; 238133965Sjdp if (siz < aoutsz) 238233965Sjdp siz = aoutsz; 2383218822Sdim buff = bfd_malloc (siz); 238433965Sjdp if (buff == NULL) 238533965Sjdp goto error_return; 238633965Sjdp } 238733965Sjdp 238833965Sjdp internal_f.f_nscns = 0; 238933965Sjdp if (bfd_seek (abfd, (file_ptr) (filhsz + aoutsz), SEEK_SET) != 0) 239033965Sjdp goto error_return; 2391218822Sdim 239233965Sjdp for (current = abfd->sections; 2393218822Sdim current != NULL; 239433965Sjdp current = current->next) 239533965Sjdp { 239633965Sjdp struct internal_scnhdr section; 239733965Sjdp bfd_vma vma; 239833965Sjdp 239933965Sjdp ++internal_f.f_nscns; 240033965Sjdp 240133965Sjdp strncpy (section.s_name, current->name, sizeof section.s_name); 240233965Sjdp 240333965Sjdp /* This seems to be correct for Irix 4 shared libraries. */ 240433965Sjdp vma = bfd_get_section_vma (abfd, current); 2405218822Sdim if (streq (current->name, _LIB)) 240633965Sjdp section.s_vaddr = 0; 240733965Sjdp else 240833965Sjdp section.s_vaddr = vma; 240933965Sjdp 241033965Sjdp section.s_paddr = current->lma; 2411218822Sdim section.s_size = current->size; 241233965Sjdp 241333965Sjdp /* If this section is unloadable then the scnptr will be 0. */ 241433965Sjdp if ((current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) 241533965Sjdp section.s_scnptr = 0; 241633965Sjdp else 241733965Sjdp section.s_scnptr = current->filepos; 241833965Sjdp section.s_relptr = current->rel_filepos; 241933965Sjdp 242033965Sjdp /* FIXME: the lnnoptr of the .sbss or .sdata section of an 242133965Sjdp object file produced by the assembler is supposed to point to 242233965Sjdp information about how much room is required by objects of 242333965Sjdp various different sizes. I think this only matters if we 242433965Sjdp want the linker to compute the best size to use, or 242533965Sjdp something. I don't know what happens if the information is 242633965Sjdp not present. */ 2427218822Sdim if (! streq (current->name, _PDATA)) 242833965Sjdp section.s_lnnoptr = 0; 242933965Sjdp else 243033965Sjdp { 243133965Sjdp /* The Alpha ECOFF .pdata section uses the lnnoptr field to 243233965Sjdp hold the number of entries in the section (each entry is 243333965Sjdp 8 bytes). We stored this in the line_filepos field in 243433965Sjdp ecoff_compute_section_file_positions. */ 243533965Sjdp section.s_lnnoptr = current->line_filepos; 243633965Sjdp } 243733965Sjdp 243833965Sjdp section.s_nreloc = current->reloc_count; 243933965Sjdp section.s_nlnno = 0; 244033965Sjdp section.s_flags = ecoff_sec_to_styp_flags (current->name, 244133965Sjdp current->flags); 244233965Sjdp 2443218822Sdim if (bfd_coff_swap_scnhdr_out (abfd, (void *) §ion, buff) == 0 244489857Sobrien || bfd_bwrite (buff, scnhsz, abfd) != scnhsz) 244533965Sjdp goto error_return; 244633965Sjdp 244733965Sjdp if ((section.s_flags & STYP_TEXT) != 0 244833965Sjdp || ((section.s_flags & STYP_RDATA) != 0 244933965Sjdp && ecoff_data (abfd)->rdata_in_text) 245033965Sjdp || section.s_flags == STYP_PDATA 245133965Sjdp || (section.s_flags & STYP_DYNAMIC) != 0 245233965Sjdp || (section.s_flags & STYP_LIBLIST) != 0 245333965Sjdp || (section.s_flags & STYP_RELDYN) != 0 245433965Sjdp || section.s_flags == STYP_CONFLIC 245533965Sjdp || (section.s_flags & STYP_DYNSTR) != 0 245633965Sjdp || (section.s_flags & STYP_DYNSYM) != 0 245733965Sjdp || (section.s_flags & STYP_HASH) != 0 245833965Sjdp || (section.s_flags & STYP_ECOFF_INIT) != 0 245933965Sjdp || (section.s_flags & STYP_ECOFF_FINI) != 0 246033965Sjdp || section.s_flags == STYP_RCONST) 246133965Sjdp { 2462218822Sdim text_size += current->size; 246333965Sjdp if (! set_text_start || text_start > vma) 246433965Sjdp { 246533965Sjdp text_start = vma; 2466130561Sobrien set_text_start = TRUE; 246733965Sjdp } 246833965Sjdp } 246933965Sjdp else if ((section.s_flags & STYP_RDATA) != 0 247033965Sjdp || (section.s_flags & STYP_DATA) != 0 247133965Sjdp || (section.s_flags & STYP_LITA) != 0 247233965Sjdp || (section.s_flags & STYP_LIT8) != 0 247333965Sjdp || (section.s_flags & STYP_LIT4) != 0 247433965Sjdp || (section.s_flags & STYP_SDATA) != 0 247533965Sjdp || section.s_flags == STYP_XDATA 247633965Sjdp || (section.s_flags & STYP_GOT) != 0) 247733965Sjdp { 2478218822Sdim data_size += current->size; 247933965Sjdp if (! set_data_start || data_start > vma) 248033965Sjdp { 248133965Sjdp data_start = vma; 2482130561Sobrien set_data_start = TRUE; 248333965Sjdp } 248433965Sjdp } 248533965Sjdp else if ((section.s_flags & STYP_BSS) != 0 248633965Sjdp || (section.s_flags & STYP_SBSS) != 0) 2487218822Sdim bss_size += current->size; 248833965Sjdp else if (section.s_flags == 0 248933965Sjdp || (section.s_flags & STYP_ECOFF_LIB) != 0 249033965Sjdp || section.s_flags == STYP_COMMENT) 2491104834Sobrien /* Do nothing. */ ; 249233965Sjdp else 249333965Sjdp abort (); 249477298Sobrien } 249533965Sjdp 249633965Sjdp /* Set up the file header. */ 249733965Sjdp internal_f.f_magic = ecoff_get_magic (abfd); 249833965Sjdp 249933965Sjdp /* We will NOT put a fucking timestamp in the header here. Every 250033965Sjdp time you put it back, I will come in and take it out again. I'm 250133965Sjdp sorry. This field does not belong here. We fill it with a 0 so 250233965Sjdp it compares the same but is not a reasonable time. -- 250333965Sjdp gnu@cygnus.com. */ 250433965Sjdp internal_f.f_timdat = 0; 250533965Sjdp 250633965Sjdp if (bfd_get_symcount (abfd) != 0) 250733965Sjdp { 250833965Sjdp /* The ECOFF f_nsyms field is not actually the number of 250933965Sjdp symbols, it's the size of symbolic information header. */ 251033965Sjdp internal_f.f_nsyms = external_hdr_size; 251133965Sjdp internal_f.f_symptr = ecoff_data (abfd)->sym_filepos; 251233965Sjdp } 251333965Sjdp else 251433965Sjdp { 251533965Sjdp internal_f.f_nsyms = 0; 251633965Sjdp internal_f.f_symptr = 0; 251733965Sjdp } 251833965Sjdp 251933965Sjdp internal_f.f_opthdr = aoutsz; 252033965Sjdp 252133965Sjdp internal_f.f_flags = F_LNNO; 252233965Sjdp if (reloc_size == 0) 252333965Sjdp internal_f.f_flags |= F_RELFLG; 252433965Sjdp if (bfd_get_symcount (abfd) == 0) 252533965Sjdp internal_f.f_flags |= F_LSYMS; 252633965Sjdp if (abfd->flags & EXEC_P) 252733965Sjdp internal_f.f_flags |= F_EXEC; 252833965Sjdp 252933965Sjdp if (bfd_little_endian (abfd)) 253033965Sjdp internal_f.f_flags |= F_AR32WR; 253133965Sjdp else 253233965Sjdp internal_f.f_flags |= F_AR32W; 253333965Sjdp 253433965Sjdp /* Set up the ``optional'' header. */ 253533965Sjdp if ((abfd->flags & D_PAGED) != 0) 253633965Sjdp internal_a.magic = ECOFF_AOUT_ZMAGIC; 253733965Sjdp else 253833965Sjdp internal_a.magic = ECOFF_AOUT_OMAGIC; 253933965Sjdp 254033965Sjdp /* FIXME: Is this really correct? */ 254133965Sjdp internal_a.vstamp = symhdr->vstamp; 254233965Sjdp 254333965Sjdp /* At least on Ultrix, these have to be rounded to page boundaries. 254433965Sjdp FIXME: Is this true on other platforms? */ 254533965Sjdp if ((abfd->flags & D_PAGED) != 0) 254633965Sjdp { 254733965Sjdp internal_a.tsize = (text_size + round - 1) &~ (round - 1); 254833965Sjdp internal_a.text_start = text_start &~ (round - 1); 254933965Sjdp internal_a.dsize = (data_size + round - 1) &~ (round - 1); 255033965Sjdp internal_a.data_start = data_start &~ (round - 1); 255133965Sjdp } 255233965Sjdp else 255333965Sjdp { 255433965Sjdp internal_a.tsize = text_size; 255533965Sjdp internal_a.text_start = text_start; 255633965Sjdp internal_a.dsize = data_size; 255733965Sjdp internal_a.data_start = data_start; 255833965Sjdp } 255933965Sjdp 256033965Sjdp /* On Ultrix, the initial portions of the .sbss and .bss segments 256133965Sjdp are at the end of the data section. The bsize field in the 256233965Sjdp optional header records how many bss bytes are required beyond 256333965Sjdp those in the data section. The value is not rounded to a page 256433965Sjdp boundary. */ 256533965Sjdp if (bss_size < internal_a.dsize - data_size) 256633965Sjdp bss_size = 0; 256733965Sjdp else 256833965Sjdp bss_size -= internal_a.dsize - data_size; 256933965Sjdp internal_a.bsize = bss_size; 257033965Sjdp internal_a.bss_start = internal_a.data_start + internal_a.dsize; 257133965Sjdp 257233965Sjdp internal_a.entry = bfd_get_start_address (abfd); 257333965Sjdp 257433965Sjdp internal_a.gp_value = ecoff_data (abfd)->gp; 257533965Sjdp 257633965Sjdp internal_a.gprmask = ecoff_data (abfd)->gprmask; 257733965Sjdp internal_a.fprmask = ecoff_data (abfd)->fprmask; 257833965Sjdp for (i = 0; i < 4; i++) 257933965Sjdp internal_a.cprmask[i] = ecoff_data (abfd)->cprmask[i]; 258033965Sjdp 258133965Sjdp /* Let the backend adjust the headers if necessary. */ 258233965Sjdp if (backend->adjust_headers) 258333965Sjdp { 258433965Sjdp if (! (*backend->adjust_headers) (abfd, &internal_f, &internal_a)) 258533965Sjdp goto error_return; 258633965Sjdp } 258733965Sjdp 258833965Sjdp /* Write out the file header and the optional header. */ 258933965Sjdp if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 259033965Sjdp goto error_return; 259133965Sjdp 2592218822Sdim bfd_coff_swap_filehdr_out (abfd, (void *) &internal_f, buff); 259389857Sobrien if (bfd_bwrite (buff, filhsz, abfd) != filhsz) 259433965Sjdp goto error_return; 259533965Sjdp 2596218822Sdim bfd_coff_swap_aouthdr_out (abfd, (void *) &internal_a, buff); 259789857Sobrien if (bfd_bwrite (buff, aoutsz, abfd) != aoutsz) 259833965Sjdp goto error_return; 259933965Sjdp 260033965Sjdp /* Build the external symbol information. This must be done before 260133965Sjdp writing out the relocs so that we know the symbol indices. We 260233965Sjdp don't do this if this BFD was created by the backend linker, 260333965Sjdp since it will have already handled the symbols and relocs. */ 260433965Sjdp if (! ecoff_data (abfd)->linker) 260533965Sjdp { 260633965Sjdp symhdr->iextMax = 0; 260733965Sjdp symhdr->issExtMax = 0; 260833965Sjdp debug->external_ext = debug->external_ext_end = NULL; 260933965Sjdp debug->ssext = debug->ssext_end = NULL; 2610104834Sobrien if (! bfd_ecoff_debug_externals (abfd, debug, &backend->debug_swap, 2611104834Sobrien (abfd->flags & EXEC_P) == 0, 2612104834Sobrien ecoff_get_extr, ecoff_set_index)) 261333965Sjdp goto error_return; 261433965Sjdp 261533965Sjdp /* Write out the relocs. */ 261633965Sjdp for (current = abfd->sections; 2617218822Sdim current != NULL; 261833965Sjdp current = current->next) 261933965Sjdp { 262033965Sjdp arelent **reloc_ptr_ptr; 262133965Sjdp arelent **reloc_end; 262233965Sjdp char *out_ptr; 262389857Sobrien bfd_size_type amt; 262433965Sjdp 262533965Sjdp if (current->reloc_count == 0) 262633965Sjdp continue; 262733965Sjdp 262889857Sobrien amt = current->reloc_count * external_reloc_size; 262989857Sobrien reloc_buff = bfd_alloc (abfd, amt); 263033965Sjdp if (reloc_buff == NULL) 263133965Sjdp goto error_return; 263233965Sjdp 263333965Sjdp reloc_ptr_ptr = current->orelocation; 263433965Sjdp reloc_end = reloc_ptr_ptr + current->reloc_count; 263533965Sjdp out_ptr = (char *) reloc_buff; 2636218822Sdim 263733965Sjdp for (; 263833965Sjdp reloc_ptr_ptr < reloc_end; 263933965Sjdp reloc_ptr_ptr++, out_ptr += external_reloc_size) 264033965Sjdp { 264133965Sjdp arelent *reloc; 264233965Sjdp asymbol *sym; 264333965Sjdp struct internal_reloc in; 264477298Sobrien 2645218822Sdim memset ((void *) &in, 0, sizeof in); 264633965Sjdp 264733965Sjdp reloc = *reloc_ptr_ptr; 264833965Sjdp sym = *reloc->sym_ptr_ptr; 264933965Sjdp 2650218822Sdim /* If the howto field has not been initialised then skip this reloc. 2651218822Sdim This assumes that an error message has been issued elsewhere. */ 2652218822Sdim if (reloc->howto == NULL) 2653218822Sdim continue; 2654218822Sdim 265533965Sjdp in.r_vaddr = (reloc->address 265633965Sjdp + bfd_get_section_vma (abfd, current)); 265733965Sjdp in.r_type = reloc->howto->type; 265833965Sjdp 265933965Sjdp if ((sym->flags & BSF_SECTION_SYM) == 0) 266033965Sjdp { 266133965Sjdp in.r_symndx = ecoff_get_sym_index (*reloc->sym_ptr_ptr); 266233965Sjdp in.r_extern = 1; 266333965Sjdp } 266433965Sjdp else 266533965Sjdp { 266689857Sobrien const char *name; 2667218822Sdim unsigned int i; 2668218822Sdim static struct 2669218822Sdim { 2670218822Sdim const char * name; 2671218822Sdim long r_symndx; 2672218822Sdim } 2673218822Sdim section_symndx [] = 2674218822Sdim { 2675218822Sdim { _TEXT, RELOC_SECTION_TEXT }, 2676218822Sdim { _RDATA, RELOC_SECTION_RDATA }, 2677218822Sdim { _DATA, RELOC_SECTION_DATA }, 2678218822Sdim { _SDATA, RELOC_SECTION_SDATA }, 2679218822Sdim { _SBSS, RELOC_SECTION_SBSS }, 2680218822Sdim { _BSS, RELOC_SECTION_BSS }, 2681218822Sdim { _INIT, RELOC_SECTION_INIT }, 2682218822Sdim { _LIT8, RELOC_SECTION_LIT8 }, 2683218822Sdim { _LIT4, RELOC_SECTION_LIT4 }, 2684218822Sdim { _XDATA, RELOC_SECTION_XDATA }, 2685218822Sdim { _PDATA, RELOC_SECTION_PDATA }, 2686218822Sdim { _FINI, RELOC_SECTION_FINI }, 2687218822Sdim { _LITA, RELOC_SECTION_LITA }, 2688218822Sdim { "*ABS*", RELOC_SECTION_ABS }, 2689218822Sdim { _RCONST, RELOC_SECTION_RCONST } 2690218822Sdim }; 269133965Sjdp 269233965Sjdp name = bfd_get_section_name (abfd, bfd_get_section (sym)); 2693218822Sdim 2694218822Sdim for (i = 0; i < ARRAY_SIZE (section_symndx); i++) 2695218822Sdim if (streq (name, section_symndx[i].name)) 2696218822Sdim { 2697218822Sdim in.r_symndx = section_symndx[i].r_symndx; 2698218822Sdim break; 2699218822Sdim } 2700218822Sdim 2701218822Sdim if (i == ARRAY_SIZE (section_symndx)) 270233965Sjdp abort (); 270333965Sjdp in.r_extern = 0; 270433965Sjdp } 270533965Sjdp 270633965Sjdp (*adjust_reloc_out) (abfd, reloc, &in); 270733965Sjdp 2708218822Sdim (*swap_reloc_out) (abfd, &in, (void *) out_ptr); 270933965Sjdp } 271033965Sjdp 271133965Sjdp if (bfd_seek (abfd, current->rel_filepos, SEEK_SET) != 0) 271233965Sjdp goto error_return; 271389857Sobrien amt = current->reloc_count * external_reloc_size; 271489857Sobrien if (bfd_bwrite (reloc_buff, amt, abfd) != amt) 271533965Sjdp goto error_return; 271633965Sjdp bfd_release (abfd, reloc_buff); 271733965Sjdp reloc_buff = NULL; 271833965Sjdp } 271933965Sjdp 272033965Sjdp /* Write out the symbolic debugging information. */ 272133965Sjdp if (bfd_get_symcount (abfd) > 0) 272233965Sjdp { 272333965Sjdp /* Write out the debugging information. */ 2724104834Sobrien if (! bfd_ecoff_write_debug (abfd, debug, &backend->debug_swap, 2725104834Sobrien ecoff_data (abfd)->sym_filepos)) 272633965Sjdp goto error_return; 272733965Sjdp } 272833965Sjdp } 272933965Sjdp 273033965Sjdp /* The .bss section of a demand paged executable must receive an 273133965Sjdp entire page. If there are symbols, the symbols will start on the 273233965Sjdp next page. If there are no symbols, we must fill out the page by 273333965Sjdp hand. */ 273433965Sjdp if (bfd_get_symcount (abfd) == 0 273533965Sjdp && (abfd->flags & EXEC_P) != 0 273633965Sjdp && (abfd->flags & D_PAGED) != 0) 273733965Sjdp { 273833965Sjdp char c; 273933965Sjdp 274033965Sjdp if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1, 274133965Sjdp SEEK_SET) != 0) 274233965Sjdp goto error_return; 274389857Sobrien if (bfd_bread (&c, (bfd_size_type) 1, abfd) == 0) 274433965Sjdp c = 0; 274533965Sjdp if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1, 274633965Sjdp SEEK_SET) != 0) 274733965Sjdp goto error_return; 274889857Sobrien if (bfd_bwrite (&c, (bfd_size_type) 1, abfd) != 1) 274933965Sjdp goto error_return; 275033965Sjdp } 275133965Sjdp 275233965Sjdp if (reloc_buff != NULL) 275333965Sjdp bfd_release (abfd, reloc_buff); 275433965Sjdp if (buff != NULL) 275533965Sjdp free (buff); 2756130561Sobrien return TRUE; 275733965Sjdp error_return: 275833965Sjdp if (reloc_buff != NULL) 275933965Sjdp bfd_release (abfd, reloc_buff); 276033965Sjdp if (buff != NULL) 276133965Sjdp free (buff); 2762130561Sobrien return FALSE; 276333965Sjdp} 276433965Sjdp 276533965Sjdp/* Archive handling. ECOFF uses what appears to be a unique type of 276633965Sjdp archive header (armap). The byte ordering of the armap and the 276733965Sjdp contents are encoded in the name of the armap itself. At least for 276833965Sjdp now, we only support archives with the same byte ordering in the 276933965Sjdp armap and the contents. 277033965Sjdp 277133965Sjdp The first four bytes in the armap are the number of symbol 277233965Sjdp definitions. This is always a power of two. 277333965Sjdp 277433965Sjdp This is followed by the symbol definitions. Each symbol definition 277533965Sjdp occupies 8 bytes. The first four bytes are the offset from the 277633965Sjdp start of the armap strings to the null-terminated string naming 277733965Sjdp this symbol. The second four bytes are the file offset to the 277833965Sjdp archive member which defines this symbol. If the second four bytes 277933965Sjdp are 0, then this is not actually a symbol definition, and it should 278033965Sjdp be ignored. 278133965Sjdp 278233965Sjdp The symbols are hashed into the armap with a closed hashing scheme. 278333965Sjdp See the functions below for the details of the algorithm. 278433965Sjdp 278533965Sjdp After the symbol definitions comes four bytes holding the size of 278633965Sjdp the string table, followed by the string table itself. */ 278733965Sjdp 278833965Sjdp/* The name of an archive headers looks like this: 278933965Sjdp __________E[BL]E[BL]_ (with a trailing space). 279033965Sjdp The trailing space is changed to an X if the archive is changed to 279133965Sjdp indicate that the armap is out of date. 279233965Sjdp 279333965Sjdp The Alpha seems to use ________64E[BL]E[BL]_. */ 279433965Sjdp 2795218822Sdim#define ARMAP_BIG_ENDIAN 'B' 2796218822Sdim#define ARMAP_LITTLE_ENDIAN 'L' 2797218822Sdim#define ARMAP_MARKER 'E' 2798218822Sdim#define ARMAP_START_LENGTH 10 2799218822Sdim#define ARMAP_HEADER_MARKER_INDEX 10 2800218822Sdim#define ARMAP_HEADER_ENDIAN_INDEX 11 2801218822Sdim#define ARMAP_OBJECT_MARKER_INDEX 12 2802218822Sdim#define ARMAP_OBJECT_ENDIAN_INDEX 13 2803218822Sdim#define ARMAP_END_INDEX 14 2804218822Sdim#define ARMAP_END "_ " 280533965Sjdp 280633965Sjdp/* This is a magic number used in the hashing algorithm. */ 2807218822Sdim#define ARMAP_HASH_MAGIC 0x9dd68ab5 280833965Sjdp 280933965Sjdp/* This returns the hash value to use for a string. It also sets 281033965Sjdp *REHASH to the rehash adjustment if the first slot is taken. SIZE 281133965Sjdp is the number of entries in the hash table, and HLOG is the log 281233965Sjdp base 2 of SIZE. */ 281333965Sjdp 281433965Sjdpstatic unsigned int 2815218822Sdimecoff_armap_hash (const char *s, 2816218822Sdim unsigned int *rehash, 2817218822Sdim unsigned int size, 2818218822Sdim unsigned int hlog) 281933965Sjdp{ 282033965Sjdp unsigned int hash; 282133965Sjdp 282233965Sjdp if (hlog == 0) 282333965Sjdp return 0; 282433965Sjdp hash = *s++; 282533965Sjdp while (*s != '\0') 282633965Sjdp hash = ((hash >> 27) | (hash << 5)) + *s++; 282733965Sjdp hash *= ARMAP_HASH_MAGIC; 282833965Sjdp *rehash = (hash & (size - 1)) | 1; 282933965Sjdp return hash >> (32 - hlog); 283033965Sjdp} 283133965Sjdp 283233965Sjdp/* Read in the armap. */ 283333965Sjdp 2834130561Sobrienbfd_boolean 2835218822Sdim_bfd_ecoff_slurp_armap (bfd *abfd) 283633965Sjdp{ 283733965Sjdp char nextname[17]; 283833965Sjdp unsigned int i; 283933965Sjdp struct areltdata *mapdata; 284033965Sjdp bfd_size_type parsed_size; 284133965Sjdp char *raw_armap; 284233965Sjdp struct artdata *ardata; 284333965Sjdp unsigned int count; 284433965Sjdp char *raw_ptr; 284533965Sjdp struct symdef *symdef_ptr; 284633965Sjdp char *stringbase; 284789857Sobrien bfd_size_type amt; 284877298Sobrien 284933965Sjdp /* Get the name of the first element. */ 2850218822Sdim i = bfd_bread ((void *) nextname, (bfd_size_type) 16, abfd); 285133965Sjdp if (i == 0) 2852130561Sobrien return TRUE; 285333965Sjdp if (i != 16) 2854130561Sobrien return FALSE; 285533965Sjdp 285633965Sjdp if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) 2857130561Sobrien return FALSE; 285833965Sjdp 285933965Sjdp /* Irix 4.0.5F apparently can use either an ECOFF armap or a 286033965Sjdp standard COFF armap. We could move the ECOFF armap stuff into 286133965Sjdp bfd_slurp_armap, but that seems inappropriate since no other 286233965Sjdp target uses this format. Instead, we check directly for a COFF 286333965Sjdp armap. */ 2864218822Sdim if (CONST_STRNEQ (nextname, "/ ")) 286533965Sjdp return bfd_slurp_armap (abfd); 286633965Sjdp 286733965Sjdp /* See if the first element is an armap. */ 2868218822Sdim if (! strneq (nextname, ecoff_backend (abfd)->armap_start, ARMAP_START_LENGTH) 286933965Sjdp || nextname[ARMAP_HEADER_MARKER_INDEX] != ARMAP_MARKER 287033965Sjdp || (nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN 287133965Sjdp && nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN) 287233965Sjdp || nextname[ARMAP_OBJECT_MARKER_INDEX] != ARMAP_MARKER 287333965Sjdp || (nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN 287433965Sjdp && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN) 2875218822Sdim || ! strneq (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1)) 287633965Sjdp { 2877130561Sobrien bfd_has_map (abfd) = FALSE; 2878130561Sobrien return TRUE; 287933965Sjdp } 288033965Sjdp 288133965Sjdp /* Make sure we have the right byte ordering. */ 288233965Sjdp if (((nextname[ARMAP_HEADER_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN) 288333965Sjdp ^ (bfd_header_big_endian (abfd))) 288433965Sjdp || ((nextname[ARMAP_OBJECT_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN) 288533965Sjdp ^ (bfd_big_endian (abfd)))) 288633965Sjdp { 288733965Sjdp bfd_set_error (bfd_error_wrong_format); 2888130561Sobrien return FALSE; 288933965Sjdp } 289033965Sjdp 289133965Sjdp /* Read in the armap. */ 289233965Sjdp ardata = bfd_ardata (abfd); 289333965Sjdp mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); 2894218822Sdim if (mapdata == NULL) 2895130561Sobrien return FALSE; 289633965Sjdp parsed_size = mapdata->parsed_size; 2897218822Sdim bfd_release (abfd, (void *) mapdata); 289877298Sobrien 2899218822Sdim raw_armap = bfd_alloc (abfd, parsed_size); 2900218822Sdim if (raw_armap == NULL) 2901130561Sobrien return FALSE; 290277298Sobrien 2903218822Sdim if (bfd_bread ((void *) raw_armap, parsed_size, abfd) != parsed_size) 290433965Sjdp { 290533965Sjdp if (bfd_get_error () != bfd_error_system_call) 290633965Sjdp bfd_set_error (bfd_error_malformed_archive); 2907218822Sdim bfd_release (abfd, (void *) raw_armap); 2908130561Sobrien return FALSE; 290933965Sjdp } 291077298Sobrien 2911218822Sdim ardata->tdata = (void *) raw_armap; 291233965Sjdp 291389857Sobrien count = H_GET_32 (abfd, raw_armap); 291433965Sjdp 291533965Sjdp ardata->symdef_count = 0; 2916218822Sdim ardata->cache = NULL; 291733965Sjdp 291833965Sjdp /* This code used to overlay the symdefs over the raw archive data, 291933965Sjdp but that doesn't work on a 64 bit host. */ 292033965Sjdp stringbase = raw_armap + count * 8 + 8; 292133965Sjdp 292233965Sjdp#ifdef CHECK_ARMAP_HASH 292333965Sjdp { 292433965Sjdp unsigned int hlog; 292533965Sjdp 292633965Sjdp /* Double check that I have the hashing algorithm right by making 292733965Sjdp sure that every symbol can be looked up successfully. */ 292833965Sjdp hlog = 0; 292933965Sjdp for (i = 1; i < count; i <<= 1) 293033965Sjdp hlog++; 293133965Sjdp BFD_ASSERT (i == count); 293233965Sjdp 293333965Sjdp raw_ptr = raw_armap + 4; 293433965Sjdp for (i = 0; i < count; i++, raw_ptr += 8) 293533965Sjdp { 293633965Sjdp unsigned int name_offset, file_offset; 293733965Sjdp unsigned int hash, rehash, srch; 293877298Sobrien 293989857Sobrien name_offset = H_GET_32 (abfd, raw_ptr); 294089857Sobrien file_offset = H_GET_32 (abfd, (raw_ptr + 4)); 294133965Sjdp if (file_offset == 0) 294233965Sjdp continue; 294333965Sjdp hash = ecoff_armap_hash (stringbase + name_offset, &rehash, count, 294433965Sjdp hlog); 294533965Sjdp if (hash == i) 294633965Sjdp continue; 294733965Sjdp 294833965Sjdp /* See if we can rehash to this location. */ 294933965Sjdp for (srch = (hash + rehash) & (count - 1); 295033965Sjdp srch != hash && srch != i; 295133965Sjdp srch = (srch + rehash) & (count - 1)) 295289857Sobrien BFD_ASSERT (H_GET_32 (abfd, (raw_armap + 8 + srch * 8)) != 0); 295333965Sjdp BFD_ASSERT (srch == i); 295433965Sjdp } 295533965Sjdp } 295633965Sjdp 295733965Sjdp#endif /* CHECK_ARMAP_HASH */ 295833965Sjdp 295933965Sjdp raw_ptr = raw_armap + 4; 296033965Sjdp for (i = 0; i < count; i++, raw_ptr += 8) 296189857Sobrien if (H_GET_32 (abfd, (raw_ptr + 4)) != 0) 296233965Sjdp ++ardata->symdef_count; 296333965Sjdp 296489857Sobrien amt = ardata->symdef_count; 296589857Sobrien amt *= sizeof (struct symdef); 2966218822Sdim symdef_ptr = bfd_alloc (abfd, amt); 296733965Sjdp if (!symdef_ptr) 2968130561Sobrien return FALSE; 296933965Sjdp 297033965Sjdp ardata->symdefs = (carsym *) symdef_ptr; 297133965Sjdp 297233965Sjdp raw_ptr = raw_armap + 4; 297333965Sjdp for (i = 0; i < count; i++, raw_ptr += 8) 297433965Sjdp { 297533965Sjdp unsigned int name_offset, file_offset; 297633965Sjdp 297789857Sobrien file_offset = H_GET_32 (abfd, (raw_ptr + 4)); 297833965Sjdp if (file_offset == 0) 297933965Sjdp continue; 298089857Sobrien name_offset = H_GET_32 (abfd, raw_ptr); 298133965Sjdp symdef_ptr->s.name = stringbase + name_offset; 298233965Sjdp symdef_ptr->file_offset = file_offset; 298333965Sjdp ++symdef_ptr; 298433965Sjdp } 298533965Sjdp 298633965Sjdp ardata->first_file_filepos = bfd_tell (abfd); 298733965Sjdp /* Pad to an even boundary. */ 298833965Sjdp ardata->first_file_filepos += ardata->first_file_filepos % 2; 298933965Sjdp 2990130561Sobrien bfd_has_map (abfd) = TRUE; 299133965Sjdp 2992130561Sobrien return TRUE; 299333965Sjdp} 299433965Sjdp 299533965Sjdp/* Write out an armap. */ 299633965Sjdp 2997130561Sobrienbfd_boolean 2998218822Sdim_bfd_ecoff_write_armap (bfd *abfd, 2999218822Sdim unsigned int elength, 3000218822Sdim struct orl *map, 3001218822Sdim unsigned int orl_count, 3002218822Sdim int stridx) 300333965Sjdp{ 300433965Sjdp unsigned int hashsize, hashlog; 300589857Sobrien bfd_size_type symdefsize; 300633965Sjdp int padit; 300733965Sjdp unsigned int stringsize; 300833965Sjdp unsigned int mapsize; 300933965Sjdp file_ptr firstreal; 301033965Sjdp struct ar_hdr hdr; 301133965Sjdp struct stat statbuf; 301233965Sjdp unsigned int i; 301333965Sjdp bfd_byte temp[4]; 301433965Sjdp bfd_byte *hashtable; 301533965Sjdp bfd *current; 301633965Sjdp bfd *last_elt; 301733965Sjdp 301833965Sjdp /* Ultrix appears to use as a hash table size the least power of two 301933965Sjdp greater than twice the number of entries. */ 302038889Sjdp for (hashlog = 0; ((unsigned int) 1 << hashlog) <= 2 * orl_count; hashlog++) 302133965Sjdp ; 302233965Sjdp hashsize = 1 << hashlog; 302333965Sjdp 302433965Sjdp symdefsize = hashsize * 8; 302533965Sjdp padit = stridx % 2; 302633965Sjdp stringsize = stridx + padit; 302733965Sjdp 302877298Sobrien /* Include 8 bytes to store symdefsize and stringsize in output. */ 302933965Sjdp mapsize = symdefsize + stringsize + 8; 303033965Sjdp 303133965Sjdp firstreal = SARMAG + sizeof (struct ar_hdr) + mapsize + elength; 303233965Sjdp 3033218822Sdim memset ((void *) &hdr, 0, sizeof hdr); 303433965Sjdp 303533965Sjdp /* Work out the ECOFF armap name. */ 303633965Sjdp strcpy (hdr.ar_name, ecoff_backend (abfd)->armap_start); 303733965Sjdp hdr.ar_name[ARMAP_HEADER_MARKER_INDEX] = ARMAP_MARKER; 303833965Sjdp hdr.ar_name[ARMAP_HEADER_ENDIAN_INDEX] = 303933965Sjdp (bfd_header_big_endian (abfd) 304033965Sjdp ? ARMAP_BIG_ENDIAN 304133965Sjdp : ARMAP_LITTLE_ENDIAN); 304233965Sjdp hdr.ar_name[ARMAP_OBJECT_MARKER_INDEX] = ARMAP_MARKER; 304333965Sjdp hdr.ar_name[ARMAP_OBJECT_ENDIAN_INDEX] = 304433965Sjdp bfd_big_endian (abfd) ? ARMAP_BIG_ENDIAN : ARMAP_LITTLE_ENDIAN; 304533965Sjdp memcpy (hdr.ar_name + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1); 304633965Sjdp 304733965Sjdp /* Write the timestamp of the archive header to be just a little bit 304833965Sjdp later than the timestamp of the file, otherwise the linker will 304933965Sjdp complain that the index is out of date. Actually, the Ultrix 305033965Sjdp linker just checks the archive name; the GNU linker may check the 305133965Sjdp date. */ 305233965Sjdp stat (abfd->filename, &statbuf); 3053251227Spfg sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60)); 305433965Sjdp 305533965Sjdp /* The DECstation uses zeroes for the uid, gid and mode of the 305633965Sjdp armap. */ 305733965Sjdp hdr.ar_uid[0] = '0'; 305833965Sjdp hdr.ar_gid[0] = '0'; 305977298Sobrien /* Building gcc ends up extracting the armap as a file - twice. */ 306060484Sobrien hdr.ar_mode[0] = '6'; 306160484Sobrien hdr.ar_mode[1] = '4'; 306260484Sobrien hdr.ar_mode[2] = '4'; 306333965Sjdp 306433965Sjdp sprintf (hdr.ar_size, "%-10d", (int) mapsize); 306533965Sjdp 306633965Sjdp hdr.ar_fmag[0] = '`'; 306733965Sjdp hdr.ar_fmag[1] = '\012'; 306833965Sjdp 306933965Sjdp /* Turn all null bytes in the header into spaces. */ 307033965Sjdp for (i = 0; i < sizeof (struct ar_hdr); i++) 307177298Sobrien if (((char *) (&hdr))[i] == '\0') 307277298Sobrien (((char *) (&hdr))[i]) = ' '; 307333965Sjdp 3074218822Sdim if (bfd_bwrite ((void *) &hdr, (bfd_size_type) sizeof (struct ar_hdr), abfd) 307533965Sjdp != sizeof (struct ar_hdr)) 3076130561Sobrien return FALSE; 307733965Sjdp 307889857Sobrien H_PUT_32 (abfd, hashsize, temp); 3079218822Sdim if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4) 3080130561Sobrien return FALSE; 308177298Sobrien 3082218822Sdim hashtable = bfd_zalloc (abfd, symdefsize); 308333965Sjdp if (!hashtable) 3084130561Sobrien return FALSE; 308533965Sjdp 308633965Sjdp current = abfd->archive_head; 308733965Sjdp last_elt = current; 308833965Sjdp for (i = 0; i < orl_count; i++) 308933965Sjdp { 3090218822Sdim unsigned int hash, rehash = 0; 309133965Sjdp 309233965Sjdp /* Advance firstreal to the file position of this archive 309333965Sjdp element. */ 309489857Sobrien if (map[i].u.abfd != last_elt) 309533965Sjdp { 309633965Sjdp do 309733965Sjdp { 309833965Sjdp firstreal += arelt_size (current) + sizeof (struct ar_hdr); 309933965Sjdp firstreal += firstreal % 2; 3100218822Sdim current = current->archive_next; 310133965Sjdp } 310289857Sobrien while (current != map[i].u.abfd); 310333965Sjdp } 310433965Sjdp 310533965Sjdp last_elt = current; 310633965Sjdp 310733965Sjdp hash = ecoff_armap_hash (*map[i].name, &rehash, hashsize, hashlog); 310889857Sobrien if (H_GET_32 (abfd, (hashtable + (hash * 8) + 4)) != 0) 310933965Sjdp { 311033965Sjdp unsigned int srch; 311133965Sjdp 311233965Sjdp /* The desired slot is already taken. */ 311333965Sjdp for (srch = (hash + rehash) & (hashsize - 1); 311433965Sjdp srch != hash; 311533965Sjdp srch = (srch + rehash) & (hashsize - 1)) 311689857Sobrien if (H_GET_32 (abfd, (hashtable + (srch * 8) + 4)) == 0) 311733965Sjdp break; 311833965Sjdp 311933965Sjdp BFD_ASSERT (srch != hash); 312033965Sjdp 312133965Sjdp hash = srch; 312233965Sjdp } 312377298Sobrien 312489857Sobrien H_PUT_32 (abfd, map[i].namidx, (hashtable + hash * 8)); 312589857Sobrien H_PUT_32 (abfd, firstreal, (hashtable + hash * 8 + 4)); 312633965Sjdp } 312733965Sjdp 3128218822Sdim if (bfd_bwrite ((void *) hashtable, symdefsize, abfd) != symdefsize) 3129130561Sobrien return FALSE; 313033965Sjdp 313133965Sjdp bfd_release (abfd, hashtable); 313233965Sjdp 313333965Sjdp /* Now write the strings. */ 313489857Sobrien H_PUT_32 (abfd, stringsize, temp); 3135218822Sdim if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4) 3136130561Sobrien return FALSE; 313733965Sjdp for (i = 0; i < orl_count; i++) 313833965Sjdp { 313933965Sjdp bfd_size_type len; 314033965Sjdp 314133965Sjdp len = strlen (*map[i].name) + 1; 3142218822Sdim if (bfd_bwrite ((void *) (*map[i].name), len, abfd) != len) 3143130561Sobrien return FALSE; 314433965Sjdp } 314533965Sjdp 314633965Sjdp /* The spec sez this should be a newline. But in order to be 314733965Sjdp bug-compatible for DECstation ar we use a null. */ 314833965Sjdp if (padit) 314933965Sjdp { 315089857Sobrien if (bfd_bwrite ("", (bfd_size_type) 1, abfd) != 1) 3151130561Sobrien return FALSE; 315233965Sjdp } 315333965Sjdp 3154130561Sobrien return TRUE; 315533965Sjdp} 315633965Sjdp 315733965Sjdp/* See whether this BFD is an archive. If it is, read in the armap 315833965Sjdp and the extended name table. */ 315933965Sjdp 316033965Sjdpconst bfd_target * 3161218822Sdim_bfd_ecoff_archive_p (bfd *abfd) 316233965Sjdp{ 316333965Sjdp struct artdata *tdata_hold; 316433965Sjdp char armag[SARMAG + 1]; 316589857Sobrien bfd_size_type amt; 316633965Sjdp 3167218822Sdim if (bfd_bread ((void *) armag, (bfd_size_type) SARMAG, abfd) != SARMAG) 316833965Sjdp { 316933965Sjdp if (bfd_get_error () != bfd_error_system_call) 317033965Sjdp bfd_set_error (bfd_error_wrong_format); 3171218822Sdim return NULL; 317233965Sjdp } 317333965Sjdp 3174218822Sdim if (! strneq (armag, ARMAG, SARMAG)) 317533965Sjdp { 317633965Sjdp bfd_set_error (bfd_error_wrong_format); 317733965Sjdp return NULL; 317833965Sjdp } 317933965Sjdp 3180104834Sobrien tdata_hold = bfd_ardata (abfd); 3181104834Sobrien 318289857Sobrien amt = sizeof (struct artdata); 3183218822Sdim bfd_ardata (abfd) = bfd_zalloc (abfd, amt); 3184218822Sdim if (bfd_ardata (abfd) == NULL) 318533965Sjdp { 3186104834Sobrien bfd_ardata (abfd) = tdata_hold; 3187218822Sdim return NULL; 318833965Sjdp } 318933965Sjdp 319033965Sjdp bfd_ardata (abfd)->first_file_filepos = SARMAG; 3191218822Sdim /* Already cleared by bfd_zalloc above. 3192218822Sdim bfd_ardata (abfd)->cache = NULL; 3193218822Sdim bfd_ardata (abfd)->archive_head = NULL; 3194218822Sdim bfd_ardata (abfd)->symdefs = NULL; 3195218822Sdim bfd_ardata (abfd)->extended_names = NULL; 3196218822Sdim bfd_ardata (abfd)->extended_names_size = 0; 3197218822Sdim bfd_ardata (abfd)->tdata = NULL; */ 319877298Sobrien 3199104834Sobrien if (! _bfd_ecoff_slurp_armap (abfd) 3200104834Sobrien || ! _bfd_ecoff_slurp_extended_name_table (abfd)) 320133965Sjdp { 320233965Sjdp bfd_release (abfd, bfd_ardata (abfd)); 3203104834Sobrien bfd_ardata (abfd) = tdata_hold; 3204218822Sdim return NULL; 320533965Sjdp } 320677298Sobrien 320733965Sjdp if (bfd_has_map (abfd)) 320833965Sjdp { 320933965Sjdp bfd *first; 321033965Sjdp 321133965Sjdp /* This archive has a map, so we may presume that the contents 321233965Sjdp are object files. Make sure that if the first file in the 321333965Sjdp archive can be recognized as an object file, it is for this 321433965Sjdp target. If not, assume that this is the wrong format. If 321533965Sjdp the first file is not an object file, somebody is doing 321633965Sjdp something weird, and we permit it so that ar -t will work. */ 321733965Sjdp 3218218822Sdim first = bfd_openr_next_archived_file (abfd, NULL); 321933965Sjdp if (first != NULL) 322033965Sjdp { 3221130561Sobrien first->target_defaulted = FALSE; 322233965Sjdp if (bfd_check_format (first, bfd_object) 322333965Sjdp && first->xvec != abfd->xvec) 322433965Sjdp { 3225104834Sobrien /* We ought to close `first' here, but we can't, because 3226104834Sobrien we have no way to remove it from the archive cache. 3227218822Sdim It's almost impossible to figure out when we can 3228104834Sobrien release bfd_ardata. FIXME. */ 3229104834Sobrien bfd_set_error (bfd_error_wrong_object_format); 3230104834Sobrien bfd_ardata (abfd) = tdata_hold; 323133965Sjdp return NULL; 323233965Sjdp } 3233104834Sobrien /* And we ought to close `first' here too. */ 323433965Sjdp } 323533965Sjdp } 323633965Sjdp 323733965Sjdp return abfd->xvec; 323833965Sjdp} 323933965Sjdp 324033965Sjdp/* ECOFF linker code. */ 324133965Sjdp 324233965Sjdp/* Routine to create an entry in an ECOFF link hash table. */ 324333965Sjdp 324433965Sjdpstatic struct bfd_hash_entry * 3245218822Sdimecoff_link_hash_newfunc (struct bfd_hash_entry *entry, 3246218822Sdim struct bfd_hash_table *table, 3247218822Sdim const char *string) 324833965Sjdp{ 324933965Sjdp struct ecoff_link_hash_entry *ret = (struct ecoff_link_hash_entry *) entry; 325033965Sjdp 325133965Sjdp /* Allocate the structure if it has not already been allocated by a 325233965Sjdp subclass. */ 3253218822Sdim if (ret == NULL) 325433965Sjdp ret = ((struct ecoff_link_hash_entry *) 325533965Sjdp bfd_hash_allocate (table, sizeof (struct ecoff_link_hash_entry))); 3256218822Sdim if (ret == NULL) 325733965Sjdp return NULL; 325833965Sjdp 325933965Sjdp /* Call the allocation method of the superclass. */ 326033965Sjdp ret = ((struct ecoff_link_hash_entry *) 326133965Sjdp _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, 326233965Sjdp table, string)); 326333965Sjdp 326433965Sjdp if (ret) 326533965Sjdp { 326633965Sjdp /* Set local fields. */ 326733965Sjdp ret->indx = -1; 326833965Sjdp ret->abfd = NULL; 326933965Sjdp ret->written = 0; 327033965Sjdp ret->small = 0; 327133965Sjdp } 3272218822Sdim memset ((void *) &ret->esym, 0, sizeof ret->esym); 327333965Sjdp 327433965Sjdp return (struct bfd_hash_entry *) ret; 327533965Sjdp} 327633965Sjdp 327733965Sjdp/* Create an ECOFF link hash table. */ 327833965Sjdp 327933965Sjdpstruct bfd_link_hash_table * 3280218822Sdim_bfd_ecoff_bfd_link_hash_table_create (bfd *abfd) 328133965Sjdp{ 328233965Sjdp struct ecoff_link_hash_table *ret; 328389857Sobrien bfd_size_type amt = sizeof (struct ecoff_link_hash_table); 328433965Sjdp 3285218822Sdim ret = bfd_malloc (amt); 328633965Sjdp if (ret == NULL) 328733965Sjdp return NULL; 3288218822Sdim if (!_bfd_link_hash_table_init (&ret->root, abfd, 3289218822Sdim ecoff_link_hash_newfunc, 3290218822Sdim sizeof (struct ecoff_link_hash_entry))) 329133965Sjdp { 329233965Sjdp free (ret); 3293218822Sdim return NULL; 329433965Sjdp } 329533965Sjdp return &ret->root; 329633965Sjdp} 329733965Sjdp 329833965Sjdp/* Look up an entry in an ECOFF link hash table. */ 329933965Sjdp 330033965Sjdp#define ecoff_link_hash_lookup(table, string, create, copy, follow) \ 330133965Sjdp ((struct ecoff_link_hash_entry *) \ 330233965Sjdp bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) 330333965Sjdp 330433965Sjdp/* Traverse an ECOFF link hash table. */ 330533965Sjdp 330633965Sjdp#define ecoff_link_hash_traverse(table, func, info) \ 330733965Sjdp (bfd_link_hash_traverse \ 330833965Sjdp (&(table)->root, \ 3309218822Sdim (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \ 331033965Sjdp (info))) 331133965Sjdp 331233965Sjdp/* Get the ECOFF link hash table from the info structure. This is 331333965Sjdp just a cast. */ 331433965Sjdp 331533965Sjdp#define ecoff_hash_table(p) ((struct ecoff_link_hash_table *) ((p)->hash)) 331633965Sjdp 331733965Sjdp/* Add the external symbols of an object file to the global linker 331833965Sjdp hash table. The external symbols and strings we are passed are 331933965Sjdp just allocated on the stack, and will be discarded. We must 332033965Sjdp explicitly save any information we may need later on in the link. 332133965Sjdp We do not want to read the external symbol information again. */ 332233965Sjdp 3323130561Sobrienstatic bfd_boolean 3324218822Sdimecoff_link_add_externals (bfd *abfd, 3325218822Sdim struct bfd_link_info *info, 3326218822Sdim void * external_ext, 3327218822Sdim char *ssext) 332833965Sjdp{ 332933965Sjdp const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 3330218822Sdim void (* const swap_ext_in) (bfd *, void *, EXTR *) 333133965Sjdp = backend->debug_swap.swap_ext_in; 333233965Sjdp bfd_size_type external_ext_size = backend->debug_swap.external_ext_size; 333333965Sjdp unsigned long ext_count; 3334107492Sobrien struct bfd_link_hash_entry **sym_hash; 333533965Sjdp char *ext_ptr; 333633965Sjdp char *ext_end; 333789857Sobrien bfd_size_type amt; 333833965Sjdp 333933965Sjdp ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax; 334033965Sjdp 334189857Sobrien amt = ext_count; 334289857Sobrien amt *= sizeof (struct bfd_link_hash_entry *); 3343218822Sdim sym_hash = bfd_alloc (abfd, amt); 334433965Sjdp if (!sym_hash) 3345130561Sobrien return FALSE; 3346107492Sobrien ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) sym_hash; 334733965Sjdp 334833965Sjdp ext_ptr = (char *) external_ext; 334933965Sjdp ext_end = ext_ptr + ext_count * external_ext_size; 335033965Sjdp for (; ext_ptr < ext_end; ext_ptr += external_ext_size, sym_hash++) 335133965Sjdp { 335233965Sjdp EXTR esym; 3353130561Sobrien bfd_boolean skip; 335433965Sjdp bfd_vma value; 335533965Sjdp asection *section; 335633965Sjdp const char *name; 335733965Sjdp struct ecoff_link_hash_entry *h; 335833965Sjdp 335933965Sjdp *sym_hash = NULL; 336033965Sjdp 3361218822Sdim (*swap_ext_in) (abfd, (void *) ext_ptr, &esym); 336233965Sjdp 336333965Sjdp /* Skip debugging symbols. */ 3364130561Sobrien skip = FALSE; 336533965Sjdp switch (esym.asym.st) 336633965Sjdp { 336733965Sjdp case stGlobal: 336833965Sjdp case stStatic: 336933965Sjdp case stLabel: 337033965Sjdp case stProc: 337133965Sjdp case stStaticProc: 337233965Sjdp break; 337333965Sjdp default: 3374130561Sobrien skip = TRUE; 337533965Sjdp break; 337633965Sjdp } 337733965Sjdp 337833965Sjdp if (skip) 337933965Sjdp continue; 338033965Sjdp 338133965Sjdp /* Get the information for this symbol. */ 338233965Sjdp value = esym.asym.value; 338333965Sjdp switch (esym.asym.sc) 338433965Sjdp { 338533965Sjdp default: 338633965Sjdp case scNil: 338733965Sjdp case scRegister: 338833965Sjdp case scCdbLocal: 338933965Sjdp case scBits: 339033965Sjdp case scCdbSystem: 339133965Sjdp case scRegImage: 339233965Sjdp case scInfo: 339333965Sjdp case scUserStruct: 339433965Sjdp case scVar: 339533965Sjdp case scVarRegister: 339633965Sjdp case scVariant: 339733965Sjdp case scBasedVar: 339833965Sjdp case scXData: 339933965Sjdp case scPData: 340033965Sjdp section = NULL; 340133965Sjdp break; 340233965Sjdp case scText: 3403218822Sdim section = bfd_make_section_old_way (abfd, _TEXT); 340433965Sjdp value -= section->vma; 340533965Sjdp break; 340633965Sjdp case scData: 3407218822Sdim section = bfd_make_section_old_way (abfd, _DATA); 340833965Sjdp value -= section->vma; 340933965Sjdp break; 341033965Sjdp case scBss: 3411218822Sdim section = bfd_make_section_old_way (abfd, _BSS); 341233965Sjdp value -= section->vma; 341333965Sjdp break; 341433965Sjdp case scAbs: 341533965Sjdp section = bfd_abs_section_ptr; 341633965Sjdp break; 341733965Sjdp case scUndefined: 341833965Sjdp section = bfd_und_section_ptr; 341933965Sjdp break; 342033965Sjdp case scSData: 3421218822Sdim section = bfd_make_section_old_way (abfd, _SDATA); 342233965Sjdp value -= section->vma; 342333965Sjdp break; 342433965Sjdp case scSBss: 3425218822Sdim section = bfd_make_section_old_way (abfd, _SBSS); 342633965Sjdp value -= section->vma; 342733965Sjdp break; 342833965Sjdp case scRData: 3429218822Sdim section = bfd_make_section_old_way (abfd, _RDATA); 343033965Sjdp value -= section->vma; 343133965Sjdp break; 343233965Sjdp case scCommon: 343333965Sjdp if (value > ecoff_data (abfd)->gp_size) 343433965Sjdp { 343533965Sjdp section = bfd_com_section_ptr; 343633965Sjdp break; 343733965Sjdp } 343833965Sjdp /* Fall through. */ 343933965Sjdp case scSCommon: 344033965Sjdp if (ecoff_scom_section.name == NULL) 344133965Sjdp { 344233965Sjdp /* Initialize the small common section. */ 344333965Sjdp ecoff_scom_section.name = SCOMMON; 344433965Sjdp ecoff_scom_section.flags = SEC_IS_COMMON; 344533965Sjdp ecoff_scom_section.output_section = &ecoff_scom_section; 344633965Sjdp ecoff_scom_section.symbol = &ecoff_scom_symbol; 344733965Sjdp ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr; 344833965Sjdp ecoff_scom_symbol.name = SCOMMON; 344933965Sjdp ecoff_scom_symbol.flags = BSF_SECTION_SYM; 345033965Sjdp ecoff_scom_symbol.section = &ecoff_scom_section; 345133965Sjdp ecoff_scom_symbol_ptr = &ecoff_scom_symbol; 345233965Sjdp } 345333965Sjdp section = &ecoff_scom_section; 345433965Sjdp break; 345533965Sjdp case scSUndefined: 345633965Sjdp section = bfd_und_section_ptr; 345733965Sjdp break; 345833965Sjdp case scInit: 3459218822Sdim section = bfd_make_section_old_way (abfd, _INIT); 346033965Sjdp value -= section->vma; 346133965Sjdp break; 346233965Sjdp case scFini: 3463218822Sdim section = bfd_make_section_old_way (abfd, _FINI); 346433965Sjdp value -= section->vma; 346533965Sjdp break; 346633965Sjdp case scRConst: 3467218822Sdim section = bfd_make_section_old_way (abfd, _RCONST); 346833965Sjdp value -= section->vma; 346933965Sjdp break; 347033965Sjdp } 347133965Sjdp 3472218822Sdim if (section == NULL) 347333965Sjdp continue; 347433965Sjdp 347533965Sjdp name = ssext + esym.asym.iss; 347633965Sjdp 347733965Sjdp if (! (_bfd_generic_link_add_one_symbol 347833965Sjdp (info, abfd, name, 347989857Sobrien (flagword) (esym.weakext ? BSF_WEAK : BSF_GLOBAL), 3480218822Sdim section, value, NULL, TRUE, TRUE, sym_hash))) 3481130561Sobrien return FALSE; 348233965Sjdp 3483107492Sobrien h = (struct ecoff_link_hash_entry *) *sym_hash; 348433965Sjdp 348533965Sjdp /* If we are building an ECOFF hash table, save the external 348633965Sjdp symbol information. */ 348733965Sjdp if (info->hash->creator->flavour == bfd_get_flavour (abfd)) 348833965Sjdp { 3489218822Sdim if (h->abfd == NULL 349033965Sjdp || (! bfd_is_und_section (section) 349133965Sjdp && (! bfd_is_com_section (section) 349233965Sjdp || (h->root.type != bfd_link_hash_defined 349333965Sjdp && h->root.type != bfd_link_hash_defweak)))) 349433965Sjdp { 349533965Sjdp h->abfd = abfd; 349633965Sjdp h->esym = esym; 349733965Sjdp } 349833965Sjdp 349933965Sjdp /* Remember whether this symbol was small undefined. */ 350033965Sjdp if (esym.asym.sc == scSUndefined) 350133965Sjdp h->small = 1; 350233965Sjdp 350333965Sjdp /* If this symbol was ever small undefined, it needs to wind 350433965Sjdp up in a GP relative section. We can't control the 350533965Sjdp section of a defined symbol, but we can control the 350633965Sjdp section of a common symbol. This case is actually needed 350733965Sjdp on Ultrix 4.2 to handle the symbol cred in -lckrb. */ 350833965Sjdp if (h->small 350933965Sjdp && h->root.type == bfd_link_hash_common 3510218822Sdim && streq (h->root.u.c.p->section->name, SCOMMON)) 351133965Sjdp { 351233965Sjdp h->root.u.c.p->section = bfd_make_section_old_way (abfd, 351333965Sjdp SCOMMON); 351433965Sjdp h->root.u.c.p->section->flags = SEC_ALLOC; 351533965Sjdp if (h->esym.asym.sc == scCommon) 351633965Sjdp h->esym.asym.sc = scSCommon; 351733965Sjdp } 351833965Sjdp } 351933965Sjdp } 352033965Sjdp 3521130561Sobrien return TRUE; 352233965Sjdp} 352333965Sjdp 3524218822Sdim/* Add symbols from an ECOFF object file to the global linker hash 3525218822Sdim table. */ 352633965Sjdp 3527218822Sdimstatic bfd_boolean 3528218822Sdimecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) 352933965Sjdp{ 3530218822Sdim HDRR *symhdr; 3531218822Sdim bfd_size_type external_ext_size; 3532218822Sdim void * external_ext = NULL; 3533218822Sdim bfd_size_type esize; 3534218822Sdim char *ssext = NULL; 3535218822Sdim bfd_boolean result; 353633965Sjdp 3537218822Sdim if (! ecoff_slurp_symbolic_header (abfd)) 3538218822Sdim return FALSE; 353933965Sjdp 3540218822Sdim /* If there are no symbols, we don't want it. */ 3541218822Sdim if (bfd_get_symcount (abfd) == 0) 3542218822Sdim return TRUE; 3543218822Sdim 3544218822Sdim symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; 3545218822Sdim 3546218822Sdim /* Read in the external symbols and external strings. */ 3547218822Sdim external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size; 3548218822Sdim esize = symhdr->iextMax * external_ext_size; 3549218822Sdim external_ext = bfd_malloc (esize); 3550218822Sdim if (external_ext == NULL && esize != 0) 3551218822Sdim goto error_return; 3552218822Sdim 3553218822Sdim if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0 3554218822Sdim || bfd_bread (external_ext, esize, abfd) != esize) 3555218822Sdim goto error_return; 3556218822Sdim 3557218822Sdim ssext = bfd_malloc ((bfd_size_type) symhdr->issExtMax); 3558218822Sdim if (ssext == NULL && symhdr->issExtMax != 0) 3559218822Sdim goto error_return; 3560218822Sdim 3561218822Sdim if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0 3562218822Sdim || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd) 3563218822Sdim != (bfd_size_type) symhdr->issExtMax)) 3564218822Sdim goto error_return; 3565218822Sdim 3566218822Sdim result = ecoff_link_add_externals (abfd, info, external_ext, ssext); 3567218822Sdim 3568218822Sdim if (ssext != NULL) 3569218822Sdim free (ssext); 3570218822Sdim if (external_ext != NULL) 3571218822Sdim free (external_ext); 3572218822Sdim return result; 3573218822Sdim 3574218822Sdim error_return: 3575218822Sdim if (ssext != NULL) 3576218822Sdim free (ssext); 3577218822Sdim if (external_ext != NULL) 3578218822Sdim free (external_ext); 3579218822Sdim return FALSE; 3580218822Sdim} 3581218822Sdim 3582218822Sdim/* This is called if we used _bfd_generic_link_add_archive_symbols 3583218822Sdim because we were not dealing with an ECOFF archive. */ 3584218822Sdim 3585218822Sdimstatic bfd_boolean 3586218822Sdimecoff_link_check_archive_element (bfd *abfd, 3587218822Sdim struct bfd_link_info *info, 3588218822Sdim bfd_boolean *pneeded) 358933965Sjdp{ 359033965Sjdp const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 3591218822Sdim void (* const swap_ext_in) (bfd *, void *, EXTR *) 3592218822Sdim = backend->debug_swap.swap_ext_in; 359333965Sjdp HDRR *symhdr; 3594218822Sdim bfd_size_type external_ext_size; 3595218822Sdim void * external_ext = NULL; 3596218822Sdim bfd_size_type esize; 3597218822Sdim char *ssext = NULL; 3598218822Sdim char *ext_ptr; 3599218822Sdim char *ext_end; 360033965Sjdp 3601218822Sdim *pneeded = FALSE; 360233965Sjdp 3603218822Sdim if (! ecoff_slurp_symbolic_header (abfd)) 3604218822Sdim goto error_return; 360533965Sjdp 3606218822Sdim /* If there are no symbols, we don't want it. */ 3607218822Sdim if (bfd_get_symcount (abfd) == 0) 3608218822Sdim goto successful_return; 360933965Sjdp 3610218822Sdim symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; 3611218822Sdim 3612218822Sdim /* Read in the external symbols and external strings. */ 3613218822Sdim external_ext_size = backend->debug_swap.external_ext_size; 3614218822Sdim esize = symhdr->iextMax * external_ext_size; 3615218822Sdim external_ext = bfd_malloc (esize); 3616218822Sdim if (external_ext == NULL && esize != 0) 3617218822Sdim goto error_return; 3618218822Sdim 3619218822Sdim if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0 3620218822Sdim || bfd_bread (external_ext, esize, abfd) != esize) 3621218822Sdim goto error_return; 3622218822Sdim 3623218822Sdim ssext = bfd_malloc ((bfd_size_type) symhdr->issExtMax); 3624218822Sdim if (ssext == NULL && symhdr->issExtMax != 0) 3625218822Sdim goto error_return; 3626218822Sdim 3627218822Sdim if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0 3628218822Sdim || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd) 3629218822Sdim != (bfd_size_type) symhdr->issExtMax)) 3630218822Sdim goto error_return; 3631218822Sdim 3632218822Sdim /* Look through the external symbols to see if they define some 3633218822Sdim symbol that is currently undefined. */ 3634218822Sdim ext_ptr = (char *) external_ext; 3635218822Sdim ext_end = ext_ptr + esize; 3636218822Sdim for (; ext_ptr < ext_end; ext_ptr += external_ext_size) 363733965Sjdp { 3638218822Sdim EXTR esym; 3639218822Sdim bfd_boolean def; 3640218822Sdim const char *name; 3641218822Sdim struct bfd_link_hash_entry *h; 364233965Sjdp 3643218822Sdim (*swap_ext_in) (abfd, (void *) ext_ptr, &esym); 3644218822Sdim 3645218822Sdim /* See if this symbol defines something. */ 3646218822Sdim if (esym.asym.st != stGlobal 3647218822Sdim && esym.asym.st != stLabel 3648218822Sdim && esym.asym.st != stProc) 3649218822Sdim continue; 3650218822Sdim 3651218822Sdim switch (esym.asym.sc) 365233965Sjdp { 3653218822Sdim case scText: 3654218822Sdim case scData: 3655218822Sdim case scBss: 3656218822Sdim case scAbs: 3657218822Sdim case scSData: 3658218822Sdim case scSBss: 3659218822Sdim case scRData: 3660218822Sdim case scCommon: 3661218822Sdim case scSCommon: 3662218822Sdim case scInit: 3663218822Sdim case scFini: 3664218822Sdim case scRConst: 3665218822Sdim def = TRUE; 3666218822Sdim break; 3667218822Sdim default: 3668218822Sdim def = FALSE; 3669218822Sdim break; 367033965Sjdp } 367133965Sjdp 3672218822Sdim if (! def) 3673218822Sdim continue; 367433965Sjdp 3675218822Sdim name = ssext + esym.asym.iss; 3676218822Sdim h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); 367733965Sjdp 3678218822Sdim /* Unlike the generic linker, we do not pull in elements because 3679218822Sdim of common symbols. */ 3680218822Sdim if (h == NULL 3681218822Sdim || h->type != bfd_link_hash_undefined) 3682218822Sdim continue; 3683218822Sdim 3684218822Sdim /* Include this element. */ 3685218822Sdim if (! (*info->callbacks->add_archive_element) (info, abfd, name)) 3686218822Sdim goto error_return; 3687218822Sdim if (! ecoff_link_add_externals (abfd, info, external_ext, ssext)) 3688218822Sdim goto error_return; 3689218822Sdim 3690218822Sdim *pneeded = TRUE; 3691218822Sdim goto successful_return; 369233965Sjdp } 369333965Sjdp 3694218822Sdim successful_return: 3695218822Sdim if (external_ext != NULL) 3696218822Sdim free (external_ext); 3697218822Sdim if (ssext != NULL) 3698218822Sdim free (ssext); 3699218822Sdim return TRUE; 3700218822Sdim error_return: 3701218822Sdim if (external_ext != NULL) 3702218822Sdim free (external_ext); 3703218822Sdim if (ssext != NULL) 3704218822Sdim free (ssext); 3705218822Sdim return FALSE; 3706218822Sdim} 370733965Sjdp 3708218822Sdim/* Add the symbols from an archive file to the global hash table. 3709218822Sdim This looks through the undefined symbols, looks each one up in the 3710218822Sdim archive hash table, and adds any associated object file. We do not 3711218822Sdim use _bfd_generic_link_add_archive_symbols because ECOFF archives 3712218822Sdim already have a hash table, so there is no reason to construct 3713218822Sdim another one. */ 371433965Sjdp 3715218822Sdimstatic bfd_boolean 3716218822Sdimecoff_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) 3717218822Sdim{ 3718218822Sdim const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 3719218822Sdim const bfd_byte *raw_armap; 3720218822Sdim struct bfd_link_hash_entry **pundef; 3721218822Sdim unsigned int armap_count; 3722218822Sdim unsigned int armap_log; 3723218822Sdim unsigned int i; 3724218822Sdim const bfd_byte *hashtable; 3725218822Sdim const char *stringbase; 372633965Sjdp 3727218822Sdim if (! bfd_has_map (abfd)) 372833965Sjdp { 3729218822Sdim /* An empty archive is a special case. */ 3730218822Sdim if (bfd_openr_next_archived_file (abfd, NULL) == NULL) 3731218822Sdim return TRUE; 3732218822Sdim bfd_set_error (bfd_error_no_armap); 3733218822Sdim return FALSE; 373433965Sjdp } 373533965Sjdp 3736218822Sdim /* If we don't have any raw data for this archive, as can happen on 3737218822Sdim Irix 4.0.5F, we call the generic routine. 3738218822Sdim FIXME: We should be more clever about this, since someday tdata 3739218822Sdim may get to something for a generic archive. */ 3740218822Sdim raw_armap = (const bfd_byte *) bfd_ardata (abfd)->tdata; 3741218822Sdim if (raw_armap == NULL) 3742218822Sdim return (_bfd_generic_link_add_archive_symbols 3743218822Sdim (abfd, info, ecoff_link_check_archive_element)); 3744218822Sdim 3745218822Sdim armap_count = H_GET_32 (abfd, raw_armap); 3746218822Sdim 3747218822Sdim armap_log = 0; 3748218822Sdim for (i = 1; i < armap_count; i <<= 1) 3749218822Sdim armap_log++; 3750218822Sdim BFD_ASSERT (i == armap_count); 3751218822Sdim 3752218822Sdim hashtable = raw_armap + 4; 3753218822Sdim stringbase = (const char *) raw_armap + armap_count * 8 + 8; 3754218822Sdim 3755218822Sdim /* Look through the list of undefined symbols. */ 3756218822Sdim pundef = &info->hash->undefs; 3757218822Sdim while (*pundef != NULL) 375833965Sjdp { 375933965Sjdp struct bfd_link_hash_entry *h; 3760218822Sdim unsigned int hash, rehash = 0; 3761218822Sdim unsigned int file_offset; 3762218822Sdim const char *name; 3763218822Sdim bfd *element; 376433965Sjdp 3765218822Sdim h = *pundef; 3766218822Sdim 3767218822Sdim /* When a symbol is defined, it is not necessarily removed from 3768218822Sdim the list. */ 3769218822Sdim if (h->type != bfd_link_hash_undefined 3770218822Sdim && h->type != bfd_link_hash_common) 377133965Sjdp { 3772218822Sdim /* Remove this entry from the list, for general cleanliness 3773218822Sdim and because we are going to look through the list again 3774218822Sdim if we search any more libraries. We can't remove the 3775218822Sdim entry if it is the tail, because that would lose any 3776218822Sdim entries we add to the list later on. */ 3777218822Sdim if (*pundef != info->hash->undefs_tail) 3778218822Sdim *pundef = (*pundef)->u.undef.next; 3779218822Sdim else 3780218822Sdim pundef = &(*pundef)->u.undef.next; 3781218822Sdim continue; 3782218822Sdim } 378333965Sjdp 3784218822Sdim /* Native ECOFF linkers do not pull in archive elements merely 3785218822Sdim to satisfy common definitions, so neither do we. We leave 3786218822Sdim them on the list, though, in case we are linking against some 3787218822Sdim other object format. */ 3788218822Sdim if (h->type != bfd_link_hash_undefined) 3789218822Sdim { 3790218822Sdim pundef = &(*pundef)->u.undef.next; 3791218822Sdim continue; 379233965Sjdp } 3793218822Sdim 3794218822Sdim /* Look for this symbol in the archive hash table. */ 3795218822Sdim hash = ecoff_armap_hash (h->root.string, &rehash, armap_count, 3796218822Sdim armap_log); 3797218822Sdim 3798218822Sdim file_offset = H_GET_32 (abfd, hashtable + (hash * 8) + 4); 3799218822Sdim if (file_offset == 0) 380033965Sjdp { 3801218822Sdim /* Nothing in this slot. */ 3802218822Sdim pundef = &(*pundef)->u.undef.next; 3803218822Sdim continue; 380433965Sjdp } 380533965Sjdp 3806218822Sdim name = stringbase + H_GET_32 (abfd, hashtable + (hash * 8)); 3807218822Sdim if (name[0] != h->root.string[0] 3808218822Sdim || ! streq (name, h->root.string)) 380933965Sjdp { 3810218822Sdim unsigned int srch; 3811218822Sdim bfd_boolean found; 3812218822Sdim 3813218822Sdim /* That was the wrong symbol. Try rehashing. */ 3814218822Sdim found = FALSE; 3815218822Sdim for (srch = (hash + rehash) & (armap_count - 1); 3816218822Sdim srch != hash; 3817218822Sdim srch = (srch + rehash) & (armap_count - 1)) 381833965Sjdp { 3819218822Sdim file_offset = H_GET_32 (abfd, hashtable + (srch * 8) + 4); 3820218822Sdim if (file_offset == 0) 3821218822Sdim break; 3822218822Sdim name = stringbase + H_GET_32 (abfd, hashtable + (srch * 8)); 3823218822Sdim if (name[0] == h->root.string[0] 3824218822Sdim && streq (name, h->root.string)) 3825218822Sdim { 3826218822Sdim found = TRUE; 3827218822Sdim break; 3828218822Sdim } 382933965Sjdp } 3830218822Sdim 3831218822Sdim if (! found) 383233965Sjdp { 3833218822Sdim pundef = &(*pundef)->u.undef.next; 3834218822Sdim continue; 383533965Sjdp } 3836218822Sdim 3837218822Sdim hash = srch; 383833965Sjdp } 383933965Sjdp 3840218822Sdim element = (*backend->get_elt_at_filepos) (abfd, (file_ptr) file_offset); 3841218822Sdim if (element == NULL) 3842218822Sdim return FALSE; 384333965Sjdp 3844218822Sdim if (! bfd_check_format (element, bfd_object)) 3845218822Sdim return FALSE; 384633965Sjdp 3847218822Sdim /* Unlike the generic linker, we know that this element provides 3848218822Sdim a definition for an undefined symbol and we know that we want 3849218822Sdim to include it. We don't need to check anything. */ 3850218822Sdim if (! (*info->callbacks->add_archive_element) (info, element, name)) 3851218822Sdim return FALSE; 3852218822Sdim if (! ecoff_link_add_object_symbols (element, info)) 3853218822Sdim return FALSE; 3854218822Sdim 3855218822Sdim pundef = &(*pundef)->u.undef.next; 3856218822Sdim } 3857218822Sdim 3858130561Sobrien return TRUE; 385933965Sjdp} 386033965Sjdp 3861218822Sdim/* Given an ECOFF BFD, add symbols to the global hash table as 3862218822Sdim appropriate. */ 3863218822Sdim 3864218822Sdimbfd_boolean 3865218822Sdim_bfd_ecoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 3866218822Sdim{ 3867218822Sdim switch (bfd_get_format (abfd)) 3868218822Sdim { 3869218822Sdim case bfd_object: 3870218822Sdim return ecoff_link_add_object_symbols (abfd, info); 3871218822Sdim case bfd_archive: 3872218822Sdim return ecoff_link_add_archive_symbols (abfd, info); 3873218822Sdim default: 3874218822Sdim bfd_set_error (bfd_error_wrong_format); 3875218822Sdim return FALSE; 3876218822Sdim } 3877218822Sdim} 3878218822Sdim 3879218822Sdim 3880218822Sdim/* ECOFF final link routines. */ 3881218822Sdim 3882218822Sdim/* Structure used to pass information to ecoff_link_write_external. */ 3883218822Sdim 3884218822Sdimstruct extsym_info 3885218822Sdim{ 3886218822Sdim bfd *abfd; 3887218822Sdim struct bfd_link_info *info; 3888218822Sdim}; 3889218822Sdim 389033965Sjdp/* Accumulate the debugging information for an input BFD into the 389133965Sjdp output BFD. This must read in the symbolic information of the 389233965Sjdp input BFD. */ 389333965Sjdp 3894130561Sobrienstatic bfd_boolean 3895218822Sdimecoff_final_link_debug_accumulate (bfd *output_bfd, 3896218822Sdim bfd *input_bfd, 3897218822Sdim struct bfd_link_info *info, 3898218822Sdim void * handle) 389933965Sjdp{ 390033965Sjdp struct ecoff_debug_info * const debug = &ecoff_data (input_bfd)->debug_info; 390133965Sjdp const struct ecoff_debug_swap * const swap = 390233965Sjdp &ecoff_backend (input_bfd)->debug_swap; 390333965Sjdp HDRR *symhdr = &debug->symbolic_header; 3904130561Sobrien bfd_boolean ret; 390533965Sjdp 390689857Sobrien#define READ(ptr, offset, count, size, type) \ 390789857Sobrien if (symhdr->count == 0) \ 390889857Sobrien debug->ptr = NULL; \ 390989857Sobrien else \ 391089857Sobrien { \ 391189857Sobrien bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ 3912218822Sdim debug->ptr = bfd_malloc (amt); \ 391389857Sobrien if (debug->ptr == NULL) \ 391489857Sobrien { \ 3915130561Sobrien ret = FALSE; \ 391689857Sobrien goto return_something; \ 391789857Sobrien } \ 391889857Sobrien if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ 391989857Sobrien || bfd_bread (debug->ptr, amt, input_bfd) != amt) \ 392089857Sobrien { \ 3921130561Sobrien ret = FALSE; \ 392289857Sobrien goto return_something; \ 392389857Sobrien } \ 392433965Sjdp } 392533965Sjdp 392633965Sjdp /* If raw_syments is not NULL, then the data was already by read by 392733965Sjdp _bfd_ecoff_slurp_symbolic_info. */ 392833965Sjdp if (ecoff_data (input_bfd)->raw_syments == NULL) 392933965Sjdp { 393033965Sjdp READ (line, cbLineOffset, cbLine, sizeof (unsigned char), 393133965Sjdp unsigned char *); 3932218822Sdim READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); 3933218822Sdim READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *); 3934218822Sdim READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *); 3935218822Sdim READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *); 393633965Sjdp READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), 393733965Sjdp union aux_ext *); 393833965Sjdp READ (ss, cbSsOffset, issMax, sizeof (char), char *); 3939218822Sdim READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *); 3940218822Sdim READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *); 394133965Sjdp } 394233965Sjdp#undef READ 394333965Sjdp 394433965Sjdp /* We do not read the external strings or the external symbols. */ 394533965Sjdp 394633965Sjdp ret = (bfd_ecoff_debug_accumulate 394733965Sjdp (handle, output_bfd, &ecoff_data (output_bfd)->debug_info, 394833965Sjdp &ecoff_backend (output_bfd)->debug_swap, 394933965Sjdp input_bfd, debug, swap, info)); 395033965Sjdp 395133965Sjdp return_something: 395233965Sjdp if (ecoff_data (input_bfd)->raw_syments == NULL) 395333965Sjdp { 395433965Sjdp if (debug->line != NULL) 395533965Sjdp free (debug->line); 395633965Sjdp if (debug->external_dnr != NULL) 395733965Sjdp free (debug->external_dnr); 395833965Sjdp if (debug->external_pdr != NULL) 395933965Sjdp free (debug->external_pdr); 396033965Sjdp if (debug->external_sym != NULL) 396133965Sjdp free (debug->external_sym); 396233965Sjdp if (debug->external_opt != NULL) 396333965Sjdp free (debug->external_opt); 396433965Sjdp if (debug->external_aux != NULL) 396533965Sjdp free (debug->external_aux); 396633965Sjdp if (debug->ss != NULL) 396733965Sjdp free (debug->ss); 396833965Sjdp if (debug->external_fdr != NULL) 396933965Sjdp free (debug->external_fdr); 397033965Sjdp if (debug->external_rfd != NULL) 397133965Sjdp free (debug->external_rfd); 397233965Sjdp 397333965Sjdp /* Make sure we don't accidentally follow one of these pointers 397433965Sjdp into freed memory. */ 397533965Sjdp debug->line = NULL; 397633965Sjdp debug->external_dnr = NULL; 397733965Sjdp debug->external_pdr = NULL; 397833965Sjdp debug->external_sym = NULL; 397933965Sjdp debug->external_opt = NULL; 398033965Sjdp debug->external_aux = NULL; 398133965Sjdp debug->ss = NULL; 398233965Sjdp debug->external_fdr = NULL; 398333965Sjdp debug->external_rfd = NULL; 398433965Sjdp } 398533965Sjdp 398633965Sjdp return ret; 398733965Sjdp} 398833965Sjdp 398933965Sjdp/* Relocate and write an ECOFF section into an ECOFF output file. */ 399033965Sjdp 3991130561Sobrienstatic bfd_boolean 3992218822Sdimecoff_indirect_link_order (bfd *output_bfd, 3993218822Sdim struct bfd_link_info *info, 3994218822Sdim asection *output_section, 3995218822Sdim struct bfd_link_order *link_order) 399633965Sjdp{ 399733965Sjdp asection *input_section; 399833965Sjdp bfd *input_bfd; 399933965Sjdp bfd_byte *contents = NULL; 400033965Sjdp bfd_size_type external_reloc_size; 400133965Sjdp bfd_size_type external_relocs_size; 4002218822Sdim void * external_relocs = NULL; 400333965Sjdp 400433965Sjdp BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); 400533965Sjdp 400633965Sjdp input_section = link_order->u.indirect.section; 400733965Sjdp input_bfd = input_section->owner; 4008218822Sdim if (input_section->size == 0) 4009218822Sdim return TRUE; 401033965Sjdp 401133965Sjdp BFD_ASSERT (input_section->output_section == output_section); 401233965Sjdp BFD_ASSERT (input_section->output_offset == link_order->offset); 4013218822Sdim BFD_ASSERT (input_section->size == link_order->size); 401433965Sjdp 4015218822Sdim /* Get the section contents. */ 4016218822Sdim if (!bfd_malloc_and_get_section (input_bfd, input_section, &contents)) 401733965Sjdp goto error_return; 401833965Sjdp 401933965Sjdp /* Get the relocs. If we are relaxing MIPS code, they will already 402033965Sjdp have been read in. Otherwise, we read them in now. */ 402133965Sjdp external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size; 402233965Sjdp external_relocs_size = external_reloc_size * input_section->reloc_count; 402333965Sjdp 4024218822Sdim external_relocs = bfd_malloc (external_relocs_size); 4025218822Sdim if (external_relocs == NULL && external_relocs_size != 0) 4026218822Sdim goto error_return; 402733965Sjdp 4028218822Sdim if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0 4029218822Sdim || (bfd_bread (external_relocs, external_relocs_size, input_bfd) 4030218822Sdim != external_relocs_size)) 4031218822Sdim goto error_return; 403233965Sjdp 403333965Sjdp /* Relocate the section contents. */ 403433965Sjdp if (! ((*ecoff_backend (input_bfd)->relocate_section) 403533965Sjdp (output_bfd, info, input_bfd, input_section, contents, 403633965Sjdp external_relocs))) 403733965Sjdp goto error_return; 403833965Sjdp 403933965Sjdp /* Write out the relocated section. */ 404033965Sjdp if (! bfd_set_section_contents (output_bfd, 404133965Sjdp output_section, 4042218822Sdim contents, 4043218822Sdim input_section->output_offset, 4044218822Sdim input_section->size)) 404533965Sjdp goto error_return; 404633965Sjdp 4047130561Sobrien /* If we are producing relocatable output, the relocs were 404833965Sjdp modified, and we write them out now. We use the reloc_count 404933965Sjdp field of output_section to keep track of the number of relocs we 405033965Sjdp have output so far. */ 4051130561Sobrien if (info->relocatable) 405233965Sjdp { 405389857Sobrien file_ptr pos = (output_section->rel_filepos 405489857Sobrien + output_section->reloc_count * external_reloc_size); 405589857Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 405689857Sobrien || (bfd_bwrite (external_relocs, external_relocs_size, output_bfd) 405733965Sjdp != external_relocs_size)) 405833965Sjdp goto error_return; 405933965Sjdp output_section->reloc_count += input_section->reloc_count; 406033965Sjdp } 406133965Sjdp 406233965Sjdp if (contents != NULL) 406333965Sjdp free (contents); 4064218822Sdim if (external_relocs != NULL) 406533965Sjdp free (external_relocs); 4066130561Sobrien return TRUE; 406733965Sjdp 406833965Sjdp error_return: 406933965Sjdp if (contents != NULL) 407033965Sjdp free (contents); 4071218822Sdim if (external_relocs != NULL) 407233965Sjdp free (external_relocs); 4073130561Sobrien return FALSE; 407433965Sjdp} 407533965Sjdp 407633965Sjdp/* Generate a reloc when linking an ECOFF file. This is a reloc 407733965Sjdp requested by the linker, and does come from any input file. This 407833965Sjdp is used to build constructor and destructor tables when linking 407933965Sjdp with -Ur. */ 408033965Sjdp 4081130561Sobrienstatic bfd_boolean 4082218822Sdimecoff_reloc_link_order (bfd *output_bfd, 4083218822Sdim struct bfd_link_info *info, 4084218822Sdim asection *output_section, 4085218822Sdim struct bfd_link_order *link_order) 408633965Sjdp{ 408733965Sjdp enum bfd_link_order_type type; 408833965Sjdp asection *section; 408933965Sjdp bfd_vma addend; 409033965Sjdp arelent rel; 409133965Sjdp struct internal_reloc in; 409233965Sjdp bfd_size_type external_reloc_size; 409333965Sjdp bfd_byte *rbuf; 4094130561Sobrien bfd_boolean ok; 409589857Sobrien file_ptr pos; 409633965Sjdp 409733965Sjdp type = link_order->type; 409833965Sjdp section = NULL; 409933965Sjdp addend = link_order->u.reloc.p->addend; 410033965Sjdp 410133965Sjdp /* We set up an arelent to pass to the backend adjust_reloc_out 410233965Sjdp routine. */ 410333965Sjdp rel.address = link_order->offset; 410433965Sjdp 410533965Sjdp rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); 410633965Sjdp if (rel.howto == 0) 410733965Sjdp { 410833965Sjdp bfd_set_error (bfd_error_bad_value); 4109130561Sobrien return FALSE; 411033965Sjdp } 411133965Sjdp 411233965Sjdp if (type == bfd_section_reloc_link_order) 411333965Sjdp { 411433965Sjdp section = link_order->u.reloc.p->u.section; 411533965Sjdp rel.sym_ptr_ptr = section->symbol_ptr_ptr; 411633965Sjdp } 411733965Sjdp else 411833965Sjdp { 411933965Sjdp struct bfd_link_hash_entry *h; 412033965Sjdp 412133965Sjdp /* Treat a reloc against a defined symbol as though it were 412233965Sjdp actually against the section. */ 412333965Sjdp h = bfd_wrapped_link_hash_lookup (output_bfd, info, 412433965Sjdp link_order->u.reloc.p->u.name, 4125130561Sobrien FALSE, FALSE, FALSE); 412633965Sjdp if (h != NULL 412733965Sjdp && (h->type == bfd_link_hash_defined 412833965Sjdp || h->type == bfd_link_hash_defweak)) 412933965Sjdp { 413033965Sjdp type = bfd_section_reloc_link_order; 413133965Sjdp section = h->u.def.section->output_section; 413233965Sjdp /* It seems that we ought to add the symbol value to the 413333965Sjdp addend here, but in practice it has already been added 413433965Sjdp because it was passed to constructor_callback. */ 413533965Sjdp addend += section->vma + h->u.def.section->output_offset; 413633965Sjdp } 413733965Sjdp else 413833965Sjdp { 413933965Sjdp /* We can't set up a reloc against a symbol correctly, 414033965Sjdp because we have no asymbol structure. Currently no 414133965Sjdp adjust_reloc_out routine cares. */ 4142218822Sdim rel.sym_ptr_ptr = NULL; 414333965Sjdp } 414433965Sjdp } 414533965Sjdp 414633965Sjdp /* All ECOFF relocs are in-place. Put the addend into the object 414733965Sjdp file. */ 414833965Sjdp 414933965Sjdp BFD_ASSERT (rel.howto->partial_inplace); 415033965Sjdp if (addend != 0) 415133965Sjdp { 415233965Sjdp bfd_size_type size; 415333965Sjdp bfd_reloc_status_type rstat; 415433965Sjdp bfd_byte *buf; 415533965Sjdp 415633965Sjdp size = bfd_get_reloc_size (rel.howto); 4157218822Sdim buf = bfd_zmalloc (size); 4158218822Sdim if (buf == NULL) 4159130561Sobrien return FALSE; 416089857Sobrien rstat = _bfd_relocate_contents (rel.howto, output_bfd, 416189857Sobrien (bfd_vma) addend, buf); 416233965Sjdp switch (rstat) 416333965Sjdp { 416433965Sjdp case bfd_reloc_ok: 416533965Sjdp break; 416633965Sjdp default: 416733965Sjdp case bfd_reloc_outofrange: 416833965Sjdp abort (); 416933965Sjdp case bfd_reloc_overflow: 417033965Sjdp if (! ((*info->callbacks->reloc_overflow) 4171218822Sdim (info, NULL, 417233965Sjdp (link_order->type == bfd_section_reloc_link_order 417333965Sjdp ? bfd_section_name (output_bfd, section) 417433965Sjdp : link_order->u.reloc.p->u.name), 4175218822Sdim rel.howto->name, addend, NULL, 4176218822Sdim NULL, (bfd_vma) 0))) 417733965Sjdp { 417833965Sjdp free (buf); 4179130561Sobrien return FALSE; 418033965Sjdp } 418133965Sjdp break; 418233965Sjdp } 4183218822Sdim ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf, 418433965Sjdp (file_ptr) link_order->offset, size); 418533965Sjdp free (buf); 418633965Sjdp if (! ok) 4187130561Sobrien return FALSE; 418833965Sjdp } 418933965Sjdp 419033965Sjdp rel.addend = 0; 419133965Sjdp 419289857Sobrien /* Move the information into an internal_reloc structure. */ 419333965Sjdp in.r_vaddr = (rel.address 419433965Sjdp + bfd_get_section_vma (output_bfd, output_section)); 419533965Sjdp in.r_type = rel.howto->type; 419633965Sjdp 419733965Sjdp if (type == bfd_symbol_reloc_link_order) 419833965Sjdp { 419933965Sjdp struct ecoff_link_hash_entry *h; 420033965Sjdp 420133965Sjdp h = ((struct ecoff_link_hash_entry *) 420233965Sjdp bfd_wrapped_link_hash_lookup (output_bfd, info, 420333965Sjdp link_order->u.reloc.p->u.name, 4204130561Sobrien FALSE, FALSE, TRUE)); 4205218822Sdim if (h != NULL 420633965Sjdp && h->indx != -1) 420733965Sjdp in.r_symndx = h->indx; 420833965Sjdp else 420933965Sjdp { 421033965Sjdp if (! ((*info->callbacks->unattached_reloc) 4211218822Sdim (info, link_order->u.reloc.p->u.name, NULL, 4212218822Sdim NULL, (bfd_vma) 0))) 4213130561Sobrien return FALSE; 421433965Sjdp in.r_symndx = 0; 421533965Sjdp } 421633965Sjdp in.r_extern = 1; 421733965Sjdp } 421833965Sjdp else 421933965Sjdp { 422089857Sobrien const char *name; 4221218822Sdim unsigned int i; 4222218822Sdim static struct 4223218822Sdim { 4224218822Sdim const char * name; 4225218822Sdim long r_symndx; 4226218822Sdim } 4227218822Sdim section_symndx [] = 4228218822Sdim { 4229218822Sdim { _TEXT, RELOC_SECTION_TEXT }, 4230218822Sdim { _RDATA, RELOC_SECTION_RDATA }, 4231218822Sdim { _DATA, RELOC_SECTION_DATA }, 4232218822Sdim { _SDATA, RELOC_SECTION_SDATA }, 4233218822Sdim { _SBSS, RELOC_SECTION_SBSS }, 4234218822Sdim { _BSS, RELOC_SECTION_BSS }, 4235218822Sdim { _INIT, RELOC_SECTION_INIT }, 4236218822Sdim { _LIT8, RELOC_SECTION_LIT8 }, 4237218822Sdim { _LIT4, RELOC_SECTION_LIT4 }, 4238218822Sdim { _XDATA, RELOC_SECTION_XDATA }, 4239218822Sdim { _PDATA, RELOC_SECTION_PDATA }, 4240218822Sdim { _FINI, RELOC_SECTION_FINI }, 4241218822Sdim { _LITA, RELOC_SECTION_LITA }, 4242218822Sdim { "*ABS*", RELOC_SECTION_ABS }, 4243218822Sdim { _RCONST, RELOC_SECTION_RCONST } 4244218822Sdim }; 424533965Sjdp 424633965Sjdp name = bfd_get_section_name (output_bfd, section); 4247218822Sdim 4248218822Sdim for (i = 0; i < ARRAY_SIZE (section_symndx); i++) 4249218822Sdim if (streq (name, section_symndx[i].name)) 4250218822Sdim { 4251218822Sdim in.r_symndx = section_symndx[i].r_symndx; 4252218822Sdim break; 4253218822Sdim } 4254218822Sdim 4255218822Sdim if (i == ARRAY_SIZE (section_symndx)) 425633965Sjdp abort (); 4257218822Sdim 425833965Sjdp in.r_extern = 0; 425933965Sjdp } 426033965Sjdp 426133965Sjdp /* Let the BFD backend adjust the reloc. */ 426233965Sjdp (*ecoff_backend (output_bfd)->adjust_reloc_out) (output_bfd, &rel, &in); 426333965Sjdp 426433965Sjdp /* Get some memory and swap out the reloc. */ 426533965Sjdp external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size; 4266218822Sdim rbuf = bfd_malloc (external_reloc_size); 4267218822Sdim if (rbuf == NULL) 4268130561Sobrien return FALSE; 426933965Sjdp 4270218822Sdim (*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (void *) rbuf); 427133965Sjdp 427289857Sobrien pos = (output_section->rel_filepos 427389857Sobrien + output_section->reloc_count * external_reloc_size); 427489857Sobrien ok = (bfd_seek (output_bfd, pos, SEEK_SET) == 0 4275218822Sdim && (bfd_bwrite ((void *) rbuf, external_reloc_size, output_bfd) 427633965Sjdp == external_reloc_size)); 427733965Sjdp 427833965Sjdp if (ok) 427933965Sjdp ++output_section->reloc_count; 428033965Sjdp 428133965Sjdp free (rbuf); 428233965Sjdp 428333965Sjdp return ok; 428433965Sjdp} 4285218822Sdim 4286218822Sdim/* Put out information for an external symbol. These come only from 4287218822Sdim the hash table. */ 4288218822Sdim 4289218822Sdimstatic bfd_boolean 4290218822Sdimecoff_link_write_external (struct ecoff_link_hash_entry *h, void * data) 4291218822Sdim{ 4292218822Sdim struct extsym_info *einfo = (struct extsym_info *) data; 4293218822Sdim bfd *output_bfd = einfo->abfd; 4294218822Sdim bfd_boolean strip; 4295218822Sdim 4296218822Sdim if (h->root.type == bfd_link_hash_warning) 4297218822Sdim { 4298218822Sdim h = (struct ecoff_link_hash_entry *) h->root.u.i.link; 4299218822Sdim if (h->root.type == bfd_link_hash_new) 4300218822Sdim return TRUE; 4301218822Sdim } 4302218822Sdim 4303218822Sdim /* We need to check if this symbol is being stripped. */ 4304218822Sdim if (h->root.type == bfd_link_hash_undefined 4305218822Sdim || h->root.type == bfd_link_hash_undefweak) 4306218822Sdim strip = FALSE; 4307218822Sdim else if (einfo->info->strip == strip_all 4308218822Sdim || (einfo->info->strip == strip_some 4309218822Sdim && bfd_hash_lookup (einfo->info->keep_hash, 4310218822Sdim h->root.root.string, 4311218822Sdim FALSE, FALSE) == NULL)) 4312218822Sdim strip = TRUE; 4313218822Sdim else 4314218822Sdim strip = FALSE; 4315218822Sdim 4316218822Sdim if (strip || h->written) 4317218822Sdim return TRUE; 4318218822Sdim 4319218822Sdim if (h->abfd == NULL) 4320218822Sdim { 4321218822Sdim h->esym.jmptbl = 0; 4322218822Sdim h->esym.cobol_main = 0; 4323218822Sdim h->esym.weakext = 0; 4324218822Sdim h->esym.reserved = 0; 4325218822Sdim h->esym.ifd = ifdNil; 4326218822Sdim h->esym.asym.value = 0; 4327218822Sdim h->esym.asym.st = stGlobal; 4328218822Sdim 4329218822Sdim if (h->root.type != bfd_link_hash_defined 4330218822Sdim && h->root.type != bfd_link_hash_defweak) 4331218822Sdim h->esym.asym.sc = scAbs; 4332218822Sdim else 4333218822Sdim { 4334218822Sdim asection *output_section; 4335218822Sdim const char *name; 4336218822Sdim unsigned int i; 4337218822Sdim static struct 4338218822Sdim { 4339218822Sdim const char * name; 4340218822Sdim int sc; 4341218822Sdim } 4342218822Sdim section_storage_classes [] = 4343218822Sdim { 4344218822Sdim { _TEXT, scText }, 4345218822Sdim { _DATA, scData }, 4346218822Sdim { _SDATA, scSData }, 4347218822Sdim { _RDATA, scRData }, 4348218822Sdim { _BSS, scBss }, 4349218822Sdim { _SBSS, scSBss }, 4350218822Sdim { _INIT, scInit }, 4351218822Sdim { _FINI, scFini }, 4352218822Sdim { _PDATA, scPData }, 4353218822Sdim { _XDATA, scXData }, 4354218822Sdim { _RCONST, scRConst } 4355218822Sdim }; 4356218822Sdim 4357218822Sdim output_section = h->root.u.def.section->output_section; 4358218822Sdim name = bfd_section_name (output_section->owner, output_section); 4359218822Sdim 4360218822Sdim for (i = 0; i < ARRAY_SIZE (section_storage_classes); i++) 4361218822Sdim if (streq (name, section_storage_classes[i].name)) 4362218822Sdim { 4363218822Sdim h->esym.asym.sc = section_storage_classes[i].sc; 4364218822Sdim break; 4365218822Sdim } 4366218822Sdim 4367218822Sdim if (i == ARRAY_SIZE (section_storage_classes)) 4368218822Sdim h->esym.asym.sc = scAbs; 4369218822Sdim } 4370218822Sdim 4371218822Sdim h->esym.asym.reserved = 0; 4372218822Sdim h->esym.asym.index = indexNil; 4373218822Sdim } 4374218822Sdim else if (h->esym.ifd != -1) 4375218822Sdim { 4376218822Sdim struct ecoff_debug_info *debug; 4377218822Sdim 4378218822Sdim /* Adjust the FDR index for the symbol by that used for the 4379218822Sdim input BFD. */ 4380218822Sdim debug = &ecoff_data (h->abfd)->debug_info; 4381218822Sdim BFD_ASSERT (h->esym.ifd >= 0 4382218822Sdim && h->esym.ifd < debug->symbolic_header.ifdMax); 4383218822Sdim h->esym.ifd = debug->ifdmap[h->esym.ifd]; 4384218822Sdim } 4385218822Sdim 4386218822Sdim switch (h->root.type) 4387218822Sdim { 4388218822Sdim default: 4389218822Sdim case bfd_link_hash_warning: 4390218822Sdim case bfd_link_hash_new: 4391218822Sdim abort (); 4392218822Sdim case bfd_link_hash_undefined: 4393218822Sdim case bfd_link_hash_undefweak: 4394218822Sdim if (h->esym.asym.sc != scUndefined 4395218822Sdim && h->esym.asym.sc != scSUndefined) 4396218822Sdim h->esym.asym.sc = scUndefined; 4397218822Sdim break; 4398218822Sdim case bfd_link_hash_defined: 4399218822Sdim case bfd_link_hash_defweak: 4400218822Sdim if (h->esym.asym.sc == scUndefined 4401218822Sdim || h->esym.asym.sc == scSUndefined) 4402218822Sdim h->esym.asym.sc = scAbs; 4403218822Sdim else if (h->esym.asym.sc == scCommon) 4404218822Sdim h->esym.asym.sc = scBss; 4405218822Sdim else if (h->esym.asym.sc == scSCommon) 4406218822Sdim h->esym.asym.sc = scSBss; 4407218822Sdim h->esym.asym.value = (h->root.u.def.value 4408218822Sdim + h->root.u.def.section->output_section->vma 4409218822Sdim + h->root.u.def.section->output_offset); 4410218822Sdim break; 4411218822Sdim case bfd_link_hash_common: 4412218822Sdim if (h->esym.asym.sc != scCommon 4413218822Sdim && h->esym.asym.sc != scSCommon) 4414218822Sdim h->esym.asym.sc = scCommon; 4415218822Sdim h->esym.asym.value = h->root.u.c.size; 4416218822Sdim break; 4417218822Sdim case bfd_link_hash_indirect: 4418218822Sdim /* We ignore these symbols, since the indirected symbol is 4419218822Sdim already in the hash table. */ 4420218822Sdim return TRUE; 4421218822Sdim } 4422218822Sdim 4423218822Sdim /* bfd_ecoff_debug_one_external uses iextMax to keep track of the 4424218822Sdim symbol number. */ 4425218822Sdim h->indx = ecoff_data (output_bfd)->debug_info.symbolic_header.iextMax; 4426218822Sdim h->written = 1; 4427218822Sdim 4428218822Sdim return (bfd_ecoff_debug_one_external 4429218822Sdim (output_bfd, &ecoff_data (output_bfd)->debug_info, 4430218822Sdim &ecoff_backend (output_bfd)->debug_swap, h->root.root.string, 4431218822Sdim &h->esym)); 4432218822Sdim} 4433218822Sdim 4434218822Sdim/* ECOFF final link routine. This looks through all the input BFDs 4435218822Sdim and gathers together all the debugging information, and then 4436218822Sdim processes all the link order information. This may cause it to 4437218822Sdim close and reopen some input BFDs; I'll see how bad this is. */ 4438218822Sdim 4439218822Sdimbfd_boolean 4440218822Sdim_bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) 4441218822Sdim{ 4442218822Sdim const struct ecoff_backend_data * const backend = ecoff_backend (abfd); 4443218822Sdim struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info; 4444218822Sdim HDRR *symhdr; 4445218822Sdim void * handle; 4446218822Sdim bfd *input_bfd; 4447218822Sdim asection *o; 4448218822Sdim struct bfd_link_order *p; 4449218822Sdim struct extsym_info einfo; 4450218822Sdim 4451218822Sdim /* We accumulate the debugging information counts in the symbolic 4452218822Sdim header. */ 4453218822Sdim symhdr = &debug->symbolic_header; 4454218822Sdim symhdr->vstamp = 0; 4455218822Sdim symhdr->ilineMax = 0; 4456218822Sdim symhdr->cbLine = 0; 4457218822Sdim symhdr->idnMax = 0; 4458218822Sdim symhdr->ipdMax = 0; 4459218822Sdim symhdr->isymMax = 0; 4460218822Sdim symhdr->ioptMax = 0; 4461218822Sdim symhdr->iauxMax = 0; 4462218822Sdim symhdr->issMax = 0; 4463218822Sdim symhdr->issExtMax = 0; 4464218822Sdim symhdr->ifdMax = 0; 4465218822Sdim symhdr->crfd = 0; 4466218822Sdim symhdr->iextMax = 0; 4467218822Sdim 4468218822Sdim /* We accumulate the debugging information itself in the debug_info 4469218822Sdim structure. */ 4470218822Sdim debug->line = NULL; 4471218822Sdim debug->external_dnr = NULL; 4472218822Sdim debug->external_pdr = NULL; 4473218822Sdim debug->external_sym = NULL; 4474218822Sdim debug->external_opt = NULL; 4475218822Sdim debug->external_aux = NULL; 4476218822Sdim debug->ss = NULL; 4477218822Sdim debug->ssext = debug->ssext_end = NULL; 4478218822Sdim debug->external_fdr = NULL; 4479218822Sdim debug->external_rfd = NULL; 4480218822Sdim debug->external_ext = debug->external_ext_end = NULL; 4481218822Sdim 4482218822Sdim handle = bfd_ecoff_debug_init (abfd, debug, &backend->debug_swap, info); 4483218822Sdim if (handle == NULL) 4484218822Sdim return FALSE; 4485218822Sdim 4486218822Sdim /* Accumulate the debugging symbols from each input BFD. */ 4487218822Sdim for (input_bfd = info->input_bfds; 4488218822Sdim input_bfd != NULL; 4489218822Sdim input_bfd = input_bfd->link_next) 4490218822Sdim { 4491218822Sdim bfd_boolean ret; 4492218822Sdim 4493218822Sdim if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour) 4494218822Sdim { 4495218822Sdim /* Arbitrarily set the symbolic header vstamp to the vstamp 4496218822Sdim of the first object file in the link. */ 4497218822Sdim if (symhdr->vstamp == 0) 4498218822Sdim symhdr->vstamp 4499218822Sdim = ecoff_data (input_bfd)->debug_info.symbolic_header.vstamp; 4500218822Sdim ret = ecoff_final_link_debug_accumulate (abfd, input_bfd, info, 4501218822Sdim handle); 4502218822Sdim } 4503218822Sdim else 4504218822Sdim ret = bfd_ecoff_debug_accumulate_other (handle, abfd, 4505218822Sdim debug, &backend->debug_swap, 4506218822Sdim input_bfd, info); 4507218822Sdim if (! ret) 4508218822Sdim return FALSE; 4509218822Sdim 4510218822Sdim /* Combine the register masks. */ 4511218822Sdim ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask; 4512218822Sdim ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask; 4513218822Sdim ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0]; 4514218822Sdim ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1]; 4515218822Sdim ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2]; 4516218822Sdim ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3]; 4517218822Sdim } 4518218822Sdim 4519218822Sdim /* Write out the external symbols. */ 4520218822Sdim einfo.abfd = abfd; 4521218822Sdim einfo.info = info; 4522218822Sdim ecoff_link_hash_traverse (ecoff_hash_table (info), 4523218822Sdim ecoff_link_write_external, 4524218822Sdim (void *) &einfo); 4525218822Sdim 4526218822Sdim if (info->relocatable) 4527218822Sdim { 4528218822Sdim /* We need to make a pass over the link_orders to count up the 4529218822Sdim number of relocations we will need to output, so that we know 4530218822Sdim how much space they will take up. */ 4531218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 4532218822Sdim { 4533218822Sdim o->reloc_count = 0; 4534218822Sdim for (p = o->map_head.link_order; 4535218822Sdim p != NULL; 4536218822Sdim p = p->next) 4537218822Sdim if (p->type == bfd_indirect_link_order) 4538218822Sdim o->reloc_count += p->u.indirect.section->reloc_count; 4539218822Sdim else if (p->type == bfd_section_reloc_link_order 4540218822Sdim || p->type == bfd_symbol_reloc_link_order) 4541218822Sdim ++o->reloc_count; 4542218822Sdim } 4543218822Sdim } 4544218822Sdim 4545218822Sdim /* Compute the reloc and symbol file positions. */ 4546218822Sdim ecoff_compute_reloc_file_positions (abfd); 4547218822Sdim 4548218822Sdim /* Write out the debugging information. */ 4549218822Sdim if (! bfd_ecoff_write_accumulated_debug (handle, abfd, debug, 4550218822Sdim &backend->debug_swap, info, 4551218822Sdim ecoff_data (abfd)->sym_filepos)) 4552218822Sdim return FALSE; 4553218822Sdim 4554218822Sdim bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info); 4555218822Sdim 4556218822Sdim if (info->relocatable) 4557218822Sdim { 4558218822Sdim /* Now reset the reloc_count field of the sections in the output 4559218822Sdim BFD to 0, so that we can use them to keep track of how many 4560218822Sdim relocs we have output thus far. */ 4561218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 4562218822Sdim o->reloc_count = 0; 4563218822Sdim } 4564218822Sdim 4565218822Sdim /* Get a value for the GP register. */ 4566218822Sdim if (ecoff_data (abfd)->gp == 0) 4567218822Sdim { 4568218822Sdim struct bfd_link_hash_entry *h; 4569218822Sdim 4570218822Sdim h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE); 4571218822Sdim if (h != NULL 4572218822Sdim && h->type == bfd_link_hash_defined) 4573218822Sdim ecoff_data (abfd)->gp = (h->u.def.value 4574218822Sdim + h->u.def.section->output_section->vma 4575218822Sdim + h->u.def.section->output_offset); 4576218822Sdim else if (info->relocatable) 4577218822Sdim { 4578218822Sdim bfd_vma lo; 4579218822Sdim 4580218822Sdim /* Make up a value. */ 4581218822Sdim lo = (bfd_vma) -1; 4582218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 4583218822Sdim { 4584218822Sdim if (o->vma < lo 4585218822Sdim && (streq (o->name, _SBSS) 4586218822Sdim || streq (o->name, _SDATA) 4587218822Sdim || streq (o->name, _LIT4) 4588218822Sdim || streq (o->name, _LIT8) 4589218822Sdim || streq (o->name, _LITA))) 4590218822Sdim lo = o->vma; 4591218822Sdim } 4592218822Sdim ecoff_data (abfd)->gp = lo + 0x8000; 4593218822Sdim } 4594218822Sdim else 4595218822Sdim { 4596218822Sdim /* If the relocate_section function needs to do a reloc 4597218822Sdim involving the GP value, it should make a reloc_dangerous 4598218822Sdim callback to warn that GP is not defined. */ 4599218822Sdim } 4600218822Sdim } 4601218822Sdim 4602218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 4603218822Sdim { 4604218822Sdim for (p = o->map_head.link_order; 4605218822Sdim p != NULL; 4606218822Sdim p = p->next) 4607218822Sdim { 4608218822Sdim if (p->type == bfd_indirect_link_order 4609218822Sdim && (bfd_get_flavour (p->u.indirect.section->owner) 4610218822Sdim == bfd_target_ecoff_flavour)) 4611218822Sdim { 4612218822Sdim if (! ecoff_indirect_link_order (abfd, info, o, p)) 4613218822Sdim return FALSE; 4614218822Sdim } 4615218822Sdim else if (p->type == bfd_section_reloc_link_order 4616218822Sdim || p->type == bfd_symbol_reloc_link_order) 4617218822Sdim { 4618218822Sdim if (! ecoff_reloc_link_order (abfd, info, o, p)) 4619218822Sdim return FALSE; 4620218822Sdim } 4621218822Sdim else 4622218822Sdim { 4623218822Sdim if (! _bfd_default_link_order (abfd, info, o, p)) 4624218822Sdim return FALSE; 4625218822Sdim } 4626218822Sdim } 4627218822Sdim } 4628218822Sdim 4629218822Sdim bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax; 4630218822Sdim 4631218822Sdim ecoff_data (abfd)->linker = TRUE; 4632218822Sdim 4633218822Sdim return TRUE; 4634218822Sdim} 4635