133965Sjdp/* COFF specific linker code. 2218822Sdim Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 3218822Sdim 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 433965Sjdp Written by Ian Lance Taylor, Cygnus Support. 533965Sjdp 6130561Sobrien This file is part of BFD, the Binary File Descriptor library. 733965Sjdp 8130561Sobrien This program is free software; you can redistribute it and/or modify 9130561Sobrien it under the terms of the GNU General Public License as published by 10130561Sobrien the Free Software Foundation; either version 2 of the License, or 11130561Sobrien (at your option) any later version. 1233965Sjdp 13130561Sobrien This program is distributed in the hope that it will be useful, 14130561Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 15130561Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130561Sobrien GNU General Public License for more details. 1733965Sjdp 18130561Sobrien You should have received a copy of the GNU General Public License 19130561Sobrien along with this program; if not, write to the Free Software 20218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2133965Sjdp 2233965Sjdp/* This file contains the COFF backend linker code. */ 2333965Sjdp 24218822Sdim#include "sysdep.h" 2533965Sjdp#include "bfd.h" 2633965Sjdp#include "bfdlink.h" 2733965Sjdp#include "libbfd.h" 2833965Sjdp#include "coff/internal.h" 2933965Sjdp#include "libcoff.h" 30130561Sobrien#include "safe-ctype.h" 3133965Sjdp 32130561Sobrienstatic bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info); 33130561Sobrienstatic bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded); 34130561Sobrienstatic bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info); 3533965Sjdp 36130561Sobrien/* Return TRUE if SYM is a weak, external symbol. */ 3777298Sobrien#define IS_WEAK_EXTERNAL(abfd, sym) \ 3877298Sobrien ((sym).n_sclass == C_WEAKEXT \ 3977298Sobrien || (obj_pe (abfd) && (sym).n_sclass == C_NT_WEAK)) 4077298Sobrien 41130561Sobrien/* Return TRUE if SYM is an external symbol. */ 4277298Sobrien#define IS_EXTERNAL(abfd, sym) \ 4377298Sobrien ((sym).n_sclass == C_EXT || IS_WEAK_EXTERNAL (abfd, sym)) 4477298Sobrien 4560484Sobrien/* Define macros so that the ISFCN, et. al., macros work correctly. 4660484Sobrien These macros are defined in include/coff/internal.h in terms of 4760484Sobrien N_TMASK, etc. These definitions require a user to define local 4860484Sobrien variables with the appropriate names, and with values from the 4960484Sobrien coff_data (abfd) structure. */ 5060484Sobrien 5160484Sobrien#define N_TMASK n_tmask 5260484Sobrien#define N_BTSHFT n_btshft 5360484Sobrien#define N_BTMASK n_btmask 5460484Sobrien 5533965Sjdp/* Create an entry in a COFF linker hash table. */ 5633965Sjdp 5733965Sjdpstruct bfd_hash_entry * 58130561Sobrien_bfd_coff_link_hash_newfunc (struct bfd_hash_entry *entry, 59130561Sobrien struct bfd_hash_table *table, 60130561Sobrien const char *string) 6133965Sjdp{ 6233965Sjdp struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry; 6333965Sjdp 6433965Sjdp /* Allocate the structure if it has not already been allocated by a 6533965Sjdp subclass. */ 6633965Sjdp if (ret == (struct coff_link_hash_entry *) NULL) 6733965Sjdp ret = ((struct coff_link_hash_entry *) 6833965Sjdp bfd_hash_allocate (table, sizeof (struct coff_link_hash_entry))); 6933965Sjdp if (ret == (struct coff_link_hash_entry *) NULL) 7033965Sjdp return (struct bfd_hash_entry *) ret; 7133965Sjdp 7233965Sjdp /* Call the allocation method of the superclass. */ 7333965Sjdp ret = ((struct coff_link_hash_entry *) 7433965Sjdp _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, 7533965Sjdp table, string)); 7633965Sjdp if (ret != (struct coff_link_hash_entry *) NULL) 7733965Sjdp { 7833965Sjdp /* Set local fields. */ 7933965Sjdp ret->indx = -1; 8033965Sjdp ret->type = T_NULL; 8133965Sjdp ret->class = C_NULL; 8233965Sjdp ret->numaux = 0; 8333965Sjdp ret->auxbfd = NULL; 8433965Sjdp ret->aux = NULL; 8533965Sjdp } 8633965Sjdp 8733965Sjdp return (struct bfd_hash_entry *) ret; 8833965Sjdp} 8933965Sjdp 9033965Sjdp/* Initialize a COFF linker hash table. */ 9133965Sjdp 92130561Sobrienbfd_boolean 93130561Sobrien_bfd_coff_link_hash_table_init (struct coff_link_hash_table *table, 94130561Sobrien bfd *abfd, 95130561Sobrien struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, 96130561Sobrien struct bfd_hash_table *, 97218822Sdim const char *), 98218822Sdim unsigned int entsize) 9933965Sjdp{ 100218822Sdim memset (&table->stab_info, 0, sizeof (table->stab_info)); 101218822Sdim return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize); 10233965Sjdp} 10333965Sjdp 10433965Sjdp/* Create a COFF linker hash table. */ 10533965Sjdp 10633965Sjdpstruct bfd_link_hash_table * 107130561Sobrien_bfd_coff_link_hash_table_create (bfd *abfd) 10833965Sjdp{ 10933965Sjdp struct coff_link_hash_table *ret; 11089857Sobrien bfd_size_type amt = sizeof (struct coff_link_hash_table); 11133965Sjdp 112130561Sobrien ret = bfd_malloc (amt); 11333965Sjdp if (ret == NULL) 11433965Sjdp return NULL; 115130561Sobrien 11633965Sjdp if (! _bfd_coff_link_hash_table_init (ret, abfd, 117218822Sdim _bfd_coff_link_hash_newfunc, 118218822Sdim sizeof (struct coff_link_hash_entry))) 11933965Sjdp { 120104834Sobrien free (ret); 12133965Sjdp return (struct bfd_link_hash_table *) NULL; 12233965Sjdp } 12333965Sjdp return &ret->root; 12433965Sjdp} 12533965Sjdp 12633965Sjdp/* Create an entry in a COFF debug merge hash table. */ 12733965Sjdp 12833965Sjdpstruct bfd_hash_entry * 129130561Sobrien_bfd_coff_debug_merge_hash_newfunc (struct bfd_hash_entry *entry, 130130561Sobrien struct bfd_hash_table *table, 131130561Sobrien const char *string) 13233965Sjdp{ 13333965Sjdp struct coff_debug_merge_hash_entry *ret = 13433965Sjdp (struct coff_debug_merge_hash_entry *) entry; 13533965Sjdp 13633965Sjdp /* Allocate the structure if it has not already been allocated by a 13733965Sjdp subclass. */ 13833965Sjdp if (ret == (struct coff_debug_merge_hash_entry *) NULL) 13933965Sjdp ret = ((struct coff_debug_merge_hash_entry *) 14033965Sjdp bfd_hash_allocate (table, 14133965Sjdp sizeof (struct coff_debug_merge_hash_entry))); 14233965Sjdp if (ret == (struct coff_debug_merge_hash_entry *) NULL) 14333965Sjdp return (struct bfd_hash_entry *) ret; 14433965Sjdp 14533965Sjdp /* Call the allocation method of the superclass. */ 14633965Sjdp ret = ((struct coff_debug_merge_hash_entry *) 14733965Sjdp bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 14833965Sjdp if (ret != (struct coff_debug_merge_hash_entry *) NULL) 14933965Sjdp { 15033965Sjdp /* Set local fields. */ 15133965Sjdp ret->types = NULL; 15233965Sjdp } 15333965Sjdp 15433965Sjdp return (struct bfd_hash_entry *) ret; 15533965Sjdp} 15633965Sjdp 15733965Sjdp/* Given a COFF BFD, add symbols to the global hash table as 15833965Sjdp appropriate. */ 15933965Sjdp 160130561Sobrienbfd_boolean 161130561Sobrien_bfd_coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 16233965Sjdp{ 16333965Sjdp switch (bfd_get_format (abfd)) 16433965Sjdp { 16533965Sjdp case bfd_object: 16633965Sjdp return coff_link_add_object_symbols (abfd, info); 16733965Sjdp case bfd_archive: 168130561Sobrien return _bfd_generic_link_add_archive_symbols 169130561Sobrien (abfd, info, coff_link_check_archive_element); 17033965Sjdp default: 17133965Sjdp bfd_set_error (bfd_error_wrong_format); 172130561Sobrien return FALSE; 17333965Sjdp } 17433965Sjdp} 17533965Sjdp 17633965Sjdp/* Add symbols from a COFF object file. */ 17733965Sjdp 178130561Sobrienstatic bfd_boolean 179130561Sobriencoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) 18033965Sjdp{ 18133965Sjdp if (! _bfd_coff_get_external_symbols (abfd)) 182130561Sobrien return FALSE; 18333965Sjdp if (! coff_link_add_symbols (abfd, info)) 184130561Sobrien return FALSE; 18533965Sjdp 186130561Sobrien if (! info->keep_memory 187130561Sobrien && ! _bfd_coff_free_symbols (abfd)) 188130561Sobrien return FALSE; 18933965Sjdp 190130561Sobrien return TRUE; 19133965Sjdp} 19233965Sjdp 19333965Sjdp/* Look through the symbols to see if this object file should be 19433965Sjdp included in the link. */ 19533965Sjdp 196130561Sobrienstatic bfd_boolean 197130561Sobriencoff_link_check_ar_symbols (bfd *abfd, 198130561Sobrien struct bfd_link_info *info, 199130561Sobrien bfd_boolean *pneeded) 20033965Sjdp{ 20133965Sjdp bfd_size_type symesz; 20233965Sjdp bfd_byte *esym; 20333965Sjdp bfd_byte *esym_end; 20433965Sjdp 205130561Sobrien *pneeded = FALSE; 20633965Sjdp 20733965Sjdp symesz = bfd_coff_symesz (abfd); 20833965Sjdp esym = (bfd_byte *) obj_coff_external_syms (abfd); 20933965Sjdp esym_end = esym + obj_raw_syment_count (abfd) * symesz; 21033965Sjdp while (esym < esym_end) 21133965Sjdp { 21233965Sjdp struct internal_syment sym; 21360484Sobrien enum coff_symbol_classification classification; 21433965Sjdp 215130561Sobrien bfd_coff_swap_sym_in (abfd, esym, &sym); 21633965Sjdp 21760484Sobrien classification = bfd_coff_classify_symbol (abfd, &sym); 21860484Sobrien if (classification == COFF_SYMBOL_GLOBAL 21960484Sobrien || classification == COFF_SYMBOL_COMMON) 22033965Sjdp { 22133965Sjdp const char *name; 22233965Sjdp char buf[SYMNMLEN + 1]; 22333965Sjdp struct bfd_link_hash_entry *h; 22433965Sjdp 22533965Sjdp /* This symbol is externally visible, and is defined by this 22633965Sjdp object file. */ 22733965Sjdp name = _bfd_coff_internal_syment_name (abfd, &sym, buf); 22833965Sjdp if (name == NULL) 229130561Sobrien return FALSE; 230130561Sobrien h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); 23133965Sjdp 232130561Sobrien /* Auto import. */ 233130561Sobrien if (!h 234130561Sobrien && info->pei386_auto_import 235218822Sdim && CONST_STRNEQ (name, "__imp_")) 236130561Sobrien h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE); 237130561Sobrien 23833965Sjdp /* We are only interested in symbols that are currently 23933965Sjdp undefined. If a symbol is currently known to be common, 24033965Sjdp COFF linkers do not bring in an object file which defines 24133965Sjdp it. */ 24233965Sjdp if (h != (struct bfd_link_hash_entry *) NULL 24333965Sjdp && h->type == bfd_link_hash_undefined) 24433965Sjdp { 24533965Sjdp if (! (*info->callbacks->add_archive_element) (info, abfd, name)) 246130561Sobrien return FALSE; 247130561Sobrien *pneeded = TRUE; 248130561Sobrien return TRUE; 24933965Sjdp } 25033965Sjdp } 25133965Sjdp 25233965Sjdp esym += (sym.n_numaux + 1) * symesz; 25333965Sjdp } 25433965Sjdp 25533965Sjdp /* We do not need this object file. */ 256130561Sobrien return TRUE; 25733965Sjdp} 25833965Sjdp 259130561Sobrien/* Check a single archive element to see if we need to include it in 260130561Sobrien the link. *PNEEDED is set according to whether this element is 261130561Sobrien needed in the link or not. This is called via 262130561Sobrien _bfd_generic_link_add_archive_symbols. */ 263130561Sobrien 264130561Sobrienstatic bfd_boolean 265130561Sobriencoff_link_check_archive_element (bfd *abfd, 266130561Sobrien struct bfd_link_info *info, 267130561Sobrien bfd_boolean *pneeded) 268130561Sobrien{ 269130561Sobrien if (! _bfd_coff_get_external_symbols (abfd)) 270130561Sobrien return FALSE; 271130561Sobrien 272130561Sobrien if (! coff_link_check_ar_symbols (abfd, info, pneeded)) 273130561Sobrien return FALSE; 274130561Sobrien 275130561Sobrien if (*pneeded 276130561Sobrien && ! coff_link_add_symbols (abfd, info)) 277130561Sobrien return FALSE; 278130561Sobrien 279130561Sobrien if ((! info->keep_memory || ! *pneeded) 280130561Sobrien && ! _bfd_coff_free_symbols (abfd)) 281130561Sobrien return FALSE; 282130561Sobrien 283130561Sobrien return TRUE; 284130561Sobrien} 285130561Sobrien 28633965Sjdp/* Add all the symbols from an object file to the hash table. */ 28733965Sjdp 288130561Sobrienstatic bfd_boolean 289130561Sobriencoff_link_add_symbols (bfd *abfd, 290130561Sobrien struct bfd_link_info *info) 29133965Sjdp{ 29260484Sobrien unsigned int n_tmask = coff_data (abfd)->local_n_tmask; 29360484Sobrien unsigned int n_btshft = coff_data (abfd)->local_n_btshft; 29460484Sobrien unsigned int n_btmask = coff_data (abfd)->local_n_btmask; 295130561Sobrien bfd_boolean keep_syms; 296130561Sobrien bfd_boolean default_copy; 29733965Sjdp bfd_size_type symcount; 29833965Sjdp struct coff_link_hash_entry **sym_hash; 29933965Sjdp bfd_size_type symesz; 30033965Sjdp bfd_byte *esym; 30133965Sjdp bfd_byte *esym_end; 30289857Sobrien bfd_size_type amt; 30333965Sjdp 30433965Sjdp /* Keep the symbols during this function, in case the linker needs 30533965Sjdp to read the generic symbols in order to report an error message. */ 30633965Sjdp keep_syms = obj_coff_keep_syms (abfd); 307130561Sobrien obj_coff_keep_syms (abfd) = TRUE; 30833965Sjdp 30933965Sjdp if (info->keep_memory) 310130561Sobrien default_copy = FALSE; 31133965Sjdp else 312130561Sobrien default_copy = TRUE; 31333965Sjdp 31433965Sjdp symcount = obj_raw_syment_count (abfd); 31533965Sjdp 31633965Sjdp /* We keep a list of the linker hash table entries that correspond 31733965Sjdp to particular symbols. */ 31889857Sobrien amt = symcount * sizeof (struct coff_link_hash_entry *); 319130561Sobrien sym_hash = bfd_zalloc (abfd, amt); 32033965Sjdp if (sym_hash == NULL && symcount != 0) 32133965Sjdp goto error_return; 32233965Sjdp obj_coff_sym_hashes (abfd) = sym_hash; 32333965Sjdp 32433965Sjdp symesz = bfd_coff_symesz (abfd); 32533965Sjdp BFD_ASSERT (symesz == bfd_coff_auxesz (abfd)); 32633965Sjdp esym = (bfd_byte *) obj_coff_external_syms (abfd); 32733965Sjdp esym_end = esym + symcount * symesz; 32833965Sjdp while (esym < esym_end) 32933965Sjdp { 33033965Sjdp struct internal_syment sym; 33160484Sobrien enum coff_symbol_classification classification; 332130561Sobrien bfd_boolean copy; 33333965Sjdp 334130561Sobrien bfd_coff_swap_sym_in (abfd, esym, &sym); 33533965Sjdp 33660484Sobrien classification = bfd_coff_classify_symbol (abfd, &sym); 33760484Sobrien if (classification != COFF_SYMBOL_LOCAL) 33833965Sjdp { 33933965Sjdp const char *name; 34033965Sjdp char buf[SYMNMLEN + 1]; 34133965Sjdp flagword flags; 34233965Sjdp asection *section; 34333965Sjdp bfd_vma value; 344130561Sobrien bfd_boolean addit; 34533965Sjdp 34633965Sjdp /* This symbol is externally visible. */ 34733965Sjdp 34833965Sjdp name = _bfd_coff_internal_syment_name (abfd, &sym, buf); 34933965Sjdp if (name == NULL) 35033965Sjdp goto error_return; 35133965Sjdp 35233965Sjdp /* We must copy the name into memory if we got it from the 35333965Sjdp syment itself, rather than the string table. */ 35433965Sjdp copy = default_copy; 35533965Sjdp if (sym._n._n_n._n_zeroes != 0 35633965Sjdp || sym._n._n_n._n_offset == 0) 357130561Sobrien copy = TRUE; 35833965Sjdp 35933965Sjdp value = sym.n_value; 36033965Sjdp 36160484Sobrien switch (classification) 36233965Sjdp { 36360484Sobrien default: 36460484Sobrien abort (); 36560484Sobrien 36660484Sobrien case COFF_SYMBOL_GLOBAL: 36733965Sjdp flags = BSF_EXPORT | BSF_GLOBAL; 36833965Sjdp section = coff_section_from_bfd_index (abfd, sym.n_scnum); 36938889Sjdp if (! obj_pe (abfd)) 37038889Sjdp value -= section->vma; 37160484Sobrien break; 37260484Sobrien 37360484Sobrien case COFF_SYMBOL_UNDEFINED: 37460484Sobrien flags = 0; 37560484Sobrien section = bfd_und_section_ptr; 37660484Sobrien break; 37760484Sobrien 37860484Sobrien case COFF_SYMBOL_COMMON: 37960484Sobrien flags = BSF_GLOBAL; 38060484Sobrien section = bfd_com_section_ptr; 38160484Sobrien break; 38260484Sobrien 38360484Sobrien case COFF_SYMBOL_PE_SECTION: 38460484Sobrien flags = BSF_SECTION_SYM | BSF_GLOBAL; 38560484Sobrien section = coff_section_from_bfd_index (abfd, sym.n_scnum); 38660484Sobrien break; 38733965Sjdp } 38833965Sjdp 38977298Sobrien if (IS_WEAK_EXTERNAL (abfd, sym)) 39060484Sobrien flags = BSF_WEAK; 39133965Sjdp 392130561Sobrien addit = TRUE; 39360484Sobrien 39460484Sobrien /* In the PE format, section symbols actually refer to the 39560484Sobrien start of the output section. We handle them specially 39660484Sobrien here. */ 39760484Sobrien if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0) 39860484Sobrien { 39960484Sobrien *sym_hash = coff_link_hash_lookup (coff_hash_table (info), 400130561Sobrien name, FALSE, copy, FALSE); 40160484Sobrien if (*sym_hash != NULL) 40260484Sobrien { 40360484Sobrien if (((*sym_hash)->coff_link_hash_flags 40460484Sobrien & COFF_LINK_HASH_PE_SECTION_SYMBOL) == 0 40560484Sobrien && (*sym_hash)->root.type != bfd_link_hash_undefined 40660484Sobrien && (*sym_hash)->root.type != bfd_link_hash_undefweak) 40760484Sobrien (*_bfd_error_handler) 40860484Sobrien ("Warning: symbol `%s' is both section and non-section", 40960484Sobrien name); 41060484Sobrien 411130561Sobrien addit = FALSE; 41260484Sobrien } 41360484Sobrien } 41460484Sobrien 41560484Sobrien /* The Microsoft Visual C compiler does string pooling by 41660484Sobrien hashing the constants to an internal symbol name, and 41789857Sobrien relying on the linker comdat support to discard 41860484Sobrien duplicate names. However, if one string is a literal and 41960484Sobrien one is a data initializer, one will end up in the .data 42060484Sobrien section and one will end up in the .rdata section. The 42160484Sobrien Microsoft linker will combine them into the .data 42260484Sobrien section, which seems to be wrong since it might cause the 42360484Sobrien literal to change. 42460484Sobrien 42560484Sobrien As long as there are no external references to the 42660484Sobrien symbols, which there shouldn't be, we can treat the .data 42760484Sobrien and .rdata instances as separate symbols. The comdat 42860484Sobrien code in the linker will do the appropriate merging. Here 42960484Sobrien we avoid getting a multiple definition error for one of 43060484Sobrien these special symbols. 43160484Sobrien 43260484Sobrien FIXME: I don't think this will work in the case where 43360484Sobrien there are two object files which use the constants as a 43460484Sobrien literal and two object files which use it as a data 43560484Sobrien initializer. One or the other of the second object files 43660484Sobrien is going to wind up with an inappropriate reference. */ 43760484Sobrien if (obj_pe (abfd) 43860484Sobrien && (classification == COFF_SYMBOL_GLOBAL 43960484Sobrien || classification == COFF_SYMBOL_PE_SECTION) 440218822Sdim && coff_section_data (abfd, section) != NULL 441218822Sdim && coff_section_data (abfd, section)->comdat != NULL 442218822Sdim && CONST_STRNEQ (name, "??_") 443218822Sdim && strcmp (name, coff_section_data (abfd, section)->comdat->name) == 0) 44460484Sobrien { 44560484Sobrien if (*sym_hash == NULL) 44660484Sobrien *sym_hash = coff_link_hash_lookup (coff_hash_table (info), 447130561Sobrien name, FALSE, copy, FALSE); 44860484Sobrien if (*sym_hash != NULL 44960484Sobrien && (*sym_hash)->root.type == bfd_link_hash_defined 450218822Sdim && coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat != NULL 451218822Sdim && strcmp (coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat->name, 452218822Sdim coff_section_data (abfd, section)->comdat->name) == 0) 453130561Sobrien addit = FALSE; 45460484Sobrien } 45560484Sobrien 45660484Sobrien if (addit) 45760484Sobrien { 45860484Sobrien if (! (bfd_coff_link_add_one_symbol 45960484Sobrien (info, abfd, name, flags, section, value, 460130561Sobrien (const char *) NULL, copy, FALSE, 46160484Sobrien (struct bfd_link_hash_entry **) sym_hash))) 46260484Sobrien goto error_return; 46360484Sobrien } 46460484Sobrien 46560484Sobrien if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0) 46660484Sobrien (*sym_hash)->coff_link_hash_flags |= 46760484Sobrien COFF_LINK_HASH_PE_SECTION_SYMBOL; 46860484Sobrien 46960484Sobrien /* Limit the alignment of a common symbol to the possible 47060484Sobrien alignment of a section. There is no point to permitting 47160484Sobrien a higher alignment for a common symbol: we can not 47260484Sobrien guarantee it, and it may cause us to allocate extra space 47360484Sobrien in the common section. */ 47433965Sjdp if (section == bfd_com_section_ptr 47533965Sjdp && (*sym_hash)->root.type == bfd_link_hash_common 47633965Sjdp && ((*sym_hash)->root.u.c.p->alignment_power 47733965Sjdp > bfd_coff_default_section_alignment_power (abfd))) 47833965Sjdp (*sym_hash)->root.u.c.p->alignment_power 47933965Sjdp = bfd_coff_default_section_alignment_power (abfd); 48033965Sjdp 48133965Sjdp if (info->hash->creator->flavour == bfd_get_flavour (abfd)) 48233965Sjdp { 48360484Sobrien /* If we don't have any symbol information currently in 48460484Sobrien the hash table, or if we are looking at a symbol 48560484Sobrien definition, then update the symbol class and type in 48660484Sobrien the hash table. */ 48760484Sobrien if (((*sym_hash)->class == C_NULL 48860484Sobrien && (*sym_hash)->type == T_NULL) 48960484Sobrien || sym.n_scnum != 0 49060484Sobrien || (sym.n_value != 0 49160484Sobrien && (*sym_hash)->root.type != bfd_link_hash_defined 49260484Sobrien && (*sym_hash)->root.type != bfd_link_hash_defweak)) 49360484Sobrien { 49460484Sobrien (*sym_hash)->class = sym.n_sclass; 49560484Sobrien if (sym.n_type != T_NULL) 49660484Sobrien { 49760484Sobrien /* We want to warn if the type changed, but not 49860484Sobrien if it changed from an unspecified type. 49960484Sobrien Testing the whole type byte may work, but the 50060484Sobrien change from (e.g.) a function of unspecified 50160484Sobrien type to function of known type also wants to 50260484Sobrien skip the warning. */ 50360484Sobrien if ((*sym_hash)->type != T_NULL 50460484Sobrien && (*sym_hash)->type != sym.n_type 50560484Sobrien && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type) 50660484Sobrien && (BTYPE ((*sym_hash)->type) == T_NULL 50760484Sobrien || BTYPE (sym.n_type) == T_NULL))) 50860484Sobrien (*_bfd_error_handler) 509218822Sdim (_("Warning: type of symbol `%s' changed from %d to %d in %B"), 510218822Sdim abfd, name, (*sym_hash)->type, sym.n_type); 51160484Sobrien 51260484Sobrien /* We don't want to change from a meaningful 51360484Sobrien base type to a null one, but if we know 51460484Sobrien nothing, take what little we might now know. */ 51560484Sobrien if (BTYPE (sym.n_type) != T_NULL 51660484Sobrien || (*sym_hash)->type == T_NULL) 51760484Sobrien (*sym_hash)->type = sym.n_type; 51860484Sobrien } 51960484Sobrien (*sym_hash)->auxbfd = abfd; 52033965Sjdp if (sym.n_numaux != 0) 52133965Sjdp { 52233965Sjdp union internal_auxent *alloc; 52333965Sjdp unsigned int i; 52433965Sjdp bfd_byte *eaux; 52533965Sjdp union internal_auxent *iaux; 52633965Sjdp 52733965Sjdp (*sym_hash)->numaux = sym.n_numaux; 52833965Sjdp alloc = ((union internal_auxent *) 52933965Sjdp bfd_hash_allocate (&info->hash->table, 53033965Sjdp (sym.n_numaux 53133965Sjdp * sizeof (*alloc)))); 53233965Sjdp if (alloc == NULL) 53333965Sjdp goto error_return; 53433965Sjdp for (i = 0, eaux = esym + symesz, iaux = alloc; 53533965Sjdp i < sym.n_numaux; 53633965Sjdp i++, eaux += symesz, iaux++) 537130561Sobrien bfd_coff_swap_aux_in (abfd, eaux, sym.n_type, 53889857Sobrien sym.n_sclass, (int) i, 539130561Sobrien sym.n_numaux, iaux); 54033965Sjdp (*sym_hash)->aux = alloc; 54133965Sjdp } 54233965Sjdp } 54333965Sjdp } 54460484Sobrien 54560484Sobrien if (classification == COFF_SYMBOL_PE_SECTION 54660484Sobrien && (*sym_hash)->numaux != 0) 54760484Sobrien { 54860484Sobrien /* Some PE sections (such as .bss) have a zero size in 54960484Sobrien the section header, but a non-zero size in the AUX 55060484Sobrien record. Correct that here. 55160484Sobrien 55260484Sobrien FIXME: This is not at all the right place to do this. 55360484Sobrien For example, it won't help objdump. This needs to be 55460484Sobrien done when we swap in the section header. */ 55560484Sobrien BFD_ASSERT ((*sym_hash)->numaux == 1); 556218822Sdim if (section->size == 0) 557218822Sdim section->size = (*sym_hash)->aux[0].x_scn.x_scnlen; 55860484Sobrien 55960484Sobrien /* FIXME: We could test whether the section sizes 56060484Sobrien matches the size in the aux entry, but apparently 56160484Sobrien that sometimes fails unexpectedly. */ 56260484Sobrien } 56333965Sjdp } 56433965Sjdp 56533965Sjdp esym += (sym.n_numaux + 1) * symesz; 56633965Sjdp sym_hash += sym.n_numaux + 1; 56733965Sjdp } 56833965Sjdp 569130561Sobrien /* If this is a non-traditional, non-relocatable link, try to 57033965Sjdp optimize the handling of any .stab/.stabstr sections. */ 571130561Sobrien if (! info->relocatable 57233965Sjdp && ! info->traditional_format 57333965Sjdp && info->hash->creator->flavour == bfd_get_flavour (abfd) 57433965Sjdp && (info->strip != strip_all && info->strip != strip_debugger)) 57533965Sjdp { 576130561Sobrien asection *stabstr; 57733965Sjdp 578130561Sobrien stabstr = bfd_get_section_by_name (abfd, ".stabstr"); 579130561Sobrien 580130561Sobrien if (stabstr != NULL) 58133965Sjdp { 582130561Sobrien bfd_size_type string_offset = 0; 583130561Sobrien asection *stab; 584130561Sobrien 585130561Sobrien for (stab = abfd->sections; stab; stab = stab->next) 586218822Sdim if (CONST_STRNEQ (stab->name, ".stab") 587130561Sobrien && (!stab->name[5] 588130561Sobrien || (stab->name[5] == '.' && ISDIGIT (stab->name[6])))) 58933965Sjdp { 59033965Sjdp struct coff_link_hash_table *table; 591130561Sobrien struct coff_section_tdata *secdata 592130561Sobrien = coff_section_data (abfd, stab); 593130561Sobrien 59433965Sjdp if (secdata == NULL) 59533965Sjdp { 59689857Sobrien amt = sizeof (struct coff_section_tdata); 597130561Sobrien stab->used_by_bfd = bfd_zalloc (abfd, amt); 59833965Sjdp if (stab->used_by_bfd == NULL) 59933965Sjdp goto error_return; 60033965Sjdp secdata = coff_section_data (abfd, stab); 60133965Sjdp } 60233965Sjdp 60333965Sjdp table = coff_hash_table (info); 60433965Sjdp 60533965Sjdp if (! _bfd_link_section_stabs (abfd, &table->stab_info, 60633965Sjdp stab, stabstr, 607130561Sobrien &secdata->stab_info, 608130561Sobrien &string_offset)) 60933965Sjdp goto error_return; 61033965Sjdp } 61133965Sjdp } 61233965Sjdp } 61333965Sjdp 61433965Sjdp obj_coff_keep_syms (abfd) = keep_syms; 61533965Sjdp 616130561Sobrien return TRUE; 61733965Sjdp 61833965Sjdp error_return: 61933965Sjdp obj_coff_keep_syms (abfd) = keep_syms; 620130561Sobrien return FALSE; 62133965Sjdp} 62233965Sjdp 62333965Sjdp/* Do the final link step. */ 62433965Sjdp 625130561Sobrienbfd_boolean 626130561Sobrien_bfd_coff_final_link (bfd *abfd, 627130561Sobrien struct bfd_link_info *info) 62833965Sjdp{ 62933965Sjdp bfd_size_type symesz; 63033965Sjdp struct coff_final_link_info finfo; 631130561Sobrien bfd_boolean debug_merge_allocated; 632130561Sobrien bfd_boolean long_section_names; 63333965Sjdp asection *o; 63433965Sjdp struct bfd_link_order *p; 63589857Sobrien bfd_size_type max_sym_count; 63689857Sobrien bfd_size_type max_lineno_count; 63789857Sobrien bfd_size_type max_reloc_count; 63889857Sobrien bfd_size_type max_output_reloc_count; 63989857Sobrien bfd_size_type max_contents_size; 64033965Sjdp file_ptr rel_filepos; 64133965Sjdp unsigned int relsz; 64233965Sjdp file_ptr line_filepos; 64333965Sjdp unsigned int linesz; 64433965Sjdp bfd *sub; 64533965Sjdp bfd_byte *external_relocs = NULL; 64633965Sjdp char strbuf[STRING_SIZE_SIZE]; 64789857Sobrien bfd_size_type amt; 64833965Sjdp 64933965Sjdp symesz = bfd_coff_symesz (abfd); 65033965Sjdp 65133965Sjdp finfo.info = info; 65233965Sjdp finfo.output_bfd = abfd; 65333965Sjdp finfo.strtab = NULL; 65433965Sjdp finfo.section_info = NULL; 65533965Sjdp finfo.last_file_index = -1; 65633965Sjdp finfo.last_bf_index = -1; 65733965Sjdp finfo.internal_syms = NULL; 65833965Sjdp finfo.sec_ptrs = NULL; 65933965Sjdp finfo.sym_indices = NULL; 66033965Sjdp finfo.outsyms = NULL; 66133965Sjdp finfo.linenos = NULL; 66233965Sjdp finfo.contents = NULL; 66333965Sjdp finfo.external_relocs = NULL; 66433965Sjdp finfo.internal_relocs = NULL; 665130561Sobrien finfo.global_to_static = FALSE; 666130561Sobrien debug_merge_allocated = FALSE; 66733965Sjdp 66833965Sjdp coff_data (abfd)->link_info = info; 66933965Sjdp 67033965Sjdp finfo.strtab = _bfd_stringtab_init (); 67133965Sjdp if (finfo.strtab == NULL) 67233965Sjdp goto error_return; 67333965Sjdp 67433965Sjdp if (! coff_debug_merge_hash_table_init (&finfo.debug_merge)) 67533965Sjdp goto error_return; 676130561Sobrien debug_merge_allocated = TRUE; 67733965Sjdp 67833965Sjdp /* Compute the file positions for all the sections. */ 67933965Sjdp if (! abfd->output_has_begun) 68033965Sjdp { 68133965Sjdp if (! bfd_coff_compute_section_file_positions (abfd)) 68233965Sjdp goto error_return; 68333965Sjdp } 68433965Sjdp 68533965Sjdp /* Count the line numbers and relocation entries required for the 68633965Sjdp output file. Set the file positions for the relocs. */ 68733965Sjdp rel_filepos = obj_relocbase (abfd); 68833965Sjdp relsz = bfd_coff_relsz (abfd); 68933965Sjdp max_contents_size = 0; 69033965Sjdp max_lineno_count = 0; 69133965Sjdp max_reloc_count = 0; 69233965Sjdp 693130561Sobrien long_section_names = FALSE; 69433965Sjdp for (o = abfd->sections; o != NULL; o = o->next) 69533965Sjdp { 69633965Sjdp o->reloc_count = 0; 69733965Sjdp o->lineno_count = 0; 698218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 69933965Sjdp { 70033965Sjdp if (p->type == bfd_indirect_link_order) 70133965Sjdp { 70233965Sjdp asection *sec; 70333965Sjdp 70433965Sjdp sec = p->u.indirect.section; 70533965Sjdp 70633965Sjdp /* Mark all sections which are to be included in the 70733965Sjdp link. This will normally be every section. We need 70833965Sjdp to do this so that we can identify any sections which 70933965Sjdp the linker has decided to not include. */ 710130561Sobrien sec->linker_mark = TRUE; 71133965Sjdp 71233965Sjdp if (info->strip == strip_none 71333965Sjdp || info->strip == strip_some) 71433965Sjdp o->lineno_count += sec->lineno_count; 71533965Sjdp 716130561Sobrien if (info->relocatable) 71733965Sjdp o->reloc_count += sec->reloc_count; 71833965Sjdp 719218822Sdim if (sec->rawsize > max_contents_size) 720218822Sdim max_contents_size = sec->rawsize; 721218822Sdim if (sec->size > max_contents_size) 722218822Sdim max_contents_size = sec->size; 72333965Sjdp if (sec->lineno_count > max_lineno_count) 72433965Sjdp max_lineno_count = sec->lineno_count; 72533965Sjdp if (sec->reloc_count > max_reloc_count) 72633965Sjdp max_reloc_count = sec->reloc_count; 72733965Sjdp } 728130561Sobrien else if (info->relocatable 72933965Sjdp && (p->type == bfd_section_reloc_link_order 73033965Sjdp || p->type == bfd_symbol_reloc_link_order)) 73133965Sjdp ++o->reloc_count; 73233965Sjdp } 73333965Sjdp if (o->reloc_count == 0) 73433965Sjdp o->rel_filepos = 0; 73533965Sjdp else 73633965Sjdp { 73733965Sjdp o->flags |= SEC_RELOC; 73833965Sjdp o->rel_filepos = rel_filepos; 73933965Sjdp rel_filepos += o->reloc_count * relsz; 740104834Sobrien /* In PE COFF, if there are at least 0xffff relocations an 741104834Sobrien extra relocation will be written out to encode the count. */ 742104834Sobrien if (obj_pe (abfd) && o->reloc_count >= 0xffff) 743104834Sobrien rel_filepos += relsz; 74433965Sjdp } 74533965Sjdp 74633965Sjdp if (bfd_coff_long_section_names (abfd) 74733965Sjdp && strlen (o->name) > SCNNMLEN) 74833965Sjdp { 74933965Sjdp /* This section has a long name which must go in the string 75033965Sjdp table. This must correspond to the code in 75133965Sjdp coff_write_object_contents which puts the string index 75233965Sjdp into the s_name field of the section header. That is why 753130561Sobrien we pass hash as FALSE. */ 754130561Sobrien if (_bfd_stringtab_add (finfo.strtab, o->name, FALSE, FALSE) 75533965Sjdp == (bfd_size_type) -1) 75633965Sjdp goto error_return; 757130561Sobrien long_section_names = TRUE; 75833965Sjdp } 75933965Sjdp } 76033965Sjdp 761130561Sobrien /* If doing a relocatable link, allocate space for the pointers we 76233965Sjdp need to keep. */ 763130561Sobrien if (info->relocatable) 76433965Sjdp { 76533965Sjdp unsigned int i; 76633965Sjdp 76733965Sjdp /* We use section_count + 1, rather than section_count, because 76833965Sjdp the target_index fields are 1 based. */ 76989857Sobrien amt = abfd->section_count + 1; 77089857Sobrien amt *= sizeof (struct coff_link_section_info); 771130561Sobrien finfo.section_info = bfd_malloc (amt); 77233965Sjdp if (finfo.section_info == NULL) 77333965Sjdp goto error_return; 77433965Sjdp for (i = 0; i <= abfd->section_count; i++) 77533965Sjdp { 77633965Sjdp finfo.section_info[i].relocs = NULL; 77733965Sjdp finfo.section_info[i].rel_hashes = NULL; 77833965Sjdp } 77933965Sjdp } 78033965Sjdp 78133965Sjdp /* We now know the size of the relocs, so we can determine the file 78233965Sjdp positions of the line numbers. */ 78333965Sjdp line_filepos = rel_filepos; 78433965Sjdp linesz = bfd_coff_linesz (abfd); 78533965Sjdp max_output_reloc_count = 0; 78633965Sjdp for (o = abfd->sections; o != NULL; o = o->next) 78733965Sjdp { 78833965Sjdp if (o->lineno_count == 0) 78933965Sjdp o->line_filepos = 0; 79033965Sjdp else 79133965Sjdp { 79233965Sjdp o->line_filepos = line_filepos; 79333965Sjdp line_filepos += o->lineno_count * linesz; 79433965Sjdp } 79533965Sjdp 79633965Sjdp if (o->reloc_count != 0) 79733965Sjdp { 79833965Sjdp /* We don't know the indices of global symbols until we have 79933965Sjdp written out all the local symbols. For each section in 80033965Sjdp the output file, we keep an array of pointers to hash 80133965Sjdp table entries. Each entry in the array corresponds to a 80233965Sjdp reloc. When we find a reloc against a global symbol, we 80333965Sjdp set the corresponding entry in this array so that we can 80433965Sjdp fix up the symbol index after we have written out all the 80533965Sjdp local symbols. 80633965Sjdp 80733965Sjdp Because of this problem, we also keep the relocs in 80833965Sjdp memory until the end of the link. This wastes memory, 809130561Sobrien but only when doing a relocatable link, which is not the 81033965Sjdp common case. */ 811130561Sobrien BFD_ASSERT (info->relocatable); 81289857Sobrien amt = o->reloc_count; 81389857Sobrien amt *= sizeof (struct internal_reloc); 814130561Sobrien finfo.section_info[o->target_index].relocs = bfd_malloc (amt); 81589857Sobrien amt = o->reloc_count; 81689857Sobrien amt *= sizeof (struct coff_link_hash_entry *); 817130561Sobrien finfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt); 81833965Sjdp if (finfo.section_info[o->target_index].relocs == NULL 81933965Sjdp || finfo.section_info[o->target_index].rel_hashes == NULL) 82033965Sjdp goto error_return; 82133965Sjdp 82233965Sjdp if (o->reloc_count > max_output_reloc_count) 82333965Sjdp max_output_reloc_count = o->reloc_count; 82433965Sjdp } 82533965Sjdp 82633965Sjdp /* Reset the reloc and lineno counts, so that we can use them to 82733965Sjdp count the number of entries we have output so far. */ 82833965Sjdp o->reloc_count = 0; 82933965Sjdp o->lineno_count = 0; 83033965Sjdp } 83133965Sjdp 83233965Sjdp obj_sym_filepos (abfd) = line_filepos; 83333965Sjdp 83433965Sjdp /* Figure out the largest number of symbols in an input BFD. Take 83533965Sjdp the opportunity to clear the output_has_begun fields of all the 83633965Sjdp input BFD's. */ 83733965Sjdp max_sym_count = 0; 83833965Sjdp for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 83933965Sjdp { 84033965Sjdp size_t sz; 84133965Sjdp 842130561Sobrien sub->output_has_begun = FALSE; 84333965Sjdp sz = obj_raw_syment_count (sub); 84433965Sjdp if (sz > max_sym_count) 84533965Sjdp max_sym_count = sz; 84633965Sjdp } 84733965Sjdp 84833965Sjdp /* Allocate some buffers used while linking. */ 84989857Sobrien amt = max_sym_count * sizeof (struct internal_syment); 850130561Sobrien finfo.internal_syms = bfd_malloc (amt); 85189857Sobrien amt = max_sym_count * sizeof (asection *); 852130561Sobrien finfo.sec_ptrs = bfd_malloc (amt); 85389857Sobrien amt = max_sym_count * sizeof (long); 854130561Sobrien finfo.sym_indices = bfd_malloc (amt); 855130561Sobrien finfo.outsyms = bfd_malloc ((max_sym_count + 1) * symesz); 85689857Sobrien amt = max_lineno_count * bfd_coff_linesz (abfd); 857130561Sobrien finfo.linenos = bfd_malloc (amt); 858130561Sobrien finfo.contents = bfd_malloc (max_contents_size); 85989857Sobrien amt = max_reloc_count * relsz; 860130561Sobrien finfo.external_relocs = bfd_malloc (amt); 861130561Sobrien if (! info->relocatable) 86289857Sobrien { 86389857Sobrien amt = max_reloc_count * sizeof (struct internal_reloc); 864130561Sobrien finfo.internal_relocs = bfd_malloc (amt); 86589857Sobrien } 86633965Sjdp if ((finfo.internal_syms == NULL && max_sym_count > 0) 86733965Sjdp || (finfo.sec_ptrs == NULL && max_sym_count > 0) 86833965Sjdp || (finfo.sym_indices == NULL && max_sym_count > 0) 86933965Sjdp || finfo.outsyms == NULL 87033965Sjdp || (finfo.linenos == NULL && max_lineno_count > 0) 87133965Sjdp || (finfo.contents == NULL && max_contents_size > 0) 87233965Sjdp || (finfo.external_relocs == NULL && max_reloc_count > 0) 873130561Sobrien || (! info->relocatable 87433965Sjdp && finfo.internal_relocs == NULL 87533965Sjdp && max_reloc_count > 0)) 87633965Sjdp goto error_return; 87733965Sjdp 87833965Sjdp /* We now know the position of everything in the file, except that 87933965Sjdp we don't know the size of the symbol table and therefore we don't 88033965Sjdp know where the string table starts. We just build the string 88133965Sjdp table in memory as we go along. We process all the relocations 88233965Sjdp for a single input file at once. */ 88333965Sjdp obj_raw_syment_count (abfd) = 0; 88433965Sjdp 88533965Sjdp if (coff_backend_info (abfd)->_bfd_coff_start_final_link) 88633965Sjdp { 88733965Sjdp if (! bfd_coff_start_final_link (abfd, info)) 88833965Sjdp goto error_return; 88933965Sjdp } 89033965Sjdp 89133965Sjdp for (o = abfd->sections; o != NULL; o = o->next) 89233965Sjdp { 893218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 89433965Sjdp { 89533965Sjdp if (p->type == bfd_indirect_link_order 89677298Sobrien && bfd_family_coff (p->u.indirect.section->owner)) 89733965Sjdp { 89833965Sjdp sub = p->u.indirect.section->owner; 89960484Sobrien if (! bfd_coff_link_output_has_begun (sub, & finfo)) 90033965Sjdp { 90133965Sjdp if (! _bfd_coff_link_input_bfd (&finfo, sub)) 90233965Sjdp goto error_return; 903130561Sobrien sub->output_has_begun = TRUE; 90433965Sjdp } 90533965Sjdp } 90633965Sjdp else if (p->type == bfd_section_reloc_link_order 90733965Sjdp || p->type == bfd_symbol_reloc_link_order) 90833965Sjdp { 90933965Sjdp if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p)) 91033965Sjdp goto error_return; 91133965Sjdp } 91233965Sjdp else 91333965Sjdp { 91433965Sjdp if (! _bfd_default_link_order (abfd, info, o, p)) 91533965Sjdp goto error_return; 91633965Sjdp } 91733965Sjdp } 91833965Sjdp } 91933965Sjdp 92038889Sjdp if (! bfd_coff_final_link_postscript (abfd, & finfo)) 92138889Sjdp goto error_return; 92277298Sobrien 92333965Sjdp /* Free up the buffers used by _bfd_coff_link_input_bfd. */ 92433965Sjdp 92533965Sjdp coff_debug_merge_hash_table_free (&finfo.debug_merge); 926130561Sobrien debug_merge_allocated = FALSE; 92733965Sjdp 92833965Sjdp if (finfo.internal_syms != NULL) 92933965Sjdp { 93033965Sjdp free (finfo.internal_syms); 93133965Sjdp finfo.internal_syms = NULL; 93233965Sjdp } 93333965Sjdp if (finfo.sec_ptrs != NULL) 93433965Sjdp { 93533965Sjdp free (finfo.sec_ptrs); 93633965Sjdp finfo.sec_ptrs = NULL; 93733965Sjdp } 93833965Sjdp if (finfo.sym_indices != NULL) 93933965Sjdp { 94033965Sjdp free (finfo.sym_indices); 94133965Sjdp finfo.sym_indices = NULL; 94233965Sjdp } 94333965Sjdp if (finfo.linenos != NULL) 94433965Sjdp { 94533965Sjdp free (finfo.linenos); 94633965Sjdp finfo.linenos = NULL; 94733965Sjdp } 94833965Sjdp if (finfo.contents != NULL) 94933965Sjdp { 95033965Sjdp free (finfo.contents); 95133965Sjdp finfo.contents = NULL; 95233965Sjdp } 95333965Sjdp if (finfo.external_relocs != NULL) 95433965Sjdp { 95533965Sjdp free (finfo.external_relocs); 95633965Sjdp finfo.external_relocs = NULL; 95733965Sjdp } 95833965Sjdp if (finfo.internal_relocs != NULL) 95933965Sjdp { 96033965Sjdp free (finfo.internal_relocs); 96133965Sjdp finfo.internal_relocs = NULL; 96233965Sjdp } 96333965Sjdp 96433965Sjdp /* The value of the last C_FILE symbol is supposed to be the symbol 96533965Sjdp index of the first external symbol. Write it out again if 96633965Sjdp necessary. */ 96733965Sjdp if (finfo.last_file_index != -1 96833965Sjdp && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd)) 96933965Sjdp { 97089857Sobrien file_ptr pos; 97189857Sobrien 97233965Sjdp finfo.last_file.n_value = obj_raw_syment_count (abfd); 973130561Sobrien bfd_coff_swap_sym_out (abfd, &finfo.last_file, 974130561Sobrien finfo.outsyms); 97589857Sobrien 97689857Sobrien pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz; 97789857Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0 97889857Sobrien || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz) 979130561Sobrien return FALSE; 98033965Sjdp } 98133965Sjdp 98238889Sjdp /* If doing task linking (ld --task-link) then make a pass through the 98338889Sjdp global symbols, writing out any that are defined, and making them 98477298Sobrien static. */ 98538889Sjdp if (info->task_link) 98638889Sjdp { 987130561Sobrien finfo.failed = FALSE; 98894536Sobrien coff_link_hash_traverse (coff_hash_table (info), 989130561Sobrien _bfd_coff_write_task_globals, &finfo); 99038889Sjdp if (finfo.failed) 99138889Sjdp goto error_return; 99238889Sjdp } 99338889Sjdp 99433965Sjdp /* Write out the global symbols. */ 995130561Sobrien finfo.failed = FALSE; 99694536Sobrien coff_link_hash_traverse (coff_hash_table (info), 997130561Sobrien _bfd_coff_write_global_sym, &finfo); 99833965Sjdp if (finfo.failed) 99933965Sjdp goto error_return; 100033965Sjdp 100133965Sjdp /* The outsyms buffer is used by _bfd_coff_write_global_sym. */ 100233965Sjdp if (finfo.outsyms != NULL) 100333965Sjdp { 100433965Sjdp free (finfo.outsyms); 100533965Sjdp finfo.outsyms = NULL; 100633965Sjdp } 100733965Sjdp 1008130561Sobrien if (info->relocatable && max_output_reloc_count > 0) 100933965Sjdp { 101033965Sjdp /* Now that we have written out all the global symbols, we know 101133965Sjdp the symbol indices to use for relocs against them, and we can 101233965Sjdp finally write out the relocs. */ 101389857Sobrien amt = max_output_reloc_count * relsz; 1014130561Sobrien external_relocs = bfd_malloc (amt); 101533965Sjdp if (external_relocs == NULL) 101633965Sjdp goto error_return; 101733965Sjdp 101833965Sjdp for (o = abfd->sections; o != NULL; o = o->next) 101933965Sjdp { 102033965Sjdp struct internal_reloc *irel; 102133965Sjdp struct internal_reloc *irelend; 102233965Sjdp struct coff_link_hash_entry **rel_hash; 102333965Sjdp bfd_byte *erel; 102433965Sjdp 102533965Sjdp if (o->reloc_count == 0) 102633965Sjdp continue; 102733965Sjdp 102833965Sjdp irel = finfo.section_info[o->target_index].relocs; 102933965Sjdp irelend = irel + o->reloc_count; 103033965Sjdp rel_hash = finfo.section_info[o->target_index].rel_hashes; 103133965Sjdp erel = external_relocs; 103233965Sjdp for (; irel < irelend; irel++, rel_hash++, erel += relsz) 103333965Sjdp { 103433965Sjdp if (*rel_hash != NULL) 103533965Sjdp { 103633965Sjdp BFD_ASSERT ((*rel_hash)->indx >= 0); 103733965Sjdp irel->r_symndx = (*rel_hash)->indx; 103833965Sjdp } 1039130561Sobrien bfd_coff_swap_reloc_out (abfd, irel, erel); 104033965Sjdp } 104133965Sjdp 1042130561Sobrien if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0) 104333965Sjdp goto error_return; 1044130561Sobrien if (obj_pe (abfd) && o->reloc_count >= 0xffff) 1045130561Sobrien { 1046130561Sobrien /* In PE COFF, write the count of relocs as the first 1047130561Sobrien reloc. The header overflow bit will be set 1048130561Sobrien elsewhere. */ 1049130561Sobrien struct internal_reloc incount; 1050130561Sobrien bfd_byte *excount = (bfd_byte *)bfd_malloc (relsz); 1051130561Sobrien 1052130561Sobrien memset (&incount, 0, sizeof (incount)); 1053130561Sobrien incount.r_vaddr = o->reloc_count + 1; 1054130561Sobrien bfd_coff_swap_reloc_out (abfd, (PTR) &incount, (PTR) excount); 1055130561Sobrien if (bfd_bwrite (excount, relsz, abfd) != relsz) 1056130561Sobrien /* We'll leak, but it's an error anyway. */ 1057130561Sobrien goto error_return; 1058130561Sobrien free (excount); 1059130561Sobrien } 1060130561Sobrien if (bfd_bwrite (external_relocs, 1061130561Sobrien (bfd_size_type) relsz * o->reloc_count, abfd) 1062130561Sobrien != (bfd_size_type) relsz * o->reloc_count) 1063130561Sobrien goto error_return; 106433965Sjdp } 106533965Sjdp 106633965Sjdp free (external_relocs); 106733965Sjdp external_relocs = NULL; 106833965Sjdp } 106933965Sjdp 107033965Sjdp /* Free up the section information. */ 107133965Sjdp if (finfo.section_info != NULL) 107233965Sjdp { 107333965Sjdp unsigned int i; 107433965Sjdp 107533965Sjdp for (i = 0; i < abfd->section_count; i++) 107633965Sjdp { 107733965Sjdp if (finfo.section_info[i].relocs != NULL) 107833965Sjdp free (finfo.section_info[i].relocs); 107933965Sjdp if (finfo.section_info[i].rel_hashes != NULL) 108033965Sjdp free (finfo.section_info[i].rel_hashes); 108133965Sjdp } 108233965Sjdp free (finfo.section_info); 108333965Sjdp finfo.section_info = NULL; 108433965Sjdp } 108533965Sjdp 108633965Sjdp /* If we have optimized stabs strings, output them. */ 1087218822Sdim if (coff_hash_table (info)->stab_info.stabstr != NULL) 108833965Sjdp { 108933965Sjdp if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info)) 1090130561Sobrien return FALSE; 109133965Sjdp } 109233965Sjdp 109333965Sjdp /* Write out the string table. */ 109433965Sjdp if (obj_raw_syment_count (abfd) != 0 || long_section_names) 109533965Sjdp { 109689857Sobrien file_ptr pos; 109789857Sobrien 109889857Sobrien pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz; 109989857Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0) 1100130561Sobrien return FALSE; 110133965Sjdp 110233965Sjdp#if STRING_SIZE_SIZE == 4 110389857Sobrien H_PUT_32 (abfd, 110489857Sobrien _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, 110589857Sobrien strbuf); 110633965Sjdp#else 110789857Sobrien #error Change H_PUT_32 above 110833965Sjdp#endif 110933965Sjdp 111089857Sobrien if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd) 111189857Sobrien != STRING_SIZE_SIZE) 1112130561Sobrien return FALSE; 111333965Sjdp 111433965Sjdp if (! _bfd_stringtab_emit (abfd, finfo.strtab)) 1115130561Sobrien return FALSE; 111677298Sobrien 1117130561Sobrien obj_coff_strings_written (abfd) = TRUE; 111833965Sjdp } 111933965Sjdp 112033965Sjdp _bfd_stringtab_free (finfo.strtab); 112133965Sjdp 112233965Sjdp /* Setting bfd_get_symcount to 0 will cause write_object_contents to 112333965Sjdp not try to write out the symbols. */ 112433965Sjdp bfd_get_symcount (abfd) = 0; 112533965Sjdp 1126130561Sobrien return TRUE; 112733965Sjdp 112833965Sjdp error_return: 112933965Sjdp if (debug_merge_allocated) 113033965Sjdp coff_debug_merge_hash_table_free (&finfo.debug_merge); 113133965Sjdp if (finfo.strtab != NULL) 113233965Sjdp _bfd_stringtab_free (finfo.strtab); 113333965Sjdp if (finfo.section_info != NULL) 113433965Sjdp { 113533965Sjdp unsigned int i; 113633965Sjdp 113733965Sjdp for (i = 0; i < abfd->section_count; i++) 113833965Sjdp { 113933965Sjdp if (finfo.section_info[i].relocs != NULL) 114033965Sjdp free (finfo.section_info[i].relocs); 114133965Sjdp if (finfo.section_info[i].rel_hashes != NULL) 114233965Sjdp free (finfo.section_info[i].rel_hashes); 114333965Sjdp } 114433965Sjdp free (finfo.section_info); 114533965Sjdp } 114633965Sjdp if (finfo.internal_syms != NULL) 114733965Sjdp free (finfo.internal_syms); 114833965Sjdp if (finfo.sec_ptrs != NULL) 114933965Sjdp free (finfo.sec_ptrs); 115033965Sjdp if (finfo.sym_indices != NULL) 115133965Sjdp free (finfo.sym_indices); 115233965Sjdp if (finfo.outsyms != NULL) 115333965Sjdp free (finfo.outsyms); 115433965Sjdp if (finfo.linenos != NULL) 115533965Sjdp free (finfo.linenos); 115633965Sjdp if (finfo.contents != NULL) 115733965Sjdp free (finfo.contents); 115833965Sjdp if (finfo.external_relocs != NULL) 115933965Sjdp free (finfo.external_relocs); 116033965Sjdp if (finfo.internal_relocs != NULL) 116133965Sjdp free (finfo.internal_relocs); 116233965Sjdp if (external_relocs != NULL) 116333965Sjdp free (external_relocs); 1164130561Sobrien return FALSE; 116533965Sjdp} 116633965Sjdp 1167130561Sobrien/* Parse out a -heap <reserved>,<commit> line. */ 116833965Sjdp 116933965Sjdpstatic char * 1170130561Sobriendores_com (char *ptr, bfd *output_bfd, int heap) 117133965Sjdp{ 117277298Sobrien if (coff_data(output_bfd)->pe) 117333965Sjdp { 117433965Sjdp int val = strtoul (ptr, &ptr, 0); 1175130561Sobrien 117633965Sjdp if (heap) 117789857Sobrien pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve = val; 117833965Sjdp else 117989857Sobrien pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve = val; 118033965Sjdp 118177298Sobrien if (ptr[0] == ',') 118233965Sjdp { 118389857Sobrien val = strtoul (ptr+1, &ptr, 0); 118433965Sjdp if (heap) 118589857Sobrien pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit = val; 118633965Sjdp else 118789857Sobrien pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit = val; 118833965Sjdp } 118933965Sjdp } 119033965Sjdp return ptr; 119133965Sjdp} 119233965Sjdp 1193130561Sobrienstatic char * 1194130561Sobrienget_name (char *ptr, char **dst) 119533965Sjdp{ 119633965Sjdp while (*ptr == ' ') 119733965Sjdp ptr++; 119833965Sjdp *dst = ptr; 119933965Sjdp while (*ptr && *ptr != ' ') 120033965Sjdp ptr++; 120133965Sjdp *ptr = 0; 120233965Sjdp return ptr+1; 120333965Sjdp} 120433965Sjdp 1205130561Sobrien/* Process any magic embedded commands in a section called .drectve. */ 120677298Sobrien 120733965Sjdpstatic int 1208130561Sobrienprocess_embedded_commands (bfd *output_bfd, 1209130561Sobrien struct bfd_link_info *info ATTRIBUTE_UNUSED, 1210130561Sobrien bfd *abfd) 121133965Sjdp{ 121233965Sjdp asection *sec = bfd_get_section_by_name (abfd, ".drectve"); 121333965Sjdp char *s; 121433965Sjdp char *e; 1215218822Sdim bfd_byte *copy; 1216130561Sobrien 121777298Sobrien if (!sec) 121833965Sjdp return 1; 121977298Sobrien 1220218822Sdim if (!bfd_malloc_and_get_section (abfd, sec, ©)) 122133965Sjdp { 1222218822Sdim if (copy != NULL) 1223218822Sdim free (copy); 122433965Sjdp return 0; 122533965Sjdp } 1226218822Sdim e = (char *) copy + sec->size; 1227130561Sobrien 1228218822Sdim for (s = (char *) copy; s < e ; ) 122933965Sjdp { 1230218822Sdim if (s[0] != '-') 1231130561Sobrien { 1232130561Sobrien s++; 1233130561Sobrien continue; 1234130561Sobrien } 1235218822Sdim if (CONST_STRNEQ (s, "-attr")) 123633965Sjdp { 123733965Sjdp char *name; 123833965Sjdp char *attribs; 123933965Sjdp asection *asec; 124033965Sjdp int loop = 1; 124133965Sjdp int had_write = 0; 124233965Sjdp int had_exec= 0; 1243130561Sobrien 124433965Sjdp s += 5; 1245130561Sobrien s = get_name (s, &name); 1246130561Sobrien s = get_name (s, &attribs); 1247130561Sobrien 1248130561Sobrien while (loop) 1249130561Sobrien { 1250130561Sobrien switch (*attribs++) 1251130561Sobrien { 1252130561Sobrien case 'W': 1253130561Sobrien had_write = 1; 1254130561Sobrien break; 1255130561Sobrien case 'R': 1256130561Sobrien break; 1257130561Sobrien case 'S': 1258130561Sobrien break; 1259130561Sobrien case 'X': 1260130561Sobrien had_exec = 1; 1261130561Sobrien break; 1262130561Sobrien default: 1263130561Sobrien loop = 0; 1264130561Sobrien } 1265130561Sobrien } 126633965Sjdp asec = bfd_get_section_by_name (abfd, name); 1267130561Sobrien if (asec) 1268130561Sobrien { 1269130561Sobrien if (had_exec) 1270130561Sobrien asec->flags |= SEC_CODE; 1271130561Sobrien if (!had_write) 1272130561Sobrien asec->flags |= SEC_READONLY; 1273130561Sobrien } 127433965Sjdp } 1275218822Sdim else if (CONST_STRNEQ (s, "-heap")) 1276218822Sdim s = dores_com (s + 5, output_bfd, 1); 1277130561Sobrien 1278218822Sdim else if (CONST_STRNEQ (s, "-stack")) 1279218822Sdim s = dores_com (s + 6, output_bfd, 0); 1280130561Sobrien 128177298Sobrien else 128233965Sjdp s++; 128333965Sjdp } 128433965Sjdp free (copy); 128533965Sjdp return 1; 128633965Sjdp} 128733965Sjdp 128838889Sjdp/* Place a marker against all symbols which are used by relocations. 128938889Sjdp This marker can be picked up by the 'do we skip this symbol ?' 129038889Sjdp loop in _bfd_coff_link_input_bfd() and used to prevent skipping 1291130561Sobrien that symbol. */ 129238889Sjdp 129338889Sjdpstatic void 1294130561Sobrienmark_relocs (struct coff_final_link_info *finfo, bfd *input_bfd) 129538889Sjdp{ 129638889Sjdp asection * a; 129738889Sjdp 129838889Sjdp if ((bfd_get_file_flags (input_bfd) & HAS_SYMS) == 0) 129938889Sjdp return; 130077298Sobrien 130138889Sjdp for (a = input_bfd->sections; a != (asection *) NULL; a = a->next) 130238889Sjdp { 130338889Sjdp struct internal_reloc * internal_relocs; 130438889Sjdp struct internal_reloc * irel; 130538889Sjdp struct internal_reloc * irelend; 130638889Sjdp 130738889Sjdp if ((a->flags & SEC_RELOC) == 0 || a->reloc_count < 1) 130838889Sjdp continue; 1309107492Sobrien /* Don't mark relocs in excluded sections. */ 1310107492Sobrien if (a->output_section == bfd_abs_section_ptr) 1311107492Sobrien continue; 131238889Sjdp 131338889Sjdp /* Read in the relocs. */ 131438889Sjdp internal_relocs = _bfd_coff_read_internal_relocs 1315130561Sobrien (input_bfd, a, FALSE, 131638889Sjdp finfo->external_relocs, 1317130561Sobrien finfo->info->relocatable, 1318130561Sobrien (finfo->info->relocatable 131938889Sjdp ? (finfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count) 132038889Sjdp : finfo->internal_relocs) 132138889Sjdp ); 132277298Sobrien 132338889Sjdp if (internal_relocs == NULL) 132438889Sjdp continue; 132538889Sjdp 132638889Sjdp irel = internal_relocs; 132738889Sjdp irelend = irel + a->reloc_count; 132838889Sjdp 132938889Sjdp /* Place a mark in the sym_indices array (whose entries have 133038889Sjdp been initialised to 0) for all of the symbols that are used 133138889Sjdp in the relocation table. This will then be picked up in the 1332130561Sobrien skip/don't-skip pass. */ 133338889Sjdp for (; irel < irelend; irel++) 1334130561Sobrien finfo->sym_indices[ irel->r_symndx ] = -1; 133538889Sjdp } 133638889Sjdp} 133738889Sjdp 133833965Sjdp/* Link an input file into the linker output file. This function 133933965Sjdp handles all the sections and relocations of the input file at once. */ 134033965Sjdp 1341130561Sobrienbfd_boolean 1342130561Sobrien_bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd) 134333965Sjdp{ 134460484Sobrien unsigned int n_tmask = coff_data (input_bfd)->local_n_tmask; 134560484Sobrien unsigned int n_btshft = coff_data (input_bfd)->local_n_btshft; 1346130561Sobrien bfd_boolean (*adjust_symndx) 1347130561Sobrien (bfd *, struct bfd_link_info *, bfd *, asection *, 1348130561Sobrien struct internal_reloc *, bfd_boolean *); 134933965Sjdp bfd *output_bfd; 135033965Sjdp const char *strings; 135133965Sjdp bfd_size_type syment_base; 1352130561Sobrien bfd_boolean copy, hash; 135333965Sjdp bfd_size_type isymesz; 135433965Sjdp bfd_size_type osymesz; 135533965Sjdp bfd_size_type linesz; 135633965Sjdp bfd_byte *esym; 135733965Sjdp bfd_byte *esym_end; 135833965Sjdp struct internal_syment *isymp; 135933965Sjdp asection **secpp; 136033965Sjdp long *indexp; 136133965Sjdp unsigned long output_index; 136233965Sjdp bfd_byte *outsym; 136333965Sjdp struct coff_link_hash_entry **sym_hash; 136433965Sjdp asection *o; 136533965Sjdp 136633965Sjdp /* Move all the symbols to the output file. */ 136733965Sjdp 136833965Sjdp output_bfd = finfo->output_bfd; 136933965Sjdp strings = NULL; 137033965Sjdp syment_base = obj_raw_syment_count (output_bfd); 137133965Sjdp isymesz = bfd_coff_symesz (input_bfd); 137233965Sjdp osymesz = bfd_coff_symesz (output_bfd); 137333965Sjdp linesz = bfd_coff_linesz (input_bfd); 137433965Sjdp BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd)); 137533965Sjdp 1376130561Sobrien copy = FALSE; 137733965Sjdp if (! finfo->info->keep_memory) 1378130561Sobrien copy = TRUE; 1379130561Sobrien hash = TRUE; 138033965Sjdp if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) 1381130561Sobrien hash = FALSE; 138233965Sjdp 138333965Sjdp if (! _bfd_coff_get_external_symbols (input_bfd)) 1384130561Sobrien return FALSE; 138533965Sjdp 138633965Sjdp esym = (bfd_byte *) obj_coff_external_syms (input_bfd); 138733965Sjdp esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; 138833965Sjdp isymp = finfo->internal_syms; 138933965Sjdp secpp = finfo->sec_ptrs; 139033965Sjdp indexp = finfo->sym_indices; 139133965Sjdp output_index = syment_base; 139233965Sjdp outsym = finfo->outsyms; 139333965Sjdp 1394130561Sobrien if (coff_data (output_bfd)->pe 1395130561Sobrien && ! process_embedded_commands (output_bfd, finfo->info, input_bfd)) 1396130561Sobrien return FALSE; 139733965Sjdp 1398130561Sobrien /* If we are going to perform relocations and also strip/discard some 1399130561Sobrien symbols then we must make sure that we do not strip/discard those 1400130561Sobrien symbols that are going to be involved in the relocations. */ 140138889Sjdp if (( finfo->info->strip != strip_none 140238889Sjdp || finfo->info->discard != discard_none) 1403130561Sobrien && finfo->info->relocatable) 140438889Sjdp { 1405130561Sobrien /* Mark the symbol array as 'not-used'. */ 140677298Sobrien memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp); 140777298Sobrien 140838889Sjdp mark_relocs (finfo, input_bfd); 140938889Sjdp } 141038889Sjdp 141133965Sjdp while (esym < esym_end) 141233965Sjdp { 141333965Sjdp struct internal_syment isym; 141460484Sobrien enum coff_symbol_classification classification; 1415130561Sobrien bfd_boolean skip; 1416130561Sobrien bfd_boolean global; 1417130561Sobrien bfd_boolean dont_skip_symbol; 141833965Sjdp int add; 141933965Sjdp 1420130561Sobrien bfd_coff_swap_sym_in (input_bfd, esym, isymp); 142133965Sjdp 142233965Sjdp /* Make a copy of *isymp so that the relocate_section function 142333965Sjdp always sees the original values. This is more reliable than 142433965Sjdp always recomputing the symbol value even if we are stripping 142533965Sjdp the symbol. */ 142633965Sjdp isym = *isymp; 142733965Sjdp 142860484Sobrien classification = bfd_coff_classify_symbol (input_bfd, &isym); 142960484Sobrien switch (classification) 143033965Sjdp { 143160484Sobrien default: 143260484Sobrien abort (); 143360484Sobrien case COFF_SYMBOL_GLOBAL: 143460484Sobrien case COFF_SYMBOL_PE_SECTION: 143560484Sobrien case COFF_SYMBOL_LOCAL: 143660484Sobrien *secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum); 143760484Sobrien break; 143860484Sobrien case COFF_SYMBOL_COMMON: 143960484Sobrien *secpp = bfd_com_section_ptr; 144060484Sobrien break; 144160484Sobrien case COFF_SYMBOL_UNDEFINED: 144260484Sobrien *secpp = bfd_und_section_ptr; 144360484Sobrien break; 144433965Sjdp } 144533965Sjdp 144638889Sjdp /* Extract the flag indicating if this symbol is used by a 144738889Sjdp relocation. */ 144838889Sjdp if ((finfo->info->strip != strip_none 144938889Sjdp || finfo->info->discard != discard_none) 1450130561Sobrien && finfo->info->relocatable) 145138889Sjdp dont_skip_symbol = *indexp; 145238889Sjdp else 1453130561Sobrien dont_skip_symbol = FALSE; 145477298Sobrien 145533965Sjdp *indexp = -1; 145633965Sjdp 1457130561Sobrien skip = FALSE; 1458130561Sobrien global = FALSE; 145933965Sjdp add = 1 + isym.n_numaux; 146033965Sjdp 146133965Sjdp /* If we are stripping all symbols, we want to skip this one. */ 146238889Sjdp if (finfo->info->strip == strip_all && ! dont_skip_symbol) 1463130561Sobrien skip = TRUE; 146433965Sjdp 146533965Sjdp if (! skip) 146633965Sjdp { 146760484Sobrien switch (classification) 146833965Sjdp { 146960484Sobrien default: 147060484Sobrien abort (); 147160484Sobrien case COFF_SYMBOL_GLOBAL: 147260484Sobrien case COFF_SYMBOL_COMMON: 147360484Sobrien case COFF_SYMBOL_PE_SECTION: 147433965Sjdp /* This is a global symbol. Global symbols come at the 147533965Sjdp end of the symbol table, so skip them for now. 147660484Sobrien Locally defined function symbols, however, are an 147760484Sobrien exception, and are not moved to the end. */ 1478130561Sobrien global = TRUE; 147933965Sjdp if (! ISFCN (isym.n_type)) 1480130561Sobrien skip = TRUE; 148160484Sobrien break; 148260484Sobrien 148360484Sobrien case COFF_SYMBOL_UNDEFINED: 148460484Sobrien /* Undefined symbols are left for the end. */ 1485130561Sobrien global = TRUE; 1486130561Sobrien skip = TRUE; 148760484Sobrien break; 148860484Sobrien 148960484Sobrien case COFF_SYMBOL_LOCAL: 149033965Sjdp /* This is a local symbol. Skip it if we are discarding 149133965Sjdp local symbols. */ 149238889Sjdp if (finfo->info->discard == discard_all && ! dont_skip_symbol) 1493130561Sobrien skip = TRUE; 149460484Sobrien break; 149533965Sjdp } 149633965Sjdp } 149733965Sjdp 149889857Sobrien#ifndef COFF_WITH_PE 149989857Sobrien /* Skip section symbols for sections which are not going to be 150089857Sobrien emitted. */ 150189857Sobrien if (!skip 1502130561Sobrien && dont_skip_symbol == 0 150389857Sobrien && isym.n_sclass == C_STAT 150489857Sobrien && isym.n_type == T_NULL 1505130561Sobrien && isym.n_numaux > 0 1506130561Sobrien && (*secpp)->output_section == bfd_abs_section_ptr) 1507130561Sobrien skip = TRUE; 150889857Sobrien#endif 150989857Sobrien 151033965Sjdp /* If we stripping debugging symbols, and this is a debugging 151138889Sjdp symbol, then skip it. FIXME: gas sets the section to N_ABS 151238889Sjdp for some types of debugging symbols; I don't know if this is 151338889Sjdp a bug or not. In any case, we handle it here. */ 151433965Sjdp if (! skip 151533965Sjdp && finfo->info->strip == strip_debugger 151638889Sjdp && ! dont_skip_symbol 151738889Sjdp && (isym.n_scnum == N_DEBUG 151838889Sjdp || (isym.n_scnum == N_ABS 151938889Sjdp && (isym.n_sclass == C_AUTO 152038889Sjdp || isym.n_sclass == C_REG 152138889Sjdp || isym.n_sclass == C_MOS 152238889Sjdp || isym.n_sclass == C_MOE 152338889Sjdp || isym.n_sclass == C_MOU 152438889Sjdp || isym.n_sclass == C_ARG 152538889Sjdp || isym.n_sclass == C_REGPARM 152638889Sjdp || isym.n_sclass == C_FIELD 152738889Sjdp || isym.n_sclass == C_EOS)))) 1528130561Sobrien skip = TRUE; 152933965Sjdp 153033965Sjdp /* If some symbols are stripped based on the name, work out the 153133965Sjdp name and decide whether to skip this symbol. */ 153233965Sjdp if (! skip 153333965Sjdp && (finfo->info->strip == strip_some 153433965Sjdp || finfo->info->discard == discard_l)) 153533965Sjdp { 153633965Sjdp const char *name; 153733965Sjdp char buf[SYMNMLEN + 1]; 153833965Sjdp 153933965Sjdp name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); 154033965Sjdp if (name == NULL) 1541130561Sobrien return FALSE; 154233965Sjdp 154338889Sjdp if (! dont_skip_symbol 154438889Sjdp && ((finfo->info->strip == strip_some 1545130561Sobrien && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, 1546130561Sobrien FALSE) == NULL)) 154738889Sjdp || (! global 154838889Sjdp && finfo->info->discard == discard_l 154938889Sjdp && bfd_is_local_label_name (input_bfd, name)))) 1550130561Sobrien skip = TRUE; 155133965Sjdp } 155233965Sjdp 155333965Sjdp /* If this is an enum, struct, or union tag, see if we have 155433965Sjdp already output an identical type. */ 155533965Sjdp if (! skip 155633965Sjdp && (finfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0 155733965Sjdp && (isym.n_sclass == C_ENTAG 155833965Sjdp || isym.n_sclass == C_STRTAG 155933965Sjdp || isym.n_sclass == C_UNTAG) 156033965Sjdp && isym.n_numaux == 1) 156133965Sjdp { 156233965Sjdp const char *name; 156333965Sjdp char buf[SYMNMLEN + 1]; 156433965Sjdp struct coff_debug_merge_hash_entry *mh; 156533965Sjdp struct coff_debug_merge_type *mt; 156633965Sjdp union internal_auxent aux; 156733965Sjdp struct coff_debug_merge_element **epp; 156833965Sjdp bfd_byte *esl, *eslend; 156933965Sjdp struct internal_syment *islp; 157089857Sobrien bfd_size_type amt; 157133965Sjdp 157233965Sjdp name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); 157333965Sjdp if (name == NULL) 1574130561Sobrien return FALSE; 157533965Sjdp 157633965Sjdp /* Ignore fake names invented by compiler; treat them all as 157733965Sjdp the same name. */ 157833965Sjdp if (*name == '~' || *name == '.' || *name == '$' 157933965Sjdp || (*name == bfd_get_symbol_leading_char (input_bfd) 158033965Sjdp && (name[1] == '~' || name[1] == '.' || name[1] == '$'))) 158133965Sjdp name = ""; 158233965Sjdp 158333965Sjdp mh = coff_debug_merge_hash_lookup (&finfo->debug_merge, name, 1584130561Sobrien TRUE, TRUE); 158533965Sjdp if (mh == NULL) 1586130561Sobrien return FALSE; 158733965Sjdp 158833965Sjdp /* Allocate memory to hold type information. If this turns 158933965Sjdp out to be a duplicate, we pass this address to 159033965Sjdp bfd_release. */ 159189857Sobrien amt = sizeof (struct coff_debug_merge_type); 1592130561Sobrien mt = bfd_alloc (input_bfd, amt); 159333965Sjdp if (mt == NULL) 1594130561Sobrien return FALSE; 159533965Sjdp mt->class = isym.n_sclass; 159633965Sjdp 159733965Sjdp /* Pick up the aux entry, which points to the end of the tag 159833965Sjdp entries. */ 1599130561Sobrien bfd_coff_swap_aux_in (input_bfd, (esym + isymesz), 160033965Sjdp isym.n_type, isym.n_sclass, 0, isym.n_numaux, 1601130561Sobrien &aux); 160233965Sjdp 160333965Sjdp /* Gather the elements. */ 160433965Sjdp epp = &mt->elements; 160533965Sjdp mt->elements = NULL; 160633965Sjdp islp = isymp + 2; 160733965Sjdp esl = esym + 2 * isymesz; 160833965Sjdp eslend = ((bfd_byte *) obj_coff_external_syms (input_bfd) 160933965Sjdp + aux.x_sym.x_fcnary.x_fcn.x_endndx.l * isymesz); 161033965Sjdp while (esl < eslend) 161133965Sjdp { 161233965Sjdp const char *elename; 161333965Sjdp char elebuf[SYMNMLEN + 1]; 161460484Sobrien char *name_copy; 161533965Sjdp 1616130561Sobrien bfd_coff_swap_sym_in (input_bfd, esl, islp); 161733965Sjdp 161889857Sobrien amt = sizeof (struct coff_debug_merge_element); 1619130561Sobrien *epp = bfd_alloc (input_bfd, amt); 162033965Sjdp if (*epp == NULL) 1621130561Sobrien return FALSE; 162233965Sjdp 162333965Sjdp elename = _bfd_coff_internal_syment_name (input_bfd, islp, 162433965Sjdp elebuf); 162533965Sjdp if (elename == NULL) 1626130561Sobrien return FALSE; 162733965Sjdp 162889857Sobrien amt = strlen (elename) + 1; 1629130561Sobrien name_copy = bfd_alloc (input_bfd, amt); 163060484Sobrien if (name_copy == NULL) 1631130561Sobrien return FALSE; 163260484Sobrien strcpy (name_copy, elename); 163333965Sjdp 163460484Sobrien (*epp)->name = name_copy; 163533965Sjdp (*epp)->type = islp->n_type; 163633965Sjdp (*epp)->tagndx = 0; 163733965Sjdp if (islp->n_numaux >= 1 163833965Sjdp && islp->n_type != T_NULL 163933965Sjdp && islp->n_sclass != C_EOS) 164033965Sjdp { 164133965Sjdp union internal_auxent eleaux; 164233965Sjdp long indx; 164333965Sjdp 1644130561Sobrien bfd_coff_swap_aux_in (input_bfd, (esl + isymesz), 164533965Sjdp islp->n_type, islp->n_sclass, 0, 1646130561Sobrien islp->n_numaux, &eleaux); 164733965Sjdp indx = eleaux.x_sym.x_tagndx.l; 164833965Sjdp 164933965Sjdp /* FIXME: If this tagndx entry refers to a symbol 165033965Sjdp defined later in this file, we just ignore it. 165133965Sjdp Handling this correctly would be tedious, and may 165233965Sjdp not be required. */ 165333965Sjdp if (indx > 0 165433965Sjdp && (indx 165533965Sjdp < ((esym - 165633965Sjdp (bfd_byte *) obj_coff_external_syms (input_bfd)) 165733965Sjdp / (long) isymesz))) 165833965Sjdp { 165933965Sjdp (*epp)->tagndx = finfo->sym_indices[indx]; 166033965Sjdp if ((*epp)->tagndx < 0) 166133965Sjdp (*epp)->tagndx = 0; 166233965Sjdp } 166333965Sjdp } 166433965Sjdp epp = &(*epp)->next; 166533965Sjdp *epp = NULL; 166633965Sjdp 166733965Sjdp esl += (islp->n_numaux + 1) * isymesz; 166833965Sjdp islp += islp->n_numaux + 1; 166933965Sjdp } 167033965Sjdp 167133965Sjdp /* See if we already have a definition which matches this 167233965Sjdp type. We always output the type if it has no elements, 167333965Sjdp for simplicity. */ 167433965Sjdp if (mt->elements == NULL) 1675130561Sobrien bfd_release (input_bfd, mt); 167633965Sjdp else 167733965Sjdp { 167833965Sjdp struct coff_debug_merge_type *mtl; 167933965Sjdp 168033965Sjdp for (mtl = mh->types; mtl != NULL; mtl = mtl->next) 168133965Sjdp { 168233965Sjdp struct coff_debug_merge_element *me, *mel; 168333965Sjdp 168433965Sjdp if (mtl->class != mt->class) 168533965Sjdp continue; 168633965Sjdp 168733965Sjdp for (me = mt->elements, mel = mtl->elements; 168833965Sjdp me != NULL && mel != NULL; 168933965Sjdp me = me->next, mel = mel->next) 169033965Sjdp { 169133965Sjdp if (strcmp (me->name, mel->name) != 0 169233965Sjdp || me->type != mel->type 169333965Sjdp || me->tagndx != mel->tagndx) 169433965Sjdp break; 169533965Sjdp } 169633965Sjdp 169733965Sjdp if (me == NULL && mel == NULL) 169833965Sjdp break; 169933965Sjdp } 170033965Sjdp 170133965Sjdp if (mtl == NULL || (bfd_size_type) mtl->indx >= syment_base) 170233965Sjdp { 170333965Sjdp /* This is the first definition of this type. */ 170433965Sjdp mt->indx = output_index; 170533965Sjdp mt->next = mh->types; 170633965Sjdp mh->types = mt; 170733965Sjdp } 170833965Sjdp else 170933965Sjdp { 171033965Sjdp /* This is a redefinition which can be merged. */ 1711130561Sobrien bfd_release (input_bfd, mt); 171233965Sjdp *indexp = mtl->indx; 171333965Sjdp add = (eslend - esym) / isymesz; 1714130561Sobrien skip = TRUE; 171533965Sjdp } 171633965Sjdp } 171733965Sjdp } 171833965Sjdp 171933965Sjdp /* We now know whether we are to skip this symbol or not. */ 172033965Sjdp if (! skip) 172133965Sjdp { 172233965Sjdp /* Adjust the symbol in order to output it. */ 172333965Sjdp 172433965Sjdp if (isym._n._n_n._n_zeroes == 0 172533965Sjdp && isym._n._n_n._n_offset != 0) 172633965Sjdp { 172733965Sjdp const char *name; 172833965Sjdp bfd_size_type indx; 172933965Sjdp 173033965Sjdp /* This symbol has a long name. Enter it in the string 173133965Sjdp table we are building. Note that we do not check 173233965Sjdp bfd_coff_symname_in_debug. That is only true for 173333965Sjdp XCOFF, and XCOFF requires different linking code 173433965Sjdp anyhow. */ 1735130561Sobrien name = _bfd_coff_internal_syment_name (input_bfd, &isym, NULL); 173633965Sjdp if (name == NULL) 1737130561Sobrien return FALSE; 173833965Sjdp indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy); 173933965Sjdp if (indx == (bfd_size_type) -1) 1740130561Sobrien return FALSE; 174133965Sjdp isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; 174233965Sjdp } 174333965Sjdp 174460484Sobrien switch (isym.n_sclass) 174533965Sjdp { 174660484Sobrien case C_AUTO: 174760484Sobrien case C_MOS: 174860484Sobrien case C_EOS: 174960484Sobrien case C_MOE: 175060484Sobrien case C_MOU: 175160484Sobrien case C_UNTAG: 175260484Sobrien case C_STRTAG: 175360484Sobrien case C_ENTAG: 175460484Sobrien case C_TPDEF: 175560484Sobrien case C_ARG: 175660484Sobrien case C_USTATIC: 175760484Sobrien case C_REG: 175860484Sobrien case C_REGPARM: 175960484Sobrien case C_FIELD: 176060484Sobrien /* The symbol value should not be modified. */ 176160484Sobrien break; 176233965Sjdp 176360484Sobrien case C_FCN: 176460484Sobrien if (obj_pe (input_bfd) 176560484Sobrien && strcmp (isym.n_name, ".bf") != 0 176660484Sobrien && isym.n_scnum > 0) 176760484Sobrien { 176860484Sobrien /* For PE, .lf and .ef get their value left alone, 176960484Sobrien while .bf gets relocated. However, they all have 177060484Sobrien "real" section numbers, and need to be moved into 177160484Sobrien the new section. */ 177260484Sobrien isym.n_scnum = (*secpp)->output_section->target_index; 177360484Sobrien break; 177460484Sobrien } 177560484Sobrien /* Fall through. */ 177660484Sobrien default: 177760484Sobrien case C_LABEL: /* Not completely sure about these 2 */ 177860484Sobrien case C_EXTDEF: 177960484Sobrien case C_BLOCK: 178060484Sobrien case C_EFCN: 178160484Sobrien case C_NULL: 178260484Sobrien case C_EXT: 178360484Sobrien case C_STAT: 178460484Sobrien case C_SECTION: 178560484Sobrien case C_NT_WEAK: 178660484Sobrien /* Compute new symbol location. */ 178760484Sobrien if (isym.n_scnum > 0) 178860484Sobrien { 178960484Sobrien isym.n_scnum = (*secpp)->output_section->target_index; 179060484Sobrien isym.n_value += (*secpp)->output_offset; 179160484Sobrien if (! obj_pe (input_bfd)) 179260484Sobrien isym.n_value -= (*secpp)->vma; 179360484Sobrien if (! obj_pe (finfo->output_bfd)) 179460484Sobrien isym.n_value += (*secpp)->output_section->vma; 179560484Sobrien } 179660484Sobrien break; 179760484Sobrien 179860484Sobrien case C_FILE: 179960484Sobrien /* The value of a C_FILE symbol is the symbol index of 180060484Sobrien the next C_FILE symbol. The value of the last C_FILE 180160484Sobrien symbol is the symbol index to the first external 180260484Sobrien symbol (actually, coff_renumber_symbols does not get 180360484Sobrien this right--it just sets the value of the last C_FILE 180460484Sobrien symbol to zero--and nobody has ever complained about 180560484Sobrien it). We try to get this right, below, just before we 180660484Sobrien write the symbols out, but in the general case we may 180760484Sobrien have to write the symbol out twice. */ 180833965Sjdp if (finfo->last_file_index != -1 180989857Sobrien && finfo->last_file.n_value != (bfd_vma) output_index) 181033965Sjdp { 181160484Sobrien /* We must correct the value of the last C_FILE 181260484Sobrien entry. */ 181333965Sjdp finfo->last_file.n_value = output_index; 181433965Sjdp if ((bfd_size_type) finfo->last_file_index >= syment_base) 181533965Sjdp { 181633965Sjdp /* The last C_FILE symbol is in this input file. */ 181733965Sjdp bfd_coff_swap_sym_out (output_bfd, 1818130561Sobrien &finfo->last_file, 1819130561Sobrien (finfo->outsyms 1820130561Sobrien + ((finfo->last_file_index 1821130561Sobrien - syment_base) 1822130561Sobrien * osymesz))); 182333965Sjdp } 182433965Sjdp else 182533965Sjdp { 182689857Sobrien file_ptr pos; 182789857Sobrien 182833965Sjdp /* We have already written out the last C_FILE 182933965Sjdp symbol. We need to write it out again. We 183033965Sjdp borrow *outsym temporarily. */ 183133965Sjdp bfd_coff_swap_sym_out (output_bfd, 1832130561Sobrien &finfo->last_file, outsym); 183389857Sobrien pos = obj_sym_filepos (output_bfd); 183489857Sobrien pos += finfo->last_file_index * osymesz; 183589857Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 183689857Sobrien || bfd_bwrite (outsym, osymesz, output_bfd) != osymesz) 1837130561Sobrien return FALSE; 183833965Sjdp } 183933965Sjdp } 184033965Sjdp 184133965Sjdp finfo->last_file_index = output_index; 184233965Sjdp finfo->last_file = isym; 184360484Sobrien break; 184433965Sjdp } 184533965Sjdp 184638889Sjdp /* If doing task linking, convert normal global function symbols to 184777298Sobrien static functions. */ 184877298Sobrien if (finfo->info->task_link && IS_EXTERNAL (input_bfd, isym)) 184938889Sjdp isym.n_sclass = C_STAT; 185038889Sjdp 185133965Sjdp /* Output the symbol. */ 1852130561Sobrien bfd_coff_swap_sym_out (output_bfd, &isym, outsym); 185333965Sjdp 185433965Sjdp *indexp = output_index; 185533965Sjdp 185633965Sjdp if (global) 185733965Sjdp { 185833965Sjdp long indx; 185933965Sjdp struct coff_link_hash_entry *h; 186033965Sjdp 186133965Sjdp indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd)) 186233965Sjdp / isymesz); 186333965Sjdp h = obj_coff_sym_hashes (input_bfd)[indx]; 186433965Sjdp if (h == NULL) 186533965Sjdp { 186633965Sjdp /* This can happen if there were errors earlier in 186733965Sjdp the link. */ 186833965Sjdp bfd_set_error (bfd_error_bad_value); 1869130561Sobrien return FALSE; 187033965Sjdp } 187133965Sjdp h->indx = output_index; 187233965Sjdp } 187333965Sjdp 187433965Sjdp output_index += add; 187533965Sjdp outsym += add * osymesz; 187633965Sjdp } 187733965Sjdp 187833965Sjdp esym += add * isymesz; 187933965Sjdp isymp += add; 188033965Sjdp ++secpp; 188133965Sjdp ++indexp; 188233965Sjdp for (--add; add > 0; --add) 188333965Sjdp { 188433965Sjdp *secpp++ = NULL; 188533965Sjdp *indexp++ = -1; 188633965Sjdp } 188733965Sjdp } 188833965Sjdp 188933965Sjdp /* Fix up the aux entries. This must be done in a separate pass, 189033965Sjdp because we don't know the correct symbol indices until we have 189133965Sjdp already decided which symbols we are going to keep. */ 189233965Sjdp esym = (bfd_byte *) obj_coff_external_syms (input_bfd); 189333965Sjdp esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; 189433965Sjdp isymp = finfo->internal_syms; 189533965Sjdp indexp = finfo->sym_indices; 189633965Sjdp sym_hash = obj_coff_sym_hashes (input_bfd); 189733965Sjdp outsym = finfo->outsyms; 1898130561Sobrien 189933965Sjdp while (esym < esym_end) 190033965Sjdp { 190133965Sjdp int add; 190233965Sjdp 190333965Sjdp add = 1 + isymp->n_numaux; 190433965Sjdp 190533965Sjdp if ((*indexp < 0 190633965Sjdp || (bfd_size_type) *indexp < syment_base) 190733965Sjdp && (*sym_hash == NULL 190833965Sjdp || (*sym_hash)->auxbfd != input_bfd)) 190933965Sjdp esym += add * isymesz; 191033965Sjdp else 191133965Sjdp { 191233965Sjdp struct coff_link_hash_entry *h; 191333965Sjdp int i; 191433965Sjdp 191533965Sjdp h = NULL; 191633965Sjdp if (*indexp < 0) 191733965Sjdp { 191833965Sjdp h = *sym_hash; 191933965Sjdp 192033965Sjdp /* The m68k-motorola-sysv assembler will sometimes 192133965Sjdp generate two symbols with the same name, but only one 192233965Sjdp will have aux entries. */ 192333965Sjdp BFD_ASSERT (isymp->n_numaux == 0 1924218822Sdim || h->numaux == 0 192533965Sjdp || h->numaux == isymp->n_numaux); 192633965Sjdp } 192733965Sjdp 192833965Sjdp esym += isymesz; 192933965Sjdp 193033965Sjdp if (h == NULL) 193133965Sjdp outsym += osymesz; 193233965Sjdp 193333965Sjdp /* Handle the aux entries. This handling is based on 193433965Sjdp coff_pointerize_aux. I don't know if it always correct. */ 193533965Sjdp for (i = 0; i < isymp->n_numaux && esym < esym_end; i++) 193633965Sjdp { 193733965Sjdp union internal_auxent aux; 193833965Sjdp union internal_auxent *auxp; 193933965Sjdp 1940218822Sdim if (h != NULL && h->aux != NULL && (h->numaux > i)) 194133965Sjdp auxp = h->aux + i; 194233965Sjdp else 194333965Sjdp { 1944130561Sobrien bfd_coff_swap_aux_in (input_bfd, esym, isymp->n_type, 1945130561Sobrien isymp->n_sclass, i, isymp->n_numaux, &aux); 194633965Sjdp auxp = &aux; 194733965Sjdp } 194833965Sjdp 194933965Sjdp if (isymp->n_sclass == C_FILE) 195033965Sjdp { 195133965Sjdp /* If this is a long filename, we must put it in the 195233965Sjdp string table. */ 195333965Sjdp if (auxp->x_file.x_n.x_zeroes == 0 195433965Sjdp && auxp->x_file.x_n.x_offset != 0) 195533965Sjdp { 195633965Sjdp const char *filename; 195733965Sjdp bfd_size_type indx; 195833965Sjdp 195933965Sjdp BFD_ASSERT (auxp->x_file.x_n.x_offset 196033965Sjdp >= STRING_SIZE_SIZE); 196133965Sjdp if (strings == NULL) 196233965Sjdp { 196333965Sjdp strings = _bfd_coff_read_string_table (input_bfd); 196433965Sjdp if (strings == NULL) 1965130561Sobrien return FALSE; 196633965Sjdp } 196733965Sjdp filename = strings + auxp->x_file.x_n.x_offset; 196833965Sjdp indx = _bfd_stringtab_add (finfo->strtab, filename, 196933965Sjdp hash, copy); 197033965Sjdp if (indx == (bfd_size_type) -1) 1971130561Sobrien return FALSE; 197233965Sjdp auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; 197333965Sjdp } 197433965Sjdp } 1975218822Sdim else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) 1976218822Sdim && isymp->n_sclass != C_NT_WEAK) 197733965Sjdp { 197833965Sjdp unsigned long indx; 197933965Sjdp 198033965Sjdp if (ISFCN (isymp->n_type) 198133965Sjdp || ISTAG (isymp->n_sclass) 198233965Sjdp || isymp->n_sclass == C_BLOCK 198333965Sjdp || isymp->n_sclass == C_FCN) 198433965Sjdp { 198533965Sjdp indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l; 198633965Sjdp if (indx > 0 198733965Sjdp && indx < obj_raw_syment_count (input_bfd)) 198833965Sjdp { 198933965Sjdp /* We look forward through the symbol for 199033965Sjdp the index of the next symbol we are going 199133965Sjdp to include. I don't know if this is 199233965Sjdp entirely right. */ 199333965Sjdp while ((finfo->sym_indices[indx] < 0 199433965Sjdp || ((bfd_size_type) finfo->sym_indices[indx] 199533965Sjdp < syment_base)) 199633965Sjdp && indx < obj_raw_syment_count (input_bfd)) 199733965Sjdp ++indx; 199833965Sjdp if (indx >= obj_raw_syment_count (input_bfd)) 199933965Sjdp indx = output_index; 200033965Sjdp else 200133965Sjdp indx = finfo->sym_indices[indx]; 200233965Sjdp auxp->x_sym.x_fcnary.x_fcn.x_endndx.l = indx; 200333965Sjdp } 200433965Sjdp } 200533965Sjdp 200633965Sjdp indx = auxp->x_sym.x_tagndx.l; 200733965Sjdp if (indx > 0 && indx < obj_raw_syment_count (input_bfd)) 200833965Sjdp { 200933965Sjdp long symindx; 201033965Sjdp 201133965Sjdp symindx = finfo->sym_indices[indx]; 201233965Sjdp if (symindx < 0) 201333965Sjdp auxp->x_sym.x_tagndx.l = 0; 201433965Sjdp else 201533965Sjdp auxp->x_sym.x_tagndx.l = symindx; 201633965Sjdp } 201733965Sjdp 201833965Sjdp /* The .bf symbols are supposed to be linked through 201933965Sjdp the endndx field. We need to carry this list 202033965Sjdp across object files. */ 202133965Sjdp if (i == 0 202233965Sjdp && h == NULL 202333965Sjdp && isymp->n_sclass == C_FCN 202433965Sjdp && (isymp->_n._n_n._n_zeroes != 0 202533965Sjdp || isymp->_n._n_n._n_offset == 0) 202633965Sjdp && isymp->_n._n_name[0] == '.' 202733965Sjdp && isymp->_n._n_name[1] == 'b' 202833965Sjdp && isymp->_n._n_name[2] == 'f' 202933965Sjdp && isymp->_n._n_name[3] == '\0') 203033965Sjdp { 203133965Sjdp if (finfo->last_bf_index != -1) 203233965Sjdp { 203333965Sjdp finfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.l = 203433965Sjdp *indexp; 203533965Sjdp 203633965Sjdp if ((bfd_size_type) finfo->last_bf_index 203733965Sjdp >= syment_base) 203833965Sjdp { 2039130561Sobrien void *auxout; 204033965Sjdp 204133965Sjdp /* The last .bf symbol is in this input 204233965Sjdp file. This will only happen if the 204333965Sjdp assembler did not set up the .bf 204433965Sjdp endndx symbols correctly. */ 2045130561Sobrien auxout = (finfo->outsyms 2046130561Sobrien + ((finfo->last_bf_index 2047130561Sobrien - syment_base) 2048130561Sobrien * osymesz)); 2049130561Sobrien 205033965Sjdp bfd_coff_swap_aux_out (output_bfd, 2051130561Sobrien &finfo->last_bf, 205233965Sjdp isymp->n_type, 205333965Sjdp isymp->n_sclass, 205433965Sjdp 0, isymp->n_numaux, 205533965Sjdp auxout); 205633965Sjdp } 205733965Sjdp else 205833965Sjdp { 205989857Sobrien file_ptr pos; 206089857Sobrien 206133965Sjdp /* We have already written out the last 206233965Sjdp .bf aux entry. We need to write it 206333965Sjdp out again. We borrow *outsym 206433965Sjdp temporarily. FIXME: This case should 206533965Sjdp be made faster. */ 206633965Sjdp bfd_coff_swap_aux_out (output_bfd, 2067130561Sobrien &finfo->last_bf, 206833965Sjdp isymp->n_type, 206933965Sjdp isymp->n_sclass, 207033965Sjdp 0, isymp->n_numaux, 2071130561Sobrien outsym); 207289857Sobrien pos = obj_sym_filepos (output_bfd); 207389857Sobrien pos += finfo->last_bf_index * osymesz; 207489857Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 207589857Sobrien || (bfd_bwrite (outsym, osymesz, output_bfd) 207689857Sobrien != osymesz)) 2077130561Sobrien return FALSE; 207833965Sjdp } 207933965Sjdp } 208033965Sjdp 208133965Sjdp if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.l != 0) 208233965Sjdp finfo->last_bf_index = -1; 208333965Sjdp else 208433965Sjdp { 208533965Sjdp /* The endndx field of this aux entry must 208633965Sjdp be updated with the symbol number of the 208733965Sjdp next .bf symbol. */ 208833965Sjdp finfo->last_bf = *auxp; 208933965Sjdp finfo->last_bf_index = (((outsym - finfo->outsyms) 209033965Sjdp / osymesz) 209133965Sjdp + syment_base); 209233965Sjdp } 209333965Sjdp } 209433965Sjdp } 209533965Sjdp 209633965Sjdp if (h == NULL) 209733965Sjdp { 2098130561Sobrien bfd_coff_swap_aux_out (output_bfd, auxp, isymp->n_type, 209933965Sjdp isymp->n_sclass, i, isymp->n_numaux, 2100130561Sobrien outsym); 210133965Sjdp outsym += osymesz; 210233965Sjdp } 210333965Sjdp 210433965Sjdp esym += isymesz; 210533965Sjdp } 210633965Sjdp } 210733965Sjdp 210833965Sjdp indexp += add; 210933965Sjdp isymp += add; 211033965Sjdp sym_hash += add; 211133965Sjdp } 211233965Sjdp 211333965Sjdp /* Relocate the line numbers, unless we are stripping them. */ 211433965Sjdp if (finfo->info->strip == strip_none 211533965Sjdp || finfo->info->strip == strip_some) 211633965Sjdp { 211733965Sjdp for (o = input_bfd->sections; o != NULL; o = o->next) 211833965Sjdp { 211933965Sjdp bfd_vma offset; 212033965Sjdp bfd_byte *eline; 212133965Sjdp bfd_byte *elineend; 212260484Sobrien bfd_byte *oeline; 2123130561Sobrien bfd_boolean skipping; 212489857Sobrien file_ptr pos; 212589857Sobrien bfd_size_type amt; 212633965Sjdp 212733965Sjdp /* FIXME: If SEC_HAS_CONTENTS is not for the section, then 212833965Sjdp build_link_order in ldwrite.c will not have created a 212933965Sjdp link order, which means that we will not have seen this 213033965Sjdp input section in _bfd_coff_final_link, which means that 213133965Sjdp we will not have allocated space for the line numbers of 213233965Sjdp this section. I don't think line numbers can be 213333965Sjdp meaningful for a section which does not have 213433965Sjdp SEC_HAS_CONTENTS set, but, if they do, this must be 213533965Sjdp changed. */ 213633965Sjdp if (o->lineno_count == 0 213733965Sjdp || (o->output_section->flags & SEC_HAS_CONTENTS) == 0) 213833965Sjdp continue; 213933965Sjdp 214033965Sjdp if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0 214189857Sobrien || bfd_bread (finfo->linenos, linesz * o->lineno_count, 214233965Sjdp input_bfd) != linesz * o->lineno_count) 2143130561Sobrien return FALSE; 214433965Sjdp 214533965Sjdp offset = o->output_section->vma + o->output_offset - o->vma; 214633965Sjdp eline = finfo->linenos; 214760484Sobrien oeline = finfo->linenos; 214833965Sjdp elineend = eline + linesz * o->lineno_count; 2149130561Sobrien skipping = FALSE; 215033965Sjdp for (; eline < elineend; eline += linesz) 215133965Sjdp { 215233965Sjdp struct internal_lineno iline; 215333965Sjdp 2154130561Sobrien bfd_coff_swap_lineno_in (input_bfd, eline, &iline); 215533965Sjdp 215633965Sjdp if (iline.l_lnno != 0) 215733965Sjdp iline.l_addr.l_paddr += offset; 215833965Sjdp else if (iline.l_addr.l_symndx >= 0 215933965Sjdp && ((unsigned long) iline.l_addr.l_symndx 216033965Sjdp < obj_raw_syment_count (input_bfd))) 216133965Sjdp { 216233965Sjdp long indx; 216333965Sjdp 216433965Sjdp indx = finfo->sym_indices[iline.l_addr.l_symndx]; 216533965Sjdp 216633965Sjdp if (indx < 0) 216733965Sjdp { 216833965Sjdp /* These line numbers are attached to a symbol 216960484Sobrien which we are stripping. We must discard the 217060484Sobrien line numbers because reading them back with 217160484Sobrien no associated symbol (or associating them all 217260484Sobrien with symbol #0) will fail. We can't regain 217360484Sobrien the space in the output file, but at least 217460484Sobrien they're dense. */ 2175130561Sobrien skipping = TRUE; 217633965Sjdp } 217733965Sjdp else 217833965Sjdp { 217933965Sjdp struct internal_syment is; 218033965Sjdp union internal_auxent ia; 218133965Sjdp 218233965Sjdp /* Fix up the lnnoptr field in the aux entry of 218333965Sjdp the symbol. It turns out that we can't do 218433965Sjdp this when we modify the symbol aux entries, 218533965Sjdp because gas sometimes screws up the lnnoptr 218633965Sjdp field and makes it an offset from the start 218733965Sjdp of the line numbers rather than an absolute 218833965Sjdp file index. */ 218933965Sjdp bfd_coff_swap_sym_in (output_bfd, 2190130561Sobrien (finfo->outsyms 2191130561Sobrien + ((indx - syment_base) 2192130561Sobrien * osymesz)), &is); 219333965Sjdp if ((ISFCN (is.n_type) 219433965Sjdp || is.n_sclass == C_BLOCK) 219533965Sjdp && is.n_numaux >= 1) 219633965Sjdp { 2197130561Sobrien void *auxptr; 219833965Sjdp 2199130561Sobrien auxptr = (finfo->outsyms 2200130561Sobrien + ((indx - syment_base + 1) 2201130561Sobrien * osymesz)); 220233965Sjdp bfd_coff_swap_aux_in (output_bfd, auxptr, 220333965Sjdp is.n_type, is.n_sclass, 2204130561Sobrien 0, is.n_numaux, &ia); 220533965Sjdp ia.x_sym.x_fcnary.x_fcn.x_lnnoptr = 220633965Sjdp (o->output_section->line_filepos 220733965Sjdp + o->output_section->lineno_count * linesz 220833965Sjdp + eline - finfo->linenos); 2209130561Sobrien bfd_coff_swap_aux_out (output_bfd, &ia, 221033965Sjdp is.n_type, is.n_sclass, 0, 221133965Sjdp is.n_numaux, auxptr); 221233965Sjdp } 221360484Sobrien 2214130561Sobrien skipping = FALSE; 221533965Sjdp } 221633965Sjdp 221733965Sjdp iline.l_addr.l_symndx = indx; 221833965Sjdp } 221933965Sjdp 222060484Sobrien if (!skipping) 222160484Sobrien { 2222130561Sobrien bfd_coff_swap_lineno_out (output_bfd, &iline, oeline); 222360484Sobrien oeline += linesz; 222460484Sobrien } 222533965Sjdp } 222633965Sjdp 222789857Sobrien pos = o->output_section->line_filepos; 222889857Sobrien pos += o->output_section->lineno_count * linesz; 222989857Sobrien amt = oeline - finfo->linenos; 223089857Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 223189857Sobrien || bfd_bwrite (finfo->linenos, amt, output_bfd) != amt) 2232130561Sobrien return FALSE; 223333965Sjdp 223489857Sobrien o->output_section->lineno_count += amt / linesz; 223533965Sjdp } 223633965Sjdp } 223733965Sjdp 223833965Sjdp /* If we swapped out a C_FILE symbol, guess that the next C_FILE 223933965Sjdp symbol will be the first symbol in the next input file. In the 224033965Sjdp normal case, this will save us from writing out the C_FILE symbol 224133965Sjdp again. */ 224233965Sjdp if (finfo->last_file_index != -1 224333965Sjdp && (bfd_size_type) finfo->last_file_index >= syment_base) 224433965Sjdp { 224533965Sjdp finfo->last_file.n_value = output_index; 2246130561Sobrien bfd_coff_swap_sym_out (output_bfd, &finfo->last_file, 2247130561Sobrien (finfo->outsyms 2248130561Sobrien + ((finfo->last_file_index - syment_base) 2249130561Sobrien * osymesz))); 225033965Sjdp } 225133965Sjdp 225233965Sjdp /* Write the modified symbols to the output file. */ 225333965Sjdp if (outsym > finfo->outsyms) 225433965Sjdp { 225589857Sobrien file_ptr pos; 225689857Sobrien bfd_size_type amt; 225789857Sobrien 225889857Sobrien pos = obj_sym_filepos (output_bfd) + syment_base * osymesz; 225989857Sobrien amt = outsym - finfo->outsyms; 226089857Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 226189857Sobrien || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt) 2262130561Sobrien return FALSE; 226333965Sjdp 226433965Sjdp BFD_ASSERT ((obj_raw_syment_count (output_bfd) 226533965Sjdp + (outsym - finfo->outsyms) / osymesz) 226633965Sjdp == output_index); 226733965Sjdp 226833965Sjdp obj_raw_syment_count (output_bfd) = output_index; 226933965Sjdp } 227033965Sjdp 227133965Sjdp /* Relocate the contents of each section. */ 227233965Sjdp adjust_symndx = coff_backend_info (input_bfd)->_bfd_coff_adjust_symndx; 227333965Sjdp for (o = input_bfd->sections; o != NULL; o = o->next) 227433965Sjdp { 227533965Sjdp bfd_byte *contents; 227633965Sjdp struct coff_section_tdata *secdata; 227733965Sjdp 227833965Sjdp if (! o->linker_mark) 2279130561Sobrien /* This section was omitted from the link. */ 2280130561Sobrien continue; 228133965Sjdp 2282218822Sdim if ((o->flags & SEC_LINKER_CREATED) != 0) 2283218822Sdim continue; 2284218822Sdim 228533965Sjdp if ((o->flags & SEC_HAS_CONTENTS) == 0 2286218822Sdim || (o->size == 0 && (o->flags & SEC_RELOC) == 0)) 228733965Sjdp { 228833965Sjdp if ((o->flags & SEC_RELOC) != 0 228933965Sjdp && o->reloc_count != 0) 229033965Sjdp { 2291218822Sdim (*_bfd_error_handler) 2292218822Sdim (_("%B: relocs in section `%A', but it has no contents"), 2293218822Sdim input_bfd, o); 229433965Sjdp bfd_set_error (bfd_error_no_contents); 2295130561Sobrien return FALSE; 229633965Sjdp } 229733965Sjdp 229833965Sjdp continue; 229933965Sjdp } 230033965Sjdp 230133965Sjdp secdata = coff_section_data (input_bfd, o); 230233965Sjdp if (secdata != NULL && secdata->contents != NULL) 230333965Sjdp contents = secdata->contents; 230433965Sjdp else 230533965Sjdp { 2306218822Sdim bfd_size_type x = o->rawsize ? o->rawsize : o->size; 2307218822Sdim if (! bfd_get_section_contents (input_bfd, o, finfo->contents, 0, x)) 2308130561Sobrien return FALSE; 230933965Sjdp contents = finfo->contents; 231033965Sjdp } 231133965Sjdp 231233965Sjdp if ((o->flags & SEC_RELOC) != 0) 231333965Sjdp { 231433965Sjdp int target_index; 231533965Sjdp struct internal_reloc *internal_relocs; 231633965Sjdp struct internal_reloc *irel; 231733965Sjdp 231833965Sjdp /* Read in the relocs. */ 231933965Sjdp target_index = o->output_section->target_index; 232033965Sjdp internal_relocs = (_bfd_coff_read_internal_relocs 2321130561Sobrien (input_bfd, o, FALSE, finfo->external_relocs, 2322130561Sobrien finfo->info->relocatable, 2323130561Sobrien (finfo->info->relocatable 232433965Sjdp ? (finfo->section_info[target_index].relocs 232533965Sjdp + o->output_section->reloc_count) 232633965Sjdp : finfo->internal_relocs))); 232733965Sjdp if (internal_relocs == NULL) 2328130561Sobrien return FALSE; 232933965Sjdp 233033965Sjdp /* Call processor specific code to relocate the section 233133965Sjdp contents. */ 233233965Sjdp if (! bfd_coff_relocate_section (output_bfd, finfo->info, 233333965Sjdp input_bfd, o, 233433965Sjdp contents, 233533965Sjdp internal_relocs, 233633965Sjdp finfo->internal_syms, 233733965Sjdp finfo->sec_ptrs)) 2338130561Sobrien return FALSE; 233933965Sjdp 2340130561Sobrien if (finfo->info->relocatable) 234133965Sjdp { 234233965Sjdp bfd_vma offset; 234333965Sjdp struct internal_reloc *irelend; 234433965Sjdp struct coff_link_hash_entry **rel_hash; 234533965Sjdp 234633965Sjdp offset = o->output_section->vma + o->output_offset - o->vma; 234733965Sjdp irel = internal_relocs; 234833965Sjdp irelend = irel + o->reloc_count; 234933965Sjdp rel_hash = (finfo->section_info[target_index].rel_hashes 235033965Sjdp + o->output_section->reloc_count); 235133965Sjdp for (; irel < irelend; irel++, rel_hash++) 235233965Sjdp { 235333965Sjdp struct coff_link_hash_entry *h; 2354130561Sobrien bfd_boolean adjusted; 235533965Sjdp 235633965Sjdp *rel_hash = NULL; 235733965Sjdp 235833965Sjdp /* Adjust the reloc address and symbol index. */ 235933965Sjdp irel->r_vaddr += offset; 236033965Sjdp 236133965Sjdp if (irel->r_symndx == -1) 236233965Sjdp continue; 236333965Sjdp 236433965Sjdp if (adjust_symndx) 236533965Sjdp { 236633965Sjdp if (! (*adjust_symndx) (output_bfd, finfo->info, 236733965Sjdp input_bfd, o, irel, 236833965Sjdp &adjusted)) 2369130561Sobrien return FALSE; 237033965Sjdp if (adjusted) 237133965Sjdp continue; 237233965Sjdp } 237333965Sjdp 237433965Sjdp h = obj_coff_sym_hashes (input_bfd)[irel->r_symndx]; 237533965Sjdp if (h != NULL) 237633965Sjdp { 237733965Sjdp /* This is a global symbol. */ 237833965Sjdp if (h->indx >= 0) 237933965Sjdp irel->r_symndx = h->indx; 238033965Sjdp else 238133965Sjdp { 238233965Sjdp /* This symbol is being written at the end 238333965Sjdp of the file, and we do not yet know the 238433965Sjdp symbol index. We save the pointer to the 238533965Sjdp hash table entry in the rel_hash list. 238633965Sjdp We set the indx field to -2 to indicate 238733965Sjdp that this symbol must not be stripped. */ 238833965Sjdp *rel_hash = h; 238933965Sjdp h->indx = -2; 239033965Sjdp } 239133965Sjdp } 239233965Sjdp else 239333965Sjdp { 239433965Sjdp long indx; 239533965Sjdp 239633965Sjdp indx = finfo->sym_indices[irel->r_symndx]; 239733965Sjdp if (indx != -1) 239833965Sjdp irel->r_symndx = indx; 239933965Sjdp else 240033965Sjdp { 240133965Sjdp struct internal_syment *is; 240233965Sjdp const char *name; 240333965Sjdp char buf[SYMNMLEN + 1]; 240433965Sjdp 240533965Sjdp /* This reloc is against a symbol we are 240638889Sjdp stripping. This should have been handled 240738889Sjdp by the 'dont_skip_symbol' code in the while 240877298Sobrien loop at the top of this function. */ 240933965Sjdp is = finfo->internal_syms + irel->r_symndx; 241033965Sjdp 241133965Sjdp name = (_bfd_coff_internal_syment_name 241233965Sjdp (input_bfd, is, buf)); 241333965Sjdp if (name == NULL) 2414130561Sobrien return FALSE; 241533965Sjdp 241633965Sjdp if (! ((*finfo->info->callbacks->unattached_reloc) 241733965Sjdp (finfo->info, name, input_bfd, o, 241833965Sjdp irel->r_vaddr))) 2419130561Sobrien return FALSE; 242033965Sjdp } 242133965Sjdp } 242233965Sjdp } 242333965Sjdp 242433965Sjdp o->output_section->reloc_count += o->reloc_count; 242533965Sjdp } 242633965Sjdp } 242733965Sjdp 242833965Sjdp /* Write out the modified section contents. */ 242933965Sjdp if (secdata == NULL || secdata->stab_info == NULL) 243033965Sjdp { 243189857Sobrien file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd); 243233965Sjdp if (! bfd_set_section_contents (output_bfd, o->output_section, 2433218822Sdim contents, loc, o->size)) 2434130561Sobrien return FALSE; 243533965Sjdp } 243633965Sjdp else 243733965Sjdp { 243833965Sjdp if (! (_bfd_write_section_stabs 243933965Sjdp (output_bfd, &coff_hash_table (finfo->info)->stab_info, 244033965Sjdp o, &secdata->stab_info, contents))) 2441130561Sobrien return FALSE; 244233965Sjdp } 244333965Sjdp } 244433965Sjdp 2445130561Sobrien if (! finfo->info->keep_memory 2446130561Sobrien && ! _bfd_coff_free_symbols (input_bfd)) 2447130561Sobrien return FALSE; 244833965Sjdp 2449130561Sobrien return TRUE; 245033965Sjdp} 245133965Sjdp 245233965Sjdp/* Write out a global symbol. Called via coff_link_hash_traverse. */ 245333965Sjdp 2454130561Sobrienbfd_boolean 2455130561Sobrien_bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data) 245633965Sjdp{ 245733965Sjdp struct coff_final_link_info *finfo = (struct coff_final_link_info *) data; 245833965Sjdp bfd *output_bfd; 245933965Sjdp struct internal_syment isym; 246033965Sjdp bfd_size_type symesz; 246133965Sjdp unsigned int i; 246289857Sobrien file_ptr pos; 246333965Sjdp 246433965Sjdp output_bfd = finfo->output_bfd; 246533965Sjdp 246694536Sobrien if (h->root.type == bfd_link_hash_warning) 246794536Sobrien { 246894536Sobrien h = (struct coff_link_hash_entry *) h->root.u.i.link; 246994536Sobrien if (h->root.type == bfd_link_hash_new) 2470130561Sobrien return TRUE; 247194536Sobrien } 247294536Sobrien 247333965Sjdp if (h->indx >= 0) 2474130561Sobrien return TRUE; 247533965Sjdp 247633965Sjdp if (h->indx != -2 247733965Sjdp && (finfo->info->strip == strip_all 247833965Sjdp || (finfo->info->strip == strip_some 247933965Sjdp && (bfd_hash_lookup (finfo->info->keep_hash, 2480130561Sobrien h->root.root.string, FALSE, FALSE) 248133965Sjdp == NULL)))) 2482130561Sobrien return TRUE; 248333965Sjdp 248433965Sjdp switch (h->root.type) 248533965Sjdp { 248633965Sjdp default: 248733965Sjdp case bfd_link_hash_new: 248894536Sobrien case bfd_link_hash_warning: 248933965Sjdp abort (); 2490130561Sobrien return FALSE; 249133965Sjdp 249233965Sjdp case bfd_link_hash_undefined: 249333965Sjdp case bfd_link_hash_undefweak: 249433965Sjdp isym.n_scnum = N_UNDEF; 249533965Sjdp isym.n_value = 0; 249633965Sjdp break; 249733965Sjdp 249833965Sjdp case bfd_link_hash_defined: 249933965Sjdp case bfd_link_hash_defweak: 250033965Sjdp { 250133965Sjdp asection *sec; 250233965Sjdp 250333965Sjdp sec = h->root.u.def.section->output_section; 250433965Sjdp if (bfd_is_abs_section (sec)) 250533965Sjdp isym.n_scnum = N_ABS; 250633965Sjdp else 250733965Sjdp isym.n_scnum = sec->target_index; 250833965Sjdp isym.n_value = (h->root.u.def.value 250933965Sjdp + h->root.u.def.section->output_offset); 251038889Sjdp if (! obj_pe (finfo->output_bfd)) 251138889Sjdp isym.n_value += sec->vma; 251233965Sjdp } 251333965Sjdp break; 251433965Sjdp 251533965Sjdp case bfd_link_hash_common: 251633965Sjdp isym.n_scnum = N_UNDEF; 251733965Sjdp isym.n_value = h->root.u.c.size; 251833965Sjdp break; 251933965Sjdp 252033965Sjdp case bfd_link_hash_indirect: 252133965Sjdp /* Just ignore these. They can't be handled anyhow. */ 2522130561Sobrien return TRUE; 252333965Sjdp } 252433965Sjdp 252533965Sjdp if (strlen (h->root.root.string) <= SYMNMLEN) 252633965Sjdp strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN); 252733965Sjdp else 252833965Sjdp { 2529130561Sobrien bfd_boolean hash; 253033965Sjdp bfd_size_type indx; 253133965Sjdp 2532130561Sobrien hash = TRUE; 253333965Sjdp if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) 2534130561Sobrien hash = FALSE; 253533965Sjdp indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash, 2536130561Sobrien FALSE); 253733965Sjdp if (indx == (bfd_size_type) -1) 253833965Sjdp { 2539130561Sobrien finfo->failed = TRUE; 2540130561Sobrien return FALSE; 254133965Sjdp } 254233965Sjdp isym._n._n_n._n_zeroes = 0; 254333965Sjdp isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; 254433965Sjdp } 254533965Sjdp 254633965Sjdp isym.n_sclass = h->class; 254733965Sjdp isym.n_type = h->type; 254833965Sjdp 254933965Sjdp if (isym.n_sclass == C_NULL) 255033965Sjdp isym.n_sclass = C_EXT; 255133965Sjdp 255260484Sobrien /* If doing task linking and this is the pass where we convert 255360484Sobrien defined globals to statics, then do that conversion now. If the 255460484Sobrien symbol is not being converted, just ignore it and it will be 255577298Sobrien output during a later pass. */ 255638889Sjdp if (finfo->global_to_static) 255738889Sjdp { 255877298Sobrien if (! IS_EXTERNAL (output_bfd, isym)) 2559130561Sobrien return TRUE; 256077298Sobrien 256138889Sjdp isym.n_sclass = C_STAT; 256238889Sjdp } 256338889Sjdp 2564130561Sobrien /* When a weak symbol is not overridden by a strong one, 256577298Sobrien turn it into an external symbol when not building a 2566130561Sobrien shared or relocatable object. */ 256777298Sobrien if (! finfo->info->shared 2568130561Sobrien && ! finfo->info->relocatable 256977298Sobrien && IS_WEAK_EXTERNAL (finfo->output_bfd, isym)) 257077298Sobrien isym.n_sclass = C_EXT; 257177298Sobrien 257233965Sjdp isym.n_numaux = h->numaux; 257377298Sobrien 2574130561Sobrien bfd_coff_swap_sym_out (output_bfd, &isym, finfo->outsyms); 257533965Sjdp 257633965Sjdp symesz = bfd_coff_symesz (output_bfd); 257733965Sjdp 257889857Sobrien pos = obj_sym_filepos (output_bfd); 257989857Sobrien pos += obj_raw_syment_count (output_bfd) * symesz; 258089857Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 258189857Sobrien || bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz) 258233965Sjdp { 2583130561Sobrien finfo->failed = TRUE; 2584130561Sobrien return FALSE; 258533965Sjdp } 258633965Sjdp 258733965Sjdp h->indx = obj_raw_syment_count (output_bfd); 258833965Sjdp 258933965Sjdp ++obj_raw_syment_count (output_bfd); 259033965Sjdp 259160484Sobrien /* Write out any associated aux entries. Most of the aux entries 259260484Sobrien will have been modified in _bfd_coff_link_input_bfd. We have to 259360484Sobrien handle section aux entries here, now that we have the final 259460484Sobrien relocation and line number counts. */ 259533965Sjdp for (i = 0; i < isym.n_numaux; i++) 259633965Sjdp { 259760484Sobrien union internal_auxent *auxp; 259860484Sobrien 259960484Sobrien auxp = h->aux + i; 260060484Sobrien 260160484Sobrien /* Look for a section aux entry here using the same tests that 260260484Sobrien coff_swap_aux_out uses. */ 260360484Sobrien if (i == 0 260460484Sobrien && (isym.n_sclass == C_STAT 260560484Sobrien || isym.n_sclass == C_HIDDEN) 260660484Sobrien && isym.n_type == T_NULL 260760484Sobrien && (h->root.type == bfd_link_hash_defined 260860484Sobrien || h->root.type == bfd_link_hash_defweak)) 260960484Sobrien { 261060484Sobrien asection *sec; 261160484Sobrien 261260484Sobrien sec = h->root.u.def.section->output_section; 261360484Sobrien if (sec != NULL) 261460484Sobrien { 2615218822Sdim auxp->x_scn.x_scnlen = sec->size; 261660484Sobrien 261760484Sobrien /* For PE, an overflow on the final link reportedly does 261860484Sobrien not matter. FIXME: Why not? */ 261960484Sobrien if (sec->reloc_count > 0xffff 262060484Sobrien && (! obj_pe (output_bfd) 2621130561Sobrien || finfo->info->relocatable)) 262260484Sobrien (*_bfd_error_handler) 262360484Sobrien (_("%s: %s: reloc overflow: 0x%lx > 0xffff"), 262460484Sobrien bfd_get_filename (output_bfd), 262560484Sobrien bfd_get_section_name (output_bfd, sec), 262660484Sobrien sec->reloc_count); 262760484Sobrien 262860484Sobrien if (sec->lineno_count > 0xffff 262960484Sobrien && (! obj_pe (output_bfd) 2630130561Sobrien || finfo->info->relocatable)) 263160484Sobrien (*_bfd_error_handler) 263260484Sobrien (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"), 263360484Sobrien bfd_get_filename (output_bfd), 263460484Sobrien bfd_get_section_name (output_bfd, sec), 263560484Sobrien sec->lineno_count); 263660484Sobrien 263760484Sobrien auxp->x_scn.x_nreloc = sec->reloc_count; 263860484Sobrien auxp->x_scn.x_nlinno = sec->lineno_count; 263960484Sobrien auxp->x_scn.x_checksum = 0; 264060484Sobrien auxp->x_scn.x_associated = 0; 264160484Sobrien auxp->x_scn.x_comdat = 0; 264260484Sobrien } 264360484Sobrien } 264460484Sobrien 2645130561Sobrien bfd_coff_swap_aux_out (output_bfd, auxp, isym.n_type, 264689857Sobrien isym.n_sclass, (int) i, isym.n_numaux, 2647130561Sobrien finfo->outsyms); 264889857Sobrien if (bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz) 264933965Sjdp { 2650130561Sobrien finfo->failed = TRUE; 2651130561Sobrien return FALSE; 265233965Sjdp } 265333965Sjdp ++obj_raw_syment_count (output_bfd); 265433965Sjdp } 265533965Sjdp 2656130561Sobrien return TRUE; 265733965Sjdp} 265833965Sjdp 265938889Sjdp/* Write out task global symbols, converting them to statics. Called 266038889Sjdp via coff_link_hash_traverse. Calls bfd_coff_write_global_sym to do 266177298Sobrien the dirty work, if the symbol we are processing needs conversion. */ 266238889Sjdp 2663130561Sobrienbfd_boolean 2664130561Sobrien_bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data) 266538889Sjdp{ 266638889Sjdp struct coff_final_link_info *finfo = (struct coff_final_link_info *) data; 2667130561Sobrien bfd_boolean rtnval = TRUE; 2668130561Sobrien bfd_boolean save_global_to_static; 266938889Sjdp 267094536Sobrien if (h->root.type == bfd_link_hash_warning) 267194536Sobrien h = (struct coff_link_hash_entry *) h->root.u.i.link; 267294536Sobrien 267338889Sjdp if (h->indx < 0) 267438889Sjdp { 267538889Sjdp switch (h->root.type) 267638889Sjdp { 267738889Sjdp case bfd_link_hash_defined: 267838889Sjdp case bfd_link_hash_defweak: 267938889Sjdp save_global_to_static = finfo->global_to_static; 2680130561Sobrien finfo->global_to_static = TRUE; 268138889Sjdp rtnval = _bfd_coff_write_global_sym (h, data); 268238889Sjdp finfo->global_to_static = save_global_to_static; 268338889Sjdp break; 268438889Sjdp default: 268538889Sjdp break; 268638889Sjdp } 268738889Sjdp } 268838889Sjdp return (rtnval); 268938889Sjdp} 269038889Sjdp 269133965Sjdp/* Handle a link order which is supposed to generate a reloc. */ 269233965Sjdp 2693130561Sobrienbfd_boolean 2694130561Sobrien_bfd_coff_reloc_link_order (bfd *output_bfd, 2695130561Sobrien struct coff_final_link_info *finfo, 2696130561Sobrien asection *output_section, 2697130561Sobrien struct bfd_link_order *link_order) 269833965Sjdp{ 269933965Sjdp reloc_howto_type *howto; 270033965Sjdp struct internal_reloc *irel; 270133965Sjdp struct coff_link_hash_entry **rel_hash_ptr; 270233965Sjdp 270333965Sjdp howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); 270433965Sjdp if (howto == NULL) 270533965Sjdp { 270633965Sjdp bfd_set_error (bfd_error_bad_value); 2707130561Sobrien return FALSE; 270833965Sjdp } 270933965Sjdp 271033965Sjdp if (link_order->u.reloc.p->addend != 0) 271133965Sjdp { 271233965Sjdp bfd_size_type size; 271333965Sjdp bfd_byte *buf; 271433965Sjdp bfd_reloc_status_type rstat; 2715130561Sobrien bfd_boolean ok; 271689857Sobrien file_ptr loc; 271733965Sjdp 271833965Sjdp size = bfd_get_reloc_size (howto); 2719130561Sobrien buf = bfd_zmalloc (size); 272033965Sjdp if (buf == NULL) 2721130561Sobrien return FALSE; 272233965Sjdp 272333965Sjdp rstat = _bfd_relocate_contents (howto, output_bfd, 272489857Sobrien (bfd_vma) link_order->u.reloc.p->addend,\ 272589857Sobrien buf); 272633965Sjdp switch (rstat) 272733965Sjdp { 272833965Sjdp case bfd_reloc_ok: 272933965Sjdp break; 273033965Sjdp default: 273133965Sjdp case bfd_reloc_outofrange: 273233965Sjdp abort (); 273333965Sjdp case bfd_reloc_overflow: 273433965Sjdp if (! ((*finfo->info->callbacks->reloc_overflow) 2735218822Sdim (finfo->info, NULL, 273633965Sjdp (link_order->type == bfd_section_reloc_link_order 273733965Sjdp ? bfd_section_name (output_bfd, 273833965Sjdp link_order->u.reloc.p->u.section) 273933965Sjdp : link_order->u.reloc.p->u.name), 274033965Sjdp howto->name, link_order->u.reloc.p->addend, 274133965Sjdp (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) 274233965Sjdp { 274333965Sjdp free (buf); 2744130561Sobrien return FALSE; 274533965Sjdp } 274633965Sjdp break; 274733965Sjdp } 274889857Sobrien loc = link_order->offset * bfd_octets_per_byte (output_bfd); 2749130561Sobrien ok = bfd_set_section_contents (output_bfd, output_section, buf, 275089857Sobrien loc, size); 275133965Sjdp free (buf); 275233965Sjdp if (! ok) 2753130561Sobrien return FALSE; 275433965Sjdp } 275533965Sjdp 275633965Sjdp /* Store the reloc information in the right place. It will get 275733965Sjdp swapped and written out at the end of the final_link routine. */ 275833965Sjdp irel = (finfo->section_info[output_section->target_index].relocs 275933965Sjdp + output_section->reloc_count); 276033965Sjdp rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes 276133965Sjdp + output_section->reloc_count); 276233965Sjdp 276333965Sjdp memset (irel, 0, sizeof (struct internal_reloc)); 276433965Sjdp *rel_hash_ptr = NULL; 276533965Sjdp 276633965Sjdp irel->r_vaddr = output_section->vma + link_order->offset; 276733965Sjdp 276833965Sjdp if (link_order->type == bfd_section_reloc_link_order) 276933965Sjdp { 277033965Sjdp /* We need to somehow locate a symbol in the right section. The 277133965Sjdp symbol must either have a value of zero, or we must adjust 277233965Sjdp the addend by the value of the symbol. FIXME: Write this 277333965Sjdp when we need it. The old linker couldn't handle this anyhow. */ 277433965Sjdp abort (); 277533965Sjdp *rel_hash_ptr = NULL; 277633965Sjdp irel->r_symndx = 0; 277733965Sjdp } 277833965Sjdp else 277933965Sjdp { 278033965Sjdp struct coff_link_hash_entry *h; 278133965Sjdp 278233965Sjdp h = ((struct coff_link_hash_entry *) 278333965Sjdp bfd_wrapped_link_hash_lookup (output_bfd, finfo->info, 278433965Sjdp link_order->u.reloc.p->u.name, 2785130561Sobrien FALSE, FALSE, TRUE)); 278633965Sjdp if (h != NULL) 278733965Sjdp { 278833965Sjdp if (h->indx >= 0) 278933965Sjdp irel->r_symndx = h->indx; 279033965Sjdp else 279133965Sjdp { 279233965Sjdp /* Set the index to -2 to force this symbol to get 279333965Sjdp written out. */ 279433965Sjdp h->indx = -2; 279533965Sjdp *rel_hash_ptr = h; 279633965Sjdp irel->r_symndx = 0; 279733965Sjdp } 279833965Sjdp } 279933965Sjdp else 280033965Sjdp { 280133965Sjdp if (! ((*finfo->info->callbacks->unattached_reloc) 280233965Sjdp (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL, 280333965Sjdp (asection *) NULL, (bfd_vma) 0))) 2804130561Sobrien return FALSE; 280533965Sjdp irel->r_symndx = 0; 280633965Sjdp } 280733965Sjdp } 280833965Sjdp 280933965Sjdp /* FIXME: Is this always right? */ 281033965Sjdp irel->r_type = howto->type; 281133965Sjdp 281233965Sjdp /* r_size is only used on the RS/6000, which needs its own linker 281333965Sjdp routines anyhow. r_extern is only used for ECOFF. */ 281433965Sjdp 281533965Sjdp /* FIXME: What is the right value for r_offset? Is zero OK? */ 281633965Sjdp ++output_section->reloc_count; 281733965Sjdp 2818130561Sobrien return TRUE; 281933965Sjdp} 282033965Sjdp 282133965Sjdp/* A basic reloc handling routine which may be used by processors with 282233965Sjdp simple relocs. */ 282333965Sjdp 2824130561Sobrienbfd_boolean 2825130561Sobrien_bfd_coff_generic_relocate_section (bfd *output_bfd, 2826130561Sobrien struct bfd_link_info *info, 2827130561Sobrien bfd *input_bfd, 2828130561Sobrien asection *input_section, 2829130561Sobrien bfd_byte *contents, 2830130561Sobrien struct internal_reloc *relocs, 2831130561Sobrien struct internal_syment *syms, 2832130561Sobrien asection **sections) 283333965Sjdp{ 283433965Sjdp struct internal_reloc *rel; 283533965Sjdp struct internal_reloc *relend; 283633965Sjdp 283733965Sjdp rel = relocs; 283833965Sjdp relend = rel + input_section->reloc_count; 283933965Sjdp for (; rel < relend; rel++) 284033965Sjdp { 284133965Sjdp long symndx; 284233965Sjdp struct coff_link_hash_entry *h; 284333965Sjdp struct internal_syment *sym; 284433965Sjdp bfd_vma addend; 284533965Sjdp bfd_vma val; 284633965Sjdp reloc_howto_type *howto; 284733965Sjdp bfd_reloc_status_type rstat; 284833965Sjdp 284933965Sjdp symndx = rel->r_symndx; 285033965Sjdp 285133965Sjdp if (symndx == -1) 285233965Sjdp { 285333965Sjdp h = NULL; 285433965Sjdp sym = NULL; 285533965Sjdp } 285660484Sobrien else if (symndx < 0 285760484Sobrien || (unsigned long) symndx >= obj_raw_syment_count (input_bfd)) 285860484Sobrien { 285960484Sobrien (*_bfd_error_handler) 2860218822Sdim ("%B: illegal symbol index %ld in relocs", input_bfd, symndx); 2861130561Sobrien return FALSE; 286260484Sobrien } 286333965Sjdp else 286477298Sobrien { 286533965Sjdp h = obj_coff_sym_hashes (input_bfd)[symndx]; 286633965Sjdp sym = syms + symndx; 286733965Sjdp } 286833965Sjdp 286933965Sjdp /* COFF treats common symbols in one of two ways. Either the 287033965Sjdp size of the symbol is included in the section contents, or it 287133965Sjdp is not. We assume that the size is not included, and force 287233965Sjdp the rtype_to_howto function to adjust the addend as needed. */ 287333965Sjdp if (sym != NULL && sym->n_scnum != 0) 287433965Sjdp addend = - sym->n_value; 287533965Sjdp else 287633965Sjdp addend = 0; 287733965Sjdp 287833965Sjdp howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, 287933965Sjdp sym, &addend); 288033965Sjdp if (howto == NULL) 2881130561Sobrien return FALSE; 288233965Sjdp 2883130561Sobrien /* If we are doing a relocatable link, then we can just ignore 288433965Sjdp a PC relative reloc that is pcrel_offset. It will already 2885130561Sobrien have the correct value. If this is not a relocatable link, 288633965Sjdp then we should ignore the symbol value. */ 288733965Sjdp if (howto->pc_relative && howto->pcrel_offset) 288833965Sjdp { 2889130561Sobrien if (info->relocatable) 289033965Sjdp continue; 289133965Sjdp if (sym != NULL && sym->n_scnum != 0) 289233965Sjdp addend += sym->n_value; 289333965Sjdp } 289433965Sjdp 289533965Sjdp val = 0; 289633965Sjdp 289733965Sjdp if (h == NULL) 289833965Sjdp { 289933965Sjdp asection *sec; 290033965Sjdp 290133965Sjdp if (symndx == -1) 290233965Sjdp { 290333965Sjdp sec = bfd_abs_section_ptr; 290433965Sjdp val = 0; 290533965Sjdp } 290633965Sjdp else 290733965Sjdp { 290833965Sjdp sec = sections[symndx]; 290933965Sjdp val = (sec->output_section->vma 291033965Sjdp + sec->output_offset 291138889Sjdp + sym->n_value); 291238889Sjdp if (! obj_pe (input_bfd)) 291338889Sjdp val -= sec->vma; 291433965Sjdp } 291533965Sjdp } 291633965Sjdp else 291733965Sjdp { 291833965Sjdp if (h->root.type == bfd_link_hash_defined 291933965Sjdp || h->root.type == bfd_link_hash_defweak) 292033965Sjdp { 2921218822Sdim /* Defined weak symbols are a GNU extension. */ 292233965Sjdp asection *sec; 292333965Sjdp 292433965Sjdp sec = h->root.u.def.section; 292533965Sjdp val = (h->root.u.def.value 292633965Sjdp + sec->output_section->vma 292733965Sjdp + sec->output_offset); 2928218822Sdim } 292933965Sjdp 293077298Sobrien else if (h->root.type == bfd_link_hash_undefweak) 2931218822Sdim { 2932218822Sdim if (h->class == C_NT_WEAK && h->numaux == 1) 2933218822Sdim { 2934218822Sdim /* See _Microsoft Portable Executable and Common Object 2935218822Sdim File Format Specification_, section 5.5.3. 2936218822Sdim Note that weak symbols without aux records are a GNU 2937218822Sdim extension. 2938218822Sdim FIXME: All weak externals are treated as having 2939218822Sdim characteristic IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY (1). 2940218822Sdim These behave as per SVR4 ABI: A library member 2941218822Sdim will resolve a weak external only if a normal 2942218822Sdim external causes the library member to be linked. 2943218822Sdim See also linker.c: generic_link_check_archive_element. */ 2944218822Sdim asection *sec; 2945218822Sdim struct coff_link_hash_entry *h2 = 2946218822Sdim input_bfd->tdata.coff_obj_data->sym_hashes[ 2947218822Sdim h->aux->x_sym.x_tagndx.l]; 294877298Sobrien 2949218822Sdim if (!h2 || h2->root.type == bfd_link_hash_undefined) 2950218822Sdim { 2951218822Sdim sec = bfd_abs_section_ptr; 2952218822Sdim val = 0; 2953218822Sdim } 2954218822Sdim else 2955218822Sdim { 2956218822Sdim sec = h2->root.u.def.section; 2957218822Sdim val = h2->root.u.def.value 2958218822Sdim + sec->output_section->vma + sec->output_offset; 2959218822Sdim } 2960218822Sdim } 2961218822Sdim else 2962218822Sdim /* This is a GNU extension. */ 2963218822Sdim val = 0; 2964218822Sdim } 2965218822Sdim 2966130561Sobrien else if (! info->relocatable) 296733965Sjdp { 296833965Sjdp if (! ((*info->callbacks->undefined_symbol) 296933965Sjdp (info, h->root.root.string, input_bfd, input_section, 2970130561Sobrien rel->r_vaddr - input_section->vma, TRUE))) 2971130561Sobrien return FALSE; 297233965Sjdp } 297333965Sjdp } 297433965Sjdp 297533965Sjdp if (info->base_file) 297633965Sjdp { 297777298Sobrien /* Emit a reloc if the backend thinks it needs it. */ 297838889Sjdp if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto)) 297933965Sjdp { 298038889Sjdp /* Relocation to a symbol in a section which isn't 298138889Sjdp absolute. We output the address here to a file. 298238889Sjdp This file is then read by dlltool when generating the 298338889Sjdp reloc section. Note that the base file is not 298438889Sjdp portable between systems. We write out a long here, 298538889Sjdp and dlltool reads in a long. */ 298677298Sobrien long addr = (rel->r_vaddr 298777298Sobrien - input_section->vma 298877298Sobrien + input_section->output_offset 298938889Sjdp + input_section->output_section->vma); 299038889Sjdp if (coff_data (output_bfd)->pe) 299133965Sjdp addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; 299238889Sjdp if (fwrite (&addr, 1, sizeof (long), (FILE *) info->base_file) 299338889Sjdp != sizeof (long)) 299438889Sjdp { 299538889Sjdp bfd_set_error (bfd_error_system_call); 2996130561Sobrien return FALSE; 299738889Sjdp } 299833965Sjdp } 299933965Sjdp } 300077298Sobrien 300133965Sjdp rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, 300233965Sjdp contents, 300333965Sjdp rel->r_vaddr - input_section->vma, 300433965Sjdp val, addend); 300533965Sjdp 300633965Sjdp switch (rstat) 300733965Sjdp { 300833965Sjdp default: 300933965Sjdp abort (); 301033965Sjdp case bfd_reloc_ok: 301133965Sjdp break; 301233965Sjdp case bfd_reloc_outofrange: 301333965Sjdp (*_bfd_error_handler) 3014218822Sdim (_("%B: bad reloc address 0x%lx in section `%A'"), 3015218822Sdim input_bfd, input_section, (unsigned long) rel->r_vaddr); 3016130561Sobrien return FALSE; 301733965Sjdp case bfd_reloc_overflow: 301833965Sjdp { 301933965Sjdp const char *name; 302033965Sjdp char buf[SYMNMLEN + 1]; 302133965Sjdp 302233965Sjdp if (symndx == -1) 302333965Sjdp name = "*ABS*"; 302433965Sjdp else if (h != NULL) 3025218822Sdim name = NULL; 302633965Sjdp else 302733965Sjdp { 302833965Sjdp name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); 302933965Sjdp if (name == NULL) 3030130561Sobrien return FALSE; 303133965Sjdp } 303233965Sjdp 303333965Sjdp if (! ((*info->callbacks->reloc_overflow) 3034218822Sdim (info, (h ? &h->root : NULL), name, howto->name, 3035218822Sdim (bfd_vma) 0, input_bfd, input_section, 3036218822Sdim rel->r_vaddr - input_section->vma))) 3037130561Sobrien return FALSE; 303833965Sjdp } 303933965Sjdp } 304033965Sjdp } 3041130561Sobrien return TRUE; 304233965Sjdp} 3043