133965Sjdp/* Support for the generic parts of COFF, for BFD. 278828Sobrien Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3218822Sdim 2000, 2001, 2002, 2003, 2004, 2005, 2007 438889Sjdp Free Software Foundation, Inc. 533965Sjdp Written by Cygnus Support. 633965Sjdp 7218822Sdim This file is part of BFD, the Binary File Descriptor library. 833965Sjdp 9218822Sdim This program is free software; you can redistribute it and/or modify 10218822Sdim it under the terms of the GNU General Public License as published by 11218822Sdim the Free Software Foundation; either version 2 of the License, or 12218822Sdim (at your option) any later version. 1333965Sjdp 14218822Sdim This program is distributed in the hope that it will be useful, 15218822Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 16218822Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17218822Sdim GNU General Public License for more details. 1833965Sjdp 19218822Sdim You should have received a copy of the GNU General Public License 20218822Sdim 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 2333965Sjdp/* Most of this hacked by Steve Chamberlain, sac@cygnus.com. 2433965Sjdp Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */ 2533965Sjdp 2633965Sjdp/* This file contains COFF code that is not dependent on any 2733965Sjdp particular COFF target. There is only one version of this file in 2833965Sjdp libbfd.a, so no target specific code may be put in here. Or, to 2933965Sjdp put it another way, 3033965Sjdp 3133965Sjdp ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE ********** 3233965Sjdp 3333965Sjdp If you need to add some target specific behaviour, add a new hook 3433965Sjdp function to bfd_coff_backend_data. 3533965Sjdp 3633965Sjdp Some of these functions are also called by the ECOFF routines. 3733965Sjdp Those functions may not use any COFF specific information, such as 3833965Sjdp coff_data (abfd). */ 3933965Sjdp 40218822Sdim#include "sysdep.h" 4133965Sjdp#include "bfd.h" 4233965Sjdp#include "libbfd.h" 4333965Sjdp#include "coff/internal.h" 4433965Sjdp#include "libcoff.h" 4533965Sjdp 4633965Sjdp/* Take a section header read from a coff file (in HOST byte order), 4733965Sjdp and make a BFD "section" out of it. This is used by ECOFF. */ 48218822Sdim 49130561Sobrienstatic bfd_boolean 50218822Sdimmake_a_section_from_file (bfd *abfd, 51218822Sdim struct internal_scnhdr *hdr, 52218822Sdim unsigned int target_index) 5333965Sjdp{ 5433965Sjdp asection *return_section; 5533965Sjdp char *name; 56130561Sobrien bfd_boolean result = TRUE; 5789857Sobrien flagword flags; 5833965Sjdp 5933965Sjdp name = NULL; 6033965Sjdp 6133965Sjdp /* Handle long section names as in PE. */ 6233965Sjdp if (bfd_coff_long_section_names (abfd) 6333965Sjdp && hdr->s_name[0] == '/') 6433965Sjdp { 6533965Sjdp char buf[SCNNMLEN]; 6633965Sjdp long strindex; 6733965Sjdp char *p; 6833965Sjdp const char *strings; 6933965Sjdp 7033965Sjdp memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1); 7133965Sjdp buf[SCNNMLEN - 1] = '\0'; 7233965Sjdp strindex = strtol (buf, &p, 10); 7333965Sjdp if (*p == '\0' && strindex >= 0) 7433965Sjdp { 7533965Sjdp strings = _bfd_coff_read_string_table (abfd); 7633965Sjdp if (strings == NULL) 77130561Sobrien return FALSE; 7833965Sjdp /* FIXME: For extra safety, we should make sure that 7933965Sjdp strindex does not run us past the end, but right now we 8033965Sjdp don't know the length of the string table. */ 8133965Sjdp strings += strindex; 8289857Sobrien name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1); 8333965Sjdp if (name == NULL) 84130561Sobrien return FALSE; 8533965Sjdp strcpy (name, strings); 8633965Sjdp } 8733965Sjdp } 8833965Sjdp 8933965Sjdp if (name == NULL) 9033965Sjdp { 9133965Sjdp /* Assorted wastage to null-terminate the name, thanks AT&T! */ 9289857Sobrien name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1); 9333965Sjdp if (name == NULL) 94130561Sobrien return FALSE; 9533965Sjdp strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); 9633965Sjdp name[sizeof (hdr->s_name)] = 0; 9733965Sjdp } 9833965Sjdp 9933965Sjdp return_section = bfd_make_section_anyway (abfd, name); 10033965Sjdp if (return_section == NULL) 101130561Sobrien return FALSE; 10233965Sjdp 10333965Sjdp return_section->vma = hdr->s_vaddr; 10433965Sjdp return_section->lma = hdr->s_paddr; 105218822Sdim return_section->size = hdr->s_size; 10633965Sjdp return_section->filepos = hdr->s_scnptr; 10733965Sjdp return_section->rel_filepos = hdr->s_relptr; 10833965Sjdp return_section->reloc_count = hdr->s_nreloc; 10933965Sjdp 11033965Sjdp bfd_coff_set_alignment_hook (abfd, return_section, hdr); 11133965Sjdp 11233965Sjdp return_section->line_filepos = hdr->s_lnnoptr; 11333965Sjdp 11433965Sjdp return_section->lineno_count = hdr->s_nlnno; 11533965Sjdp return_section->userdata = NULL; 116218822Sdim return_section->next = NULL; 11733965Sjdp return_section->target_index = target_index; 11833965Sjdp 11989857Sobrien if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section, 12089857Sobrien & flags)) 121130561Sobrien result = FALSE; 12289857Sobrien 12389857Sobrien return_section->flags = flags; 12489857Sobrien 12533965Sjdp /* At least on i386-coff, the line number count for a shared library 12633965Sjdp section must be ignored. */ 12733965Sjdp if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0) 12833965Sjdp return_section->lineno_count = 0; 12933965Sjdp 13033965Sjdp if (hdr->s_nreloc != 0) 13133965Sjdp return_section->flags |= SEC_RELOC; 132218822Sdim /* FIXME: should this check 'hdr->s_size > 0'. */ 13333965Sjdp if (hdr->s_scnptr != 0) 13433965Sjdp return_section->flags |= SEC_HAS_CONTENTS; 13589857Sobrien 13689857Sobrien return result; 13733965Sjdp} 13833965Sjdp 13933965Sjdp/* Read in a COFF object and make it into a BFD. This is used by 14033965Sjdp ECOFF as well. */ 14133965Sjdp 14233965Sjdpstatic const bfd_target * 143218822Sdimcoff_real_object_p (bfd *abfd, 144218822Sdim unsigned nscns, 145218822Sdim struct internal_filehdr *internal_f, 146218822Sdim struct internal_aouthdr *internal_a) 14733965Sjdp{ 14833965Sjdp flagword oflags = abfd->flags; 14933965Sjdp bfd_vma ostart = bfd_get_start_address (abfd); 150218822Sdim void * tdata; 151218822Sdim void * tdata_save; 152218822Sdim bfd_size_type readsize; /* Length of file_info. */ 15333965Sjdp unsigned int scnhsz; 15433965Sjdp char *external_sections; 15533965Sjdp 15633965Sjdp if (!(internal_f->f_flags & F_RELFLG)) 15733965Sjdp abfd->flags |= HAS_RELOC; 15833965Sjdp if ((internal_f->f_flags & F_EXEC)) 15933965Sjdp abfd->flags |= EXEC_P; 16033965Sjdp if (!(internal_f->f_flags & F_LNNO)) 16133965Sjdp abfd->flags |= HAS_LINENO; 16233965Sjdp if (!(internal_f->f_flags & F_LSYMS)) 16333965Sjdp abfd->flags |= HAS_LOCALS; 16433965Sjdp 16533965Sjdp /* FIXME: How can we set D_PAGED correctly? */ 16633965Sjdp if ((internal_f->f_flags & F_EXEC) != 0) 16733965Sjdp abfd->flags |= D_PAGED; 16833965Sjdp 16933965Sjdp bfd_get_symcount (abfd) = internal_f->f_nsyms; 17033965Sjdp if (internal_f->f_nsyms) 17133965Sjdp abfd->flags |= HAS_SYMS; 17233965Sjdp 17333965Sjdp if (internal_a != (struct internal_aouthdr *) NULL) 17433965Sjdp bfd_get_start_address (abfd) = internal_a->entry; 17533965Sjdp else 17633965Sjdp bfd_get_start_address (abfd) = 0; 17733965Sjdp 17833965Sjdp /* Set up the tdata area. ECOFF uses its own routine, and overrides 17933965Sjdp abfd->flags. */ 180104834Sobrien tdata_save = abfd->tdata.any; 181218822Sdim tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a); 18233965Sjdp if (tdata == NULL) 183104834Sobrien goto fail2; 18433965Sjdp 18533965Sjdp scnhsz = bfd_coff_scnhsz (abfd); 18689857Sobrien readsize = (bfd_size_type) nscns * scnhsz; 187218822Sdim external_sections = bfd_alloc (abfd, readsize); 18833965Sjdp if (!external_sections) 18933965Sjdp goto fail; 19033965Sjdp 191218822Sdim if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize) 19233965Sjdp goto fail; 19333965Sjdp 19460484Sobrien /* Set the arch/mach *before* swapping in sections; section header swapping 19577298Sobrien may depend on arch/mach info. */ 196218822Sdim if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f)) 19760484Sobrien goto fail; 19860484Sobrien 199130561Sobrien /* Now copy data as required; construct all asections etc. */ 20033965Sjdp if (nscns != 0) 20133965Sjdp { 20233965Sjdp unsigned int i; 20333965Sjdp for (i = 0; i < nscns; i++) 20433965Sjdp { 20533965Sjdp struct internal_scnhdr tmp; 20633965Sjdp bfd_coff_swap_scnhdr_in (abfd, 207218822Sdim (void *) (external_sections + i * scnhsz), 208218822Sdim (void *) & tmp); 20933965Sjdp if (! make_a_section_from_file (abfd, &tmp, i + 1)) 21033965Sjdp goto fail; 21133965Sjdp } 21233965Sjdp } 21333965Sjdp 21433965Sjdp return abfd->xvec; 21533965Sjdp 21633965Sjdp fail: 21733965Sjdp bfd_release (abfd, tdata); 218104834Sobrien fail2: 219104834Sobrien abfd->tdata.any = tdata_save; 22033965Sjdp abfd->flags = oflags; 22133965Sjdp bfd_get_start_address (abfd) = ostart; 22233965Sjdp return (const bfd_target *) NULL; 22333965Sjdp} 22433965Sjdp 22533965Sjdp/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is 22633965Sjdp not a COFF file. This is also used by ECOFF. */ 22733965Sjdp 22833965Sjdpconst bfd_target * 229218822Sdimcoff_object_p (bfd *abfd) 23033965Sjdp{ 23189857Sobrien bfd_size_type filhsz; 23289857Sobrien bfd_size_type aoutsz; 23389857Sobrien unsigned int nscns; 234218822Sdim void * filehdr; 23533965Sjdp struct internal_filehdr internal_f; 23633965Sjdp struct internal_aouthdr internal_a; 23733965Sjdp 238218822Sdim /* Figure out how much to read. */ 23933965Sjdp filhsz = bfd_coff_filhsz (abfd); 24033965Sjdp aoutsz = bfd_coff_aoutsz (abfd); 24133965Sjdp 24233965Sjdp filehdr = bfd_alloc (abfd, filhsz); 24333965Sjdp if (filehdr == NULL) 244104834Sobrien return NULL; 24589857Sobrien if (bfd_bread (filehdr, filhsz, abfd) != filhsz) 24633965Sjdp { 24733965Sjdp if (bfd_get_error () != bfd_error_system_call) 24833965Sjdp bfd_set_error (bfd_error_wrong_format); 249104834Sobrien bfd_release (abfd, filehdr); 250104834Sobrien return NULL; 25133965Sjdp } 25233965Sjdp bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f); 25333965Sjdp bfd_release (abfd, filehdr); 25433965Sjdp 25589857Sobrien /* The XCOFF format has two sizes for the f_opthdr. SMALL_AOUTSZ 25689857Sobrien (less than aoutsz) used in object files and AOUTSZ (equal to 25789857Sobrien aoutsz) in executables. The bfd_coff_swap_aouthdr_in function 25889857Sobrien expects this header to be aoutsz bytes in length, so we use that 25989857Sobrien value in the call to bfd_alloc below. But we must be careful to 26089857Sobrien only read in f_opthdr bytes in the call to bfd_bread. We should 26189857Sobrien also attempt to catch corrupt or non-COFF binaries with a strange 26289857Sobrien value for f_opthdr. */ 263104834Sobrien if (! bfd_coff_bad_format_hook (abfd, &internal_f) 26489857Sobrien || internal_f.f_opthdr > aoutsz) 26533965Sjdp { 26633965Sjdp bfd_set_error (bfd_error_wrong_format); 267104834Sobrien return NULL; 26833965Sjdp } 26933965Sjdp nscns = internal_f.f_nscns; 27033965Sjdp 27133965Sjdp if (internal_f.f_opthdr) 27233965Sjdp { 273218822Sdim void * opthdr; 27433965Sjdp 27533965Sjdp opthdr = bfd_alloc (abfd, aoutsz); 27633965Sjdp if (opthdr == NULL) 277104834Sobrien return NULL; 27889857Sobrien if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd) 27938889Sjdp != internal_f.f_opthdr) 28033965Sjdp { 281104834Sobrien bfd_release (abfd, opthdr); 282104834Sobrien return NULL; 28333965Sjdp } 284218822Sdim bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a); 285104834Sobrien bfd_release (abfd, opthdr); 28633965Sjdp } 28733965Sjdp 28833965Sjdp return coff_real_object_p (abfd, nscns, &internal_f, 28933965Sjdp (internal_f.f_opthdr != 0 29033965Sjdp ? &internal_a 29133965Sjdp : (struct internal_aouthdr *) NULL)); 29233965Sjdp} 29333965Sjdp 29433965Sjdp/* Get the BFD section from a COFF symbol section number. */ 29533965Sjdp 29633965Sjdpasection * 297218822Sdimcoff_section_from_bfd_index (bfd *abfd, int index) 29833965Sjdp{ 299130561Sobrien struct bfd_section *answer = abfd->sections; 30033965Sjdp 30133965Sjdp if (index == N_ABS) 30233965Sjdp return bfd_abs_section_ptr; 30333965Sjdp if (index == N_UNDEF) 30433965Sjdp return bfd_und_section_ptr; 30533965Sjdp if (index == N_DEBUG) 30633965Sjdp return bfd_abs_section_ptr; 30733965Sjdp 30833965Sjdp while (answer) 30933965Sjdp { 31033965Sjdp if (answer->target_index == index) 31133965Sjdp return answer; 31233965Sjdp answer = answer->next; 31333965Sjdp } 31433965Sjdp 31533965Sjdp /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a 31633965Sjdp has a bad symbol table in biglitpow.o. */ 31733965Sjdp return bfd_und_section_ptr; 31833965Sjdp} 31933965Sjdp 32033965Sjdp/* Get the upper bound of a COFF symbol table. */ 32133965Sjdp 32233965Sjdplong 323218822Sdimcoff_get_symtab_upper_bound (bfd *abfd) 32433965Sjdp{ 32533965Sjdp if (!bfd_coff_slurp_symbol_table (abfd)) 32633965Sjdp return -1; 32733965Sjdp 32833965Sjdp return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *)); 32933965Sjdp} 33033965Sjdp 33133965Sjdp/* Canonicalize a COFF symbol table. */ 33233965Sjdp 33333965Sjdplong 334218822Sdimcoff_canonicalize_symtab (bfd *abfd, asymbol **alocation) 33533965Sjdp{ 33633965Sjdp unsigned int counter; 33733965Sjdp coff_symbol_type *symbase; 33833965Sjdp coff_symbol_type **location = (coff_symbol_type **) alocation; 33933965Sjdp 34033965Sjdp if (!bfd_coff_slurp_symbol_table (abfd)) 34133965Sjdp return -1; 34233965Sjdp 34333965Sjdp symbase = obj_symbols (abfd); 34433965Sjdp counter = bfd_get_symcount (abfd); 34533965Sjdp while (counter-- > 0) 34633965Sjdp *location++ = symbase++; 34733965Sjdp 34833965Sjdp *location = NULL; 34933965Sjdp 35033965Sjdp return bfd_get_symcount (abfd); 35133965Sjdp} 35233965Sjdp 35333965Sjdp/* Get the name of a symbol. The caller must pass in a buffer of size 35433965Sjdp >= SYMNMLEN + 1. */ 35533965Sjdp 35633965Sjdpconst char * 357218822Sdim_bfd_coff_internal_syment_name (bfd *abfd, 358218822Sdim const struct internal_syment *sym, 359218822Sdim char *buf) 36033965Sjdp{ 36133965Sjdp /* FIXME: It's not clear this will work correctly if sizeof 36233965Sjdp (_n_zeroes) != 4. */ 36333965Sjdp if (sym->_n._n_n._n_zeroes != 0 36433965Sjdp || sym->_n._n_n._n_offset == 0) 36533965Sjdp { 36633965Sjdp memcpy (buf, sym->_n._n_name, SYMNMLEN); 36733965Sjdp buf[SYMNMLEN] = '\0'; 36833965Sjdp return buf; 36933965Sjdp } 37033965Sjdp else 37133965Sjdp { 37233965Sjdp const char *strings; 37333965Sjdp 37433965Sjdp BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE); 37533965Sjdp strings = obj_coff_strings (abfd); 37633965Sjdp if (strings == NULL) 37733965Sjdp { 37833965Sjdp strings = _bfd_coff_read_string_table (abfd); 37933965Sjdp if (strings == NULL) 38033965Sjdp return NULL; 38133965Sjdp } 38233965Sjdp return strings + sym->_n._n_n._n_offset; 38333965Sjdp } 38433965Sjdp} 38533965Sjdp 38633965Sjdp/* Read in and swap the relocs. This returns a buffer holding the 387130561Sobrien relocs for section SEC in file ABFD. If CACHE is TRUE and 38833965Sjdp INTERNAL_RELOCS is NULL, the relocs read in will be saved in case 38933965Sjdp the function is called again. If EXTERNAL_RELOCS is not NULL, it 39033965Sjdp is a buffer large enough to hold the unswapped relocs. If 39133965Sjdp INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold 392130561Sobrien the swapped relocs. If REQUIRE_INTERNAL is TRUE, then the return 39333965Sjdp value must be INTERNAL_RELOCS. The function returns NULL on error. */ 39433965Sjdp 39533965Sjdpstruct internal_reloc * 396218822Sdim_bfd_coff_read_internal_relocs (bfd *abfd, 397218822Sdim asection *sec, 398218822Sdim bfd_boolean cache, 399218822Sdim bfd_byte *external_relocs, 400218822Sdim bfd_boolean require_internal, 401218822Sdim struct internal_reloc *internal_relocs) 40233965Sjdp{ 40333965Sjdp bfd_size_type relsz; 40433965Sjdp bfd_byte *free_external = NULL; 40533965Sjdp struct internal_reloc *free_internal = NULL; 40633965Sjdp bfd_byte *erel; 40733965Sjdp bfd_byte *erel_end; 40833965Sjdp struct internal_reloc *irel; 40989857Sobrien bfd_size_type amt; 41033965Sjdp 41133965Sjdp if (coff_section_data (abfd, sec) != NULL 41233965Sjdp && coff_section_data (abfd, sec)->relocs != NULL) 41333965Sjdp { 41433965Sjdp if (! require_internal) 41533965Sjdp return coff_section_data (abfd, sec)->relocs; 41633965Sjdp memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs, 41733965Sjdp sec->reloc_count * sizeof (struct internal_reloc)); 41833965Sjdp return internal_relocs; 41933965Sjdp } 42033965Sjdp 42133965Sjdp relsz = bfd_coff_relsz (abfd); 42233965Sjdp 42389857Sobrien amt = sec->reloc_count * relsz; 42433965Sjdp if (external_relocs == NULL) 42533965Sjdp { 426218822Sdim free_external = bfd_malloc (amt); 42733965Sjdp if (free_external == NULL && sec->reloc_count > 0) 42833965Sjdp goto error_return; 42933965Sjdp external_relocs = free_external; 43033965Sjdp } 43133965Sjdp 43233965Sjdp if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 43389857Sobrien || bfd_bread (external_relocs, amt, abfd) != amt) 43433965Sjdp goto error_return; 43533965Sjdp 43633965Sjdp if (internal_relocs == NULL) 43733965Sjdp { 43889857Sobrien amt = sec->reloc_count; 43989857Sobrien amt *= sizeof (struct internal_reloc); 440218822Sdim free_internal = bfd_malloc (amt); 44133965Sjdp if (free_internal == NULL && sec->reloc_count > 0) 44233965Sjdp goto error_return; 44333965Sjdp internal_relocs = free_internal; 44433965Sjdp } 44533965Sjdp 44633965Sjdp /* Swap in the relocs. */ 44733965Sjdp erel = external_relocs; 44833965Sjdp erel_end = erel + relsz * sec->reloc_count; 44933965Sjdp irel = internal_relocs; 45033965Sjdp for (; erel < erel_end; erel += relsz, irel++) 451218822Sdim bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel); 45233965Sjdp 45333965Sjdp if (free_external != NULL) 45433965Sjdp { 45533965Sjdp free (free_external); 45633965Sjdp free_external = NULL; 45733965Sjdp } 45833965Sjdp 45933965Sjdp if (cache && free_internal != NULL) 46033965Sjdp { 46133965Sjdp if (coff_section_data (abfd, sec) == NULL) 46233965Sjdp { 46389857Sobrien amt = sizeof (struct coff_section_tdata); 464218822Sdim sec->used_by_bfd = bfd_zalloc (abfd, amt); 46533965Sjdp if (sec->used_by_bfd == NULL) 46633965Sjdp goto error_return; 46733965Sjdp coff_section_data (abfd, sec)->contents = NULL; 46833965Sjdp } 46933965Sjdp coff_section_data (abfd, sec)->relocs = free_internal; 47033965Sjdp } 47133965Sjdp 47233965Sjdp return internal_relocs; 47333965Sjdp 47433965Sjdp error_return: 47533965Sjdp if (free_external != NULL) 47633965Sjdp free (free_external); 47733965Sjdp if (free_internal != NULL) 47833965Sjdp free (free_internal); 47933965Sjdp return NULL; 48033965Sjdp} 48133965Sjdp 48233965Sjdp/* Set lineno_count for the output sections of a COFF file. */ 48333965Sjdp 48433965Sjdpint 485218822Sdimcoff_count_linenumbers (bfd *abfd) 48633965Sjdp{ 48733965Sjdp unsigned int limit = bfd_get_symcount (abfd); 48833965Sjdp unsigned int i; 48933965Sjdp int total = 0; 49033965Sjdp asymbol **p; 49133965Sjdp asection *s; 49233965Sjdp 49333965Sjdp if (limit == 0) 49433965Sjdp { 49533965Sjdp /* This may be from the backend linker, in which case the 49633965Sjdp lineno_count in the sections is correct. */ 49733965Sjdp for (s = abfd->sections; s != NULL; s = s->next) 49833965Sjdp total += s->lineno_count; 49933965Sjdp return total; 50033965Sjdp } 50133965Sjdp 50233965Sjdp for (s = abfd->sections; s != NULL; s = s->next) 50333965Sjdp BFD_ASSERT (s->lineno_count == 0); 50433965Sjdp 50533965Sjdp for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) 50633965Sjdp { 50733965Sjdp asymbol *q_maybe = *p; 50833965Sjdp 50977298Sobrien if (bfd_family_coff (bfd_asymbol_bfd (q_maybe))) 51033965Sjdp { 51133965Sjdp coff_symbol_type *q = coffsymbol (q_maybe); 51233965Sjdp 51333965Sjdp /* The AIX 4.1 compiler can sometimes generate line numbers 51433965Sjdp attached to debugging symbols. We try to simply ignore 51533965Sjdp those here. */ 51633965Sjdp if (q->lineno != NULL 51733965Sjdp && q->symbol.section->owner != NULL) 51833965Sjdp { 51933965Sjdp /* This symbol has line numbers. Increment the owning 52033965Sjdp section's linenumber count. */ 52133965Sjdp alent *l = q->lineno; 52233965Sjdp 52389857Sobrien do 52433965Sjdp { 52589857Sobrien asection * sec = q->symbol.section->output_section; 526130561Sobrien 52789857Sobrien /* Do not try to update fields in read-only sections. */ 52889857Sobrien if (! bfd_is_const_section (sec)) 52989857Sobrien sec->lineno_count ++; 53089857Sobrien 53133965Sjdp ++total; 53233965Sjdp ++l; 53333965Sjdp } 53489857Sobrien while (l->line_number != 0); 53533965Sjdp } 53633965Sjdp } 53733965Sjdp } 53833965Sjdp 53933965Sjdp return total; 54033965Sjdp} 54133965Sjdp 54233965Sjdp/* Takes a bfd and a symbol, returns a pointer to the coff specific 54333965Sjdp area of the symbol if there is one. */ 54433965Sjdp 54533965Sjdpcoff_symbol_type * 546218822Sdimcoff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED, 547218822Sdim asymbol *symbol) 54833965Sjdp{ 54977298Sobrien if (!bfd_family_coff (bfd_asymbol_bfd (symbol))) 55033965Sjdp return (coff_symbol_type *) NULL; 55133965Sjdp 55233965Sjdp if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL) 55333965Sjdp return (coff_symbol_type *) NULL; 55433965Sjdp 55533965Sjdp return (coff_symbol_type *) symbol; 55633965Sjdp} 55733965Sjdp 55833965Sjdpstatic void 559218822Sdimfixup_symbol_value (bfd *abfd, 560218822Sdim coff_symbol_type *coff_symbol_ptr, 561218822Sdim struct internal_syment *syment) 56233965Sjdp{ 563218822Sdim /* Normalize the symbol flags. */ 56433965Sjdp if (bfd_is_com_section (coff_symbol_ptr->symbol.section)) 56533965Sjdp { 566218822Sdim /* A common symbol is undefined with a value. */ 56733965Sjdp syment->n_scnum = N_UNDEF; 56833965Sjdp syment->n_value = coff_symbol_ptr->symbol.value; 56933965Sjdp } 57060484Sobrien else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) != 0 57160484Sobrien && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0) 57233965Sjdp { 57333965Sjdp syment->n_value = coff_symbol_ptr->symbol.value; 57433965Sjdp } 57533965Sjdp else if (bfd_is_und_section (coff_symbol_ptr->symbol.section)) 57633965Sjdp { 57733965Sjdp syment->n_scnum = N_UNDEF; 57833965Sjdp syment->n_value = 0; 57933965Sjdp } 58060484Sobrien /* FIXME: Do we need to handle the absolute section here? */ 58133965Sjdp else 58233965Sjdp { 58333965Sjdp if (coff_symbol_ptr->symbol.section) 58433965Sjdp { 58533965Sjdp syment->n_scnum = 58633965Sjdp coff_symbol_ptr->symbol.section->output_section->target_index; 58733965Sjdp 58838889Sjdp syment->n_value = (coff_symbol_ptr->symbol.value 58938889Sjdp + coff_symbol_ptr->symbol.section->output_offset); 59038889Sjdp if (! obj_pe (abfd)) 59177298Sobrien { 59277298Sobrien syment->n_value += (syment->n_sclass == C_STATLAB) 59377298Sobrien ? coff_symbol_ptr->symbol.section->output_section->lma 59477298Sobrien : coff_symbol_ptr->symbol.section->output_section->vma; 59577298Sobrien } 59633965Sjdp } 59733965Sjdp else 59833965Sjdp { 59933965Sjdp BFD_ASSERT (0); 60033965Sjdp /* This can happen, but I don't know why yet (steve@cygnus.com) */ 60133965Sjdp syment->n_scnum = N_ABS; 60233965Sjdp syment->n_value = coff_symbol_ptr->symbol.value; 60333965Sjdp } 60433965Sjdp } 60533965Sjdp} 60633965Sjdp 60733965Sjdp/* Run through all the symbols in the symbol table and work out what 60833965Sjdp their indexes into the symbol table will be when output. 60933965Sjdp 61033965Sjdp Coff requires that each C_FILE symbol points to the next one in the 61133965Sjdp chain, and that the last one points to the first external symbol. We 61233965Sjdp do that here too. */ 61333965Sjdp 614130561Sobrienbfd_boolean 615218822Sdimcoff_renumber_symbols (bfd *bfd_ptr, int *first_undef) 61633965Sjdp{ 61733965Sjdp unsigned int symbol_count = bfd_get_symcount (bfd_ptr); 61833965Sjdp asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; 61933965Sjdp unsigned int native_index = 0; 620218822Sdim struct internal_syment *last_file = NULL; 62133965Sjdp unsigned int symbol_index; 62233965Sjdp 62333965Sjdp /* COFF demands that undefined symbols come after all other symbols. 62433965Sjdp Since we don't need to impose this extra knowledge on all our 62533965Sjdp client programs, deal with that here. Sort the symbol table; 62633965Sjdp just move the undefined symbols to the end, leaving the rest 62733965Sjdp alone. The O'Reilly book says that defined global symbols come 62833965Sjdp at the end before the undefined symbols, so we do that here as 62933965Sjdp well. */ 63033965Sjdp /* @@ Do we have some condition we could test for, so we don't always 63133965Sjdp have to do this? I don't think relocatability is quite right, but 63233965Sjdp I'm not certain. [raeburn:19920508.1711EST] */ 63333965Sjdp { 63433965Sjdp asymbol **newsyms; 63533965Sjdp unsigned int i; 63689857Sobrien bfd_size_type amt; 63733965Sjdp 63889857Sobrien amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1); 639218822Sdim newsyms = bfd_alloc (bfd_ptr, amt); 64033965Sjdp if (!newsyms) 641130561Sobrien return FALSE; 64233965Sjdp bfd_ptr->outsymbols = newsyms; 64333965Sjdp for (i = 0; i < symbol_count; i++) 64433965Sjdp if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 64533965Sjdp || (!bfd_is_und_section (symbol_ptr_ptr[i]->section) 64633965Sjdp && !bfd_is_com_section (symbol_ptr_ptr[i]->section) 64760484Sobrien && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0 64860484Sobrien || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) 64960484Sobrien == 0)))) 65033965Sjdp *newsyms++ = symbol_ptr_ptr[i]; 65133965Sjdp 65233965Sjdp for (i = 0; i < symbol_count; i++) 65333965Sjdp if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 65433965Sjdp && !bfd_is_und_section (symbol_ptr_ptr[i]->section) 65533965Sjdp && (bfd_is_com_section (symbol_ptr_ptr[i]->section) 65660484Sobrien || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0 65760484Sobrien && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) 65860484Sobrien != 0)))) 65933965Sjdp *newsyms++ = symbol_ptr_ptr[i]; 66033965Sjdp 66133965Sjdp *first_undef = newsyms - bfd_ptr->outsymbols; 66233965Sjdp 66333965Sjdp for (i = 0; i < symbol_count; i++) 66433965Sjdp if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 66533965Sjdp && bfd_is_und_section (symbol_ptr_ptr[i]->section)) 66633965Sjdp *newsyms++ = symbol_ptr_ptr[i]; 66733965Sjdp *newsyms = (asymbol *) NULL; 66833965Sjdp symbol_ptr_ptr = bfd_ptr->outsymbols; 66933965Sjdp } 67033965Sjdp 67133965Sjdp for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 67233965Sjdp { 67333965Sjdp coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); 67477298Sobrien symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; 67533965Sjdp if (coff_symbol_ptr && coff_symbol_ptr->native) 67633965Sjdp { 67733965Sjdp combined_entry_type *s = coff_symbol_ptr->native; 67833965Sjdp int i; 67933965Sjdp 68033965Sjdp if (s->u.syment.n_sclass == C_FILE) 68133965Sjdp { 682218822Sdim if (last_file != NULL) 68333965Sjdp last_file->n_value = native_index; 68433965Sjdp last_file = &(s->u.syment); 68533965Sjdp } 68633965Sjdp else 687218822Sdim /* Modify the symbol values according to their section and 688218822Sdim type. */ 689218822Sdim fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment)); 69033965Sjdp 69133965Sjdp for (i = 0; i < s->u.syment.n_numaux + 1; i++) 69233965Sjdp s[i].offset = native_index++; 69333965Sjdp } 69433965Sjdp else 695218822Sdim native_index++; 69633965Sjdp } 697218822Sdim 69833965Sjdp obj_conv_table_size (bfd_ptr) = native_index; 69933965Sjdp 700130561Sobrien return TRUE; 70133965Sjdp} 70233965Sjdp 70333965Sjdp/* Run thorough the symbol table again, and fix it so that all 70433965Sjdp pointers to entries are changed to the entries' index in the output 70533965Sjdp symbol table. */ 70633965Sjdp 70733965Sjdpvoid 708218822Sdimcoff_mangle_symbols (bfd *bfd_ptr) 70933965Sjdp{ 71033965Sjdp unsigned int symbol_count = bfd_get_symcount (bfd_ptr); 71133965Sjdp asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; 71233965Sjdp unsigned int symbol_index; 71333965Sjdp 71433965Sjdp for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 71533965Sjdp { 71633965Sjdp coff_symbol_type *coff_symbol_ptr = 71733965Sjdp coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); 71833965Sjdp 71933965Sjdp if (coff_symbol_ptr && coff_symbol_ptr->native) 72033965Sjdp { 72133965Sjdp int i; 72233965Sjdp combined_entry_type *s = coff_symbol_ptr->native; 72333965Sjdp 72433965Sjdp if (s->fix_value) 72533965Sjdp { 72633965Sjdp /* FIXME: We should use a union here. */ 72733965Sjdp s->u.syment.n_value = 72889857Sobrien (bfd_vma)((combined_entry_type *) 72989857Sobrien ((unsigned long) s->u.syment.n_value))->offset; 73033965Sjdp s->fix_value = 0; 73133965Sjdp } 73233965Sjdp if (s->fix_line) 73333965Sjdp { 73433965Sjdp /* The value is the offset into the line number entries 73533965Sjdp for the symbol's section. On output, the symbol's 73633965Sjdp section should be N_DEBUG. */ 73733965Sjdp s->u.syment.n_value = 73833965Sjdp (coff_symbol_ptr->symbol.section->output_section->line_filepos 73933965Sjdp + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr)); 74033965Sjdp coff_symbol_ptr->symbol.section = 74133965Sjdp coff_section_from_bfd_index (bfd_ptr, N_DEBUG); 74233965Sjdp BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING); 74333965Sjdp } 74433965Sjdp for (i = 0; i < s->u.syment.n_numaux; i++) 74533965Sjdp { 74633965Sjdp combined_entry_type *a = s + i + 1; 74733965Sjdp if (a->fix_tag) 74833965Sjdp { 74933965Sjdp a->u.auxent.x_sym.x_tagndx.l = 75033965Sjdp a->u.auxent.x_sym.x_tagndx.p->offset; 75133965Sjdp a->fix_tag = 0; 75233965Sjdp } 75333965Sjdp if (a->fix_end) 75433965Sjdp { 75533965Sjdp a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l = 75633965Sjdp a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset; 75733965Sjdp a->fix_end = 0; 75833965Sjdp } 75933965Sjdp if (a->fix_scnlen) 76033965Sjdp { 76133965Sjdp a->u.auxent.x_csect.x_scnlen.l = 76233965Sjdp a->u.auxent.x_csect.x_scnlen.p->offset; 76333965Sjdp a->fix_scnlen = 0; 76433965Sjdp } 76533965Sjdp } 76633965Sjdp } 76733965Sjdp } 76833965Sjdp} 76933965Sjdp 77033965Sjdpstatic void 771218822Sdimcoff_fix_symbol_name (bfd *abfd, 772218822Sdim asymbol *symbol, 773218822Sdim combined_entry_type *native, 774218822Sdim bfd_size_type *string_size_p, 775218822Sdim asection **debug_string_section_p, 776218822Sdim bfd_size_type *debug_string_size_p) 77733965Sjdp{ 77833965Sjdp unsigned int name_length; 77933965Sjdp union internal_auxent *auxent; 78033965Sjdp char *name = (char *) (symbol->name); 78133965Sjdp 782218822Sdim if (name == NULL) 78333965Sjdp { 784218822Sdim /* COFF symbols always have names, so we'll make one up. */ 78533965Sjdp symbol->name = "strange"; 78633965Sjdp name = (char *) symbol->name; 78733965Sjdp } 78833965Sjdp name_length = strlen (name); 78933965Sjdp 79033965Sjdp if (native->u.syment.n_sclass == C_FILE 79133965Sjdp && native->u.syment.n_numaux > 0) 79233965Sjdp { 79360484Sobrien unsigned int filnmlen; 79460484Sobrien 79577298Sobrien if (bfd_coff_force_symnames_in_strings (abfd)) 79677298Sobrien { 79777298Sobrien native->u.syment._n._n_n._n_offset = 79877298Sobrien (*string_size_p + STRING_SIZE_SIZE); 79977298Sobrien native->u.syment._n._n_n._n_zeroes = 0; 80077298Sobrien *string_size_p += 6; /* strlen(".file") + 1 */ 80177298Sobrien } 80277298Sobrien else 80377298Sobrien strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); 80477298Sobrien 80533965Sjdp auxent = &(native + 1)->u.auxent; 80633965Sjdp 80760484Sobrien filnmlen = bfd_coff_filnmlen (abfd); 80860484Sobrien 80933965Sjdp if (bfd_coff_long_filenames (abfd)) 81033965Sjdp { 81160484Sobrien if (name_length <= filnmlen) 812218822Sdim strncpy (auxent->x_file.x_fname, name, filnmlen); 81333965Sjdp else 81433965Sjdp { 81533965Sjdp auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; 81633965Sjdp auxent->x_file.x_n.x_zeroes = 0; 81733965Sjdp *string_size_p += name_length + 1; 81833965Sjdp } 81933965Sjdp } 82033965Sjdp else 82133965Sjdp { 82260484Sobrien strncpy (auxent->x_file.x_fname, name, filnmlen); 82360484Sobrien if (name_length > filnmlen) 82460484Sobrien name[filnmlen] = '\0'; 82533965Sjdp } 82633965Sjdp } 82733965Sjdp else 82833965Sjdp { 82977298Sobrien if (name_length <= SYMNMLEN && !bfd_coff_force_symnames_in_strings (abfd)) 830218822Sdim /* This name will fit into the symbol neatly. */ 831218822Sdim strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN); 832218822Sdim 83333965Sjdp else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment)) 83433965Sjdp { 83533965Sjdp native->u.syment._n._n_n._n_offset = (*string_size_p 83633965Sjdp + STRING_SIZE_SIZE); 83733965Sjdp native->u.syment._n._n_n._n_zeroes = 0; 83833965Sjdp *string_size_p += name_length + 1; 83933965Sjdp } 84033965Sjdp else 84133965Sjdp { 84289857Sobrien file_ptr filepos; 84377298Sobrien bfd_byte buf[4]; 84477298Sobrien int prefix_len = bfd_coff_debug_string_prefix_length (abfd); 84533965Sjdp 84633965Sjdp /* This name should be written into the .debug section. For 84733965Sjdp some reason each name is preceded by a two byte length 84833965Sjdp and also followed by a null byte. FIXME: We assume that 84933965Sjdp the .debug section has already been created, and that it 85033965Sjdp is large enough. */ 85133965Sjdp if (*debug_string_section_p == (asection *) NULL) 85233965Sjdp *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug"); 85333965Sjdp filepos = bfd_tell (abfd); 85477298Sobrien if (prefix_len == 4) 85589857Sobrien bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf); 85677298Sobrien else 85789857Sobrien bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf); 85877298Sobrien 85933965Sjdp if (!bfd_set_section_contents (abfd, 86033965Sjdp *debug_string_section_p, 861218822Sdim (void *) buf, 86233965Sjdp (file_ptr) *debug_string_size_p, 86377298Sobrien (bfd_size_type) prefix_len) 86433965Sjdp || !bfd_set_section_contents (abfd, 86533965Sjdp *debug_string_section_p, 866218822Sdim (void *) symbol->name, 86789857Sobrien (file_ptr) (*debug_string_size_p 86889857Sobrien + prefix_len), 86933965Sjdp (bfd_size_type) name_length + 1)) 87033965Sjdp abort (); 87133965Sjdp if (bfd_seek (abfd, filepos, SEEK_SET) != 0) 87233965Sjdp abort (); 87377298Sobrien native->u.syment._n._n_n._n_offset = 87477298Sobrien *debug_string_size_p + prefix_len; 87533965Sjdp native->u.syment._n._n_n._n_zeroes = 0; 87677298Sobrien *debug_string_size_p += name_length + 1 + prefix_len; 87733965Sjdp } 87833965Sjdp } 87933965Sjdp} 88033965Sjdp 88133965Sjdp/* We need to keep track of the symbol index so that when we write out 88233965Sjdp the relocs we can get the index for a symbol. This method is a 88333965Sjdp hack. FIXME. */ 88433965Sjdp 88533965Sjdp#define set_index(symbol, idx) ((symbol)->udata.i = (idx)) 88633965Sjdp 88733965Sjdp/* Write a symbol out to a COFF file. */ 88833965Sjdp 889130561Sobrienstatic bfd_boolean 890218822Sdimcoff_write_symbol (bfd *abfd, 891218822Sdim asymbol *symbol, 892218822Sdim combined_entry_type *native, 893218822Sdim bfd_vma *written, 894218822Sdim bfd_size_type *string_size_p, 895218822Sdim asection **debug_string_section_p, 896218822Sdim bfd_size_type *debug_string_size_p) 89733965Sjdp{ 89833965Sjdp unsigned int numaux = native->u.syment.n_numaux; 89933965Sjdp int type = native->u.syment.n_type; 90033965Sjdp int class = native->u.syment.n_sclass; 901218822Sdim void * buf; 90233965Sjdp bfd_size_type symesz; 90333965Sjdp 90433965Sjdp if (native->u.syment.n_sclass == C_FILE) 90533965Sjdp symbol->flags |= BSF_DEBUGGING; 90633965Sjdp 90733965Sjdp if (symbol->flags & BSF_DEBUGGING 90833965Sjdp && bfd_is_abs_section (symbol->section)) 909218822Sdim native->u.syment.n_scnum = N_DEBUG; 910218822Sdim 91133965Sjdp else if (bfd_is_abs_section (symbol->section)) 912218822Sdim native->u.syment.n_scnum = N_ABS; 913218822Sdim 91433965Sjdp else if (bfd_is_und_section (symbol->section)) 915218822Sdim native->u.syment.n_scnum = N_UNDEF; 916218822Sdim 91733965Sjdp else 918218822Sdim native->u.syment.n_scnum = 919218822Sdim symbol->section->output_section->target_index; 92033965Sjdp 92133965Sjdp coff_fix_symbol_name (abfd, symbol, native, string_size_p, 92233965Sjdp debug_string_section_p, debug_string_size_p); 92333965Sjdp 92433965Sjdp symesz = bfd_coff_symesz (abfd); 92533965Sjdp buf = bfd_alloc (abfd, symesz); 92633965Sjdp if (!buf) 927130561Sobrien return FALSE; 92833965Sjdp bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); 92989857Sobrien if (bfd_bwrite (buf, symesz, abfd) != symesz) 930130561Sobrien return FALSE; 93133965Sjdp bfd_release (abfd, buf); 93233965Sjdp 93333965Sjdp if (native->u.syment.n_numaux > 0) 93433965Sjdp { 93533965Sjdp bfd_size_type auxesz; 93633965Sjdp unsigned int j; 93733965Sjdp 93833965Sjdp auxesz = bfd_coff_auxesz (abfd); 93933965Sjdp buf = bfd_alloc (abfd, auxesz); 94033965Sjdp if (!buf) 941130561Sobrien return FALSE; 94233965Sjdp for (j = 0; j < native->u.syment.n_numaux; j++) 94333965Sjdp { 94433965Sjdp bfd_coff_swap_aux_out (abfd, 94533965Sjdp &((native + j + 1)->u.auxent), 946218822Sdim type, class, (int) j, 94733965Sjdp native->u.syment.n_numaux, 94833965Sjdp buf); 94989857Sobrien if (bfd_bwrite (buf, auxesz, abfd) != auxesz) 950130561Sobrien return FALSE; 95133965Sjdp } 95233965Sjdp bfd_release (abfd, buf); 95333965Sjdp } 95433965Sjdp 95533965Sjdp /* Store the index for use when we write out the relocs. */ 95633965Sjdp set_index (symbol, *written); 95733965Sjdp 95833965Sjdp *written += numaux + 1; 959130561Sobrien return TRUE; 96033965Sjdp} 96133965Sjdp 96233965Sjdp/* Write out a symbol to a COFF file that does not come from a COFF 96333965Sjdp file originally. This symbol may have been created by the linker, 96433965Sjdp or we may be linking a non COFF file to a COFF file. */ 96533965Sjdp 966130561Sobrienstatic bfd_boolean 967218822Sdimcoff_write_alien_symbol (bfd *abfd, 968218822Sdim asymbol *symbol, 969218822Sdim bfd_vma *written, 970218822Sdim bfd_size_type *string_size_p, 971218822Sdim asection **debug_string_section_p, 972218822Sdim bfd_size_type *debug_string_size_p) 97333965Sjdp{ 97433965Sjdp combined_entry_type *native; 97533965Sjdp combined_entry_type dummy; 97633965Sjdp 97733965Sjdp native = &dummy; 97833965Sjdp native->u.syment.n_type = T_NULL; 97933965Sjdp native->u.syment.n_flags = 0; 98033965Sjdp if (bfd_is_und_section (symbol->section)) 98133965Sjdp { 98233965Sjdp native->u.syment.n_scnum = N_UNDEF; 98333965Sjdp native->u.syment.n_value = symbol->value; 98433965Sjdp } 98533965Sjdp else if (bfd_is_com_section (symbol->section)) 98633965Sjdp { 98733965Sjdp native->u.syment.n_scnum = N_UNDEF; 98833965Sjdp native->u.syment.n_value = symbol->value; 98933965Sjdp } 99033965Sjdp else if (symbol->flags & BSF_DEBUGGING) 99133965Sjdp { 99233965Sjdp /* There isn't much point to writing out a debugging symbol 99333965Sjdp unless we are prepared to convert it into COFF debugging 99433965Sjdp format. So, we just ignore them. We must clobber the symbol 99533965Sjdp name to keep it from being put in the string table. */ 99633965Sjdp symbol->name = ""; 997130561Sobrien return TRUE; 99833965Sjdp } 99933965Sjdp else 100033965Sjdp { 100133965Sjdp native->u.syment.n_scnum = 100233965Sjdp symbol->section->output_section->target_index; 100333965Sjdp native->u.syment.n_value = (symbol->value 100433965Sjdp + symbol->section->output_offset); 100538889Sjdp if (! obj_pe (abfd)) 100638889Sjdp native->u.syment.n_value += symbol->section->output_section->vma; 100733965Sjdp 100889857Sobrien /* Copy the any flags from the file header into the symbol. 100933965Sjdp FIXME: Why? */ 101033965Sjdp { 101133965Sjdp coff_symbol_type *c = coff_symbol_from (abfd, symbol); 101233965Sjdp if (c != (coff_symbol_type *) NULL) 101333965Sjdp native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; 101433965Sjdp } 101533965Sjdp } 101633965Sjdp 101733965Sjdp native->u.syment.n_type = 0; 101833965Sjdp if (symbol->flags & BSF_LOCAL) 101933965Sjdp native->u.syment.n_sclass = C_STAT; 102060484Sobrien else if (symbol->flags & BSF_WEAK) 102160484Sobrien native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT; 102233965Sjdp else 102333965Sjdp native->u.syment.n_sclass = C_EXT; 102433965Sjdp native->u.syment.n_numaux = 0; 102533965Sjdp 102633965Sjdp return coff_write_symbol (abfd, symbol, native, written, string_size_p, 102733965Sjdp debug_string_section_p, debug_string_size_p); 102833965Sjdp} 102933965Sjdp 103033965Sjdp/* Write a native symbol to a COFF file. */ 103133965Sjdp 1032130561Sobrienstatic bfd_boolean 1033218822Sdimcoff_write_native_symbol (bfd *abfd, 1034218822Sdim coff_symbol_type *symbol, 1035218822Sdim bfd_vma *written, 1036218822Sdim bfd_size_type *string_size_p, 1037218822Sdim asection **debug_string_section_p, 1038218822Sdim bfd_size_type *debug_string_size_p) 103933965Sjdp{ 104033965Sjdp combined_entry_type *native = symbol->native; 104133965Sjdp alent *lineno = symbol->lineno; 104233965Sjdp 104333965Sjdp /* If this symbol has an associated line number, we must store the 104433965Sjdp symbol index in the line number field. We also tag the auxent to 104533965Sjdp point to the right place in the lineno table. */ 104633965Sjdp if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL) 104733965Sjdp { 104833965Sjdp unsigned int count = 0; 1049218822Sdim 105033965Sjdp lineno[count].u.offset = *written; 105133965Sjdp if (native->u.syment.n_numaux) 105233965Sjdp { 105333965Sjdp union internal_auxent *a = &((native + 1)->u.auxent); 105433965Sjdp 105533965Sjdp a->x_sym.x_fcnary.x_fcn.x_lnnoptr = 105633965Sjdp symbol->symbol.section->output_section->moving_line_filepos; 105733965Sjdp } 105833965Sjdp 105933965Sjdp /* Count and relocate all other linenumbers. */ 106033965Sjdp count++; 106133965Sjdp while (lineno[count].line_number != 0) 106233965Sjdp { 106333965Sjdp lineno[count].u.offset += 106433965Sjdp (symbol->symbol.section->output_section->vma 106533965Sjdp + symbol->symbol.section->output_offset); 106633965Sjdp count++; 106733965Sjdp } 1068130561Sobrien symbol->done_lineno = TRUE; 106933965Sjdp 107089857Sobrien if (! bfd_is_const_section (symbol->symbol.section->output_section)) 107189857Sobrien symbol->symbol.section->output_section->moving_line_filepos += 107289857Sobrien count * bfd_coff_linesz (abfd); 107333965Sjdp } 107433965Sjdp 107533965Sjdp return coff_write_symbol (abfd, &(symbol->symbol), native, written, 107633965Sjdp string_size_p, debug_string_section_p, 107733965Sjdp debug_string_size_p); 107833965Sjdp} 107933965Sjdp 108033965Sjdp/* Write out the COFF symbols. */ 108133965Sjdp 1082130561Sobrienbfd_boolean 1083218822Sdimcoff_write_symbols (bfd *abfd) 108433965Sjdp{ 108533965Sjdp bfd_size_type string_size; 108633965Sjdp asection *debug_string_section; 108733965Sjdp bfd_size_type debug_string_size; 108833965Sjdp unsigned int i; 108933965Sjdp unsigned int limit = bfd_get_symcount (abfd); 1090218822Sdim bfd_vma written = 0; 109133965Sjdp asymbol **p; 109233965Sjdp 109333965Sjdp string_size = 0; 109433965Sjdp debug_string_section = NULL; 109533965Sjdp debug_string_size = 0; 109633965Sjdp 109733965Sjdp /* If this target supports long section names, they must be put into 109833965Sjdp the string table. This is supported by PE. This code must 109933965Sjdp handle section names just as they are handled in 110033965Sjdp coff_write_object_contents. */ 110133965Sjdp if (bfd_coff_long_section_names (abfd)) 110233965Sjdp { 110333965Sjdp asection *o; 110433965Sjdp 110533965Sjdp for (o = abfd->sections; o != NULL; o = o->next) 110633965Sjdp { 110733965Sjdp size_t len; 110833965Sjdp 110933965Sjdp len = strlen (o->name); 111033965Sjdp if (len > SCNNMLEN) 111133965Sjdp string_size += len + 1; 111233965Sjdp } 111333965Sjdp } 111433965Sjdp 1115218822Sdim /* Seek to the right place. */ 111633965Sjdp if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) 1117130561Sobrien return FALSE; 111833965Sjdp 1119218822Sdim /* Output all the symbols we have. */ 112033965Sjdp written = 0; 112133965Sjdp for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) 112233965Sjdp { 112333965Sjdp asymbol *symbol = *p; 112433965Sjdp coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol); 112533965Sjdp 112633965Sjdp if (c_symbol == (coff_symbol_type *) NULL 112733965Sjdp || c_symbol->native == (combined_entry_type *) NULL) 112833965Sjdp { 112933965Sjdp if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size, 113033965Sjdp &debug_string_section, 113133965Sjdp &debug_string_size)) 1132130561Sobrien return FALSE; 113333965Sjdp } 113433965Sjdp else 113533965Sjdp { 113633965Sjdp if (!coff_write_native_symbol (abfd, c_symbol, &written, 113733965Sjdp &string_size, &debug_string_section, 113833965Sjdp &debug_string_size)) 1139130561Sobrien return FALSE; 114033965Sjdp } 114133965Sjdp } 114233965Sjdp 114333965Sjdp obj_raw_syment_count (abfd) = written; 114433965Sjdp 1145218822Sdim /* Now write out strings. */ 114633965Sjdp if (string_size != 0) 114733965Sjdp { 114833965Sjdp unsigned int size = string_size + STRING_SIZE_SIZE; 114933965Sjdp bfd_byte buffer[STRING_SIZE_SIZE]; 115033965Sjdp 115133965Sjdp#if STRING_SIZE_SIZE == 4 115289857Sobrien H_PUT_32 (abfd, size, buffer); 115333965Sjdp#else 115489857Sobrien #error Change H_PUT_32 115533965Sjdp#endif 1156218822Sdim if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) 115789857Sobrien != sizeof (buffer)) 1158130561Sobrien return FALSE; 115933965Sjdp 116033965Sjdp /* Handle long section names. This code must handle section 116133965Sjdp names just as they are handled in coff_write_object_contents. */ 116233965Sjdp if (bfd_coff_long_section_names (abfd)) 116333965Sjdp { 116433965Sjdp asection *o; 116533965Sjdp 116633965Sjdp for (o = abfd->sections; o != NULL; o = o->next) 116733965Sjdp { 116833965Sjdp size_t len; 116933965Sjdp 117033965Sjdp len = strlen (o->name); 117133965Sjdp if (len > SCNNMLEN) 117233965Sjdp { 117389857Sobrien if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd) 117489857Sobrien != len + 1) 1175130561Sobrien return FALSE; 117633965Sjdp } 117733965Sjdp } 117833965Sjdp } 117933965Sjdp 118033965Sjdp for (p = abfd->outsymbols, i = 0; 118133965Sjdp i < limit; 118233965Sjdp i++, p++) 118333965Sjdp { 118433965Sjdp asymbol *q = *p; 118533965Sjdp size_t name_length = strlen (q->name); 118633965Sjdp coff_symbol_type *c_symbol = coff_symbol_from (abfd, q); 118733965Sjdp size_t maxlen; 118833965Sjdp 118933965Sjdp /* Figure out whether the symbol name should go in the string 119033965Sjdp table. Symbol names that are short enough are stored 119133965Sjdp directly in the syment structure. File names permit a 119233965Sjdp different, longer, length in the syment structure. On 119333965Sjdp XCOFF, some symbol names are stored in the .debug section 119433965Sjdp rather than in the string table. */ 119533965Sjdp 119633965Sjdp if (c_symbol == NULL 119733965Sjdp || c_symbol->native == NULL) 1198218822Sdim /* This is not a COFF symbol, so it certainly is not a 1199218822Sdim file name, nor does it go in the .debug section. */ 1200218822Sdim maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; 1201218822Sdim 120233965Sjdp else if (bfd_coff_symname_in_debug (abfd, 120333965Sjdp &c_symbol->native->u.syment)) 1204218822Sdim /* This symbol name is in the XCOFF .debug section. 1205218822Sdim Don't write it into the string table. */ 1206218822Sdim maxlen = name_length; 1207218822Sdim 120833965Sjdp else if (c_symbol->native->u.syment.n_sclass == C_FILE 120933965Sjdp && c_symbol->native->u.syment.n_numaux > 0) 121077298Sobrien { 121177298Sobrien if (bfd_coff_force_symnames_in_strings (abfd)) 121289857Sobrien { 121389857Sobrien if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) 1214130561Sobrien return FALSE; 121589857Sobrien } 121677298Sobrien maxlen = bfd_coff_filnmlen (abfd); 121777298Sobrien } 121833965Sjdp else 121977298Sobrien maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; 122033965Sjdp 122133965Sjdp if (name_length > maxlen) 122233965Sjdp { 1223218822Sdim if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1, 122489857Sobrien abfd) != name_length + 1) 1225130561Sobrien return FALSE; 122633965Sjdp } 122733965Sjdp } 122833965Sjdp } 122933965Sjdp else 123033965Sjdp { 123133965Sjdp /* We would normally not write anything here, but we'll write 123233965Sjdp out 4 so that any stupid coff reader which tries to read the 123333965Sjdp string table even when there isn't one won't croak. */ 123433965Sjdp unsigned int size = STRING_SIZE_SIZE; 123533965Sjdp bfd_byte buffer[STRING_SIZE_SIZE]; 123633965Sjdp 123733965Sjdp#if STRING_SIZE_SIZE == 4 123889857Sobrien H_PUT_32 (abfd, size, buffer); 123933965Sjdp#else 124089857Sobrien #error Change H_PUT_32 124133965Sjdp#endif 1242218822Sdim if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd) 124333965Sjdp != STRING_SIZE_SIZE) 1244130561Sobrien return FALSE; 124533965Sjdp } 124633965Sjdp 124733965Sjdp /* Make sure the .debug section was created to be the correct size. 124833965Sjdp We should create it ourselves on the fly, but we don't because 124933965Sjdp BFD won't let us write to any section until we know how large all 125033965Sjdp the sections are. We could still do it by making another pass 125133965Sjdp over the symbols. FIXME. */ 125233965Sjdp BFD_ASSERT (debug_string_size == 0 125333965Sjdp || (debug_string_section != (asection *) NULL 125433965Sjdp && (BFD_ALIGN (debug_string_size, 125533965Sjdp 1 << debug_string_section->alignment_power) 1256218822Sdim == debug_string_section->size))); 125733965Sjdp 1258130561Sobrien return TRUE; 125933965Sjdp} 126033965Sjdp 1261130561Sobrienbfd_boolean 1262218822Sdimcoff_write_linenumbers (bfd *abfd) 126333965Sjdp{ 126433965Sjdp asection *s; 126533965Sjdp bfd_size_type linesz; 1266218822Sdim void * buff; 126733965Sjdp 126833965Sjdp linesz = bfd_coff_linesz (abfd); 126933965Sjdp buff = bfd_alloc (abfd, linesz); 127033965Sjdp if (!buff) 1271130561Sobrien return FALSE; 127233965Sjdp for (s = abfd->sections; s != (asection *) NULL; s = s->next) 127333965Sjdp { 127433965Sjdp if (s->lineno_count) 127533965Sjdp { 127633965Sjdp asymbol **q = abfd->outsymbols; 127733965Sjdp if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0) 1278130561Sobrien return FALSE; 1279218822Sdim /* Find all the linenumbers in this section. */ 128033965Sjdp while (*q) 128133965Sjdp { 128233965Sjdp asymbol *p = *q; 128333965Sjdp if (p->section->output_section == s) 128433965Sjdp { 128533965Sjdp alent *l = 128633965Sjdp BFD_SEND (bfd_asymbol_bfd (p), _get_lineno, 128733965Sjdp (bfd_asymbol_bfd (p), p)); 128833965Sjdp if (l) 128933965Sjdp { 1290218822Sdim /* Found a linenumber entry, output. */ 129133965Sjdp struct internal_lineno out; 1292218822Sdim memset ((void *) & out, 0, sizeof (out)); 129333965Sjdp out.l_lnno = 0; 129433965Sjdp out.l_addr.l_symndx = l->u.offset; 129533965Sjdp bfd_coff_swap_lineno_out (abfd, &out, buff); 129689857Sobrien if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) 129789857Sobrien != linesz) 1298130561Sobrien return FALSE; 129933965Sjdp l++; 130033965Sjdp while (l->line_number) 130133965Sjdp { 130233965Sjdp out.l_lnno = l->line_number; 130333965Sjdp out.l_addr.l_symndx = l->u.offset; 130433965Sjdp bfd_coff_swap_lineno_out (abfd, &out, buff); 130589857Sobrien if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) 130689857Sobrien != linesz) 1307130561Sobrien return FALSE; 130833965Sjdp l++; 130933965Sjdp } 131033965Sjdp } 131133965Sjdp } 131233965Sjdp q++; 131333965Sjdp } 131433965Sjdp } 131533965Sjdp } 131633965Sjdp bfd_release (abfd, buff); 1317130561Sobrien return TRUE; 131833965Sjdp} 131933965Sjdp 132033965Sjdpalent * 1321218822Sdimcoff_get_lineno (bfd *ignore_abfd ATTRIBUTE_UNUSED, asymbol *symbol) 132233965Sjdp{ 132333965Sjdp return coffsymbol (symbol)->lineno; 132433965Sjdp} 132533965Sjdp 132633965Sjdp/* This function transforms the offsets into the symbol table into 132733965Sjdp pointers to syments. */ 132833965Sjdp 132933965Sjdpstatic void 1330218822Sdimcoff_pointerize_aux (bfd *abfd, 1331218822Sdim combined_entry_type *table_base, 1332218822Sdim combined_entry_type *symbol, 1333218822Sdim unsigned int indaux, 1334218822Sdim combined_entry_type *auxent) 133533965Sjdp{ 133638889Sjdp unsigned int type = symbol->u.syment.n_type; 133738889Sjdp unsigned int class = symbol->u.syment.n_sclass; 133833965Sjdp 133933965Sjdp if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) 134033965Sjdp { 134133965Sjdp if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) 134233965Sjdp (abfd, table_base, symbol, indaux, auxent)) 134333965Sjdp return; 134433965Sjdp } 134533965Sjdp 1346218822Sdim /* Don't bother if this is a file or a section. */ 134733965Sjdp if (class == C_STAT && type == T_NULL) 134833965Sjdp return; 134933965Sjdp if (class == C_FILE) 135033965Sjdp return; 135133965Sjdp 1352218822Sdim /* Otherwise patch up. */ 1353218822Sdim#define N_TMASK coff_data (abfd)->local_n_tmask 135433965Sjdp#define N_BTSHFT coff_data (abfd)->local_n_btshft 1355218822Sdim 135633965Sjdp if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN) 135733965Sjdp && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) 135833965Sjdp { 135933965Sjdp auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = 136033965Sjdp table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; 136133965Sjdp auxent->fix_end = 1; 136233965Sjdp } 136333965Sjdp /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can 136433965Sjdp generate one, so we must be careful to ignore it. */ 136533965Sjdp if (auxent->u.auxent.x_sym.x_tagndx.l > 0) 136633965Sjdp { 136733965Sjdp auxent->u.auxent.x_sym.x_tagndx.p = 136833965Sjdp table_base + auxent->u.auxent.x_sym.x_tagndx.l; 136933965Sjdp auxent->fix_tag = 1; 137033965Sjdp } 137133965Sjdp} 137233965Sjdp 137333965Sjdp/* Allocate space for the ".debug" section, and read it. 137433965Sjdp We did not read the debug section until now, because 137577298Sobrien we didn't want to go to the trouble until someone needed it. */ 137633965Sjdp 137733965Sjdpstatic char * 1378218822Sdimbuild_debug_section (bfd *abfd) 137933965Sjdp{ 138033965Sjdp char *debug_section; 138189857Sobrien file_ptr position; 138289857Sobrien bfd_size_type sec_size; 138333965Sjdp 138433965Sjdp asection *sect = bfd_get_section_by_name (abfd, ".debug"); 138533965Sjdp 138633965Sjdp if (!sect) 138733965Sjdp { 138833965Sjdp bfd_set_error (bfd_error_no_debug_section); 138933965Sjdp return NULL; 139033965Sjdp } 139133965Sjdp 1392218822Sdim sec_size = sect->size; 1393218822Sdim debug_section = bfd_alloc (abfd, sec_size); 139433965Sjdp if (debug_section == NULL) 139533965Sjdp return NULL; 139633965Sjdp 139777298Sobrien /* Seek to the beginning of the `.debug' section and read it. 139833965Sjdp Save the current position first; it is needed by our caller. 139933965Sjdp Then read debug section and reset the file pointer. */ 140033965Sjdp 140133965Sjdp position = bfd_tell (abfd); 140233965Sjdp if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0 140389857Sobrien || bfd_bread (debug_section, sec_size, abfd) != sec_size 140433965Sjdp || bfd_seek (abfd, position, SEEK_SET) != 0) 140533965Sjdp return NULL; 140633965Sjdp return debug_section; 140733965Sjdp} 140833965Sjdp 140933965Sjdp/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be 141033965Sjdp \0-terminated, but will not exceed 'maxlen' characters. The copy *will* 141133965Sjdp be \0-terminated. */ 1412218822Sdim 141333965Sjdpstatic char * 1414218822Sdimcopy_name (bfd *abfd, char *name, size_t maxlen) 141533965Sjdp{ 141689857Sobrien size_t len; 141733965Sjdp char *newname; 141833965Sjdp 141933965Sjdp for (len = 0; len < maxlen; ++len) 1420218822Sdim if (name[len] == '\0') 1421218822Sdim break; 142233965Sjdp 1423218822Sdim if ((newname = bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL) 1424218822Sdim return NULL; 1425218822Sdim 142633965Sjdp strncpy (newname, name, len); 142733965Sjdp newname[len] = '\0'; 142833965Sjdp return newname; 142933965Sjdp} 143033965Sjdp 143133965Sjdp/* Read in the external symbols. */ 143233965Sjdp 1433130561Sobrienbfd_boolean 1434218822Sdim_bfd_coff_get_external_symbols (bfd *abfd) 143533965Sjdp{ 143633965Sjdp bfd_size_type symesz; 143789857Sobrien bfd_size_type size; 1438218822Sdim void * syms; 143933965Sjdp 144033965Sjdp if (obj_coff_external_syms (abfd) != NULL) 1441130561Sobrien return TRUE; 144233965Sjdp 144333965Sjdp symesz = bfd_coff_symesz (abfd); 144433965Sjdp 144533965Sjdp size = obj_raw_syment_count (abfd) * symesz; 144633965Sjdp 1447218822Sdim syms = bfd_malloc (size); 144833965Sjdp if (syms == NULL && size != 0) 1449130561Sobrien return FALSE; 145033965Sjdp 145133965Sjdp if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 145289857Sobrien || bfd_bread (syms, size, abfd) != size) 145333965Sjdp { 145433965Sjdp if (syms != NULL) 145533965Sjdp free (syms); 1456130561Sobrien return FALSE; 145733965Sjdp } 145833965Sjdp 145933965Sjdp obj_coff_external_syms (abfd) = syms; 146033965Sjdp 1461130561Sobrien return TRUE; 146233965Sjdp} 146333965Sjdp 146433965Sjdp/* Read in the external strings. The strings are not loaded until 146533965Sjdp they are needed. This is because we have no simple way of 146633965Sjdp detecting a missing string table in an archive. */ 146733965Sjdp 146833965Sjdpconst char * 1469218822Sdim_bfd_coff_read_string_table (bfd *abfd) 147033965Sjdp{ 147133965Sjdp char extstrsize[STRING_SIZE_SIZE]; 147289857Sobrien bfd_size_type strsize; 147333965Sjdp char *strings; 147489857Sobrien file_ptr pos; 147533965Sjdp 147633965Sjdp if (obj_coff_strings (abfd) != NULL) 147733965Sjdp return obj_coff_strings (abfd); 147833965Sjdp 147933965Sjdp if (obj_sym_filepos (abfd) == 0) 148033965Sjdp { 148133965Sjdp bfd_set_error (bfd_error_no_symbols); 148233965Sjdp return NULL; 148333965Sjdp } 148433965Sjdp 148589857Sobrien pos = obj_sym_filepos (abfd); 148689857Sobrien pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd); 148789857Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0) 148833965Sjdp return NULL; 148977298Sobrien 149089857Sobrien if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd) 149189857Sobrien != sizeof extstrsize) 149233965Sjdp { 149333965Sjdp if (bfd_get_error () != bfd_error_file_truncated) 149433965Sjdp return NULL; 149533965Sjdp 149633965Sjdp /* There is no string table. */ 149733965Sjdp strsize = STRING_SIZE_SIZE; 149833965Sjdp } 149933965Sjdp else 150033965Sjdp { 150133965Sjdp#if STRING_SIZE_SIZE == 4 150289857Sobrien strsize = H_GET_32 (abfd, extstrsize); 150333965Sjdp#else 150489857Sobrien #error Change H_GET_32 150533965Sjdp#endif 150633965Sjdp } 150733965Sjdp 150833965Sjdp if (strsize < STRING_SIZE_SIZE) 150933965Sjdp { 151033965Sjdp (*_bfd_error_handler) 1511218822Sdim (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize); 151233965Sjdp bfd_set_error (bfd_error_bad_value); 151333965Sjdp return NULL; 151433965Sjdp } 151533965Sjdp 1516218822Sdim strings = bfd_malloc (strsize); 151733965Sjdp if (strings == NULL) 151833965Sjdp return NULL; 151933965Sjdp 152089857Sobrien if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd) 152133965Sjdp != strsize - STRING_SIZE_SIZE) 152233965Sjdp { 152333965Sjdp free (strings); 152433965Sjdp return NULL; 152533965Sjdp } 152633965Sjdp 152733965Sjdp obj_coff_strings (abfd) = strings; 152833965Sjdp 152933965Sjdp return strings; 153033965Sjdp} 153133965Sjdp 153233965Sjdp/* Free up the external symbols and strings read from a COFF file. */ 153333965Sjdp 1534130561Sobrienbfd_boolean 1535218822Sdim_bfd_coff_free_symbols (bfd *abfd) 153633965Sjdp{ 153733965Sjdp if (obj_coff_external_syms (abfd) != NULL 153833965Sjdp && ! obj_coff_keep_syms (abfd)) 153933965Sjdp { 154033965Sjdp free (obj_coff_external_syms (abfd)); 154133965Sjdp obj_coff_external_syms (abfd) = NULL; 154233965Sjdp } 154333965Sjdp if (obj_coff_strings (abfd) != NULL 154433965Sjdp && ! obj_coff_keep_strings (abfd)) 154533965Sjdp { 154633965Sjdp free (obj_coff_strings (abfd)); 154733965Sjdp obj_coff_strings (abfd) = NULL; 154833965Sjdp } 1549130561Sobrien return TRUE; 155033965Sjdp} 155133965Sjdp 155233965Sjdp/* Read a symbol table into freshly bfd_allocated memory, swap it, and 155333965Sjdp knit the symbol names into a normalized form. By normalized here I 155433965Sjdp mean that all symbols have an n_offset pointer that points to a null- 155533965Sjdp terminated string. */ 155633965Sjdp 155733965Sjdpcombined_entry_type * 1558218822Sdimcoff_get_normalized_symtab (bfd *abfd) 155933965Sjdp{ 156033965Sjdp combined_entry_type *internal; 156133965Sjdp combined_entry_type *internal_ptr; 156233965Sjdp combined_entry_type *symbol_ptr; 156333965Sjdp combined_entry_type *internal_end; 156489857Sobrien size_t symesz; 156533965Sjdp char *raw_src; 156633965Sjdp char *raw_end; 156733965Sjdp const char *string_table = NULL; 156833965Sjdp char *debug_section = NULL; 156989857Sobrien bfd_size_type size; 157033965Sjdp 157133965Sjdp if (obj_raw_syments (abfd) != NULL) 157233965Sjdp return obj_raw_syments (abfd); 157333965Sjdp 157433965Sjdp size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type); 1575218822Sdim internal = bfd_zalloc (abfd, size); 157633965Sjdp if (internal == NULL && size != 0) 157733965Sjdp return NULL; 157833965Sjdp internal_end = internal + obj_raw_syment_count (abfd); 157933965Sjdp 158033965Sjdp if (! _bfd_coff_get_external_symbols (abfd)) 158133965Sjdp return NULL; 158233965Sjdp 158333965Sjdp raw_src = (char *) obj_coff_external_syms (abfd); 158433965Sjdp 1585218822Sdim /* Mark the end of the symbols. */ 158633965Sjdp symesz = bfd_coff_symesz (abfd); 158733965Sjdp raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz; 158833965Sjdp 158933965Sjdp /* FIXME SOMEDAY. A string table size of zero is very weird, but 159033965Sjdp probably possible. If one shows up, it will probably kill us. */ 159133965Sjdp 1592218822Sdim /* Swap all the raw entries. */ 159333965Sjdp for (internal_ptr = internal; 159433965Sjdp raw_src < raw_end; 159533965Sjdp raw_src += symesz, internal_ptr++) 159633965Sjdp { 159733965Sjdp 159833965Sjdp unsigned int i; 1599218822Sdim bfd_coff_swap_sym_in (abfd, (void *) raw_src, 1600218822Sdim (void *) & internal_ptr->u.syment); 160133965Sjdp symbol_ptr = internal_ptr; 160233965Sjdp 160333965Sjdp for (i = 0; 160433965Sjdp i < symbol_ptr->u.syment.n_numaux; 160533965Sjdp i++) 160633965Sjdp { 160733965Sjdp internal_ptr++; 160833965Sjdp raw_src += symesz; 1609218822Sdim bfd_coff_swap_aux_in (abfd, (void *) raw_src, 161033965Sjdp symbol_ptr->u.syment.n_type, 161133965Sjdp symbol_ptr->u.syment.n_sclass, 161289857Sobrien (int) i, symbol_ptr->u.syment.n_numaux, 161333965Sjdp &(internal_ptr->u.auxent)); 161433965Sjdp coff_pointerize_aux (abfd, internal, symbol_ptr, i, 161533965Sjdp internal_ptr); 161633965Sjdp } 161733965Sjdp } 161833965Sjdp 161933965Sjdp /* Free the raw symbols, but not the strings (if we have them). */ 1620130561Sobrien obj_coff_keep_strings (abfd) = TRUE; 162133965Sjdp if (! _bfd_coff_free_symbols (abfd)) 162233965Sjdp return NULL; 162333965Sjdp 162433965Sjdp for (internal_ptr = internal; internal_ptr < internal_end; 162533965Sjdp internal_ptr++) 162633965Sjdp { 162733965Sjdp if (internal_ptr->u.syment.n_sclass == C_FILE 162833965Sjdp && internal_ptr->u.syment.n_numaux > 0) 162933965Sjdp { 1630218822Sdim /* Make a file symbol point to the name in the auxent, since 1631218822Sdim the text ".file" is redundant. */ 163233965Sjdp if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0) 163333965Sjdp { 1634218822Sdim /* The filename is a long one, point into the string table. */ 163533965Sjdp if (string_table == NULL) 163633965Sjdp { 163733965Sjdp string_table = _bfd_coff_read_string_table (abfd); 163833965Sjdp if (string_table == NULL) 163933965Sjdp return NULL; 164033965Sjdp } 164133965Sjdp 164233965Sjdp internal_ptr->u.syment._n._n_n._n_offset = 164333965Sjdp ((long) 164433965Sjdp (string_table 164533965Sjdp + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset)); 164633965Sjdp } 164733965Sjdp else 164833965Sjdp { 164960484Sobrien /* Ordinary short filename, put into memory anyway. The 165060484Sobrien Microsoft PE tools sometimes store a filename in 165160484Sobrien multiple AUX entries. */ 165260484Sobrien if (internal_ptr->u.syment.n_numaux > 1 165360484Sobrien && coff_data (abfd)->pe) 1654218822Sdim internal_ptr->u.syment._n._n_n._n_offset = 1655218822Sdim ((long) 1656218822Sdim copy_name (abfd, 1657218822Sdim (internal_ptr + 1)->u.auxent.x_file.x_fname, 1658218822Sdim internal_ptr->u.syment.n_numaux * symesz)); 165960484Sobrien else 1660218822Sdim internal_ptr->u.syment._n._n_n._n_offset = 1661218822Sdim ((long) 1662218822Sdim copy_name (abfd, 1663218822Sdim (internal_ptr + 1)->u.auxent.x_file.x_fname, 1664218822Sdim (size_t) bfd_coff_filnmlen (abfd))); 166533965Sjdp } 166633965Sjdp } 166733965Sjdp else 166833965Sjdp { 166933965Sjdp if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) 167033965Sjdp { 167133965Sjdp /* This is a "short" name. Make it long. */ 167289857Sobrien size_t i; 167389857Sobrien char *newstring; 167433965Sjdp 1675218822Sdim /* Find the length of this string without walking into memory 167633965Sjdp that isn't ours. */ 167733965Sjdp for (i = 0; i < 8; ++i) 167889857Sobrien if (internal_ptr->u.syment._n._n_name[i] == '\0') 167989857Sobrien break; 168033965Sjdp 1681218822Sdim newstring = bfd_zalloc (abfd, (bfd_size_type) (i + 1)); 168289857Sobrien if (newstring == NULL) 1683218822Sdim return NULL; 168489857Sobrien strncpy (newstring, internal_ptr->u.syment._n._n_name, i); 168533965Sjdp internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring; 168633965Sjdp internal_ptr->u.syment._n._n_n._n_zeroes = 0; 168733965Sjdp } 168833965Sjdp else if (internal_ptr->u.syment._n._n_n._n_offset == 0) 168933965Sjdp internal_ptr->u.syment._n._n_n._n_offset = (long int) ""; 169033965Sjdp else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment)) 169133965Sjdp { 169233965Sjdp /* Long name already. Point symbol at the string in the 169333965Sjdp table. */ 169433965Sjdp if (string_table == NULL) 169533965Sjdp { 169633965Sjdp string_table = _bfd_coff_read_string_table (abfd); 169733965Sjdp if (string_table == NULL) 169833965Sjdp return NULL; 169933965Sjdp } 170033965Sjdp internal_ptr->u.syment._n._n_n._n_offset = 170133965Sjdp ((long int) 170233965Sjdp (string_table 170333965Sjdp + internal_ptr->u.syment._n._n_n._n_offset)); 170433965Sjdp } 170533965Sjdp else 170633965Sjdp { 170733965Sjdp /* Long name in debug section. Very similar. */ 170833965Sjdp if (debug_section == NULL) 170933965Sjdp debug_section = build_debug_section (abfd); 171033965Sjdp internal_ptr->u.syment._n._n_n._n_offset = (long int) 171133965Sjdp (debug_section + internal_ptr->u.syment._n._n_n._n_offset); 171233965Sjdp } 171333965Sjdp } 171433965Sjdp internal_ptr += internal_ptr->u.syment.n_numaux; 171533965Sjdp } 171633965Sjdp 171733965Sjdp obj_raw_syments (abfd) = internal; 171833965Sjdp BFD_ASSERT (obj_raw_syment_count (abfd) 171933965Sjdp == (unsigned int) (internal_ptr - internal)); 172033965Sjdp 1721218822Sdim return internal; 1722218822Sdim} 172333965Sjdp 172433965Sjdplong 1725218822Sdimcoff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) 172633965Sjdp{ 172733965Sjdp if (bfd_get_format (abfd) != bfd_object) 172833965Sjdp { 172933965Sjdp bfd_set_error (bfd_error_invalid_operation); 173033965Sjdp return -1; 173133965Sjdp } 173233965Sjdp return (asect->reloc_count + 1) * sizeof (arelent *); 173333965Sjdp} 173433965Sjdp 173533965Sjdpasymbol * 1736218822Sdimcoff_make_empty_symbol (bfd *abfd) 173733965Sjdp{ 173889857Sobrien bfd_size_type amt = sizeof (coff_symbol_type); 1739218822Sdim coff_symbol_type *new = bfd_zalloc (abfd, amt); 1740218822Sdim 174133965Sjdp if (new == NULL) 1742218822Sdim return NULL; 174333965Sjdp new->symbol.section = 0; 174433965Sjdp new->native = 0; 1745218822Sdim new->lineno = NULL; 1746130561Sobrien new->done_lineno = FALSE; 174733965Sjdp new->symbol.the_bfd = abfd; 1748218822Sdim 1749218822Sdim return & new->symbol; 175033965Sjdp} 175133965Sjdp 175233965Sjdp/* Make a debugging symbol. */ 175333965Sjdp 175433965Sjdpasymbol * 1755218822Sdimcoff_bfd_make_debug_symbol (bfd *abfd, 1756218822Sdim void * ptr ATTRIBUTE_UNUSED, 1757218822Sdim unsigned long sz ATTRIBUTE_UNUSED) 175833965Sjdp{ 175989857Sobrien bfd_size_type amt = sizeof (coff_symbol_type); 1760218822Sdim coff_symbol_type *new = bfd_alloc (abfd, amt); 1761218822Sdim 176233965Sjdp if (new == NULL) 1763218822Sdim return NULL; 176433965Sjdp /* @@ The 10 is a guess at a plausible maximum number of aux entries 176533965Sjdp (but shouldn't be a constant). */ 176689857Sobrien amt = sizeof (combined_entry_type) * 10; 1767218822Sdim new->native = bfd_zalloc (abfd, amt); 176833965Sjdp if (!new->native) 1769218822Sdim return NULL; 177033965Sjdp new->symbol.section = bfd_abs_section_ptr; 177133965Sjdp new->symbol.flags = BSF_DEBUGGING; 1772218822Sdim new->lineno = NULL; 1773130561Sobrien new->done_lineno = FALSE; 177433965Sjdp new->symbol.the_bfd = abfd; 1775218822Sdim 1776218822Sdim return & new->symbol; 177733965Sjdp} 177833965Sjdp 177933965Sjdpvoid 1780218822Sdimcoff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret) 178133965Sjdp{ 178233965Sjdp bfd_symbol_info (symbol, ret); 1783218822Sdim 178433965Sjdp if (coffsymbol (symbol)->native != NULL 178533965Sjdp && coffsymbol (symbol)->native->fix_value) 1786218822Sdim ret->value = coffsymbol (symbol)->native->u.syment.n_value - 1787218822Sdim (unsigned long) obj_raw_syments (abfd); 178833965Sjdp} 178933965Sjdp 179033965Sjdp/* Return the COFF syment for a symbol. */ 179133965Sjdp 1792130561Sobrienbfd_boolean 1793218822Sdimbfd_coff_get_syment (bfd *abfd, 1794218822Sdim asymbol *symbol, 1795218822Sdim struct internal_syment *psyment) 179633965Sjdp{ 179733965Sjdp coff_symbol_type *csym; 179833965Sjdp 179933965Sjdp csym = coff_symbol_from (abfd, symbol); 180033965Sjdp if (csym == NULL || csym->native == NULL) 180133965Sjdp { 180233965Sjdp bfd_set_error (bfd_error_invalid_operation); 1803130561Sobrien return FALSE; 180433965Sjdp } 180533965Sjdp 180633965Sjdp *psyment = csym->native->u.syment; 180733965Sjdp 180833965Sjdp if (csym->native->fix_value) 180989857Sobrien psyment->n_value = psyment->n_value - 181089857Sobrien (unsigned long) obj_raw_syments (abfd); 181133965Sjdp 181233965Sjdp /* FIXME: We should handle fix_line here. */ 181333965Sjdp 1814130561Sobrien return TRUE; 181533965Sjdp} 181633965Sjdp 181733965Sjdp/* Return the COFF auxent for a symbol. */ 181833965Sjdp 1819130561Sobrienbfd_boolean 1820218822Sdimbfd_coff_get_auxent (bfd *abfd, 1821218822Sdim asymbol *symbol, 1822218822Sdim int indx, 1823218822Sdim union internal_auxent *pauxent) 182433965Sjdp{ 182533965Sjdp coff_symbol_type *csym; 182633965Sjdp combined_entry_type *ent; 182733965Sjdp 182833965Sjdp csym = coff_symbol_from (abfd, symbol); 182933965Sjdp 183033965Sjdp if (csym == NULL 183133965Sjdp || csym->native == NULL 183233965Sjdp || indx >= csym->native->u.syment.n_numaux) 183333965Sjdp { 183433965Sjdp bfd_set_error (bfd_error_invalid_operation); 1835130561Sobrien return FALSE; 183633965Sjdp } 183733965Sjdp 183833965Sjdp ent = csym->native + indx + 1; 183933965Sjdp 184033965Sjdp *pauxent = ent->u.auxent; 184133965Sjdp 184233965Sjdp if (ent->fix_tag) 184333965Sjdp pauxent->x_sym.x_tagndx.l = 184433965Sjdp ((combined_entry_type *) pauxent->x_sym.x_tagndx.p 184533965Sjdp - obj_raw_syments (abfd)); 184633965Sjdp 184733965Sjdp if (ent->fix_end) 184833965Sjdp pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l = 184933965Sjdp ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p 185033965Sjdp - obj_raw_syments (abfd)); 185133965Sjdp 185233965Sjdp if (ent->fix_scnlen) 185333965Sjdp pauxent->x_csect.x_scnlen.l = 185433965Sjdp ((combined_entry_type *) pauxent->x_csect.x_scnlen.p 185533965Sjdp - obj_raw_syments (abfd)); 185633965Sjdp 1857130561Sobrien return TRUE; 185833965Sjdp} 185933965Sjdp 186033965Sjdp/* Print out information about COFF symbol. */ 186133965Sjdp 186233965Sjdpvoid 1863218822Sdimcoff_print_symbol (bfd *abfd, 1864218822Sdim void * filep, 1865218822Sdim asymbol *symbol, 1866218822Sdim bfd_print_symbol_type how) 186733965Sjdp{ 1868218822Sdim FILE * file = (FILE *) filep; 186933965Sjdp 187033965Sjdp switch (how) 187133965Sjdp { 187233965Sjdp case bfd_print_symbol_name: 187333965Sjdp fprintf (file, "%s", symbol->name); 187433965Sjdp break; 187533965Sjdp 187633965Sjdp case bfd_print_symbol_more: 187733965Sjdp fprintf (file, "coff %s %s", 187833965Sjdp coffsymbol (symbol)->native ? "n" : "g", 187933965Sjdp coffsymbol (symbol)->lineno ? "l" : " "); 188033965Sjdp break; 188133965Sjdp 188233965Sjdp case bfd_print_symbol_all: 188333965Sjdp if (coffsymbol (symbol)->native) 188433965Sjdp { 188589857Sobrien bfd_vma val; 188633965Sjdp unsigned int aux; 188733965Sjdp combined_entry_type *combined = coffsymbol (symbol)->native; 188833965Sjdp combined_entry_type *root = obj_raw_syments (abfd); 188933965Sjdp struct lineno_cache_entry *l = coffsymbol (symbol)->lineno; 189033965Sjdp 189133965Sjdp fprintf (file, "[%3ld]", (long) (combined - root)); 189233965Sjdp 189333965Sjdp if (! combined->fix_value) 189489857Sobrien val = (bfd_vma) combined->u.syment.n_value; 189533965Sjdp else 189689857Sobrien val = combined->u.syment.n_value - (unsigned long) root; 189733965Sjdp 1898218822Sdim fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x", 189933965Sjdp combined->u.syment.n_scnum, 190033965Sjdp combined->u.syment.n_flags, 190133965Sjdp combined->u.syment.n_type, 190233965Sjdp combined->u.syment.n_sclass, 1903218822Sdim combined->u.syment.n_numaux); 1904218822Sdim#ifdef BFD64 1905218822Sdim /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit 1906218822Sdim value, but really we want to display the address in the target's 1907218822Sdim address size. Since we do not have a field in the bfd structure 1908218822Sdim to tell us this, we take a guess, based on the target's name. */ 1909218822Sdim if (strstr (bfd_get_target (abfd), "64") == NULL) 1910218822Sdim fprintf (file, "%08lx", (unsigned long) (val & 0xffffffff)); 1911218822Sdim else 191289857Sobrien#endif 1913218822Sdim fprintf_vma (file, val); 1914218822Sdim fprintf (file, " %s", symbol->name); 191533965Sjdp 191633965Sjdp for (aux = 0; aux < combined->u.syment.n_numaux; aux++) 191733965Sjdp { 191833965Sjdp combined_entry_type *auxp = combined + aux + 1; 191933965Sjdp long tagndx; 192033965Sjdp 192133965Sjdp if (auxp->fix_tag) 192233965Sjdp tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root; 192333965Sjdp else 192433965Sjdp tagndx = auxp->u.auxent.x_sym.x_tagndx.l; 192533965Sjdp 192633965Sjdp fprintf (file, "\n"); 192733965Sjdp 192833965Sjdp if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux)) 192933965Sjdp continue; 193033965Sjdp 193133965Sjdp switch (combined->u.syment.n_sclass) 193233965Sjdp { 193333965Sjdp case C_FILE: 193433965Sjdp fprintf (file, "File "); 193533965Sjdp break; 193633965Sjdp 193733965Sjdp case C_STAT: 193833965Sjdp if (combined->u.syment.n_type == T_NULL) 1939218822Sdim /* Probably a section symbol ? */ 194033965Sjdp { 194133965Sjdp fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d", 194233965Sjdp (long) auxp->u.auxent.x_scn.x_scnlen, 194333965Sjdp auxp->u.auxent.x_scn.x_nreloc, 194433965Sjdp auxp->u.auxent.x_scn.x_nlinno); 194533965Sjdp if (auxp->u.auxent.x_scn.x_checksum != 0 194633965Sjdp || auxp->u.auxent.x_scn.x_associated != 0 194733965Sjdp || auxp->u.auxent.x_scn.x_comdat != 0) 194833965Sjdp fprintf (file, " checksum 0x%lx assoc %d comdat %d", 194933965Sjdp auxp->u.auxent.x_scn.x_checksum, 195033965Sjdp auxp->u.auxent.x_scn.x_associated, 195133965Sjdp auxp->u.auxent.x_scn.x_comdat); 195233965Sjdp break; 195333965Sjdp } 1954218822Sdim /* Otherwise fall through. */ 195560484Sobrien case C_EXT: 195660484Sobrien if (ISFCN (combined->u.syment.n_type)) 195760484Sobrien { 195889857Sobrien long next, llnos; 195989857Sobrien 196089857Sobrien if (auxp->fix_end) 196189857Sobrien next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p 196289857Sobrien - root); 196389857Sobrien else 196489857Sobrien next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; 196589857Sobrien llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr; 196660484Sobrien fprintf (file, 196789857Sobrien "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld", 196889857Sobrien tagndx, auxp->u.auxent.x_sym.x_misc.x_fsize, 196989857Sobrien llnos, next); 197060484Sobrien break; 197160484Sobrien } 1972218822Sdim /* Otherwise fall through. */ 197333965Sjdp default: 197433965Sjdp fprintf (file, "AUX lnno %d size 0x%x tagndx %ld", 197533965Sjdp auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno, 197633965Sjdp auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size, 197733965Sjdp tagndx); 197833965Sjdp if (auxp->fix_end) 197933965Sjdp fprintf (file, " endndx %ld", 198033965Sjdp ((long) 198133965Sjdp (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p 198233965Sjdp - root))); 198333965Sjdp break; 198433965Sjdp } 198533965Sjdp } 198633965Sjdp 198733965Sjdp if (l) 198833965Sjdp { 198933965Sjdp fprintf (file, "\n%s :", l->u.sym->name); 199033965Sjdp l++; 199133965Sjdp while (l->line_number) 199233965Sjdp { 1993218822Sdim fprintf (file, "\n%4d : ", l->line_number); 1994218822Sdim fprintf_vma (file, l->u.offset + symbol->section->vma); 199533965Sjdp l++; 199633965Sjdp } 199733965Sjdp } 199833965Sjdp } 199933965Sjdp else 200033965Sjdp { 2001218822Sdim bfd_print_symbol_vandf (abfd, (void *) file, symbol); 200233965Sjdp fprintf (file, " %-5s %s %s %s", 200333965Sjdp symbol->section->name, 200433965Sjdp coffsymbol (symbol)->native ? "n" : "g", 200533965Sjdp coffsymbol (symbol)->lineno ? "l" : " ", 200633965Sjdp symbol->name); 200733965Sjdp } 200833965Sjdp } 200933965Sjdp} 201033965Sjdp 201133965Sjdp/* Return whether a symbol name implies a local symbol. In COFF, 201233965Sjdp local symbols generally start with ``.L''. Most targets use this 201333965Sjdp function for the is_local_label_name entry point, but some may 201433965Sjdp override it. */ 201533965Sjdp 2016130561Sobrienbfd_boolean 2017218822Sdim_bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, 2018218822Sdim const char *name) 201933965Sjdp{ 2020130561Sobrien return name[0] == '.' && name[1] == 'L'; 202133965Sjdp} 202233965Sjdp 202360484Sobrien/* Provided a BFD, a section and an offset (in bytes, not octets) into the 202460484Sobrien section, calculate and return the name of the source file and the line 202560484Sobrien nearest to the wanted location. */ 202677298Sobrien 2027130561Sobrienbfd_boolean 2028218822Sdimcoff_find_nearest_line (bfd *abfd, 2029218822Sdim asection *section, 2030218822Sdim asymbol **symbols, 2031218822Sdim bfd_vma offset, 2032218822Sdim const char **filename_ptr, 2033218822Sdim const char **functionname_ptr, 2034218822Sdim unsigned int *line_ptr) 203533965Sjdp{ 2036130561Sobrien bfd_boolean found; 203733965Sjdp unsigned int i; 203833965Sjdp unsigned int line_base; 203933965Sjdp coff_data_type *cof = coff_data (abfd); 2040218822Sdim /* Run through the raw syments if available. */ 204133965Sjdp combined_entry_type *p; 204233965Sjdp combined_entry_type *pend; 204333965Sjdp alent *l; 204433965Sjdp struct coff_section_tdata *sec_data; 204589857Sobrien bfd_size_type amt; 204633965Sjdp 204733965Sjdp /* Before looking through the symbol table, try to use a .stab 204833965Sjdp section to find the information. */ 204933965Sjdp if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, 205033965Sjdp &found, filename_ptr, 205133965Sjdp functionname_ptr, line_ptr, 205277298Sobrien &coff_data(abfd)->line_info)) 2053130561Sobrien return FALSE; 205477298Sobrien 205533965Sjdp if (found) 2056130561Sobrien return TRUE; 205733965Sjdp 205877298Sobrien /* Also try examining DWARF2 debugging information. */ 205977298Sobrien if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, 206077298Sobrien filename_ptr, functionname_ptr, 206177298Sobrien line_ptr, 0, 206277298Sobrien &coff_data(abfd)->dwarf2_find_line_info)) 2063130561Sobrien return TRUE; 206477298Sobrien 206533965Sjdp *filename_ptr = 0; 206633965Sjdp *functionname_ptr = 0; 206733965Sjdp *line_ptr = 0; 206833965Sjdp 2069218822Sdim /* Don't try and find line numbers in a non coff file. */ 207077298Sobrien if (!bfd_family_coff (abfd)) 2071130561Sobrien return FALSE; 207233965Sjdp 207333965Sjdp if (cof == NULL) 2074130561Sobrien return FALSE; 207533965Sjdp 207633965Sjdp /* Find the first C_FILE symbol. */ 207733965Sjdp p = cof->raw_syments; 207838889Sjdp if (!p) 2079130561Sobrien return FALSE; 208038889Sjdp 208133965Sjdp pend = p + cof->raw_syment_count; 208233965Sjdp while (p < pend) 208333965Sjdp { 208433965Sjdp if (p->u.syment.n_sclass == C_FILE) 208533965Sjdp break; 208633965Sjdp p += 1 + p->u.syment.n_numaux; 208733965Sjdp } 208833965Sjdp 208933965Sjdp if (p < pend) 209033965Sjdp { 209138889Sjdp bfd_vma sec_vma; 209233965Sjdp bfd_vma maxdiff; 209333965Sjdp 209433965Sjdp /* Look through the C_FILE symbols to find the best one. */ 209538889Sjdp sec_vma = bfd_get_section_vma (abfd, section); 209633965Sjdp *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; 209733965Sjdp maxdiff = (bfd_vma) 0 - (bfd_vma) 1; 209833965Sjdp while (1) 209933965Sjdp { 210033965Sjdp combined_entry_type *p2; 210133965Sjdp 210233965Sjdp for (p2 = p + 1 + p->u.syment.n_numaux; 210333965Sjdp p2 < pend; 210433965Sjdp p2 += 1 + p2->u.syment.n_numaux) 210533965Sjdp { 210633965Sjdp if (p2->u.syment.n_scnum > 0 210733965Sjdp && (section 210833965Sjdp == coff_section_from_bfd_index (abfd, 210933965Sjdp p2->u.syment.n_scnum))) 211033965Sjdp break; 211133965Sjdp if (p2->u.syment.n_sclass == C_FILE) 211233965Sjdp { 211333965Sjdp p2 = pend; 211433965Sjdp break; 211533965Sjdp } 211633965Sjdp } 211733965Sjdp 211860484Sobrien /* We use <= MAXDIFF here so that if we get a zero length 211960484Sobrien file, we actually use the next file entry. */ 212033965Sjdp if (p2 < pend 212138889Sjdp && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value 212260484Sobrien && offset + sec_vma - (bfd_vma) p2->u.syment.n_value <= maxdiff) 212333965Sjdp { 212433965Sjdp *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; 212538889Sjdp maxdiff = offset + sec_vma - p2->u.syment.n_value; 212633965Sjdp } 212733965Sjdp 212833965Sjdp /* Avoid endless loops on erroneous files by ensuring that 212933965Sjdp we always move forward in the file. */ 213089857Sobrien if (p >= cof->raw_syments + p->u.syment.n_value) 213133965Sjdp break; 213233965Sjdp 213333965Sjdp p = cof->raw_syments + p->u.syment.n_value; 213433965Sjdp if (p > pend || p->u.syment.n_sclass != C_FILE) 213533965Sjdp break; 213633965Sjdp } 213733965Sjdp } 213833965Sjdp 2139218822Sdim /* Now wander though the raw linenumbers of the section. */ 2140218822Sdim /* If we have been called on this section before, and th. e offset we 214133965Sjdp want is further down then we can prime the lookup loop. */ 214233965Sjdp sec_data = coff_section_data (abfd, section); 214333965Sjdp if (sec_data != NULL 214433965Sjdp && sec_data->i > 0 214533965Sjdp && offset >= sec_data->offset) 214633965Sjdp { 214733965Sjdp i = sec_data->i; 214833965Sjdp *functionname_ptr = sec_data->function; 214933965Sjdp line_base = sec_data->line_base; 215033965Sjdp } 215133965Sjdp else 215233965Sjdp { 215333965Sjdp i = 0; 215433965Sjdp line_base = 0; 215533965Sjdp } 215633965Sjdp 215733965Sjdp if (section->lineno != NULL) 215833965Sjdp { 215960484Sobrien bfd_vma last_value = 0; 216060484Sobrien 216133965Sjdp l = §ion->lineno[i]; 216233965Sjdp 216333965Sjdp for (; i < section->lineno_count; i++) 216433965Sjdp { 216533965Sjdp if (l->line_number == 0) 216633965Sjdp { 2167218822Sdim /* Get the symbol this line number points at. */ 216833965Sjdp coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); 216933965Sjdp if (coff->symbol.value > offset) 217033965Sjdp break; 217133965Sjdp *functionname_ptr = coff->symbol.name; 217260484Sobrien last_value = coff->symbol.value; 217333965Sjdp if (coff->native) 217433965Sjdp { 217533965Sjdp combined_entry_type *s = coff->native; 217633965Sjdp s = s + 1 + s->u.syment.n_numaux; 217733965Sjdp 217833965Sjdp /* In XCOFF a debugging symbol can follow the 217933965Sjdp function symbol. */ 218033965Sjdp if (s->u.syment.n_scnum == N_DEBUG) 218133965Sjdp s = s + 1 + s->u.syment.n_numaux; 218233965Sjdp 218333965Sjdp /* S should now point to the .bf of the function. */ 218433965Sjdp if (s->u.syment.n_numaux) 218533965Sjdp { 218633965Sjdp /* The linenumber is stored in the auxent. */ 218733965Sjdp union internal_auxent *a = &((s + 1)->u.auxent); 218833965Sjdp line_base = a->x_sym.x_misc.x_lnsz.x_lnno; 218933965Sjdp *line_ptr = line_base; 219033965Sjdp } 219133965Sjdp } 219233965Sjdp } 219333965Sjdp else 219433965Sjdp { 219538889Sjdp if (l->u.offset > offset) 219633965Sjdp break; 219733965Sjdp *line_ptr = l->line_number + line_base - 1; 219833965Sjdp } 219933965Sjdp l++; 220033965Sjdp } 220160484Sobrien 220260484Sobrien /* If we fell off the end of the loop, then assume that this 220360484Sobrien symbol has no line number info. Otherwise, symbols with no 220460484Sobrien line number info get reported with the line number of the 220560484Sobrien last line of the last symbol which does have line number 220660484Sobrien info. We use 0x100 as a slop to account for cases where the 220760484Sobrien last line has executable code. */ 220860484Sobrien if (i >= section->lineno_count 220960484Sobrien && last_value != 0 221060484Sobrien && offset - last_value > 0x100) 221160484Sobrien { 221260484Sobrien *functionname_ptr = NULL; 221360484Sobrien *line_ptr = 0; 221460484Sobrien } 221533965Sjdp } 221633965Sjdp 221733965Sjdp /* Cache the results for the next call. */ 221833965Sjdp if (sec_data == NULL && section->owner == abfd) 221933965Sjdp { 222089857Sobrien amt = sizeof (struct coff_section_tdata); 2221218822Sdim section->used_by_bfd = bfd_zalloc (abfd, amt); 222233965Sjdp sec_data = (struct coff_section_tdata *) section->used_by_bfd; 222333965Sjdp } 222433965Sjdp if (sec_data != NULL) 222533965Sjdp { 222633965Sjdp sec_data->offset = offset; 222733965Sjdp sec_data->i = i; 222833965Sjdp sec_data->function = *functionname_ptr; 222933965Sjdp sec_data->line_base = line_base; 223033965Sjdp } 223133965Sjdp 2232130561Sobrien return TRUE; 223333965Sjdp} 223433965Sjdp 2235218822Sdimbfd_boolean 2236218822Sdimcoff_find_inliner_info (bfd *abfd, 2237218822Sdim const char **filename_ptr, 2238218822Sdim const char **functionname_ptr, 2239218822Sdim unsigned int *line_ptr) 2240218822Sdim{ 2241218822Sdim bfd_boolean found; 2242218822Sdim 2243218822Sdim found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr, 2244218822Sdim functionname_ptr, line_ptr, 2245218822Sdim &coff_data(abfd)->dwarf2_find_line_info); 2246218822Sdim return (found); 2247218822Sdim} 2248218822Sdim 224933965Sjdpint 2250218822Sdimcoff_sizeof_headers (bfd *abfd, struct bfd_link_info *info) 225133965Sjdp{ 225233965Sjdp size_t size; 225333965Sjdp 2254218822Sdim if (!info->relocatable) 2255218822Sdim size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); 225633965Sjdp else 2257218822Sdim size = bfd_coff_filhsz (abfd); 225833965Sjdp 225933965Sjdp size += abfd->section_count * bfd_coff_scnhsz (abfd); 226033965Sjdp return size; 226133965Sjdp} 226260484Sobrien 226360484Sobrien/* Change the class of a coff symbol held by BFD. */ 2264218822Sdim 2265130561Sobrienbfd_boolean 2266218822Sdimbfd_coff_set_symbol_class (bfd * abfd, 2267218822Sdim asymbol * symbol, 2268218822Sdim unsigned int class) 226960484Sobrien{ 227060484Sobrien coff_symbol_type * csym; 227160484Sobrien 227260484Sobrien csym = coff_symbol_from (abfd, symbol); 227360484Sobrien if (csym == NULL) 227460484Sobrien { 227560484Sobrien bfd_set_error (bfd_error_invalid_operation); 2276130561Sobrien return FALSE; 227760484Sobrien } 227860484Sobrien else if (csym->native == NULL) 227960484Sobrien { 228060484Sobrien /* This is an alien symbol which no native coff backend data. 228160484Sobrien We cheat here by creating a fake native entry for it and 228260484Sobrien then filling in the class. This code is based on that in 228360484Sobrien coff_write_alien_symbol(). */ 228477298Sobrien 228560484Sobrien combined_entry_type * native; 228689857Sobrien bfd_size_type amt = sizeof (* native); 228760484Sobrien 2288218822Sdim native = bfd_zalloc (abfd, amt); 228960484Sobrien if (native == NULL) 2290130561Sobrien return FALSE; 229160484Sobrien 229260484Sobrien native->u.syment.n_type = T_NULL; 229360484Sobrien native->u.syment.n_sclass = class; 229477298Sobrien 229560484Sobrien if (bfd_is_und_section (symbol->section)) 229660484Sobrien { 229760484Sobrien native->u.syment.n_scnum = N_UNDEF; 229860484Sobrien native->u.syment.n_value = symbol->value; 229960484Sobrien } 230060484Sobrien else if (bfd_is_com_section (symbol->section)) 230160484Sobrien { 230260484Sobrien native->u.syment.n_scnum = N_UNDEF; 230360484Sobrien native->u.syment.n_value = symbol->value; 230460484Sobrien } 230560484Sobrien else 230660484Sobrien { 230760484Sobrien native->u.syment.n_scnum = 230860484Sobrien symbol->section->output_section->target_index; 230960484Sobrien native->u.syment.n_value = (symbol->value 231060484Sobrien + symbol->section->output_offset); 231160484Sobrien if (! obj_pe (abfd)) 231260484Sobrien native->u.syment.n_value += symbol->section->output_section->vma; 231377298Sobrien 231489857Sobrien /* Copy the any flags from the file header into the symbol. 231560484Sobrien FIXME: Why? */ 231660484Sobrien native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags; 231760484Sobrien } 231877298Sobrien 231960484Sobrien csym->native = native; 232060484Sobrien } 232160484Sobrien else 2322218822Sdim csym->native->u.syment.n_sclass = class; 232377298Sobrien 2324130561Sobrien return TRUE; 232560484Sobrien} 2326218822Sdim 2327218822Sdimstruct coff_comdat_info * 2328218822Sdimbfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec) 2329218822Sdim{ 2330218822Sdim if (bfd_get_flavour (abfd) == bfd_target_coff_flavour 2331218822Sdim && coff_section_data (abfd, sec) != NULL) 2332218822Sdim return coff_section_data (abfd, sec)->comdat; 2333218822Sdim else 2334218822Sdim return NULL; 2335218822Sdim} 2336