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, &copy))
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