xref: /openbsd-src/gnu/usr.bin/binutils/bfd/cofflink.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* COFF specific linker code.
2*007c2a45Smiod    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3b55d4692Sfgsch    Free Software Foundation, Inc.
42159047fSniklas    Written by Ian Lance Taylor, Cygnus Support.
52159047fSniklas 
62159047fSniklas    This file is part of BFD, the Binary File Descriptor library.
72159047fSniklas 
82159047fSniklas    This program is free software; you can redistribute it and/or modify
92159047fSniklas    it under the terms of the GNU General Public License as published by
102159047fSniklas    the Free Software Foundation; either version 2 of the License, or
112159047fSniklas    (at your option) any later version.
122159047fSniklas 
132159047fSniklas    This program is distributed in the hope that it will be useful,
142159047fSniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162159047fSniklas    GNU General Public License for more details.
172159047fSniklas 
182159047fSniklas    You should have received a copy of the GNU General Public License
192159047fSniklas    along with this program; if not, write to the Free Software
202159047fSniklas    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
212159047fSniklas 
222159047fSniklas /* This file contains the COFF backend linker code.  */
232159047fSniklas 
242159047fSniklas #include "bfd.h"
252159047fSniklas #include "sysdep.h"
262159047fSniklas #include "bfdlink.h"
272159047fSniklas #include "libbfd.h"
282159047fSniklas #include "coff/internal.h"
292159047fSniklas #include "libcoff.h"
30*007c2a45Smiod #include "safe-ctype.h"
312159047fSniklas 
32*007c2a45Smiod static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info);
33*007c2a45Smiod static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded);
34*007c2a45Smiod static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info);
35b305b0f1Sespie 
36c074d1c9Sdrahn /* Return TRUE if SYM is a weak, external symbol.  */
37b55d4692Sfgsch #define IS_WEAK_EXTERNAL(abfd, sym)			\
38b55d4692Sfgsch   ((sym).n_sclass == C_WEAKEXT				\
39b55d4692Sfgsch    || (obj_pe (abfd) && (sym).n_sclass == C_NT_WEAK))
40b55d4692Sfgsch 
41c074d1c9Sdrahn /* Return TRUE if SYM is an external symbol.  */
42b55d4692Sfgsch #define IS_EXTERNAL(abfd, sym)				\
43b55d4692Sfgsch   ((sym).n_sclass == C_EXT || IS_WEAK_EXTERNAL (abfd, sym))
44b55d4692Sfgsch 
45b305b0f1Sespie /* Define macros so that the ISFCN, et. al., macros work correctly.
46b305b0f1Sespie    These macros are defined in include/coff/internal.h in terms of
47b305b0f1Sespie    N_TMASK, etc.  These definitions require a user to define local
48b305b0f1Sespie    variables with the appropriate names, and with values from the
49b305b0f1Sespie    coff_data (abfd) structure.  */
50b305b0f1Sespie 
51b305b0f1Sespie #define N_TMASK n_tmask
52b305b0f1Sespie #define N_BTSHFT n_btshft
53b305b0f1Sespie #define N_BTMASK n_btmask
542159047fSniklas 
552159047fSniklas /* Create an entry in a COFF linker hash table.  */
562159047fSniklas 
572159047fSniklas struct bfd_hash_entry *
_bfd_coff_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)58*007c2a45Smiod _bfd_coff_link_hash_newfunc (struct bfd_hash_entry *entry,
59*007c2a45Smiod 			     struct bfd_hash_table *table,
60*007c2a45Smiod 			     const char *string)
612159047fSniklas {
622159047fSniklas   struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry;
632159047fSniklas 
642159047fSniklas   /* Allocate the structure if it has not already been allocated by a
652159047fSniklas      subclass.  */
662159047fSniklas   if (ret == (struct coff_link_hash_entry *) NULL)
672159047fSniklas     ret = ((struct coff_link_hash_entry *)
682159047fSniklas 	   bfd_hash_allocate (table, sizeof (struct coff_link_hash_entry)));
692159047fSniklas   if (ret == (struct coff_link_hash_entry *) NULL)
702159047fSniklas     return (struct bfd_hash_entry *) ret;
712159047fSniklas 
722159047fSniklas   /* Call the allocation method of the superclass.  */
732159047fSniklas   ret = ((struct coff_link_hash_entry *)
742159047fSniklas 	 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
752159047fSniklas 				 table, string));
762159047fSniklas   if (ret != (struct coff_link_hash_entry *) NULL)
772159047fSniklas     {
782159047fSniklas       /* Set local fields.  */
792159047fSniklas       ret->indx = -1;
802159047fSniklas       ret->type = T_NULL;
812159047fSniklas       ret->class = C_NULL;
822159047fSniklas       ret->numaux = 0;
832159047fSniklas       ret->auxbfd = NULL;
842159047fSniklas       ret->aux = NULL;
852159047fSniklas     }
862159047fSniklas 
872159047fSniklas   return (struct bfd_hash_entry *) ret;
882159047fSniklas }
892159047fSniklas 
902159047fSniklas /* Initialize a COFF linker hash table.  */
912159047fSniklas 
92c074d1c9Sdrahn bfd_boolean
_bfd_coff_link_hash_table_init(struct coff_link_hash_table * table,bfd * abfd,struct bfd_hash_entry * (* newfunc)(struct bfd_hash_entry *,struct bfd_hash_table *,const char *))93*007c2a45Smiod _bfd_coff_link_hash_table_init (struct coff_link_hash_table *table,
94*007c2a45Smiod 				bfd *abfd,
95*007c2a45Smiod 				struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
962159047fSniklas 								   struct bfd_hash_table *,
97*007c2a45Smiod 								   const char *))
982159047fSniklas {
99c88b1d6cSniklas   table->stab_info = NULL;
1002159047fSniklas   return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
1012159047fSniklas }
1022159047fSniklas 
1032159047fSniklas /* Create a COFF linker hash table.  */
1042159047fSniklas 
1052159047fSniklas struct bfd_link_hash_table *
_bfd_coff_link_hash_table_create(bfd * abfd)106*007c2a45Smiod _bfd_coff_link_hash_table_create (bfd *abfd)
1072159047fSniklas {
1082159047fSniklas   struct coff_link_hash_table *ret;
109c074d1c9Sdrahn   bfd_size_type amt = sizeof (struct coff_link_hash_table);
1102159047fSniklas 
111*007c2a45Smiod   ret = bfd_malloc (amt);
1122159047fSniklas   if (ret == NULL)
1132159047fSniklas     return NULL;
114*007c2a45Smiod 
1152159047fSniklas   if (! _bfd_coff_link_hash_table_init (ret, abfd,
1162159047fSniklas 					_bfd_coff_link_hash_newfunc))
1172159047fSniklas     {
118c074d1c9Sdrahn       free (ret);
1192159047fSniklas       return (struct bfd_link_hash_table *) NULL;
1202159047fSniklas     }
1212159047fSniklas   return &ret->root;
1222159047fSniklas }
1232159047fSniklas 
1242159047fSniklas /* Create an entry in a COFF debug merge hash table.  */
1252159047fSniklas 
126c88b1d6cSniklas struct bfd_hash_entry *
_bfd_coff_debug_merge_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)127*007c2a45Smiod _bfd_coff_debug_merge_hash_newfunc (struct bfd_hash_entry *entry,
128*007c2a45Smiod 				    struct bfd_hash_table *table,
129*007c2a45Smiod 				    const char *string)
1302159047fSniklas {
1312159047fSniklas   struct coff_debug_merge_hash_entry *ret =
1322159047fSniklas     (struct coff_debug_merge_hash_entry *) entry;
1332159047fSniklas 
1342159047fSniklas   /* Allocate the structure if it has not already been allocated by a
1352159047fSniklas      subclass.  */
1362159047fSniklas   if (ret == (struct coff_debug_merge_hash_entry *) NULL)
1372159047fSniklas     ret = ((struct coff_debug_merge_hash_entry *)
1382159047fSniklas 	   bfd_hash_allocate (table,
1392159047fSniklas 			      sizeof (struct coff_debug_merge_hash_entry)));
1402159047fSniklas   if (ret == (struct coff_debug_merge_hash_entry *) NULL)
1412159047fSniklas     return (struct bfd_hash_entry *) ret;
1422159047fSniklas 
1432159047fSniklas   /* Call the allocation method of the superclass.  */
1442159047fSniklas   ret = ((struct coff_debug_merge_hash_entry *)
1452159047fSniklas 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1462159047fSniklas   if (ret != (struct coff_debug_merge_hash_entry *) NULL)
1472159047fSniklas     {
1482159047fSniklas       /* Set local fields.  */
1492159047fSniklas       ret->types = NULL;
1502159047fSniklas     }
1512159047fSniklas 
1522159047fSniklas   return (struct bfd_hash_entry *) ret;
1532159047fSniklas }
1542159047fSniklas 
1552159047fSniklas /* Given a COFF BFD, add symbols to the global hash table as
1562159047fSniklas    appropriate.  */
1572159047fSniklas 
158c074d1c9Sdrahn bfd_boolean
_bfd_coff_link_add_symbols(bfd * abfd,struct bfd_link_info * info)159*007c2a45Smiod _bfd_coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
1602159047fSniklas {
1612159047fSniklas   switch (bfd_get_format (abfd))
1622159047fSniklas     {
1632159047fSniklas     case bfd_object:
1642159047fSniklas       return coff_link_add_object_symbols (abfd, info);
1652159047fSniklas     case bfd_archive:
166*007c2a45Smiod       return _bfd_generic_link_add_archive_symbols
167*007c2a45Smiod 	(abfd, info, coff_link_check_archive_element);
1682159047fSniklas     default:
1692159047fSniklas       bfd_set_error (bfd_error_wrong_format);
170c074d1c9Sdrahn       return FALSE;
1712159047fSniklas     }
1722159047fSniklas }
1732159047fSniklas 
1742159047fSniklas /* Add symbols from a COFF object file.  */
1752159047fSniklas 
176c074d1c9Sdrahn static bfd_boolean
coff_link_add_object_symbols(bfd * abfd,struct bfd_link_info * info)177*007c2a45Smiod coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
1782159047fSniklas {
1792159047fSniklas   if (! _bfd_coff_get_external_symbols (abfd))
180c074d1c9Sdrahn     return FALSE;
1812159047fSniklas   if (! coff_link_add_symbols (abfd, info))
182c074d1c9Sdrahn     return FALSE;
1832159047fSniklas 
184*007c2a45Smiod   if (! info->keep_memory
185*007c2a45Smiod       && ! _bfd_coff_free_symbols (abfd))
186c074d1c9Sdrahn     return FALSE;
1872159047fSniklas 
188c074d1c9Sdrahn   return TRUE;
1892159047fSniklas }
1902159047fSniklas 
1912159047fSniklas /* Look through the symbols to see if this object file should be
1922159047fSniklas    included in the link.  */
1932159047fSniklas 
194c074d1c9Sdrahn static bfd_boolean
coff_link_check_ar_symbols(bfd * abfd,struct bfd_link_info * info,bfd_boolean * pneeded)195*007c2a45Smiod coff_link_check_ar_symbols (bfd *abfd,
196*007c2a45Smiod 			    struct bfd_link_info *info,
197*007c2a45Smiod 			    bfd_boolean *pneeded)
1982159047fSniklas {
1992159047fSniklas   bfd_size_type symesz;
2002159047fSniklas   bfd_byte *esym;
2012159047fSniklas   bfd_byte *esym_end;
2022159047fSniklas 
203c074d1c9Sdrahn   *pneeded = FALSE;
2042159047fSniklas 
2052159047fSniklas   symesz = bfd_coff_symesz (abfd);
2062159047fSniklas   esym = (bfd_byte *) obj_coff_external_syms (abfd);
2072159047fSniklas   esym_end = esym + obj_raw_syment_count (abfd) * symesz;
2082159047fSniklas   while (esym < esym_end)
2092159047fSniklas     {
2102159047fSniklas       struct internal_syment sym;
211b305b0f1Sespie       enum coff_symbol_classification classification;
2122159047fSniklas 
213*007c2a45Smiod       bfd_coff_swap_sym_in (abfd, esym, &sym);
2142159047fSniklas 
215b305b0f1Sespie       classification = bfd_coff_classify_symbol (abfd, &sym);
216b305b0f1Sespie       if (classification == COFF_SYMBOL_GLOBAL
217b305b0f1Sespie 	  || classification == COFF_SYMBOL_COMMON)
2182159047fSniklas 	{
2192159047fSniklas 	  const char *name;
2202159047fSniklas 	  char buf[SYMNMLEN + 1];
2212159047fSniklas 	  struct bfd_link_hash_entry *h;
2222159047fSniklas 
2232159047fSniklas 	  /* This symbol is externally visible, and is defined by this
2242159047fSniklas              object file.  */
2252159047fSniklas 	  name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
2262159047fSniklas 	  if (name == NULL)
227c074d1c9Sdrahn 	    return FALSE;
228c074d1c9Sdrahn 	  h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
2292159047fSniklas 
230*007c2a45Smiod 	  /* Auto import.  */
231*007c2a45Smiod 	  if (!h
232*007c2a45Smiod 	      && info->pei386_auto_import
233*007c2a45Smiod 	      && !strncmp (name,"__imp_", 6))
234*007c2a45Smiod 	    h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE);
235*007c2a45Smiod 
2362159047fSniklas 	  /* We are only interested in symbols that are currently
2372159047fSniklas 	     undefined.  If a symbol is currently known to be common,
2382159047fSniklas 	     COFF linkers do not bring in an object file which defines
2392159047fSniklas 	     it.  */
2402159047fSniklas 	  if (h != (struct bfd_link_hash_entry *) NULL
2412159047fSniklas 	      && h->type == bfd_link_hash_undefined)
2422159047fSniklas 	    {
2432159047fSniklas 	      if (! (*info->callbacks->add_archive_element) (info, abfd, name))
244c074d1c9Sdrahn 		return FALSE;
245c074d1c9Sdrahn 	      *pneeded = TRUE;
246c074d1c9Sdrahn 	      return TRUE;
2472159047fSniklas 	    }
2482159047fSniklas 	}
2492159047fSniklas 
2502159047fSniklas       esym += (sym.n_numaux + 1) * symesz;
2512159047fSniklas     }
2522159047fSniklas 
2532159047fSniklas   /* We do not need this object file.  */
254c074d1c9Sdrahn   return TRUE;
2552159047fSniklas }
2562159047fSniklas 
257*007c2a45Smiod /* Check a single archive element to see if we need to include it in
258*007c2a45Smiod    the link.  *PNEEDED is set according to whether this element is
259*007c2a45Smiod    needed in the link or not.  This is called via
260*007c2a45Smiod    _bfd_generic_link_add_archive_symbols.  */
261*007c2a45Smiod 
262*007c2a45Smiod static bfd_boolean
coff_link_check_archive_element(bfd * abfd,struct bfd_link_info * info,bfd_boolean * pneeded)263*007c2a45Smiod coff_link_check_archive_element (bfd *abfd,
264*007c2a45Smiod 				 struct bfd_link_info *info,
265*007c2a45Smiod 				 bfd_boolean *pneeded)
266*007c2a45Smiod {
267*007c2a45Smiod   if (! _bfd_coff_get_external_symbols (abfd))
268*007c2a45Smiod     return FALSE;
269*007c2a45Smiod 
270*007c2a45Smiod   if (! coff_link_check_ar_symbols (abfd, info, pneeded))
271*007c2a45Smiod     return FALSE;
272*007c2a45Smiod 
273*007c2a45Smiod   if (*pneeded
274*007c2a45Smiod       && ! coff_link_add_symbols (abfd, info))
275*007c2a45Smiod     return FALSE;
276*007c2a45Smiod 
277*007c2a45Smiod   if ((! info->keep_memory || ! *pneeded)
278*007c2a45Smiod       && ! _bfd_coff_free_symbols (abfd))
279*007c2a45Smiod     return FALSE;
280*007c2a45Smiod 
281*007c2a45Smiod   return TRUE;
282*007c2a45Smiod }
283*007c2a45Smiod 
2842159047fSniklas /* Add all the symbols from an object file to the hash table.  */
2852159047fSniklas 
286c074d1c9Sdrahn static bfd_boolean
coff_link_add_symbols(bfd * abfd,struct bfd_link_info * info)287*007c2a45Smiod coff_link_add_symbols (bfd *abfd,
288*007c2a45Smiod 		       struct bfd_link_info *info)
2892159047fSniklas {
290b305b0f1Sespie   unsigned int n_tmask = coff_data (abfd)->local_n_tmask;
291b305b0f1Sespie   unsigned int n_btshft = coff_data (abfd)->local_n_btshft;
292b305b0f1Sespie   unsigned int n_btmask = coff_data (abfd)->local_n_btmask;
293c074d1c9Sdrahn   bfd_boolean keep_syms;
294c074d1c9Sdrahn   bfd_boolean default_copy;
2952159047fSniklas   bfd_size_type symcount;
2962159047fSniklas   struct coff_link_hash_entry **sym_hash;
2972159047fSniklas   bfd_size_type symesz;
2982159047fSniklas   bfd_byte *esym;
2992159047fSniklas   bfd_byte *esym_end;
300c074d1c9Sdrahn   bfd_size_type amt;
3012159047fSniklas 
302e93f7393Sniklas   /* Keep the symbols during this function, in case the linker needs
303e93f7393Sniklas      to read the generic symbols in order to report an error message.  */
304e93f7393Sniklas   keep_syms = obj_coff_keep_syms (abfd);
305c074d1c9Sdrahn   obj_coff_keep_syms (abfd) = TRUE;
306e93f7393Sniklas 
3072159047fSniklas   if (info->keep_memory)
308c074d1c9Sdrahn     default_copy = FALSE;
3092159047fSniklas   else
310c074d1c9Sdrahn     default_copy = TRUE;
3112159047fSniklas 
3122159047fSniklas   symcount = obj_raw_syment_count (abfd);
3132159047fSniklas 
3142159047fSniklas   /* We keep a list of the linker hash table entries that correspond
3152159047fSniklas      to particular symbols.  */
316c074d1c9Sdrahn   amt = symcount * sizeof (struct coff_link_hash_entry *);
317*007c2a45Smiod   sym_hash = bfd_zalloc (abfd, amt);
3182159047fSniklas   if (sym_hash == NULL && symcount != 0)
319e93f7393Sniklas     goto error_return;
3202159047fSniklas   obj_coff_sym_hashes (abfd) = sym_hash;
3212159047fSniklas 
3222159047fSniklas   symesz = bfd_coff_symesz (abfd);
3232159047fSniklas   BFD_ASSERT (symesz == bfd_coff_auxesz (abfd));
3242159047fSniklas   esym = (bfd_byte *) obj_coff_external_syms (abfd);
3252159047fSniklas   esym_end = esym + symcount * symesz;
3262159047fSniklas   while (esym < esym_end)
3272159047fSniklas     {
3282159047fSniklas       struct internal_syment sym;
329b305b0f1Sespie       enum coff_symbol_classification classification;
330c074d1c9Sdrahn       bfd_boolean copy;
3312159047fSniklas 
332*007c2a45Smiod       bfd_coff_swap_sym_in (abfd, esym, &sym);
3332159047fSniklas 
334b305b0f1Sespie       classification = bfd_coff_classify_symbol (abfd, &sym);
335b305b0f1Sespie       if (classification != COFF_SYMBOL_LOCAL)
3362159047fSniklas 	{
3372159047fSniklas 	  const char *name;
3382159047fSniklas 	  char buf[SYMNMLEN + 1];
3392159047fSniklas 	  flagword flags;
3402159047fSniklas 	  asection *section;
3412159047fSniklas 	  bfd_vma value;
342c074d1c9Sdrahn 	  bfd_boolean addit;
3432159047fSniklas 
3442159047fSniklas 	  /* This symbol is externally visible.  */
3452159047fSniklas 
3462159047fSniklas 	  name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
3472159047fSniklas 	  if (name == NULL)
348e93f7393Sniklas 	    goto error_return;
3492159047fSniklas 
3502159047fSniklas 	  /* We must copy the name into memory if we got it from the
3512159047fSniklas              syment itself, rather than the string table.  */
3522159047fSniklas 	  copy = default_copy;
3532159047fSniklas 	  if (sym._n._n_n._n_zeroes != 0
3542159047fSniklas 	      || sym._n._n_n._n_offset == 0)
355c074d1c9Sdrahn 	    copy = TRUE;
3562159047fSniklas 
3572159047fSniklas 	  value = sym.n_value;
3582159047fSniklas 
359b305b0f1Sespie 	  switch (classification)
3602159047fSniklas 	    {
361b305b0f1Sespie 	    default:
362b305b0f1Sespie 	      abort ();
363b305b0f1Sespie 
364b305b0f1Sespie 	    case COFF_SYMBOL_GLOBAL:
3652159047fSniklas 	      flags = BSF_EXPORT | BSF_GLOBAL;
3662159047fSniklas 	      section = coff_section_from_bfd_index (abfd, sym.n_scnum);
367b305b0f1Sespie 	      if (! obj_pe (abfd))
3682159047fSniklas 		value -= section->vma;
369b305b0f1Sespie 	      break;
370b305b0f1Sespie 
371b305b0f1Sespie 	    case COFF_SYMBOL_UNDEFINED:
372b305b0f1Sespie 	      flags = 0;
373b305b0f1Sespie 	      section = bfd_und_section_ptr;
374b305b0f1Sespie 	      break;
375b305b0f1Sespie 
376b305b0f1Sespie 	    case COFF_SYMBOL_COMMON:
377b305b0f1Sespie 	      flags = BSF_GLOBAL;
378b305b0f1Sespie 	      section = bfd_com_section_ptr;
379b305b0f1Sespie 	      break;
380b305b0f1Sespie 
381b305b0f1Sespie 	    case COFF_SYMBOL_PE_SECTION:
382b305b0f1Sespie 	      flags = BSF_SECTION_SYM | BSF_GLOBAL;
383b305b0f1Sespie 	      section = coff_section_from_bfd_index (abfd, sym.n_scnum);
384b305b0f1Sespie 	      break;
3852159047fSniklas 	    }
3862159047fSniklas 
387b55d4692Sfgsch 	  if (IS_WEAK_EXTERNAL (abfd, sym))
388b305b0f1Sespie 	    flags = BSF_WEAK;
389b305b0f1Sespie 
390c074d1c9Sdrahn 	  addit = TRUE;
391b305b0f1Sespie 
392b305b0f1Sespie 	  /* In the PE format, section symbols actually refer to the
393b305b0f1Sespie              start of the output section.  We handle them specially
394b305b0f1Sespie              here.  */
395b305b0f1Sespie 	  if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
396b305b0f1Sespie 	    {
397b305b0f1Sespie 	      *sym_hash = coff_link_hash_lookup (coff_hash_table (info),
398c074d1c9Sdrahn 						 name, FALSE, copy, FALSE);
399b305b0f1Sespie 	      if (*sym_hash != NULL)
400b305b0f1Sespie 		{
401b305b0f1Sespie 		  if (((*sym_hash)->coff_link_hash_flags
402b305b0f1Sespie 		       & COFF_LINK_HASH_PE_SECTION_SYMBOL) == 0
403b305b0f1Sespie 		      && (*sym_hash)->root.type != bfd_link_hash_undefined
404b305b0f1Sespie 		      && (*sym_hash)->root.type != bfd_link_hash_undefweak)
405b305b0f1Sespie 		    (*_bfd_error_handler)
406b305b0f1Sespie 		      ("Warning: symbol `%s' is both section and non-section",
407b305b0f1Sespie 		       name);
408b305b0f1Sespie 
409c074d1c9Sdrahn 		  addit = FALSE;
410b305b0f1Sespie 		}
411b305b0f1Sespie 	    }
412b305b0f1Sespie 
413b305b0f1Sespie 	  /* The Microsoft Visual C compiler does string pooling by
414b305b0f1Sespie 	     hashing the constants to an internal symbol name, and
415c074d1c9Sdrahn 	     relying on the linker comdat support to discard
416b305b0f1Sespie 	     duplicate names.  However, if one string is a literal and
417b305b0f1Sespie 	     one is a data initializer, one will end up in the .data
418b305b0f1Sespie 	     section and one will end up in the .rdata section.  The
419b305b0f1Sespie 	     Microsoft linker will combine them into the .data
420b305b0f1Sespie 	     section, which seems to be wrong since it might cause the
421b305b0f1Sespie 	     literal to change.
422b305b0f1Sespie 
423b305b0f1Sespie 	     As long as there are no external references to the
424b305b0f1Sespie 	     symbols, which there shouldn't be, we can treat the .data
425b305b0f1Sespie 	     and .rdata instances as separate symbols.  The comdat
426b305b0f1Sespie 	     code in the linker will do the appropriate merging.  Here
427b305b0f1Sespie 	     we avoid getting a multiple definition error for one of
428b305b0f1Sespie 	     these special symbols.
429b305b0f1Sespie 
430b305b0f1Sespie 	     FIXME: I don't think this will work in the case where
431b305b0f1Sespie 	     there are two object files which use the constants as a
432b305b0f1Sespie 	     literal and two object files which use it as a data
433b305b0f1Sespie 	     initializer.  One or the other of the second object files
434b305b0f1Sespie 	     is going to wind up with an inappropriate reference.  */
435b305b0f1Sespie 	  if (obj_pe (abfd)
436b305b0f1Sespie 	      && (classification == COFF_SYMBOL_GLOBAL
437b305b0f1Sespie 		  || classification == COFF_SYMBOL_PE_SECTION)
438b305b0f1Sespie 	      && section->comdat != NULL
439b305b0f1Sespie 	      && strncmp (name, "??_", 3) == 0
440b305b0f1Sespie 	      && strcmp (name, section->comdat->name) == 0)
441b305b0f1Sespie 	    {
442b305b0f1Sespie 	      if (*sym_hash == NULL)
443b305b0f1Sespie 		*sym_hash = coff_link_hash_lookup (coff_hash_table (info),
444c074d1c9Sdrahn 						   name, FALSE, copy, FALSE);
445b305b0f1Sespie 	      if (*sym_hash != NULL
446b305b0f1Sespie 		  && (*sym_hash)->root.type == bfd_link_hash_defined
447b305b0f1Sespie 		  && (*sym_hash)->root.u.def.section->comdat != NULL
448b305b0f1Sespie 		  && strcmp ((*sym_hash)->root.u.def.section->comdat->name,
449b305b0f1Sespie 			     section->comdat->name) == 0)
450c074d1c9Sdrahn 		addit = FALSE;
451b305b0f1Sespie 	    }
452b305b0f1Sespie 
453b305b0f1Sespie 	  if (addit)
454b305b0f1Sespie 	    {
455c88b1d6cSniklas 	      if (! (bfd_coff_link_add_one_symbol
4562159047fSniklas 		     (info, abfd, name, flags, section, value,
457c074d1c9Sdrahn 		      (const char *) NULL, copy, FALSE,
4582159047fSniklas 		      (struct bfd_link_hash_entry **) sym_hash)))
459e93f7393Sniklas 		goto error_return;
460b305b0f1Sespie 	    }
461b305b0f1Sespie 
462b305b0f1Sespie 	  if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
463b305b0f1Sespie 	    (*sym_hash)->coff_link_hash_flags |=
464b305b0f1Sespie 	      COFF_LINK_HASH_PE_SECTION_SYMBOL;
465b305b0f1Sespie 
466b305b0f1Sespie 	  /* Limit the alignment of a common symbol to the possible
467b305b0f1Sespie              alignment of a section.  There is no point to permitting
468b305b0f1Sespie              a higher alignment for a common symbol: we can not
469b305b0f1Sespie              guarantee it, and it may cause us to allocate extra space
470b305b0f1Sespie              in the common section.  */
471b305b0f1Sespie 	  if (section == bfd_com_section_ptr
472b305b0f1Sespie 	      && (*sym_hash)->root.type == bfd_link_hash_common
473b305b0f1Sespie 	      && ((*sym_hash)->root.u.c.p->alignment_power
474b305b0f1Sespie 		  > bfd_coff_default_section_alignment_power (abfd)))
475b305b0f1Sespie 	    (*sym_hash)->root.u.c.p->alignment_power
476b305b0f1Sespie 	      = bfd_coff_default_section_alignment_power (abfd);
4772159047fSniklas 
4782159047fSniklas 	  if (info->hash->creator->flavour == bfd_get_flavour (abfd))
4792159047fSniklas 	    {
480b305b0f1Sespie 	      /* If we don't have any symbol information currently in
481b305b0f1Sespie                  the hash table, or if we are looking at a symbol
482b305b0f1Sespie                  definition, then update the symbol class and type in
483b305b0f1Sespie                  the hash table.  */
4842159047fSniklas   	      if (((*sym_hash)->class == C_NULL
4852159047fSniklas   		   && (*sym_hash)->type == T_NULL)
4862159047fSniklas   		  || sym.n_scnum != 0
4872159047fSniklas   		  || (sym.n_value != 0
488b305b0f1Sespie   		      && (*sym_hash)->root.type != bfd_link_hash_defined
489b305b0f1Sespie   		      && (*sym_hash)->root.type != bfd_link_hash_defweak))
4902159047fSniklas   		{
4912159047fSniklas   		  (*sym_hash)->class = sym.n_sclass;
492e93f7393Sniklas   		  if (sym.n_type != T_NULL)
493e93f7393Sniklas   		    {
494b305b0f1Sespie   		      /* We want to warn if the type changed, but not
495b305b0f1Sespie   			 if it changed from an unspecified type.
496b305b0f1Sespie   			 Testing the whole type byte may work, but the
497b305b0f1Sespie   			 change from (e.g.) a function of unspecified
498b305b0f1Sespie   			 type to function of known type also wants to
499b305b0f1Sespie   			 skip the warning.  */
500e93f7393Sniklas   		      if ((*sym_hash)->type != T_NULL
501b305b0f1Sespie   			  && (*sym_hash)->type != sym.n_type
502b305b0f1Sespie   		          && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type)
503b305b0f1Sespie   		               && (BTYPE ((*sym_hash)->type) == T_NULL
504b305b0f1Sespie   		                   || BTYPE (sym.n_type) == T_NULL)))
505e93f7393Sniklas   			(*_bfd_error_handler)
506b305b0f1Sespie   			  (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
507e93f7393Sniklas   			   name, (*sym_hash)->type, sym.n_type,
508c074d1c9Sdrahn   			   bfd_archive_filename (abfd));
509b305b0f1Sespie 
510b305b0f1Sespie   		      /* We don't want to change from a meaningful
511b305b0f1Sespie   			 base type to a null one, but if we know
512b305b0f1Sespie   			 nothing, take what little we might now know.  */
513b305b0f1Sespie   		      if (BTYPE (sym.n_type) != T_NULL
514b305b0f1Sespie   			  || (*sym_hash)->type == T_NULL)
5152159047fSniklas 			(*sym_hash)->type = sym.n_type;
516e93f7393Sniklas   		    }
5172159047fSniklas   		  (*sym_hash)->auxbfd = abfd;
5182159047fSniklas 		  if (sym.n_numaux != 0)
5192159047fSniklas 		    {
5202159047fSniklas 		      union internal_auxent *alloc;
5212159047fSniklas 		      unsigned int i;
5222159047fSniklas 		      bfd_byte *eaux;
5232159047fSniklas 		      union internal_auxent *iaux;
5242159047fSniklas 
5250c6d0228Sniklas 		      (*sym_hash)->numaux = sym.n_numaux;
5262159047fSniklas 		      alloc = ((union internal_auxent *)
5272159047fSniklas 			       bfd_hash_allocate (&info->hash->table,
5282159047fSniklas 						  (sym.n_numaux
5292159047fSniklas 						   * sizeof (*alloc))));
5302159047fSniklas 		      if (alloc == NULL)
531e93f7393Sniklas 			goto error_return;
5322159047fSniklas 		      for (i = 0, eaux = esym + symesz, iaux = alloc;
5332159047fSniklas 			   i < sym.n_numaux;
5342159047fSniklas 			   i++, eaux += symesz, iaux++)
535*007c2a45Smiod 			bfd_coff_swap_aux_in (abfd, eaux, sym.n_type,
536c074d1c9Sdrahn 					      sym.n_sclass, (int) i,
537*007c2a45Smiod 					      sym.n_numaux, iaux);
5382159047fSniklas 		      (*sym_hash)->aux = alloc;
5392159047fSniklas 		    }
5402159047fSniklas 		}
5412159047fSniklas 	    }
542b305b0f1Sespie 
543b305b0f1Sespie 	  if (classification == COFF_SYMBOL_PE_SECTION
544b305b0f1Sespie 	      && (*sym_hash)->numaux != 0)
545b305b0f1Sespie 	    {
546b305b0f1Sespie 	      /* Some PE sections (such as .bss) have a zero size in
547b305b0f1Sespie                  the section header, but a non-zero size in the AUX
548b305b0f1Sespie                  record.  Correct that here.
549b305b0f1Sespie 
550b305b0f1Sespie 		 FIXME: This is not at all the right place to do this.
551b305b0f1Sespie 		 For example, it won't help objdump.  This needs to be
552b305b0f1Sespie 		 done when we swap in the section header.  */
553b305b0f1Sespie 	      BFD_ASSERT ((*sym_hash)->numaux == 1);
554b305b0f1Sespie 	      if (section->_raw_size == 0)
555b305b0f1Sespie 		section->_raw_size = (*sym_hash)->aux[0].x_scn.x_scnlen;
556b305b0f1Sespie 
557b305b0f1Sespie 	      /* FIXME: We could test whether the section sizes
558b305b0f1Sespie                  matches the size in the aux entry, but apparently
559b305b0f1Sespie                  that sometimes fails unexpectedly.  */
560b305b0f1Sespie 	    }
5612159047fSniklas 	}
5622159047fSniklas 
5632159047fSniklas       esym += (sym.n_numaux + 1) * symesz;
5642159047fSniklas       sym_hash += sym.n_numaux + 1;
5652159047fSniklas     }
5662159047fSniklas 
567*007c2a45Smiod   /* If this is a non-traditional, non-relocatable link, try to
568c88b1d6cSniklas      optimize the handling of any .stab/.stabstr sections.  */
569*007c2a45Smiod   if (! info->relocatable
570c88b1d6cSniklas       && ! info->traditional_format
571c88b1d6cSniklas       && info->hash->creator->flavour == bfd_get_flavour (abfd)
572c88b1d6cSniklas       && (info->strip != strip_all && info->strip != strip_debugger))
573c88b1d6cSniklas     {
574*007c2a45Smiod       asection *stabstr;
575c88b1d6cSniklas 
576c88b1d6cSniklas       stabstr = bfd_get_section_by_name (abfd, ".stabstr");
577c88b1d6cSniklas 
578c88b1d6cSniklas       if (stabstr != NULL)
579c88b1d6cSniklas 	{
580*007c2a45Smiod 	  bfd_size_type string_offset = 0;
581*007c2a45Smiod 	  asection *stab;
582c88b1d6cSniklas 
583*007c2a45Smiod 	  for (stab = abfd->sections; stab; stab = stab->next)
584*007c2a45Smiod 	    if (strncmp (".stab", stab->name, 5) == 0
585*007c2a45Smiod 		&& (!stab->name[5]
586*007c2a45Smiod 		    || (stab->name[5] == '.' && ISDIGIT (stab->name[6]))))
587*007c2a45Smiod 	    {
588*007c2a45Smiod 	      struct coff_link_hash_table *table;
589*007c2a45Smiod 	      struct coff_section_tdata *secdata
590*007c2a45Smiod 		= coff_section_data (abfd, stab);
591*007c2a45Smiod 
592c88b1d6cSniklas 	      if (secdata == NULL)
593c88b1d6cSniklas 		{
594c074d1c9Sdrahn 		  amt = sizeof (struct coff_section_tdata);
595*007c2a45Smiod 		  stab->used_by_bfd = bfd_zalloc (abfd, amt);
596c88b1d6cSniklas 		  if (stab->used_by_bfd == NULL)
597e93f7393Sniklas 		    goto error_return;
598c88b1d6cSniklas 		  secdata = coff_section_data (abfd, stab);
599c88b1d6cSniklas 		}
600c88b1d6cSniklas 
601c88b1d6cSniklas 	      table = coff_hash_table (info);
602c88b1d6cSniklas 
603c88b1d6cSniklas 	      if (! _bfd_link_section_stabs (abfd, &table->stab_info,
604c88b1d6cSniklas 					     stab, stabstr,
605*007c2a45Smiod 					     &secdata->stab_info,
606*007c2a45Smiod 					     &string_offset))
607e93f7393Sniklas 		goto error_return;
608c88b1d6cSniklas 	    }
609c88b1d6cSniklas 	}
610c88b1d6cSniklas     }
611c88b1d6cSniklas 
612e93f7393Sniklas   obj_coff_keep_syms (abfd) = keep_syms;
613e93f7393Sniklas 
614c074d1c9Sdrahn   return TRUE;
615e93f7393Sniklas 
616e93f7393Sniklas  error_return:
617e93f7393Sniklas   obj_coff_keep_syms (abfd) = keep_syms;
618c074d1c9Sdrahn   return FALSE;
6192159047fSniklas }
6202159047fSniklas 
6212159047fSniklas /* Do the final link step.  */
6222159047fSniklas 
623c074d1c9Sdrahn bfd_boolean
_bfd_coff_final_link(bfd * abfd,struct bfd_link_info * info)624*007c2a45Smiod _bfd_coff_final_link (bfd *abfd,
625*007c2a45Smiod 		      struct bfd_link_info *info)
6262159047fSniklas {
6272159047fSniklas   bfd_size_type symesz;
6282159047fSniklas   struct coff_final_link_info finfo;
629c074d1c9Sdrahn   bfd_boolean debug_merge_allocated;
630c074d1c9Sdrahn   bfd_boolean long_section_names;
6312159047fSniklas   asection *o;
6322159047fSniklas   struct bfd_link_order *p;
633c074d1c9Sdrahn   bfd_size_type max_sym_count;
634c074d1c9Sdrahn   bfd_size_type max_lineno_count;
635c074d1c9Sdrahn   bfd_size_type max_reloc_count;
636c074d1c9Sdrahn   bfd_size_type max_output_reloc_count;
637c074d1c9Sdrahn   bfd_size_type max_contents_size;
6382159047fSniklas   file_ptr rel_filepos;
6392159047fSniklas   unsigned int relsz;
6402159047fSniklas   file_ptr line_filepos;
6412159047fSniklas   unsigned int linesz;
6422159047fSniklas   bfd *sub;
6432159047fSniklas   bfd_byte *external_relocs = NULL;
6442159047fSniklas   char strbuf[STRING_SIZE_SIZE];
645c074d1c9Sdrahn   bfd_size_type amt;
6462159047fSniklas 
6472159047fSniklas   symesz = bfd_coff_symesz (abfd);
6482159047fSniklas 
6492159047fSniklas   finfo.info = info;
6502159047fSniklas   finfo.output_bfd = abfd;
6512159047fSniklas   finfo.strtab = NULL;
6522159047fSniklas   finfo.section_info = NULL;
6532159047fSniklas   finfo.last_file_index = -1;
654c88b1d6cSniklas   finfo.last_bf_index = -1;
6552159047fSniklas   finfo.internal_syms = NULL;
6562159047fSniklas   finfo.sec_ptrs = NULL;
6572159047fSniklas   finfo.sym_indices = NULL;
6582159047fSniklas   finfo.outsyms = NULL;
6592159047fSniklas   finfo.linenos = NULL;
6602159047fSniklas   finfo.contents = NULL;
6612159047fSniklas   finfo.external_relocs = NULL;
6622159047fSniklas   finfo.internal_relocs = NULL;
663c074d1c9Sdrahn   finfo.global_to_static = FALSE;
664c074d1c9Sdrahn   debug_merge_allocated = FALSE;
6652159047fSniklas 
6662159047fSniklas   coff_data (abfd)->link_info = info;
6672159047fSniklas 
6682159047fSniklas   finfo.strtab = _bfd_stringtab_init ();
6692159047fSniklas   if (finfo.strtab == NULL)
6702159047fSniklas     goto error_return;
6712159047fSniklas 
6722159047fSniklas   if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
6732159047fSniklas     goto error_return;
674c074d1c9Sdrahn   debug_merge_allocated = TRUE;
6752159047fSniklas 
6762159047fSniklas   /* Compute the file positions for all the sections.  */
6772159047fSniklas   if (! abfd->output_has_begun)
678b305b0f1Sespie     {
679b305b0f1Sespie       if (! bfd_coff_compute_section_file_positions (abfd))
680b305b0f1Sespie 	goto error_return;
681b305b0f1Sespie     }
6822159047fSniklas 
6832159047fSniklas   /* Count the line numbers and relocation entries required for the
6842159047fSniklas      output file.  Set the file positions for the relocs.  */
6852159047fSniklas   rel_filepos = obj_relocbase (abfd);
6862159047fSniklas   relsz = bfd_coff_relsz (abfd);
6872159047fSniklas   max_contents_size = 0;
6882159047fSniklas   max_lineno_count = 0;
6892159047fSniklas   max_reloc_count = 0;
690c88b1d6cSniklas 
691c074d1c9Sdrahn   long_section_names = FALSE;
6922159047fSniklas   for (o = abfd->sections; o != NULL; o = o->next)
6932159047fSniklas     {
6942159047fSniklas       o->reloc_count = 0;
6952159047fSniklas       o->lineno_count = 0;
6962159047fSniklas       for (p = o->link_order_head; p != NULL; p = p->next)
6972159047fSniklas 	{
6982159047fSniklas 	  if (p->type == bfd_indirect_link_order)
6992159047fSniklas 	    {
7002159047fSniklas 	      asection *sec;
7012159047fSniklas 
7022159047fSniklas 	      sec = p->u.indirect.section;
7032159047fSniklas 
704c88b1d6cSniklas 	      /* Mark all sections which are to be included in the
705c88b1d6cSniklas 		 link.  This will normally be every section.  We need
706c88b1d6cSniklas 		 to do this so that we can identify any sections which
707c88b1d6cSniklas 		 the linker has decided to not include.  */
708c074d1c9Sdrahn 	      sec->linker_mark = TRUE;
709c88b1d6cSniklas 
7102159047fSniklas 	      if (info->strip == strip_none
7112159047fSniklas 		  || info->strip == strip_some)
7122159047fSniklas 		o->lineno_count += sec->lineno_count;
7132159047fSniklas 
714*007c2a45Smiod 	      if (info->relocatable)
7152159047fSniklas 		o->reloc_count += sec->reloc_count;
7162159047fSniklas 
7172159047fSniklas 	      if (sec->_raw_size > max_contents_size)
7182159047fSniklas 		max_contents_size = sec->_raw_size;
7192159047fSniklas 	      if (sec->lineno_count > max_lineno_count)
7202159047fSniklas 		max_lineno_count = sec->lineno_count;
7212159047fSniklas 	      if (sec->reloc_count > max_reloc_count)
7222159047fSniklas 		max_reloc_count = sec->reloc_count;
7232159047fSniklas 	    }
724*007c2a45Smiod 	  else if (info->relocatable
7252159047fSniklas 		   && (p->type == bfd_section_reloc_link_order
7262159047fSniklas 		       || p->type == bfd_symbol_reloc_link_order))
7272159047fSniklas 	    ++o->reloc_count;
7282159047fSniklas 	}
7292159047fSniklas       if (o->reloc_count == 0)
7302159047fSniklas 	o->rel_filepos = 0;
7312159047fSniklas       else
7322159047fSniklas 	{
7332159047fSniklas 	  o->flags |= SEC_RELOC;
7342159047fSniklas 	  o->rel_filepos = rel_filepos;
7352159047fSniklas 	  rel_filepos += o->reloc_count * relsz;
736c074d1c9Sdrahn 	  /* In PE COFF, if there are at least 0xffff relocations an
737c074d1c9Sdrahn 	     extra relocation will be written out to encode the count.  */
738c074d1c9Sdrahn 	  if (obj_pe (abfd) && o->reloc_count >= 0xffff)
739c074d1c9Sdrahn 	    rel_filepos += relsz;
7402159047fSniklas 	}
7410c6d0228Sniklas 
7420c6d0228Sniklas       if (bfd_coff_long_section_names (abfd)
7430c6d0228Sniklas 	  && strlen (o->name) > SCNNMLEN)
7440c6d0228Sniklas 	{
7450c6d0228Sniklas 	  /* This section has a long name which must go in the string
7460c6d0228Sniklas              table.  This must correspond to the code in
7470c6d0228Sniklas              coff_write_object_contents which puts the string index
7480c6d0228Sniklas              into the s_name field of the section header.  That is why
749c074d1c9Sdrahn              we pass hash as FALSE.  */
750c074d1c9Sdrahn 	  if (_bfd_stringtab_add (finfo.strtab, o->name, FALSE, FALSE)
7510c6d0228Sniklas 	      == (bfd_size_type) -1)
7520c6d0228Sniklas 	    goto error_return;
753c074d1c9Sdrahn 	  long_section_names = TRUE;
7540c6d0228Sniklas 	}
7552159047fSniklas     }
7562159047fSniklas 
757*007c2a45Smiod   /* If doing a relocatable link, allocate space for the pointers we
7582159047fSniklas      need to keep.  */
759*007c2a45Smiod   if (info->relocatable)
7602159047fSniklas     {
7612159047fSniklas       unsigned int i;
7622159047fSniklas 
7632159047fSniklas       /* We use section_count + 1, rather than section_count, because
7642159047fSniklas          the target_index fields are 1 based.  */
765c074d1c9Sdrahn       amt = abfd->section_count + 1;
766c074d1c9Sdrahn       amt *= sizeof (struct coff_link_section_info);
767*007c2a45Smiod       finfo.section_info = bfd_malloc (amt);
7682159047fSniklas       if (finfo.section_info == NULL)
7692159047fSniklas 	goto error_return;
7702159047fSniklas       for (i = 0; i <= abfd->section_count; i++)
7712159047fSniklas 	{
7722159047fSniklas 	  finfo.section_info[i].relocs = NULL;
7732159047fSniklas 	  finfo.section_info[i].rel_hashes = NULL;
7742159047fSniklas 	}
7752159047fSniklas     }
7762159047fSniklas 
7772159047fSniklas   /* We now know the size of the relocs, so we can determine the file
7782159047fSniklas      positions of the line numbers.  */
7792159047fSniklas   line_filepos = rel_filepos;
7802159047fSniklas   linesz = bfd_coff_linesz (abfd);
7812159047fSniklas   max_output_reloc_count = 0;
7822159047fSniklas   for (o = abfd->sections; o != NULL; o = o->next)
7832159047fSniklas     {
7842159047fSniklas       if (o->lineno_count == 0)
7852159047fSniklas 	o->line_filepos = 0;
7862159047fSniklas       else
7872159047fSniklas 	{
7882159047fSniklas 	  o->line_filepos = line_filepos;
7892159047fSniklas 	  line_filepos += o->lineno_count * linesz;
7902159047fSniklas 	}
7912159047fSniklas 
7922159047fSniklas       if (o->reloc_count != 0)
7932159047fSniklas 	{
7942159047fSniklas 	  /* We don't know the indices of global symbols until we have
7952159047fSniklas              written out all the local symbols.  For each section in
7962159047fSniklas              the output file, we keep an array of pointers to hash
7972159047fSniklas              table entries.  Each entry in the array corresponds to a
7982159047fSniklas              reloc.  When we find a reloc against a global symbol, we
7992159047fSniklas              set the corresponding entry in this array so that we can
8002159047fSniklas              fix up the symbol index after we have written out all the
8012159047fSniklas              local symbols.
8022159047fSniklas 
8032159047fSniklas 	     Because of this problem, we also keep the relocs in
8042159047fSniklas 	     memory until the end of the link.  This wastes memory,
805*007c2a45Smiod 	     but only when doing a relocatable link, which is not the
8062159047fSniklas 	     common case.  */
807*007c2a45Smiod 	  BFD_ASSERT (info->relocatable);
808c074d1c9Sdrahn 	  amt = o->reloc_count;
809c074d1c9Sdrahn 	  amt *= sizeof (struct internal_reloc);
810*007c2a45Smiod 	  finfo.section_info[o->target_index].relocs = bfd_malloc (amt);
811c074d1c9Sdrahn 	  amt = o->reloc_count;
812c074d1c9Sdrahn 	  amt *= sizeof (struct coff_link_hash_entry *);
813*007c2a45Smiod 	  finfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt);
8142159047fSniklas 	  if (finfo.section_info[o->target_index].relocs == NULL
8152159047fSniklas 	      || finfo.section_info[o->target_index].rel_hashes == NULL)
8162159047fSniklas 	    goto error_return;
8172159047fSniklas 
8182159047fSniklas 	  if (o->reloc_count > max_output_reloc_count)
8192159047fSniklas 	    max_output_reloc_count = o->reloc_count;
8202159047fSniklas 	}
8212159047fSniklas 
8222159047fSniklas       /* Reset the reloc and lineno counts, so that we can use them to
8232159047fSniklas 	 count the number of entries we have output so far.  */
8242159047fSniklas       o->reloc_count = 0;
8252159047fSniklas       o->lineno_count = 0;
8262159047fSniklas     }
8272159047fSniklas 
8282159047fSniklas   obj_sym_filepos (abfd) = line_filepos;
8292159047fSniklas 
8302159047fSniklas   /* Figure out the largest number of symbols in an input BFD.  Take
8312159047fSniklas      the opportunity to clear the output_has_begun fields of all the
8322159047fSniklas      input BFD's.  */
8332159047fSniklas   max_sym_count = 0;
8342159047fSniklas   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
8352159047fSniklas     {
8362159047fSniklas       size_t sz;
8372159047fSniklas 
838c074d1c9Sdrahn       sub->output_has_begun = FALSE;
8392159047fSniklas       sz = obj_raw_syment_count (sub);
8402159047fSniklas       if (sz > max_sym_count)
8412159047fSniklas 	max_sym_count = sz;
8422159047fSniklas     }
8432159047fSniklas 
8442159047fSniklas   /* Allocate some buffers used while linking.  */
845c074d1c9Sdrahn   amt = max_sym_count * sizeof (struct internal_syment);
846*007c2a45Smiod   finfo.internal_syms = bfd_malloc (amt);
847c074d1c9Sdrahn   amt = max_sym_count * sizeof (asection *);
848*007c2a45Smiod   finfo.sec_ptrs = bfd_malloc (amt);
849c074d1c9Sdrahn   amt = max_sym_count * sizeof (long);
850*007c2a45Smiod   finfo.sym_indices = bfd_malloc (amt);
851*007c2a45Smiod   finfo.outsyms = bfd_malloc ((max_sym_count + 1) * symesz);
852c074d1c9Sdrahn   amt = max_lineno_count * bfd_coff_linesz (abfd);
853*007c2a45Smiod   finfo.linenos = bfd_malloc (amt);
854*007c2a45Smiod   finfo.contents = bfd_malloc (max_contents_size);
855c074d1c9Sdrahn   amt = max_reloc_count * relsz;
856*007c2a45Smiod   finfo.external_relocs = bfd_malloc (amt);
857*007c2a45Smiod   if (! info->relocatable)
858c074d1c9Sdrahn     {
859c074d1c9Sdrahn       amt = max_reloc_count * sizeof (struct internal_reloc);
860*007c2a45Smiod       finfo.internal_relocs = bfd_malloc (amt);
861c074d1c9Sdrahn     }
8622159047fSniklas   if ((finfo.internal_syms == NULL && max_sym_count > 0)
8632159047fSniklas       || (finfo.sec_ptrs == NULL && max_sym_count > 0)
8642159047fSniklas       || (finfo.sym_indices == NULL && max_sym_count > 0)
8652159047fSniklas       || finfo.outsyms == NULL
8662159047fSniklas       || (finfo.linenos == NULL && max_lineno_count > 0)
8672159047fSniklas       || (finfo.contents == NULL && max_contents_size > 0)
8682159047fSniklas       || (finfo.external_relocs == NULL && max_reloc_count > 0)
869*007c2a45Smiod       || (! info->relocatable
8702159047fSniklas 	  && finfo.internal_relocs == NULL
8712159047fSniklas 	  && max_reloc_count > 0))
8722159047fSniklas     goto error_return;
8732159047fSniklas 
8742159047fSniklas   /* We now know the position of everything in the file, except that
8752159047fSniklas      we don't know the size of the symbol table and therefore we don't
8762159047fSniklas      know where the string table starts.  We just build the string
8772159047fSniklas      table in memory as we go along.  We process all the relocations
8782159047fSniklas      for a single input file at once.  */
8792159047fSniklas   obj_raw_syment_count (abfd) = 0;
8802159047fSniklas 
8812159047fSniklas   if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
8822159047fSniklas     {
8832159047fSniklas       if (! bfd_coff_start_final_link (abfd, info))
8842159047fSniklas 	goto error_return;
8852159047fSniklas     }
8862159047fSniklas 
8872159047fSniklas   for (o = abfd->sections; o != NULL; o = o->next)
8882159047fSniklas     {
8892159047fSniklas       for (p = o->link_order_head; p != NULL; p = p->next)
8902159047fSniklas 	{
8912159047fSniklas 	  if (p->type == bfd_indirect_link_order
892b55d4692Sfgsch 	      && bfd_family_coff (p->u.indirect.section->owner))
8932159047fSniklas 	    {
8942159047fSniklas 	      sub = p->u.indirect.section->owner;
895b305b0f1Sespie 	      if (! bfd_coff_link_output_has_begun (sub, & finfo))
8962159047fSniklas 		{
897c88b1d6cSniklas 		  if (! _bfd_coff_link_input_bfd (&finfo, sub))
8982159047fSniklas 		    goto error_return;
899c074d1c9Sdrahn 		  sub->output_has_begun = TRUE;
9002159047fSniklas 		}
9012159047fSniklas 	    }
9022159047fSniklas 	  else if (p->type == bfd_section_reloc_link_order
9032159047fSniklas 		   || p->type == bfd_symbol_reloc_link_order)
9042159047fSniklas 	    {
905c88b1d6cSniklas 	      if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
9062159047fSniklas 		goto error_return;
9072159047fSniklas 	    }
9082159047fSniklas 	  else
9092159047fSniklas 	    {
9102159047fSniklas 	      if (! _bfd_default_link_order (abfd, info, o, p))
9112159047fSniklas 		goto error_return;
9122159047fSniklas 	    }
9132159047fSniklas 	}
9142159047fSniklas     }
9152159047fSniklas 
916b305b0f1Sespie   if (! bfd_coff_final_link_postscript (abfd, & finfo))
917b305b0f1Sespie     goto error_return;
918b305b0f1Sespie 
919c88b1d6cSniklas   /* Free up the buffers used by _bfd_coff_link_input_bfd.  */
9202159047fSniklas 
9212159047fSniklas   coff_debug_merge_hash_table_free (&finfo.debug_merge);
922c074d1c9Sdrahn   debug_merge_allocated = FALSE;
9232159047fSniklas 
9242159047fSniklas   if (finfo.internal_syms != NULL)
9252159047fSniklas     {
9262159047fSniklas       free (finfo.internal_syms);
9272159047fSniklas       finfo.internal_syms = NULL;
9282159047fSniklas     }
9292159047fSniklas   if (finfo.sec_ptrs != NULL)
9302159047fSniklas     {
9312159047fSniklas       free (finfo.sec_ptrs);
9322159047fSniklas       finfo.sec_ptrs = NULL;
9332159047fSniklas     }
9342159047fSniklas   if (finfo.sym_indices != NULL)
9352159047fSniklas     {
9362159047fSniklas       free (finfo.sym_indices);
9372159047fSniklas       finfo.sym_indices = NULL;
9382159047fSniklas     }
9392159047fSniklas   if (finfo.linenos != NULL)
9402159047fSniklas     {
9412159047fSniklas       free (finfo.linenos);
9422159047fSniklas       finfo.linenos = NULL;
9432159047fSniklas     }
9442159047fSniklas   if (finfo.contents != NULL)
9452159047fSniklas     {
9462159047fSniklas       free (finfo.contents);
9472159047fSniklas       finfo.contents = NULL;
9482159047fSniklas     }
9492159047fSniklas   if (finfo.external_relocs != NULL)
9502159047fSniklas     {
9512159047fSniklas       free (finfo.external_relocs);
9522159047fSniklas       finfo.external_relocs = NULL;
9532159047fSniklas     }
9542159047fSniklas   if (finfo.internal_relocs != NULL)
9552159047fSniklas     {
9562159047fSniklas       free (finfo.internal_relocs);
9572159047fSniklas       finfo.internal_relocs = NULL;
9582159047fSniklas     }
9592159047fSniklas 
9602159047fSniklas   /* The value of the last C_FILE symbol is supposed to be the symbol
9612159047fSniklas      index of the first external symbol.  Write it out again if
9622159047fSniklas      necessary.  */
9632159047fSniklas   if (finfo.last_file_index != -1
9642159047fSniklas       && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
9652159047fSniklas     {
966c074d1c9Sdrahn       file_ptr pos;
967c074d1c9Sdrahn 
9682159047fSniklas       finfo.last_file.n_value = obj_raw_syment_count (abfd);
969*007c2a45Smiod       bfd_coff_swap_sym_out (abfd, &finfo.last_file,
970*007c2a45Smiod 			     finfo.outsyms);
971c074d1c9Sdrahn 
972c074d1c9Sdrahn       pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz;
973c074d1c9Sdrahn       if (bfd_seek (abfd, pos, SEEK_SET) != 0
974c074d1c9Sdrahn 	  || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz)
975c074d1c9Sdrahn 	return FALSE;
9762159047fSniklas     }
9772159047fSniklas 
978b305b0f1Sespie   /* If doing task linking (ld --task-link) then make a pass through the
979b305b0f1Sespie      global symbols, writing out any that are defined, and making them
980b305b0f1Sespie      static.  */
981b305b0f1Sespie   if (info->task_link)
982b305b0f1Sespie     {
983c074d1c9Sdrahn       finfo.failed = FALSE;
984c074d1c9Sdrahn       coff_link_hash_traverse (coff_hash_table (info),
985*007c2a45Smiod 			       _bfd_coff_write_task_globals, &finfo);
986b305b0f1Sespie       if (finfo.failed)
987b305b0f1Sespie 	goto error_return;
988b305b0f1Sespie     }
989b305b0f1Sespie 
9902159047fSniklas   /* Write out the global symbols.  */
991c074d1c9Sdrahn   finfo.failed = FALSE;
992c074d1c9Sdrahn   coff_link_hash_traverse (coff_hash_table (info),
993*007c2a45Smiod 			   _bfd_coff_write_global_sym, &finfo);
9942159047fSniklas   if (finfo.failed)
9952159047fSniklas     goto error_return;
9962159047fSniklas 
997c88b1d6cSniklas   /* The outsyms buffer is used by _bfd_coff_write_global_sym.  */
9982159047fSniklas   if (finfo.outsyms != NULL)
9992159047fSniklas     {
10002159047fSniklas       free (finfo.outsyms);
10012159047fSniklas       finfo.outsyms = NULL;
10022159047fSniklas     }
10032159047fSniklas 
1004*007c2a45Smiod   if (info->relocatable && max_output_reloc_count > 0)
10052159047fSniklas     {
10062159047fSniklas       /* Now that we have written out all the global symbols, we know
10072159047fSniklas 	 the symbol indices to use for relocs against them, and we can
10082159047fSniklas 	 finally write out the relocs.  */
1009c074d1c9Sdrahn       amt = max_output_reloc_count * relsz;
1010*007c2a45Smiod       external_relocs = bfd_malloc (amt);
10112159047fSniklas       if (external_relocs == NULL)
10122159047fSniklas 	goto error_return;
10132159047fSniklas 
10142159047fSniklas       for (o = abfd->sections; o != NULL; o = o->next)
10152159047fSniklas 	{
10162159047fSniklas 	  struct internal_reloc *irel;
10172159047fSniklas 	  struct internal_reloc *irelend;
10182159047fSniklas 	  struct coff_link_hash_entry **rel_hash;
10192159047fSniklas 	  bfd_byte *erel;
10202159047fSniklas 
10212159047fSniklas 	  if (o->reloc_count == 0)
10222159047fSniklas 	    continue;
10232159047fSniklas 
10242159047fSniklas 	  irel = finfo.section_info[o->target_index].relocs;
10252159047fSniklas 	  irelend = irel + o->reloc_count;
10262159047fSniklas 	  rel_hash = finfo.section_info[o->target_index].rel_hashes;
10272159047fSniklas 	  erel = external_relocs;
10282159047fSniklas 	  for (; irel < irelend; irel++, rel_hash++, erel += relsz)
10292159047fSniklas 	    {
10302159047fSniklas 	      if (*rel_hash != NULL)
10312159047fSniklas 		{
10322159047fSniklas 		  BFD_ASSERT ((*rel_hash)->indx >= 0);
10332159047fSniklas 		  irel->r_symndx = (*rel_hash)->indx;
10342159047fSniklas 		}
1035*007c2a45Smiod 	      bfd_coff_swap_reloc_out (abfd, irel, erel);
10362159047fSniklas 	    }
10372159047fSniklas 
1038*007c2a45Smiod 	  if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
1039*007c2a45Smiod 	    goto error_return;
1040*007c2a45Smiod 	  if (obj_pe (abfd) && o->reloc_count >= 0xffff)
1041*007c2a45Smiod 	    {
1042*007c2a45Smiod 	      /* In PE COFF, write the count of relocs as the first
1043*007c2a45Smiod 		 reloc.  The header overflow bit will be set
1044*007c2a45Smiod 		 elsewhere. */
1045*007c2a45Smiod 	      struct internal_reloc incount;
1046*007c2a45Smiod 	      bfd_byte *excount = (bfd_byte *)bfd_malloc (relsz);
1047*007c2a45Smiod 
1048*007c2a45Smiod 	      memset (&incount, 0, sizeof (incount));
1049*007c2a45Smiod 	      incount.r_vaddr = o->reloc_count + 1;
1050*007c2a45Smiod 	      bfd_coff_swap_reloc_out (abfd, (PTR) &incount, (PTR) excount);
1051*007c2a45Smiod 	      if (bfd_bwrite (excount, relsz, abfd) != relsz)
1052*007c2a45Smiod 		/* We'll leak, but it's an error anyway. */
1053*007c2a45Smiod 		goto error_return;
1054*007c2a45Smiod 	      free (excount);
1055*007c2a45Smiod 	    }
1056*007c2a45Smiod 	  if (bfd_bwrite (external_relocs,
1057c074d1c9Sdrahn 			  (bfd_size_type) relsz * o->reloc_count, abfd)
1058*007c2a45Smiod 	      != (bfd_size_type) relsz * o->reloc_count)
10592159047fSniklas 	    goto error_return;
10602159047fSniklas 	}
10612159047fSniklas 
10622159047fSniklas       free (external_relocs);
10632159047fSniklas       external_relocs = NULL;
10642159047fSniklas     }
10652159047fSniklas 
10662159047fSniklas   /* Free up the section information.  */
10672159047fSniklas   if (finfo.section_info != NULL)
10682159047fSniklas     {
10692159047fSniklas       unsigned int i;
10702159047fSniklas 
10712159047fSniklas       for (i = 0; i < abfd->section_count; i++)
10722159047fSniklas 	{
10732159047fSniklas 	  if (finfo.section_info[i].relocs != NULL)
10742159047fSniklas 	    free (finfo.section_info[i].relocs);
10752159047fSniklas 	  if (finfo.section_info[i].rel_hashes != NULL)
10762159047fSniklas 	    free (finfo.section_info[i].rel_hashes);
10772159047fSniklas 	}
10782159047fSniklas       free (finfo.section_info);
10792159047fSniklas       finfo.section_info = NULL;
10802159047fSniklas     }
10812159047fSniklas 
1082c88b1d6cSniklas   /* If we have optimized stabs strings, output them.  */
1083c88b1d6cSniklas   if (coff_hash_table (info)->stab_info != NULL)
1084c88b1d6cSniklas     {
1085c88b1d6cSniklas       if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
1086c074d1c9Sdrahn 	return FALSE;
1087c88b1d6cSniklas     }
1088c88b1d6cSniklas 
10892159047fSniklas   /* Write out the string table.  */
10900c6d0228Sniklas   if (obj_raw_syment_count (abfd) != 0 || long_section_names)
10912159047fSniklas     {
1092c074d1c9Sdrahn       file_ptr pos;
1093c074d1c9Sdrahn 
1094c074d1c9Sdrahn       pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz;
1095c074d1c9Sdrahn       if (bfd_seek (abfd, pos, SEEK_SET) != 0)
1096c074d1c9Sdrahn 	return FALSE;
10972159047fSniklas 
10982159047fSniklas #if STRING_SIZE_SIZE == 4
1099c074d1c9Sdrahn       H_PUT_32 (abfd,
11002159047fSniklas 		_bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
1101c074d1c9Sdrahn 		strbuf);
11022159047fSniklas #else
1103c074d1c9Sdrahn  #error Change H_PUT_32 above
11042159047fSniklas #endif
11052159047fSniklas 
1106c074d1c9Sdrahn       if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd)
1107c074d1c9Sdrahn 	  != STRING_SIZE_SIZE)
1108c074d1c9Sdrahn 	return FALSE;
11092159047fSniklas 
11102159047fSniklas       if (! _bfd_stringtab_emit (abfd, finfo.strtab))
1111c074d1c9Sdrahn 	return FALSE;
1112b55d4692Sfgsch 
1113c074d1c9Sdrahn       obj_coff_strings_written (abfd) = TRUE;
11142159047fSniklas     }
11152159047fSniklas 
11162159047fSniklas   _bfd_stringtab_free (finfo.strtab);
11172159047fSniklas 
11182159047fSniklas   /* Setting bfd_get_symcount to 0 will cause write_object_contents to
11192159047fSniklas      not try to write out the symbols.  */
11202159047fSniklas   bfd_get_symcount (abfd) = 0;
11212159047fSniklas 
1122c074d1c9Sdrahn   return TRUE;
11232159047fSniklas 
11242159047fSniklas  error_return:
11252159047fSniklas   if (debug_merge_allocated)
11262159047fSniklas     coff_debug_merge_hash_table_free (&finfo.debug_merge);
11272159047fSniklas   if (finfo.strtab != NULL)
11282159047fSniklas     _bfd_stringtab_free (finfo.strtab);
11292159047fSniklas   if (finfo.section_info != NULL)
11302159047fSniklas     {
11312159047fSniklas       unsigned int i;
11322159047fSniklas 
11332159047fSniklas       for (i = 0; i < abfd->section_count; i++)
11342159047fSniklas 	{
11352159047fSniklas 	  if (finfo.section_info[i].relocs != NULL)
11362159047fSniklas 	    free (finfo.section_info[i].relocs);
11372159047fSniklas 	  if (finfo.section_info[i].rel_hashes != NULL)
11382159047fSniklas 	    free (finfo.section_info[i].rel_hashes);
11392159047fSniklas 	}
11402159047fSniklas       free (finfo.section_info);
11412159047fSniklas     }
11422159047fSniklas   if (finfo.internal_syms != NULL)
11432159047fSniklas     free (finfo.internal_syms);
11442159047fSniklas   if (finfo.sec_ptrs != NULL)
11452159047fSniklas     free (finfo.sec_ptrs);
11462159047fSniklas   if (finfo.sym_indices != NULL)
11472159047fSniklas     free (finfo.sym_indices);
11482159047fSniklas   if (finfo.outsyms != NULL)
11492159047fSniklas     free (finfo.outsyms);
11502159047fSniklas   if (finfo.linenos != NULL)
11512159047fSniklas     free (finfo.linenos);
11522159047fSniklas   if (finfo.contents != NULL)
11532159047fSniklas     free (finfo.contents);
11542159047fSniklas   if (finfo.external_relocs != NULL)
11552159047fSniklas     free (finfo.external_relocs);
11562159047fSniklas   if (finfo.internal_relocs != NULL)
11572159047fSniklas     free (finfo.internal_relocs);
11582159047fSniklas   if (external_relocs != NULL)
11592159047fSniklas     free (external_relocs);
1160c074d1c9Sdrahn   return FALSE;
11612159047fSniklas }
11622159047fSniklas 
1163*007c2a45Smiod /* Parse out a -heap <reserved>,<commit> line.  */
11642159047fSniklas 
11652159047fSniklas static char *
dores_com(char * ptr,bfd * output_bfd,int heap)1166*007c2a45Smiod dores_com (char *ptr, bfd *output_bfd, int heap)
11672159047fSniklas {
11682159047fSniklas   if (coff_data(output_bfd)->pe)
11692159047fSniklas     {
11702159047fSniklas       int val = strtoul (ptr, &ptr, 0);
1171*007c2a45Smiod 
11722159047fSniklas       if (heap)
11732159047fSniklas 	pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve = val;
11742159047fSniklas       else
11752159047fSniklas 	pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve = val;
11762159047fSniklas 
11772159047fSniklas       if (ptr[0] == ',')
11782159047fSniklas 	{
1179c074d1c9Sdrahn 	  val = strtoul (ptr+1, &ptr, 0);
11802159047fSniklas 	  if (heap)
11812159047fSniklas 	    pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit = val;
11822159047fSniklas 	  else
11832159047fSniklas 	    pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit = val;
11842159047fSniklas 	}
11852159047fSniklas     }
11862159047fSniklas   return ptr;
11872159047fSniklas }
11882159047fSniklas 
1189*007c2a45Smiod static char *
get_name(char * ptr,char ** dst)1190*007c2a45Smiod get_name (char *ptr, char **dst)
11912159047fSniklas {
11922159047fSniklas   while (*ptr == ' ')
11932159047fSniklas     ptr++;
11942159047fSniklas   *dst = ptr;
11952159047fSniklas   while (*ptr && *ptr != ' ')
11962159047fSniklas     ptr++;
11972159047fSniklas   *ptr = 0;
11982159047fSniklas   return ptr+1;
11992159047fSniklas }
12002159047fSniklas 
1201*007c2a45Smiod /* Process any magic embedded commands in a section called .drectve.  */
12022159047fSniklas 
12032159047fSniklas static int
process_embedded_commands(bfd * output_bfd,struct bfd_link_info * info ATTRIBUTE_UNUSED,bfd * abfd)1204*007c2a45Smiod process_embedded_commands (bfd *output_bfd,
1205*007c2a45Smiod 			   struct bfd_link_info *info ATTRIBUTE_UNUSED,
1206*007c2a45Smiod 			   bfd *abfd)
12072159047fSniklas {
12082159047fSniklas   asection *sec = bfd_get_section_by_name (abfd, ".drectve");
12092159047fSniklas   char *s;
12102159047fSniklas   char *e;
12112159047fSniklas   char *copy;
1212*007c2a45Smiod 
12132159047fSniklas   if (!sec)
12142159047fSniklas     return 1;
12152159047fSniklas 
1216c074d1c9Sdrahn   copy = bfd_malloc (sec->_raw_size);
12172159047fSniklas   if (!copy)
12182159047fSniklas     return 0;
1219*007c2a45Smiod 
1220c074d1c9Sdrahn   if (! bfd_get_section_contents (abfd, sec, copy, (bfd_vma) 0, sec->_raw_size))
12212159047fSniklas     {
12222159047fSniklas       free (copy);
12232159047fSniklas       return 0;
12242159047fSniklas     }
12252159047fSniklas   e = copy + sec->_raw_size;
1226*007c2a45Smiod 
12272159047fSniklas   for (s = copy;  s < e ; )
12282159047fSniklas     {
1229*007c2a45Smiod       if (s[0]!= '-')
1230*007c2a45Smiod 	{
12312159047fSniklas 	  s++;
12322159047fSniklas 	  continue;
12332159047fSniklas 	}
12342159047fSniklas       if (strncmp (s,"-attr", 5) == 0)
12352159047fSniklas 	{
12362159047fSniklas 	  char *name;
12372159047fSniklas 	  char *attribs;
12382159047fSniklas 	  asection *asec;
12392159047fSniklas 	  int loop = 1;
12402159047fSniklas 	  int had_write = 0;
12412159047fSniklas 	  int had_read = 0;
12422159047fSniklas 	  int had_exec= 0;
12432159047fSniklas 	  int had_shared= 0;
1244*007c2a45Smiod 
12452159047fSniklas 	  s += 5;
12462159047fSniklas 	  s = get_name (s, &name);
12472159047fSniklas 	  s = get_name (s, &attribs);
1248*007c2a45Smiod 
1249*007c2a45Smiod 	  while (loop)
1250*007c2a45Smiod 	    {
12512159047fSniklas 	      switch (*attribs++)
12522159047fSniklas 		{
12532159047fSniklas 		case 'W':
12542159047fSniklas 		  had_write = 1;
12552159047fSniklas 		  break;
12562159047fSniklas 		case 'R':
12572159047fSniklas 		  had_read = 1;
12582159047fSniklas 		  break;
12592159047fSniklas 		case 'S':
12602159047fSniklas 		  had_shared = 1;
12612159047fSniklas 		  break;
12622159047fSniklas 		case 'X':
12632159047fSniklas 		  had_exec = 1;
12642159047fSniklas 		  break;
12652159047fSniklas 		default:
12662159047fSniklas 		  loop = 0;
12672159047fSniklas 		}
12682159047fSniklas 	    }
12692159047fSniklas 	  asec = bfd_get_section_by_name (abfd, name);
1270*007c2a45Smiod 	  if (asec)
1271*007c2a45Smiod 	    {
12722159047fSniklas 	      if (had_exec)
12732159047fSniklas 		asec->flags |= SEC_CODE;
12742159047fSniklas 	      if (!had_write)
12752159047fSniklas 		asec->flags |= SEC_READONLY;
12762159047fSniklas 	    }
12772159047fSniklas 	}
12782159047fSniklas       else if (strncmp (s,"-heap", 5) == 0)
12792159047fSniklas 	s = dores_com (s+5, output_bfd, 1);
1280*007c2a45Smiod 
12812159047fSniklas       else if (strncmp (s,"-stack", 6) == 0)
12822159047fSniklas 	s = dores_com (s+6, output_bfd, 0);
1283*007c2a45Smiod 
12842159047fSniklas       else
12852159047fSniklas 	s++;
12862159047fSniklas     }
12872159047fSniklas   free (copy);
12882159047fSniklas   return 1;
12892159047fSniklas }
12902159047fSniklas 
1291b305b0f1Sespie /* Place a marker against all symbols which are used by relocations.
1292b305b0f1Sespie    This marker can be picked up by the 'do we skip this symbol ?'
1293b305b0f1Sespie    loop in _bfd_coff_link_input_bfd() and used to prevent skipping
1294*007c2a45Smiod    that symbol.  */
1295b305b0f1Sespie 
1296b305b0f1Sespie static void
mark_relocs(struct coff_final_link_info * finfo,bfd * input_bfd)1297*007c2a45Smiod mark_relocs (struct coff_final_link_info *finfo, bfd *input_bfd)
1298b305b0f1Sespie {
1299b305b0f1Sespie   asection * a;
1300b305b0f1Sespie 
1301b305b0f1Sespie   if ((bfd_get_file_flags (input_bfd) & HAS_SYMS) == 0)
1302b305b0f1Sespie     return;
1303b305b0f1Sespie 
1304b305b0f1Sespie   for (a = input_bfd->sections; a != (asection *) NULL; a = a->next)
1305b305b0f1Sespie     {
1306b305b0f1Sespie       struct internal_reloc *	internal_relocs;
1307b305b0f1Sespie       struct internal_reloc *	irel;
1308b305b0f1Sespie       struct internal_reloc *	irelend;
1309b305b0f1Sespie 
1310b305b0f1Sespie       if ((a->flags & SEC_RELOC) == 0 || a->reloc_count  < 1)
1311b305b0f1Sespie 	continue;
1312c074d1c9Sdrahn       /* Don't mark relocs in excluded sections.  */
1313c074d1c9Sdrahn       if (a->output_section == bfd_abs_section_ptr)
1314c074d1c9Sdrahn 	continue;
1315b305b0f1Sespie 
1316b305b0f1Sespie       /* Read in the relocs.  */
1317b305b0f1Sespie       internal_relocs = _bfd_coff_read_internal_relocs
1318c074d1c9Sdrahn 	(input_bfd, a, FALSE,
1319b305b0f1Sespie 	 finfo->external_relocs,
1320*007c2a45Smiod 	 finfo->info->relocatable,
1321*007c2a45Smiod 	 (finfo->info->relocatable
1322b305b0f1Sespie 	  ? (finfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
1323b305b0f1Sespie 	  : finfo->internal_relocs)
1324b305b0f1Sespie 	);
1325b305b0f1Sespie 
1326b305b0f1Sespie       if (internal_relocs == NULL)
1327b305b0f1Sespie 	continue;
1328b305b0f1Sespie 
1329b305b0f1Sespie       irel     = internal_relocs;
1330b305b0f1Sespie       irelend  = irel + a->reloc_count;
1331b305b0f1Sespie 
1332b305b0f1Sespie       /* Place a mark in the sym_indices array (whose entries have
1333b305b0f1Sespie 	 been initialised to 0) for all of the symbols that are used
1334b305b0f1Sespie 	 in the relocation table.  This will then be picked up in the
1335*007c2a45Smiod 	 skip/don't-skip pass.  */
1336b305b0f1Sespie       for (; irel < irelend; irel++)
1337b305b0f1Sespie 	finfo->sym_indices[ irel->r_symndx ] = -1;
1338b305b0f1Sespie     }
1339b305b0f1Sespie }
1340b305b0f1Sespie 
13412159047fSniklas /* Link an input file into the linker output file.  This function
13422159047fSniklas    handles all the sections and relocations of the input file at once.  */
13432159047fSniklas 
1344c074d1c9Sdrahn bfd_boolean
_bfd_coff_link_input_bfd(struct coff_final_link_info * finfo,bfd * input_bfd)1345*007c2a45Smiod _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd)
13462159047fSniklas {
1347b305b0f1Sespie   unsigned int n_tmask = coff_data (input_bfd)->local_n_tmask;
1348b305b0f1Sespie   unsigned int n_btshft = coff_data (input_bfd)->local_n_btshft;
1349b305b0f1Sespie #if 0
1350b305b0f1Sespie   unsigned int n_btmask = coff_data (input_bfd)->local_n_btmask;
1351b305b0f1Sespie #endif
1352c074d1c9Sdrahn   bfd_boolean (*adjust_symndx)
1353*007c2a45Smiod     (bfd *, struct bfd_link_info *, bfd *, asection *,
1354*007c2a45Smiod      struct internal_reloc *, bfd_boolean *);
13552159047fSniklas   bfd *output_bfd;
13562159047fSniklas   const char *strings;
13572159047fSniklas   bfd_size_type syment_base;
1358c074d1c9Sdrahn   bfd_boolean copy, hash;
13592159047fSniklas   bfd_size_type isymesz;
13602159047fSniklas   bfd_size_type osymesz;
13612159047fSniklas   bfd_size_type linesz;
13622159047fSniklas   bfd_byte *esym;
13632159047fSniklas   bfd_byte *esym_end;
13642159047fSniklas   struct internal_syment *isymp;
13652159047fSniklas   asection **secpp;
13662159047fSniklas   long *indexp;
13672159047fSniklas   unsigned long output_index;
13682159047fSniklas   bfd_byte *outsym;
13692159047fSniklas   struct coff_link_hash_entry **sym_hash;
13702159047fSniklas   asection *o;
13712159047fSniklas 
13722159047fSniklas   /* Move all the symbols to the output file.  */
13732159047fSniklas 
13742159047fSniklas   output_bfd = finfo->output_bfd;
13752159047fSniklas   strings = NULL;
13762159047fSniklas   syment_base = obj_raw_syment_count (output_bfd);
13772159047fSniklas   isymesz = bfd_coff_symesz (input_bfd);
13782159047fSniklas   osymesz = bfd_coff_symesz (output_bfd);
13792159047fSniklas   linesz = bfd_coff_linesz (input_bfd);
13802159047fSniklas   BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd));
13812159047fSniklas 
1382c074d1c9Sdrahn   copy = FALSE;
13832159047fSniklas   if (! finfo->info->keep_memory)
1384c074d1c9Sdrahn     copy = TRUE;
1385c074d1c9Sdrahn   hash = TRUE;
13862159047fSniklas   if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1387c074d1c9Sdrahn     hash = FALSE;
13882159047fSniklas 
13892159047fSniklas   if (! _bfd_coff_get_external_symbols (input_bfd))
1390c074d1c9Sdrahn     return FALSE;
13912159047fSniklas 
13922159047fSniklas   esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
13932159047fSniklas   esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
13942159047fSniklas   isymp = finfo->internal_syms;
13952159047fSniklas   secpp = finfo->sec_ptrs;
13962159047fSniklas   indexp = finfo->sym_indices;
13972159047fSniklas   output_index = syment_base;
13982159047fSniklas   outsym = finfo->outsyms;
13992159047fSniklas 
1400*007c2a45Smiod   if (coff_data (output_bfd)->pe
1401*007c2a45Smiod       && ! process_embedded_commands (output_bfd, finfo->info, input_bfd))
1402c074d1c9Sdrahn     return FALSE;
14032159047fSniklas 
1404*007c2a45Smiod   /* If we are going to perform relocations and also strip/discard some
1405*007c2a45Smiod      symbols then we must make sure that we do not strip/discard those
1406*007c2a45Smiod      symbols that are going to be involved in the relocations.  */
1407b305b0f1Sespie   if ((   finfo->info->strip   != strip_none
1408b305b0f1Sespie        || finfo->info->discard != discard_none)
1409*007c2a45Smiod       && finfo->info->relocatable)
1410b305b0f1Sespie     {
1411*007c2a45Smiod       /* Mark the symbol array as 'not-used'.  */
1412b305b0f1Sespie       memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
1413b305b0f1Sespie 
1414b305b0f1Sespie       mark_relocs (finfo, input_bfd);
1415b305b0f1Sespie     }
1416b305b0f1Sespie 
14172159047fSniklas   while (esym < esym_end)
14182159047fSniklas     {
14192159047fSniklas       struct internal_syment isym;
1420b305b0f1Sespie       enum coff_symbol_classification classification;
1421c074d1c9Sdrahn       bfd_boolean skip;
1422c074d1c9Sdrahn       bfd_boolean global;
1423c074d1c9Sdrahn       bfd_boolean dont_skip_symbol;
14242159047fSniklas       int add;
14252159047fSniklas 
1426*007c2a45Smiod       bfd_coff_swap_sym_in (input_bfd, esym, isymp);
14272159047fSniklas 
14282159047fSniklas       /* Make a copy of *isymp so that the relocate_section function
14292159047fSniklas 	 always sees the original values.  This is more reliable than
14302159047fSniklas 	 always recomputing the symbol value even if we are stripping
14312159047fSniklas 	 the symbol.  */
14322159047fSniklas       isym = *isymp;
14332159047fSniklas 
1434b305b0f1Sespie       classification = bfd_coff_classify_symbol (input_bfd, &isym);
1435b305b0f1Sespie       switch (classification)
14362159047fSniklas 	{
1437b305b0f1Sespie 	default:
1438b305b0f1Sespie 	  abort ();
1439b305b0f1Sespie 	case COFF_SYMBOL_GLOBAL:
1440b305b0f1Sespie 	case COFF_SYMBOL_PE_SECTION:
1441b305b0f1Sespie 	case COFF_SYMBOL_LOCAL:
1442b305b0f1Sespie 	  *secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
1443b305b0f1Sespie 	  break;
1444b305b0f1Sespie 	case COFF_SYMBOL_COMMON:
14452159047fSniklas 	  *secpp = bfd_com_section_ptr;
1446b305b0f1Sespie 	  break;
1447b305b0f1Sespie 	case COFF_SYMBOL_UNDEFINED:
1448b305b0f1Sespie 	  *secpp = bfd_und_section_ptr;
1449b305b0f1Sespie 	  break;
14502159047fSniklas 	}
14512159047fSniklas 
1452b305b0f1Sespie       /* Extract the flag indicating if this symbol is used by a
1453b305b0f1Sespie          relocation.  */
1454b305b0f1Sespie       if ((finfo->info->strip != strip_none
1455b305b0f1Sespie 	   || finfo->info->discard != discard_none)
1456*007c2a45Smiod 	  && finfo->info->relocatable)
1457b305b0f1Sespie 	dont_skip_symbol = *indexp;
1458b305b0f1Sespie       else
1459c074d1c9Sdrahn 	dont_skip_symbol = FALSE;
1460b305b0f1Sespie 
14612159047fSniklas       *indexp = -1;
14622159047fSniklas 
1463c074d1c9Sdrahn       skip = FALSE;
1464c074d1c9Sdrahn       global = FALSE;
14652159047fSniklas       add = 1 + isym.n_numaux;
14662159047fSniklas 
14672159047fSniklas       /* If we are stripping all symbols, we want to skip this one.  */
1468b305b0f1Sespie       if (finfo->info->strip == strip_all && ! dont_skip_symbol)
1469c074d1c9Sdrahn 	skip = TRUE;
14702159047fSniklas 
14712159047fSniklas       if (! skip)
14722159047fSniklas 	{
1473b305b0f1Sespie 	  switch (classification)
14742159047fSniklas 	    {
1475b305b0f1Sespie 	    default:
1476b305b0f1Sespie 	      abort ();
1477b305b0f1Sespie 	    case COFF_SYMBOL_GLOBAL:
1478b305b0f1Sespie 	    case COFF_SYMBOL_COMMON:
1479b305b0f1Sespie 	    case COFF_SYMBOL_PE_SECTION:
14802159047fSniklas 	      /* This is a global symbol.  Global symbols come at the
14812159047fSniklas 		 end of the symbol table, so skip them for now.
1482b305b0f1Sespie 		 Locally defined function symbols, however, are an
1483b305b0f1Sespie 		 exception, and are not moved to the end.  */
1484c074d1c9Sdrahn 	      global = TRUE;
14852159047fSniklas 	      if (! ISFCN (isym.n_type))
1486c074d1c9Sdrahn 		skip = TRUE;
1487b305b0f1Sespie 	      break;
1488b305b0f1Sespie 
1489b305b0f1Sespie 	    case COFF_SYMBOL_UNDEFINED:
1490b305b0f1Sespie 	      /* Undefined symbols are left for the end.  */
1491c074d1c9Sdrahn 	      global = TRUE;
1492c074d1c9Sdrahn 	      skip = TRUE;
1493b305b0f1Sespie 	      break;
1494b305b0f1Sespie 
1495b305b0f1Sespie 	    case COFF_SYMBOL_LOCAL:
14962159047fSniklas 	      /* This is a local symbol.  Skip it if we are discarding
14972159047fSniklas                  local symbols.  */
1498b305b0f1Sespie 	      if (finfo->info->discard == discard_all && ! dont_skip_symbol)
1499c074d1c9Sdrahn 		skip = TRUE;
1500b305b0f1Sespie 	      break;
15012159047fSniklas 	    }
15022159047fSniklas 	}
15032159047fSniklas 
1504c074d1c9Sdrahn #ifndef COFF_WITH_PE
1505c074d1c9Sdrahn       /* Skip section symbols for sections which are not going to be
1506c074d1c9Sdrahn 	 emitted.  */
1507c074d1c9Sdrahn       if (!skip
1508*007c2a45Smiod 	  && dont_skip_symbol == 0
1509c074d1c9Sdrahn 	  && isym.n_sclass == C_STAT
1510c074d1c9Sdrahn 	  && isym.n_type == T_NULL
1511*007c2a45Smiod           && isym.n_numaux > 0
1512*007c2a45Smiod 	  && (*secpp)->output_section == bfd_abs_section_ptr)
1513c074d1c9Sdrahn 	skip = TRUE;
1514c074d1c9Sdrahn #endif
1515c074d1c9Sdrahn 
15162159047fSniklas       /* If we stripping debugging symbols, and this is a debugging
1517b305b0f1Sespie          symbol, then skip it.  FIXME: gas sets the section to N_ABS
1518b305b0f1Sespie          for some types of debugging symbols; I don't know if this is
1519b305b0f1Sespie          a bug or not.  In any case, we handle it here.  */
15202159047fSniklas       if (! skip
15212159047fSniklas 	  && finfo->info->strip == strip_debugger
1522b305b0f1Sespie 	  && ! dont_skip_symbol
1523b305b0f1Sespie 	  && (isym.n_scnum == N_DEBUG
1524b305b0f1Sespie 	      || (isym.n_scnum == N_ABS
1525b305b0f1Sespie 		  && (isym.n_sclass == C_AUTO
1526b305b0f1Sespie 		      || isym.n_sclass == C_REG
1527b305b0f1Sespie 		      || isym.n_sclass == C_MOS
1528b305b0f1Sespie 		      || isym.n_sclass == C_MOE
1529b305b0f1Sespie 		      || isym.n_sclass == C_MOU
1530b305b0f1Sespie 		      || isym.n_sclass == C_ARG
1531b305b0f1Sespie 		      || isym.n_sclass == C_REGPARM
1532b305b0f1Sespie 		      || isym.n_sclass == C_FIELD
1533b305b0f1Sespie 		      || isym.n_sclass == C_EOS))))
1534c074d1c9Sdrahn 	skip = TRUE;
15352159047fSniklas 
15362159047fSniklas       /* If some symbols are stripped based on the name, work out the
15372159047fSniklas 	 name and decide whether to skip this symbol.  */
15382159047fSniklas       if (! skip
15392159047fSniklas 	  && (finfo->info->strip == strip_some
15402159047fSniklas 	      || finfo->info->discard == discard_l))
15412159047fSniklas 	{
15422159047fSniklas 	  const char *name;
15432159047fSniklas 	  char buf[SYMNMLEN + 1];
15442159047fSniklas 
15452159047fSniklas 	  name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
15462159047fSniklas 	  if (name == NULL)
1547c074d1c9Sdrahn 	    return FALSE;
15482159047fSniklas 
1549b305b0f1Sespie 	  if (! dont_skip_symbol
1550b305b0f1Sespie 	      && ((finfo->info->strip == strip_some
1551c074d1c9Sdrahn 		   && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE,
1552c074d1c9Sdrahn 				    FALSE) == NULL))
15532159047fSniklas 		   || (! global
15542159047fSniklas 		       && finfo->info->discard == discard_l
1555b305b0f1Sespie 		       && bfd_is_local_label_name (input_bfd, name))))
1556c074d1c9Sdrahn 	    skip = TRUE;
15572159047fSniklas 	}
15582159047fSniklas 
15592159047fSniklas       /* If this is an enum, struct, or union tag, see if we have
15602159047fSniklas          already output an identical type.  */
15612159047fSniklas       if (! skip
15622159047fSniklas 	  && (finfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0
15632159047fSniklas 	  && (isym.n_sclass == C_ENTAG
15642159047fSniklas 	      || isym.n_sclass == C_STRTAG
15652159047fSniklas 	      || isym.n_sclass == C_UNTAG)
15662159047fSniklas 	  && isym.n_numaux == 1)
15672159047fSniklas 	{
15682159047fSniklas 	  const char *name;
15692159047fSniklas 	  char buf[SYMNMLEN + 1];
15702159047fSniklas 	  struct coff_debug_merge_hash_entry *mh;
15712159047fSniklas 	  struct coff_debug_merge_type *mt;
15722159047fSniklas 	  union internal_auxent aux;
15732159047fSniklas 	  struct coff_debug_merge_element **epp;
15742159047fSniklas 	  bfd_byte *esl, *eslend;
15752159047fSniklas 	  struct internal_syment *islp;
1576c074d1c9Sdrahn 	  bfd_size_type amt;
15772159047fSniklas 
15782159047fSniklas 	  name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
15792159047fSniklas 	  if (name == NULL)
1580c074d1c9Sdrahn 	    return FALSE;
15812159047fSniklas 
15822159047fSniklas 	  /* Ignore fake names invented by compiler; treat them all as
15832159047fSniklas              the same name.  */
1584c88b1d6cSniklas 	  if (*name == '~' || *name == '.' || *name == '$'
15852159047fSniklas 	      || (*name == bfd_get_symbol_leading_char (input_bfd)
1586c88b1d6cSniklas 		  && (name[1] == '~' || name[1] == '.' || name[1] == '$')))
15872159047fSniklas 	    name = "";
15882159047fSniklas 
15892159047fSniklas 	  mh = coff_debug_merge_hash_lookup (&finfo->debug_merge, name,
1590c074d1c9Sdrahn 					     TRUE, TRUE);
15912159047fSniklas 	  if (mh == NULL)
1592c074d1c9Sdrahn 	    return FALSE;
15932159047fSniklas 
15942159047fSniklas 	  /* Allocate memory to hold type information.  If this turns
15952159047fSniklas              out to be a duplicate, we pass this address to
15962159047fSniklas              bfd_release.  */
1597c074d1c9Sdrahn 	  amt = sizeof (struct coff_debug_merge_type);
1598*007c2a45Smiod 	  mt = bfd_alloc (input_bfd, amt);
15992159047fSniklas 	  if (mt == NULL)
1600c074d1c9Sdrahn 	    return FALSE;
16012159047fSniklas 	  mt->class = isym.n_sclass;
16022159047fSniklas 
16032159047fSniklas 	  /* Pick up the aux entry, which points to the end of the tag
16042159047fSniklas              entries.  */
1605*007c2a45Smiod 	  bfd_coff_swap_aux_in (input_bfd, (esym + isymesz),
16062159047fSniklas 				isym.n_type, isym.n_sclass, 0, isym.n_numaux,
1607*007c2a45Smiod 				&aux);
16082159047fSniklas 
16092159047fSniklas 	  /* Gather the elements.  */
16102159047fSniklas 	  epp = &mt->elements;
16112159047fSniklas 	  mt->elements = NULL;
16122159047fSniklas 	  islp = isymp + 2;
16132159047fSniklas 	  esl = esym + 2 * isymesz;
16142159047fSniklas 	  eslend = ((bfd_byte *) obj_coff_external_syms (input_bfd)
16152159047fSniklas 		    + aux.x_sym.x_fcnary.x_fcn.x_endndx.l * isymesz);
16162159047fSniklas 	  while (esl < eslend)
16172159047fSniklas 	    {
16182159047fSniklas 	      const char *elename;
16192159047fSniklas 	      char elebuf[SYMNMLEN + 1];
1620b305b0f1Sespie 	      char *name_copy;
16212159047fSniklas 
1622*007c2a45Smiod 	      bfd_coff_swap_sym_in (input_bfd, esl, islp);
16232159047fSniklas 
1624c074d1c9Sdrahn 	      amt = sizeof (struct coff_debug_merge_element);
1625*007c2a45Smiod 	      *epp = bfd_alloc (input_bfd, amt);
16262159047fSniklas 	      if (*epp == NULL)
1627c074d1c9Sdrahn 		return FALSE;
16282159047fSniklas 
16292159047fSniklas 	      elename = _bfd_coff_internal_syment_name (input_bfd, islp,
16302159047fSniklas 							elebuf);
16312159047fSniklas 	      if (elename == NULL)
1632c074d1c9Sdrahn 		return FALSE;
16332159047fSniklas 
1634c074d1c9Sdrahn 	      amt = strlen (elename) + 1;
1635*007c2a45Smiod 	      name_copy = bfd_alloc (input_bfd, amt);
1636b305b0f1Sespie 	      if (name_copy == NULL)
1637c074d1c9Sdrahn 		return FALSE;
1638b305b0f1Sespie 	      strcpy (name_copy, elename);
16392159047fSniklas 
1640b305b0f1Sespie 	      (*epp)->name = name_copy;
16412159047fSniklas 	      (*epp)->type = islp->n_type;
16422159047fSniklas 	      (*epp)->tagndx = 0;
16432159047fSniklas 	      if (islp->n_numaux >= 1
16442159047fSniklas 		  && islp->n_type != T_NULL
16452159047fSniklas 		  && islp->n_sclass != C_EOS)
16462159047fSniklas 		{
16472159047fSniklas 		  union internal_auxent eleaux;
16482159047fSniklas 		  long indx;
16492159047fSniklas 
1650*007c2a45Smiod 		  bfd_coff_swap_aux_in (input_bfd, (esl + isymesz),
16512159047fSniklas 					islp->n_type, islp->n_sclass, 0,
1652*007c2a45Smiod 					islp->n_numaux, &eleaux);
16532159047fSniklas 		  indx = eleaux.x_sym.x_tagndx.l;
16542159047fSniklas 
16552159047fSniklas 		  /* FIXME: If this tagndx entry refers to a symbol
16562159047fSniklas 		     defined later in this file, we just ignore it.
16572159047fSniklas 		     Handling this correctly would be tedious, and may
16582159047fSniklas 		     not be required.  */
16592159047fSniklas 		  if (indx > 0
16602159047fSniklas 		      && (indx
16612159047fSniklas 			  < ((esym -
16622159047fSniklas 			      (bfd_byte *) obj_coff_external_syms (input_bfd))
16632159047fSniklas 			     / (long) isymesz)))
16642159047fSniklas 		    {
16652159047fSniklas 		      (*epp)->tagndx = finfo->sym_indices[indx];
16662159047fSniklas 		      if ((*epp)->tagndx < 0)
16672159047fSniklas 			(*epp)->tagndx = 0;
16682159047fSniklas 		    }
16692159047fSniklas 		}
16702159047fSniklas 	      epp = &(*epp)->next;
16712159047fSniklas 	      *epp = NULL;
16722159047fSniklas 
16732159047fSniklas 	      esl += (islp->n_numaux + 1) * isymesz;
16742159047fSniklas 	      islp += islp->n_numaux + 1;
16752159047fSniklas 	    }
16762159047fSniklas 
16772159047fSniklas 	  /* See if we already have a definition which matches this
1678c88b1d6cSniklas              type.  We always output the type if it has no elements,
1679c88b1d6cSniklas              for simplicity.  */
1680c88b1d6cSniklas 	  if (mt->elements == NULL)
1681*007c2a45Smiod 	    bfd_release (input_bfd, mt);
1682c88b1d6cSniklas 	  else
1683c88b1d6cSniklas 	    {
1684c88b1d6cSniklas 	      struct coff_debug_merge_type *mtl;
1685c88b1d6cSniklas 
16862159047fSniklas 	      for (mtl = mh->types; mtl != NULL; mtl = mtl->next)
16872159047fSniklas 		{
16882159047fSniklas 		  struct coff_debug_merge_element *me, *mel;
16892159047fSniklas 
16902159047fSniklas 		  if (mtl->class != mt->class)
16912159047fSniklas 		    continue;
16922159047fSniklas 
16932159047fSniklas 		  for (me = mt->elements, mel = mtl->elements;
16942159047fSniklas 		       me != NULL && mel != NULL;
16952159047fSniklas 		       me = me->next, mel = mel->next)
16962159047fSniklas 		    {
16972159047fSniklas 		      if (strcmp (me->name, mel->name) != 0
16982159047fSniklas 			  || me->type != mel->type
16992159047fSniklas 			  || me->tagndx != mel->tagndx)
17002159047fSniklas 			break;
17012159047fSniklas 		    }
17022159047fSniklas 
17032159047fSniklas 		  if (me == NULL && mel == NULL)
17042159047fSniklas 		    break;
17052159047fSniklas 		}
17062159047fSniklas 
17072159047fSniklas 	      if (mtl == NULL || (bfd_size_type) mtl->indx >= syment_base)
17082159047fSniklas 		{
17092159047fSniklas 		  /* This is the first definition of this type.  */
17102159047fSniklas 		  mt->indx = output_index;
17112159047fSniklas 		  mt->next = mh->types;
17122159047fSniklas 		  mh->types = mt;
17132159047fSniklas 		}
17142159047fSniklas 	      else
17152159047fSniklas 		{
17162159047fSniklas 		  /* This is a redefinition which can be merged.  */
1717*007c2a45Smiod 		  bfd_release (input_bfd, mt);
17182159047fSniklas 		  *indexp = mtl->indx;
17192159047fSniklas 		  add = (eslend - esym) / isymesz;
1720c074d1c9Sdrahn 		  skip = TRUE;
17212159047fSniklas 		}
17222159047fSniklas 	    }
1723c88b1d6cSniklas 	}
17242159047fSniklas 
17252159047fSniklas       /* We now know whether we are to skip this symbol or not.  */
17262159047fSniklas       if (! skip)
17272159047fSniklas 	{
17282159047fSniklas 	  /* Adjust the symbol in order to output it.  */
17292159047fSniklas 
17302159047fSniklas 	  if (isym._n._n_n._n_zeroes == 0
17312159047fSniklas 	      && isym._n._n_n._n_offset != 0)
17322159047fSniklas 	    {
17332159047fSniklas 	      const char *name;
17342159047fSniklas 	      bfd_size_type indx;
17352159047fSniklas 
17362159047fSniklas 	      /* This symbol has a long name.  Enter it in the string
17372159047fSniklas 		 table we are building.  Note that we do not check
17382159047fSniklas 		 bfd_coff_symname_in_debug.  That is only true for
17392159047fSniklas 		 XCOFF, and XCOFF requires different linking code
17402159047fSniklas 		 anyhow.  */
1741*007c2a45Smiod 	      name = _bfd_coff_internal_syment_name (input_bfd, &isym, NULL);
17422159047fSniklas 	      if (name == NULL)
1743c074d1c9Sdrahn 		return FALSE;
17442159047fSniklas 	      indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy);
17452159047fSniklas 	      if (indx == (bfd_size_type) -1)
1746c074d1c9Sdrahn 		return FALSE;
17472159047fSniklas 	      isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
17482159047fSniklas 	    }
17492159047fSniklas 
1750b305b0f1Sespie 	  switch (isym.n_sclass)
1751b305b0f1Sespie 	    {
1752b305b0f1Sespie 	    case C_AUTO:
1753b305b0f1Sespie 	    case C_MOS:
1754b305b0f1Sespie 	    case C_EOS:
1755b305b0f1Sespie 	    case C_MOE:
1756b305b0f1Sespie 	    case C_MOU:
1757b305b0f1Sespie 	    case C_UNTAG:
1758b305b0f1Sespie 	    case C_STRTAG:
1759b305b0f1Sespie 	    case C_ENTAG:
1760b305b0f1Sespie 	    case C_TPDEF:
1761b305b0f1Sespie 	    case C_ARG:
1762b305b0f1Sespie 	    case C_USTATIC:
1763b305b0f1Sespie 	    case C_REG:
1764b305b0f1Sespie 	    case C_REGPARM:
1765b305b0f1Sespie 	    case C_FIELD:
1766b305b0f1Sespie 	      /* The symbol value should not be modified.  */
1767b305b0f1Sespie 	      break;
1768b305b0f1Sespie 
1769b305b0f1Sespie 	    case C_FCN:
1770b305b0f1Sespie 	      if (obj_pe (input_bfd)
1771b305b0f1Sespie 		  && strcmp (isym.n_name, ".bf") != 0
1772b305b0f1Sespie 		  && isym.n_scnum > 0)
1773b305b0f1Sespie 		{
1774b305b0f1Sespie 		  /* For PE, .lf and .ef get their value left alone,
1775b305b0f1Sespie 		     while .bf gets relocated.  However, they all have
1776b305b0f1Sespie 		     "real" section numbers, and need to be moved into
1777b305b0f1Sespie 		     the new section.  */
1778b305b0f1Sespie 		  isym.n_scnum = (*secpp)->output_section->target_index;
1779b305b0f1Sespie 		  break;
1780b305b0f1Sespie 		}
1781b305b0f1Sespie 	      /* Fall through.  */
1782b305b0f1Sespie 	    default:
1783b305b0f1Sespie 	    case C_LABEL:  /* Not completely sure about these 2 */
1784b305b0f1Sespie 	    case C_EXTDEF:
1785b305b0f1Sespie 	    case C_BLOCK:
1786b305b0f1Sespie 	    case C_EFCN:
1787b305b0f1Sespie 	    case C_NULL:
1788b305b0f1Sespie 	    case C_EXT:
1789b305b0f1Sespie 	    case C_STAT:
1790b305b0f1Sespie 	    case C_SECTION:
1791b305b0f1Sespie 	    case C_NT_WEAK:
1792b305b0f1Sespie 	      /* Compute new symbol location.  */
17932159047fSniklas 	    if (isym.n_scnum > 0)
17942159047fSniklas 	      {
17952159047fSniklas 		isym.n_scnum = (*secpp)->output_section->target_index;
1796b305b0f1Sespie 		isym.n_value += (*secpp)->output_offset;
1797b305b0f1Sespie 		if (! obj_pe (input_bfd))
1798b305b0f1Sespie 		  isym.n_value -= (*secpp)->vma;
1799b305b0f1Sespie 		if (! obj_pe (finfo->output_bfd))
1800b305b0f1Sespie 		  isym.n_value += (*secpp)->output_section->vma;
18012159047fSniklas 	      }
1802b305b0f1Sespie 	    break;
18032159047fSniklas 
1804b305b0f1Sespie 	    case C_FILE:
1805b305b0f1Sespie 	      /* The value of a C_FILE symbol is the symbol index of
1806b305b0f1Sespie 		 the next C_FILE symbol.  The value of the last C_FILE
1807b305b0f1Sespie 		 symbol is the symbol index to the first external
1808b305b0f1Sespie 		 symbol (actually, coff_renumber_symbols does not get
1809b305b0f1Sespie 		 this right--it just sets the value of the last C_FILE
1810b305b0f1Sespie 		 symbol to zero--and nobody has ever complained about
1811b305b0f1Sespie 		 it).  We try to get this right, below, just before we
1812b305b0f1Sespie 		 write the symbols out, but in the general case we may
1813b305b0f1Sespie 		 have to write the symbol out twice.  */
18142159047fSniklas 	      if (finfo->last_file_index != -1
1815c074d1c9Sdrahn 		  && finfo->last_file.n_value != (bfd_vma) output_index)
18162159047fSniklas 		{
1817b305b0f1Sespie 		  /* We must correct the value of the last C_FILE
1818b305b0f1Sespie                      entry.  */
18192159047fSniklas 		  finfo->last_file.n_value = output_index;
18202159047fSniklas 		  if ((bfd_size_type) finfo->last_file_index >= syment_base)
18212159047fSniklas 		    {
18222159047fSniklas 		      /* The last C_FILE symbol is in this input file.  */
18232159047fSniklas 		      bfd_coff_swap_sym_out (output_bfd,
1824*007c2a45Smiod 					     &finfo->last_file,
1825*007c2a45Smiod 					     (finfo->outsyms
18262159047fSniklas 					      + ((finfo->last_file_index
18272159047fSniklas 						  - syment_base)
18282159047fSniklas 						 * osymesz)));
18292159047fSniklas 		    }
18302159047fSniklas 		  else
18312159047fSniklas 		    {
1832c074d1c9Sdrahn 		      file_ptr pos;
1833c074d1c9Sdrahn 
18342159047fSniklas 		      /* We have already written out the last C_FILE
18352159047fSniklas 			 symbol.  We need to write it out again.  We
18362159047fSniklas 			 borrow *outsym temporarily.  */
18372159047fSniklas 		      bfd_coff_swap_sym_out (output_bfd,
1838*007c2a45Smiod 					     &finfo->last_file, outsym);
1839c074d1c9Sdrahn 		      pos = obj_sym_filepos (output_bfd);
1840c074d1c9Sdrahn 		      pos += finfo->last_file_index * osymesz;
1841c074d1c9Sdrahn 		      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
1842c074d1c9Sdrahn 			  || bfd_bwrite (outsym, osymesz, output_bfd) != osymesz)
1843c074d1c9Sdrahn 			return FALSE;
18442159047fSniklas 		    }
18452159047fSniklas 		}
18462159047fSniklas 
18472159047fSniklas 	      finfo->last_file_index = output_index;
18482159047fSniklas 	      finfo->last_file = isym;
1849b305b0f1Sespie 	      break;
18502159047fSniklas 	    }
18512159047fSniklas 
1852b305b0f1Sespie 	  /* If doing task linking, convert normal global function symbols to
1853b305b0f1Sespie 	     static functions.  */
1854b55d4692Sfgsch 	  if (finfo->info->task_link && IS_EXTERNAL (input_bfd, isym))
1855b305b0f1Sespie 	    isym.n_sclass = C_STAT;
1856b305b0f1Sespie 
18572159047fSniklas 	  /* Output the symbol.  */
1858*007c2a45Smiod 	  bfd_coff_swap_sym_out (output_bfd, &isym, outsym);
18592159047fSniklas 
18602159047fSniklas 	  *indexp = output_index;
18612159047fSniklas 
18622159047fSniklas 	  if (global)
18632159047fSniklas 	    {
18642159047fSniklas 	      long indx;
18652159047fSniklas 	      struct coff_link_hash_entry *h;
18662159047fSniklas 
18672159047fSniklas 	      indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd))
18682159047fSniklas 		      / isymesz);
18692159047fSniklas 	      h = obj_coff_sym_hashes (input_bfd)[indx];
1870e93f7393Sniklas 	      if (h == NULL)
1871e93f7393Sniklas 		{
1872e93f7393Sniklas 		  /* This can happen if there were errors earlier in
1873e93f7393Sniklas                      the link.  */
1874e93f7393Sniklas 		  bfd_set_error (bfd_error_bad_value);
1875c074d1c9Sdrahn 		  return FALSE;
1876e93f7393Sniklas 		}
18772159047fSniklas 	      h->indx = output_index;
18782159047fSniklas 	    }
18792159047fSniklas 
18802159047fSniklas 	  output_index += add;
18812159047fSniklas 	  outsym += add * osymesz;
18822159047fSniklas 	}
18832159047fSniklas 
18842159047fSniklas       esym += add * isymesz;
18852159047fSniklas       isymp += add;
18862159047fSniklas       ++secpp;
18872159047fSniklas       ++indexp;
18882159047fSniklas       for (--add; add > 0; --add)
18892159047fSniklas 	{
18902159047fSniklas 	  *secpp++ = NULL;
18912159047fSniklas 	  *indexp++ = -1;
18922159047fSniklas 	}
18932159047fSniklas     }
18942159047fSniklas 
18952159047fSniklas   /* Fix up the aux entries.  This must be done in a separate pass,
18962159047fSniklas      because we don't know the correct symbol indices until we have
18972159047fSniklas      already decided which symbols we are going to keep.  */
18982159047fSniklas   esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
18992159047fSniklas   esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
19002159047fSniklas   isymp = finfo->internal_syms;
19012159047fSniklas   indexp = finfo->sym_indices;
19022159047fSniklas   sym_hash = obj_coff_sym_hashes (input_bfd);
19032159047fSniklas   outsym = finfo->outsyms;
1904*007c2a45Smiod 
19052159047fSniklas   while (esym < esym_end)
19062159047fSniklas     {
19072159047fSniklas       int add;
19082159047fSniklas 
19092159047fSniklas       add = 1 + isymp->n_numaux;
19102159047fSniklas 
19112159047fSniklas       if ((*indexp < 0
19122159047fSniklas 	   || (bfd_size_type) *indexp < syment_base)
19132159047fSniklas 	  && (*sym_hash == NULL
19142159047fSniklas 	      || (*sym_hash)->auxbfd != input_bfd))
19152159047fSniklas 	esym += add * isymesz;
19162159047fSniklas       else
19172159047fSniklas 	{
19182159047fSniklas 	  struct coff_link_hash_entry *h;
19192159047fSniklas 	  int i;
19202159047fSniklas 
19212159047fSniklas 	  h = NULL;
19222159047fSniklas 	  if (*indexp < 0)
19232159047fSniklas 	    {
19242159047fSniklas 	      h = *sym_hash;
19250c6d0228Sniklas 
19260c6d0228Sniklas 	      /* The m68k-motorola-sysv assembler will sometimes
19270c6d0228Sniklas                  generate two symbols with the same name, but only one
19280c6d0228Sniklas                  will have aux entries.  */
19290c6d0228Sniklas 	      BFD_ASSERT (isymp->n_numaux == 0
19300c6d0228Sniklas 			  || h->numaux == isymp->n_numaux);
19312159047fSniklas 	    }
19322159047fSniklas 
19332159047fSniklas 	  esym += isymesz;
19342159047fSniklas 
19352159047fSniklas 	  if (h == NULL)
19362159047fSniklas 	    outsym += osymesz;
19372159047fSniklas 
19382159047fSniklas 	  /* Handle the aux entries.  This handling is based on
19392159047fSniklas 	     coff_pointerize_aux.  I don't know if it always correct.  */
19402159047fSniklas 	  for (i = 0; i < isymp->n_numaux && esym < esym_end; i++)
19412159047fSniklas 	    {
19422159047fSniklas 	      union internal_auxent aux;
19432159047fSniklas 	      union internal_auxent *auxp;
19442159047fSniklas 
19452159047fSniklas 	      if (h != NULL)
19462159047fSniklas 		auxp = h->aux + i;
19472159047fSniklas 	      else
19482159047fSniklas 		{
1949*007c2a45Smiod 		  bfd_coff_swap_aux_in (input_bfd, esym, isymp->n_type,
1950*007c2a45Smiod 					isymp->n_sclass, i, isymp->n_numaux, &aux);
19512159047fSniklas 		  auxp = &aux;
19522159047fSniklas 		}
19532159047fSniklas 
19542159047fSniklas 	      if (isymp->n_sclass == C_FILE)
19552159047fSniklas 		{
19562159047fSniklas 		  /* If this is a long filename, we must put it in the
19572159047fSniklas 		     string table.  */
19582159047fSniklas 		  if (auxp->x_file.x_n.x_zeroes == 0
19592159047fSniklas 		      && auxp->x_file.x_n.x_offset != 0)
19602159047fSniklas 		    {
19612159047fSniklas 		      const char *filename;
19622159047fSniklas 		      bfd_size_type indx;
19632159047fSniklas 
19642159047fSniklas 		      BFD_ASSERT (auxp->x_file.x_n.x_offset
19652159047fSniklas 				  >= STRING_SIZE_SIZE);
19662159047fSniklas 		      if (strings == NULL)
19672159047fSniklas 			{
19682159047fSniklas 			  strings = _bfd_coff_read_string_table (input_bfd);
19692159047fSniklas 			  if (strings == NULL)
1970c074d1c9Sdrahn 			    return FALSE;
19712159047fSniklas 			}
19722159047fSniklas 		      filename = strings + auxp->x_file.x_n.x_offset;
19732159047fSniklas 		      indx = _bfd_stringtab_add (finfo->strtab, filename,
19742159047fSniklas 						 hash, copy);
19752159047fSniklas 		      if (indx == (bfd_size_type) -1)
1976c074d1c9Sdrahn 			return FALSE;
19772159047fSniklas 		      auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
19782159047fSniklas 		    }
19792159047fSniklas 		}
19802159047fSniklas 	      else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
19812159047fSniklas 		{
19822159047fSniklas 		  unsigned long indx;
19832159047fSniklas 
19842159047fSniklas 		  if (ISFCN (isymp->n_type)
19852159047fSniklas 		      || ISTAG (isymp->n_sclass)
1986c88b1d6cSniklas 		      || isymp->n_sclass == C_BLOCK
1987c88b1d6cSniklas 		      || isymp->n_sclass == C_FCN)
19882159047fSniklas 		    {
19892159047fSniklas 		      indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l;
19902159047fSniklas 		      if (indx > 0
19912159047fSniklas 			  && indx < obj_raw_syment_count (input_bfd))
19922159047fSniklas 			{
19932159047fSniklas 			  /* We look forward through the symbol for
19942159047fSniklas                              the index of the next symbol we are going
19952159047fSniklas                              to include.  I don't know if this is
19962159047fSniklas                              entirely right.  */
1997c88b1d6cSniklas 			  while ((finfo->sym_indices[indx] < 0
1998c88b1d6cSniklas 				  || ((bfd_size_type) finfo->sym_indices[indx]
1999c88b1d6cSniklas 				      < syment_base))
20002159047fSniklas 				 && indx < obj_raw_syment_count (input_bfd))
20012159047fSniklas 			    ++indx;
20022159047fSniklas 			  if (indx >= obj_raw_syment_count (input_bfd))
20032159047fSniklas 			    indx = output_index;
20042159047fSniklas 			  else
20052159047fSniklas 			    indx = finfo->sym_indices[indx];
20062159047fSniklas 			  auxp->x_sym.x_fcnary.x_fcn.x_endndx.l = indx;
20072159047fSniklas 			}
20082159047fSniklas 		    }
20092159047fSniklas 
20102159047fSniklas 		  indx = auxp->x_sym.x_tagndx.l;
20112159047fSniklas 		  if (indx > 0 && indx < obj_raw_syment_count (input_bfd))
20122159047fSniklas 		    {
20132159047fSniklas 		      long symindx;
20142159047fSniklas 
20152159047fSniklas 		      symindx = finfo->sym_indices[indx];
20162159047fSniklas 		      if (symindx < 0)
20172159047fSniklas 			auxp->x_sym.x_tagndx.l = 0;
20182159047fSniklas 		      else
20192159047fSniklas 			auxp->x_sym.x_tagndx.l = symindx;
20202159047fSniklas 		    }
2021c88b1d6cSniklas 
2022c88b1d6cSniklas 		  /* The .bf symbols are supposed to be linked through
2023c88b1d6cSniklas 		     the endndx field.  We need to carry this list
2024c88b1d6cSniklas 		     across object files.  */
2025c88b1d6cSniklas 		  if (i == 0
2026c88b1d6cSniklas 		      && h == NULL
2027c88b1d6cSniklas 		      && isymp->n_sclass == C_FCN
2028c88b1d6cSniklas 		      && (isymp->_n._n_n._n_zeroes != 0
2029c88b1d6cSniklas 			  || isymp->_n._n_n._n_offset == 0)
2030c88b1d6cSniklas 		      && isymp->_n._n_name[0] == '.'
2031c88b1d6cSniklas 		      && isymp->_n._n_name[1] == 'b'
2032c88b1d6cSniklas 		      && isymp->_n._n_name[2] == 'f'
2033c88b1d6cSniklas 		      && isymp->_n._n_name[3] == '\0')
2034c88b1d6cSniklas 		    {
2035c88b1d6cSniklas 		      if (finfo->last_bf_index != -1)
2036c88b1d6cSniklas 			{
2037c88b1d6cSniklas 			  finfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.l =
2038c88b1d6cSniklas 			    *indexp;
2039c88b1d6cSniklas 
2040c88b1d6cSniklas 			  if ((bfd_size_type) finfo->last_bf_index
2041c88b1d6cSniklas 			      >= syment_base)
2042c88b1d6cSniklas 			    {
2043*007c2a45Smiod 			      void *auxout;
2044c88b1d6cSniklas 
2045c88b1d6cSniklas 			      /* The last .bf symbol is in this input
2046c88b1d6cSniklas 				 file.  This will only happen if the
2047c88b1d6cSniklas 				 assembler did not set up the .bf
2048c88b1d6cSniklas 				 endndx symbols correctly.  */
2049*007c2a45Smiod 			      auxout = (finfo->outsyms
2050c88b1d6cSniklas 					+ ((finfo->last_bf_index
2051c88b1d6cSniklas 					    - syment_base)
2052c88b1d6cSniklas 					   * osymesz));
2053*007c2a45Smiod 
2054c88b1d6cSniklas 			      bfd_coff_swap_aux_out (output_bfd,
2055*007c2a45Smiod 						     &finfo->last_bf,
2056c88b1d6cSniklas 						     isymp->n_type,
2057c88b1d6cSniklas 						     isymp->n_sclass,
2058c88b1d6cSniklas 						     0, isymp->n_numaux,
2059c88b1d6cSniklas 						     auxout);
2060c88b1d6cSniklas 			    }
2061c88b1d6cSniklas 			  else
2062c88b1d6cSniklas 			    {
2063c074d1c9Sdrahn 			      file_ptr pos;
2064c074d1c9Sdrahn 
2065c88b1d6cSniklas 			      /* We have already written out the last
2066c88b1d6cSniklas                                  .bf aux entry.  We need to write it
2067c88b1d6cSniklas                                  out again.  We borrow *outsym
2068c88b1d6cSniklas                                  temporarily.  FIXME: This case should
2069c88b1d6cSniklas                                  be made faster.  */
2070c88b1d6cSniklas 			      bfd_coff_swap_aux_out (output_bfd,
2071*007c2a45Smiod 						     &finfo->last_bf,
2072c88b1d6cSniklas 						     isymp->n_type,
2073c88b1d6cSniklas 						     isymp->n_sclass,
2074c88b1d6cSniklas 						     0, isymp->n_numaux,
2075*007c2a45Smiod 						     outsym);
2076c074d1c9Sdrahn 			      pos = obj_sym_filepos (output_bfd);
2077c074d1c9Sdrahn 			      pos += finfo->last_bf_index * osymesz;
2078c074d1c9Sdrahn 			      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
2079c074d1c9Sdrahn 				  || (bfd_bwrite (outsym, osymesz, output_bfd)
2080c074d1c9Sdrahn 				      != osymesz))
2081c074d1c9Sdrahn 				return FALSE;
2082c88b1d6cSniklas 			    }
2083c88b1d6cSniklas 			}
2084c88b1d6cSniklas 
2085c88b1d6cSniklas 		      if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.l != 0)
2086c88b1d6cSniklas 			finfo->last_bf_index = -1;
2087c88b1d6cSniklas 		      else
2088c88b1d6cSniklas 			{
2089c88b1d6cSniklas 			  /* The endndx field of this aux entry must
2090c88b1d6cSniklas                              be updated with the symbol number of the
2091c88b1d6cSniklas                              next .bf symbol.  */
2092c88b1d6cSniklas 			  finfo->last_bf = *auxp;
2093c88b1d6cSniklas 			  finfo->last_bf_index = (((outsym - finfo->outsyms)
2094c88b1d6cSniklas 						   / osymesz)
2095c88b1d6cSniklas 						  + syment_base);
2096c88b1d6cSniklas 			}
2097c88b1d6cSniklas 		    }
20982159047fSniklas 		}
20992159047fSniklas 
21002159047fSniklas 	      if (h == NULL)
21012159047fSniklas 		{
2102*007c2a45Smiod 		  bfd_coff_swap_aux_out (output_bfd, auxp, isymp->n_type,
21032159047fSniklas 					 isymp->n_sclass, i, isymp->n_numaux,
2104*007c2a45Smiod 					 outsym);
21052159047fSniklas 		  outsym += osymesz;
21062159047fSniklas 		}
21072159047fSniklas 
21082159047fSniklas 	      esym += isymesz;
21092159047fSniklas 	    }
21102159047fSniklas 	}
21112159047fSniklas 
21122159047fSniklas       indexp += add;
21132159047fSniklas       isymp += add;
21142159047fSniklas       sym_hash += add;
21152159047fSniklas     }
21162159047fSniklas 
21172159047fSniklas   /* Relocate the line numbers, unless we are stripping them.  */
21182159047fSniklas   if (finfo->info->strip == strip_none
21192159047fSniklas       || finfo->info->strip == strip_some)
21202159047fSniklas     {
21212159047fSniklas       for (o = input_bfd->sections; o != NULL; o = o->next)
21222159047fSniklas 	{
21232159047fSniklas 	  bfd_vma offset;
21242159047fSniklas 	  bfd_byte *eline;
21252159047fSniklas 	  bfd_byte *elineend;
2126b305b0f1Sespie 	  bfd_byte *oeline;
2127c074d1c9Sdrahn 	  bfd_boolean skipping;
2128c074d1c9Sdrahn 	  file_ptr pos;
2129c074d1c9Sdrahn 	  bfd_size_type amt;
21302159047fSniklas 
21312159047fSniklas 	  /* FIXME: If SEC_HAS_CONTENTS is not for the section, then
21322159047fSniklas 	     build_link_order in ldwrite.c will not have created a
21332159047fSniklas 	     link order, which means that we will not have seen this
21342159047fSniklas 	     input section in _bfd_coff_final_link, which means that
21352159047fSniklas 	     we will not have allocated space for the line numbers of
21362159047fSniklas 	     this section.  I don't think line numbers can be
21372159047fSniklas 	     meaningful for a section which does not have
21382159047fSniklas 	     SEC_HAS_CONTENTS set, but, if they do, this must be
21392159047fSniklas 	     changed.  */
21402159047fSniklas 	  if (o->lineno_count == 0
21412159047fSniklas 	      || (o->output_section->flags & SEC_HAS_CONTENTS) == 0)
21422159047fSniklas 	    continue;
21432159047fSniklas 
21442159047fSniklas 	  if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0
2145c074d1c9Sdrahn 	      || bfd_bread (finfo->linenos, linesz * o->lineno_count,
21462159047fSniklas 			   input_bfd) != linesz * o->lineno_count)
2147c074d1c9Sdrahn 	    return FALSE;
21482159047fSniklas 
21492159047fSniklas 	  offset = o->output_section->vma + o->output_offset - o->vma;
21502159047fSniklas 	  eline = finfo->linenos;
2151b305b0f1Sespie 	  oeline = finfo->linenos;
21522159047fSniklas 	  elineend = eline + linesz * o->lineno_count;
2153c074d1c9Sdrahn 	  skipping = FALSE;
21542159047fSniklas 	  for (; eline < elineend; eline += linesz)
21552159047fSniklas 	    {
21562159047fSniklas 	      struct internal_lineno iline;
21572159047fSniklas 
2158*007c2a45Smiod 	      bfd_coff_swap_lineno_in (input_bfd, eline, &iline);
21592159047fSniklas 
21602159047fSniklas 	      if (iline.l_lnno != 0)
21612159047fSniklas 		iline.l_addr.l_paddr += offset;
21622159047fSniklas 	      else if (iline.l_addr.l_symndx >= 0
21632159047fSniklas 		       && ((unsigned long) iline.l_addr.l_symndx
21642159047fSniklas 			   < obj_raw_syment_count (input_bfd)))
21652159047fSniklas 		{
21662159047fSniklas 		  long indx;
21672159047fSniklas 
21682159047fSniklas 		  indx = finfo->sym_indices[iline.l_addr.l_symndx];
21692159047fSniklas 
21702159047fSniklas 		  if (indx < 0)
21712159047fSniklas 		    {
21722159047fSniklas 		      /* These line numbers are attached to a symbol
2173b305b0f1Sespie 			 which we are stripping.  We must discard the
2174b305b0f1Sespie 			 line numbers because reading them back with
2175b305b0f1Sespie 			 no associated symbol (or associating them all
2176b305b0f1Sespie 			 with symbol #0) will fail.  We can't regain
2177b305b0f1Sespie 			 the space in the output file, but at least
2178b305b0f1Sespie 			 they're dense.  */
2179c074d1c9Sdrahn 		      skipping = TRUE;
21802159047fSniklas 		    }
21812159047fSniklas 		  else
21822159047fSniklas 		    {
21832159047fSniklas 		      struct internal_syment is;
21842159047fSniklas 		      union internal_auxent ia;
21852159047fSniklas 
21862159047fSniklas 		      /* Fix up the lnnoptr field in the aux entry of
21872159047fSniklas 			 the symbol.  It turns out that we can't do
21882159047fSniklas 			 this when we modify the symbol aux entries,
21892159047fSniklas 			 because gas sometimes screws up the lnnoptr
21902159047fSniklas 			 field and makes it an offset from the start
21912159047fSniklas 			 of the line numbers rather than an absolute
21922159047fSniklas 			 file index.  */
21932159047fSniklas 		      bfd_coff_swap_sym_in (output_bfd,
2194*007c2a45Smiod 					    (finfo->outsyms
21952159047fSniklas 					     + ((indx - syment_base)
2196*007c2a45Smiod 						* osymesz)), &is);
21972159047fSniklas 		      if ((ISFCN (is.n_type)
21982159047fSniklas 			   || is.n_sclass == C_BLOCK)
21992159047fSniklas 			  && is.n_numaux >= 1)
22002159047fSniklas 			{
2201*007c2a45Smiod 			  void *auxptr;
22022159047fSniklas 
2203*007c2a45Smiod 			  auxptr = (finfo->outsyms
22042159047fSniklas 				    + ((indx - syment_base + 1)
22052159047fSniklas 				       * osymesz));
22062159047fSniklas 			  bfd_coff_swap_aux_in (output_bfd, auxptr,
22072159047fSniklas 						is.n_type, is.n_sclass,
2208*007c2a45Smiod 						0, is.n_numaux, &ia);
22092159047fSniklas 			  ia.x_sym.x_fcnary.x_fcn.x_lnnoptr =
22102159047fSniklas 			    (o->output_section->line_filepos
22112159047fSniklas 			     + o->output_section->lineno_count * linesz
22122159047fSniklas 			     + eline - finfo->linenos);
2213*007c2a45Smiod 			  bfd_coff_swap_aux_out (output_bfd, &ia,
22142159047fSniklas 						 is.n_type, is.n_sclass, 0,
22152159047fSniklas 						 is.n_numaux, auxptr);
22162159047fSniklas 			}
2217b305b0f1Sespie 
2218c074d1c9Sdrahn 		      skipping = FALSE;
22192159047fSniklas 		    }
22202159047fSniklas 
22212159047fSniklas 		  iline.l_addr.l_symndx = indx;
22222159047fSniklas 		}
22232159047fSniklas 
2224b305b0f1Sespie 	      if (!skipping)
2225b305b0f1Sespie 	        {
2226*007c2a45Smiod 		  bfd_coff_swap_lineno_out (output_bfd, &iline, oeline);
2227b305b0f1Sespie 		  oeline += linesz;
2228b305b0f1Sespie 		}
22292159047fSniklas 	    }
22302159047fSniklas 
2231c074d1c9Sdrahn 	  pos = o->output_section->line_filepos;
2232c074d1c9Sdrahn 	  pos += o->output_section->lineno_count * linesz;
2233c074d1c9Sdrahn 	  amt = oeline - finfo->linenos;
2234c074d1c9Sdrahn 	  if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
2235c074d1c9Sdrahn 	      || bfd_bwrite (finfo->linenos, amt, output_bfd) != amt)
2236c074d1c9Sdrahn 	    return FALSE;
22372159047fSniklas 
2238c074d1c9Sdrahn 	  o->output_section->lineno_count += amt / linesz;
22392159047fSniklas 	}
22402159047fSniklas     }
22412159047fSniklas 
22422159047fSniklas   /* If we swapped out a C_FILE symbol, guess that the next C_FILE
22432159047fSniklas      symbol will be the first symbol in the next input file.  In the
22442159047fSniklas      normal case, this will save us from writing out the C_FILE symbol
22452159047fSniklas      again.  */
22462159047fSniklas   if (finfo->last_file_index != -1
22472159047fSniklas       && (bfd_size_type) finfo->last_file_index >= syment_base)
22482159047fSniklas     {
22492159047fSniklas       finfo->last_file.n_value = output_index;
2250*007c2a45Smiod       bfd_coff_swap_sym_out (output_bfd, &finfo->last_file,
2251*007c2a45Smiod 			     (finfo->outsyms
22522159047fSniklas 			      + ((finfo->last_file_index - syment_base)
22532159047fSniklas 				 * osymesz)));
22542159047fSniklas     }
22552159047fSniklas 
22562159047fSniklas   /* Write the modified symbols to the output file.  */
22572159047fSniklas   if (outsym > finfo->outsyms)
22582159047fSniklas     {
2259c074d1c9Sdrahn       file_ptr pos;
2260c074d1c9Sdrahn       bfd_size_type amt;
2261c074d1c9Sdrahn 
2262c074d1c9Sdrahn       pos = obj_sym_filepos (output_bfd) + syment_base * osymesz;
2263c074d1c9Sdrahn       amt = outsym - finfo->outsyms;
2264c074d1c9Sdrahn       if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
2265c074d1c9Sdrahn 	  || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt)
2266c074d1c9Sdrahn 	return FALSE;
22672159047fSniklas 
22682159047fSniklas       BFD_ASSERT ((obj_raw_syment_count (output_bfd)
22692159047fSniklas 		   + (outsym - finfo->outsyms) / osymesz)
22702159047fSniklas 		  == output_index);
22712159047fSniklas 
22722159047fSniklas       obj_raw_syment_count (output_bfd) = output_index;
22732159047fSniklas     }
22742159047fSniklas 
22752159047fSniklas   /* Relocate the contents of each section.  */
22762159047fSniklas   adjust_symndx = coff_backend_info (input_bfd)->_bfd_coff_adjust_symndx;
22772159047fSniklas   for (o = input_bfd->sections; o != NULL; o = o->next)
22782159047fSniklas     {
22792159047fSniklas       bfd_byte *contents;
2280c88b1d6cSniklas       struct coff_section_tdata *secdata;
22812159047fSniklas 
2282c88b1d6cSniklas       if (! o->linker_mark)
2283c88b1d6cSniklas 	/* This section was omitted from the link.  */
2284c88b1d6cSniklas 	continue;
2285c88b1d6cSniklas 
2286c88b1d6cSniklas       if ((o->flags & SEC_HAS_CONTENTS) == 0
2287c88b1d6cSniklas 	  || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
22882159047fSniklas 	{
22892159047fSniklas 	  if ((o->flags & SEC_RELOC) != 0
22902159047fSniklas 	      && o->reloc_count != 0)
22912159047fSniklas 	    {
22922159047fSniklas 	      ((*_bfd_error_handler)
2293b305b0f1Sespie 	       (_("%s: relocs in section `%s', but it has no contents"),
2294c074d1c9Sdrahn 		bfd_archive_filename (input_bfd),
22952159047fSniklas 		bfd_get_section_name (input_bfd, o)));
22962159047fSniklas 	      bfd_set_error (bfd_error_no_contents);
2297c074d1c9Sdrahn 	      return FALSE;
22982159047fSniklas 	    }
22992159047fSniklas 
23002159047fSniklas 	  continue;
23012159047fSniklas 	}
23022159047fSniklas 
2303c88b1d6cSniklas       secdata = coff_section_data (input_bfd, o);
2304c88b1d6cSniklas       if (secdata != NULL && secdata->contents != NULL)
2305c88b1d6cSniklas 	contents = secdata->contents;
23062159047fSniklas       else
23072159047fSniklas 	{
23082159047fSniklas 	  if (! bfd_get_section_contents (input_bfd, o, finfo->contents,
23092159047fSniklas 					  (file_ptr) 0, o->_raw_size))
2310c074d1c9Sdrahn 	    return FALSE;
23112159047fSniklas 	  contents = finfo->contents;
23122159047fSniklas 	}
23132159047fSniklas 
23142159047fSniklas       if ((o->flags & SEC_RELOC) != 0)
23152159047fSniklas 	{
23162159047fSniklas 	  int target_index;
23172159047fSniklas 	  struct internal_reloc *internal_relocs;
23182159047fSniklas 	  struct internal_reloc *irel;
23192159047fSniklas 
23202159047fSniklas 	  /* Read in the relocs.  */
23212159047fSniklas 	  target_index = o->output_section->target_index;
23222159047fSniklas 	  internal_relocs = (_bfd_coff_read_internal_relocs
2323c074d1c9Sdrahn 			     (input_bfd, o, FALSE, finfo->external_relocs,
2324*007c2a45Smiod 			      finfo->info->relocatable,
2325*007c2a45Smiod 			      (finfo->info->relocatable
23262159047fSniklas 			       ? (finfo->section_info[target_index].relocs
23272159047fSniklas 				  + o->output_section->reloc_count)
23282159047fSniklas 			       : finfo->internal_relocs)));
23292159047fSniklas 	  if (internal_relocs == NULL)
2330c074d1c9Sdrahn 	    return FALSE;
23312159047fSniklas 
23322159047fSniklas 	  /* Call processor specific code to relocate the section
23332159047fSniklas              contents.  */
23342159047fSniklas 	  if (! bfd_coff_relocate_section (output_bfd, finfo->info,
23352159047fSniklas 					   input_bfd, o,
23362159047fSniklas 					   contents,
23372159047fSniklas 					   internal_relocs,
23382159047fSniklas 					   finfo->internal_syms,
23392159047fSniklas 					   finfo->sec_ptrs))
2340c074d1c9Sdrahn 	    return FALSE;
23412159047fSniklas 
2342*007c2a45Smiod 	  if (finfo->info->relocatable)
23432159047fSniklas 	    {
23442159047fSniklas 	      bfd_vma offset;
23452159047fSniklas 	      struct internal_reloc *irelend;
23462159047fSniklas 	      struct coff_link_hash_entry **rel_hash;
23472159047fSniklas 
23482159047fSniklas 	      offset = o->output_section->vma + o->output_offset - o->vma;
23492159047fSniklas 	      irel = internal_relocs;
23502159047fSniklas 	      irelend = irel + o->reloc_count;
23512159047fSniklas 	      rel_hash = (finfo->section_info[target_index].rel_hashes
23522159047fSniklas 			  + o->output_section->reloc_count);
23532159047fSniklas 	      for (; irel < irelend; irel++, rel_hash++)
23542159047fSniklas 		{
23552159047fSniklas 		  struct coff_link_hash_entry *h;
2356c074d1c9Sdrahn 		  bfd_boolean adjusted;
23572159047fSniklas 
23582159047fSniklas 		  *rel_hash = NULL;
23592159047fSniklas 
23602159047fSniklas 		  /* Adjust the reloc address and symbol index.  */
23612159047fSniklas 		  irel->r_vaddr += offset;
23622159047fSniklas 
23632159047fSniklas 		  if (irel->r_symndx == -1)
23642159047fSniklas 		    continue;
23652159047fSniklas 
23662159047fSniklas 		  if (adjust_symndx)
23672159047fSniklas 		    {
23682159047fSniklas 		      if (! (*adjust_symndx) (output_bfd, finfo->info,
23692159047fSniklas 					      input_bfd, o, irel,
23702159047fSniklas 					      &adjusted))
2371c074d1c9Sdrahn 			return FALSE;
23722159047fSniklas 		      if (adjusted)
23732159047fSniklas 			continue;
23742159047fSniklas 		    }
23752159047fSniklas 
23762159047fSniklas 		  h = obj_coff_sym_hashes (input_bfd)[irel->r_symndx];
23772159047fSniklas 		  if (h != NULL)
23782159047fSniklas 		    {
23792159047fSniklas 		      /* This is a global symbol.  */
23802159047fSniklas 		      if (h->indx >= 0)
23812159047fSniklas 			irel->r_symndx = h->indx;
23822159047fSniklas 		      else
23832159047fSniklas 			{
23842159047fSniklas 			  /* This symbol is being written at the end
23852159047fSniklas 			     of the file, and we do not yet know the
23862159047fSniklas 			     symbol index.  We save the pointer to the
23872159047fSniklas 			     hash table entry in the rel_hash list.
23882159047fSniklas 			     We set the indx field to -2 to indicate
23892159047fSniklas 			     that this symbol must not be stripped.  */
23902159047fSniklas 			  *rel_hash = h;
23912159047fSniklas 			  h->indx = -2;
23922159047fSniklas 			}
23932159047fSniklas 		    }
23942159047fSniklas 		  else
23952159047fSniklas 		    {
23962159047fSniklas 		      long indx;
23972159047fSniklas 
23982159047fSniklas 		      indx = finfo->sym_indices[irel->r_symndx];
23992159047fSniklas 		      if (indx != -1)
24002159047fSniklas 			irel->r_symndx = indx;
24012159047fSniklas 		      else
24022159047fSniklas 			{
24032159047fSniklas 			  struct internal_syment *is;
24042159047fSniklas 			  const char *name;
24052159047fSniklas 			  char buf[SYMNMLEN + 1];
24062159047fSniklas 
24072159047fSniklas 			  /* This reloc is against a symbol we are
2408b305b0f1Sespie                              stripping.  This should have been handled
2409b305b0f1Sespie 			     by the 'dont_skip_symbol' code in the while
2410b305b0f1Sespie 			     loop at the top of this function.  */
24112159047fSniklas 			  is = finfo->internal_syms + irel->r_symndx;
24122159047fSniklas 
24132159047fSniklas 			  name = (_bfd_coff_internal_syment_name
24142159047fSniklas 				  (input_bfd, is, buf));
24152159047fSniklas 			  if (name == NULL)
2416c074d1c9Sdrahn 			    return FALSE;
24172159047fSniklas 
24182159047fSniklas 			  if (! ((*finfo->info->callbacks->unattached_reloc)
24192159047fSniklas 				 (finfo->info, name, input_bfd, o,
24202159047fSniklas 				  irel->r_vaddr)))
2421c074d1c9Sdrahn 			    return FALSE;
24222159047fSniklas 			}
24232159047fSniklas 		    }
24242159047fSniklas 		}
24252159047fSniklas 
24262159047fSniklas 	      o->output_section->reloc_count += o->reloc_count;
24272159047fSniklas 	    }
24282159047fSniklas 	}
24292159047fSniklas 
24302159047fSniklas       /* Write out the modified section contents.  */
2431c88b1d6cSniklas       if (secdata == NULL || secdata->stab_info == NULL)
2432c88b1d6cSniklas 	{
2433c074d1c9Sdrahn 	  file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd);
2434c074d1c9Sdrahn 	  bfd_size_type amt = (o->_cooked_size != 0
2435c074d1c9Sdrahn 			       ? o->_cooked_size : o->_raw_size);
24362159047fSniklas 	  if (! bfd_set_section_contents (output_bfd, o->output_section,
2437c074d1c9Sdrahn 					  contents, loc, amt))
2438c074d1c9Sdrahn 	    return FALSE;
24392159047fSniklas 	}
2440c88b1d6cSniklas       else
2441c88b1d6cSniklas 	{
2442b305b0f1Sespie 	  if (! (_bfd_write_section_stabs
2443b305b0f1Sespie 		 (output_bfd, &coff_hash_table (finfo->info)->stab_info,
2444b305b0f1Sespie 		  o, &secdata->stab_info, contents)))
2445c074d1c9Sdrahn 	    return FALSE;
2446c88b1d6cSniklas 	}
2447c88b1d6cSniklas     }
24482159047fSniklas 
2449*007c2a45Smiod   if (! finfo->info->keep_memory
2450*007c2a45Smiod       && ! _bfd_coff_free_symbols (input_bfd))
2451c074d1c9Sdrahn     return FALSE;
24522159047fSniklas 
2453c074d1c9Sdrahn   return TRUE;
24542159047fSniklas }
24552159047fSniklas 
24562159047fSniklas /* Write out a global symbol.  Called via coff_link_hash_traverse.  */
24572159047fSniklas 
2458c074d1c9Sdrahn bfd_boolean
_bfd_coff_write_global_sym(struct coff_link_hash_entry * h,void * data)2459*007c2a45Smiod _bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data)
24602159047fSniklas {
24612159047fSniklas   struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
24622159047fSniklas   bfd *output_bfd;
24632159047fSniklas   struct internal_syment isym;
24642159047fSniklas   bfd_size_type symesz;
24652159047fSniklas   unsigned int i;
2466c074d1c9Sdrahn   file_ptr pos;
24672159047fSniklas 
24682159047fSniklas   output_bfd = finfo->output_bfd;
24692159047fSniklas 
2470c074d1c9Sdrahn   if (h->root.type == bfd_link_hash_warning)
2471c074d1c9Sdrahn     {
2472c074d1c9Sdrahn       h = (struct coff_link_hash_entry *) h->root.u.i.link;
2473c074d1c9Sdrahn       if (h->root.type == bfd_link_hash_new)
2474c074d1c9Sdrahn 	return TRUE;
2475c074d1c9Sdrahn     }
2476c074d1c9Sdrahn 
24772159047fSniklas   if (h->indx >= 0)
2478c074d1c9Sdrahn     return TRUE;
24792159047fSniklas 
24802159047fSniklas   if (h->indx != -2
24812159047fSniklas       && (finfo->info->strip == strip_all
24822159047fSniklas 	  || (finfo->info->strip == strip_some
24832159047fSniklas 	      && (bfd_hash_lookup (finfo->info->keep_hash,
2484c074d1c9Sdrahn 				   h->root.root.string, FALSE, FALSE)
24852159047fSniklas 		  == NULL))))
2486c074d1c9Sdrahn     return TRUE;
24872159047fSniklas 
24882159047fSniklas   switch (h->root.type)
24892159047fSniklas     {
24902159047fSniklas     default:
24912159047fSniklas     case bfd_link_hash_new:
2492c074d1c9Sdrahn     case bfd_link_hash_warning:
24932159047fSniklas       abort ();
2494c074d1c9Sdrahn       return FALSE;
24952159047fSniklas 
24962159047fSniklas     case bfd_link_hash_undefined:
24972159047fSniklas     case bfd_link_hash_undefweak:
24982159047fSniklas       isym.n_scnum = N_UNDEF;
24992159047fSniklas       isym.n_value = 0;
25002159047fSniklas       break;
25012159047fSniklas 
25022159047fSniklas     case bfd_link_hash_defined:
25032159047fSniklas     case bfd_link_hash_defweak:
25042159047fSniklas       {
25052159047fSniklas 	asection *sec;
25062159047fSniklas 
25072159047fSniklas 	sec = h->root.u.def.section->output_section;
25082159047fSniklas 	if (bfd_is_abs_section (sec))
25092159047fSniklas 	  isym.n_scnum = N_ABS;
25102159047fSniklas 	else
25112159047fSniklas 	  isym.n_scnum = sec->target_index;
25122159047fSniklas 	isym.n_value = (h->root.u.def.value
25132159047fSniklas 			+ h->root.u.def.section->output_offset);
2514b305b0f1Sespie 	if (! obj_pe (finfo->output_bfd))
2515b305b0f1Sespie 	  isym.n_value += sec->vma;
25162159047fSniklas       }
25172159047fSniklas       break;
25182159047fSniklas 
25192159047fSniklas     case bfd_link_hash_common:
25202159047fSniklas       isym.n_scnum = N_UNDEF;
25212159047fSniklas       isym.n_value = h->root.u.c.size;
25222159047fSniklas       break;
25232159047fSniklas 
25242159047fSniklas     case bfd_link_hash_indirect:
25252159047fSniklas       /* Just ignore these.  They can't be handled anyhow.  */
2526c074d1c9Sdrahn       return TRUE;
25272159047fSniklas     }
25282159047fSniklas 
25292159047fSniklas   if (strlen (h->root.root.string) <= SYMNMLEN)
25302159047fSniklas     strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN);
25312159047fSniklas   else
25322159047fSniklas     {
2533c074d1c9Sdrahn       bfd_boolean hash;
25342159047fSniklas       bfd_size_type indx;
25352159047fSniklas 
2536c074d1c9Sdrahn       hash = TRUE;
25372159047fSniklas       if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
2538c074d1c9Sdrahn 	hash = FALSE;
25392159047fSniklas       indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash,
2540c074d1c9Sdrahn 				 FALSE);
25412159047fSniklas       if (indx == (bfd_size_type) -1)
25422159047fSniklas 	{
2543c074d1c9Sdrahn 	  finfo->failed = TRUE;
2544c074d1c9Sdrahn 	  return FALSE;
25452159047fSniklas 	}
25462159047fSniklas       isym._n._n_n._n_zeroes = 0;
25472159047fSniklas       isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
25482159047fSniklas     }
25492159047fSniklas 
25502159047fSniklas   isym.n_sclass = h->class;
25512159047fSniklas   isym.n_type = h->type;
25522159047fSniklas 
25532159047fSniklas   if (isym.n_sclass == C_NULL)
25542159047fSniklas     isym.n_sclass = C_EXT;
25552159047fSniklas 
2556b305b0f1Sespie   /* If doing task linking and this is the pass where we convert
2557b305b0f1Sespie      defined globals to statics, then do that conversion now.  If the
2558b305b0f1Sespie      symbol is not being converted, just ignore it and it will be
2559b305b0f1Sespie      output during a later pass.  */
2560b305b0f1Sespie   if (finfo->global_to_static)
2561b305b0f1Sespie     {
2562b55d4692Sfgsch       if (! IS_EXTERNAL (output_bfd, isym))
2563c074d1c9Sdrahn 	return TRUE;
2564b55d4692Sfgsch 
2565b305b0f1Sespie       isym.n_sclass = C_STAT;
2566b305b0f1Sespie     }
2567b305b0f1Sespie 
2568*007c2a45Smiod   /* When a weak symbol is not overridden by a strong one,
2569b55d4692Sfgsch      turn it into an external symbol when not building a
2570*007c2a45Smiod      shared or relocatable object.  */
2571b55d4692Sfgsch   if (! finfo->info->shared
2572*007c2a45Smiod       && ! finfo->info->relocatable
2573b55d4692Sfgsch       && IS_WEAK_EXTERNAL (finfo->output_bfd, isym))
2574b55d4692Sfgsch     isym.n_sclass = C_EXT;
2575b55d4692Sfgsch 
25762159047fSniklas   isym.n_numaux = h->numaux;
25772159047fSniklas 
2578*007c2a45Smiod   bfd_coff_swap_sym_out (output_bfd, &isym, finfo->outsyms);
25792159047fSniklas 
25802159047fSniklas   symesz = bfd_coff_symesz (output_bfd);
25812159047fSniklas 
2582c074d1c9Sdrahn   pos = obj_sym_filepos (output_bfd);
2583c074d1c9Sdrahn   pos += obj_raw_syment_count (output_bfd) * symesz;
2584c074d1c9Sdrahn   if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
2585c074d1c9Sdrahn       || bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz)
25862159047fSniklas     {
2587c074d1c9Sdrahn       finfo->failed = TRUE;
2588c074d1c9Sdrahn       return FALSE;
25892159047fSniklas     }
25902159047fSniklas 
25912159047fSniklas   h->indx = obj_raw_syment_count (output_bfd);
25922159047fSniklas 
25932159047fSniklas   ++obj_raw_syment_count (output_bfd);
25942159047fSniklas 
2595b305b0f1Sespie   /* Write out any associated aux entries.  Most of the aux entries
2596b305b0f1Sespie      will have been modified in _bfd_coff_link_input_bfd.  We have to
2597b305b0f1Sespie      handle section aux entries here, now that we have the final
2598b305b0f1Sespie      relocation and line number counts.  */
25992159047fSniklas   for (i = 0; i < isym.n_numaux; i++)
26002159047fSniklas     {
2601b305b0f1Sespie       union internal_auxent *auxp;
2602b305b0f1Sespie 
2603b305b0f1Sespie       auxp = h->aux + i;
2604b305b0f1Sespie 
2605b305b0f1Sespie       /* Look for a section aux entry here using the same tests that
2606b305b0f1Sespie          coff_swap_aux_out uses.  */
2607b305b0f1Sespie       if (i == 0
2608b305b0f1Sespie 	  && (isym.n_sclass == C_STAT
2609b305b0f1Sespie 	      || isym.n_sclass == C_HIDDEN)
2610b305b0f1Sespie 	  && isym.n_type == T_NULL
2611b305b0f1Sespie 	  && (h->root.type == bfd_link_hash_defined
2612b305b0f1Sespie 	      || h->root.type == bfd_link_hash_defweak))
2613b305b0f1Sespie 	{
2614b305b0f1Sespie 	  asection *sec;
2615b305b0f1Sespie 
2616b305b0f1Sespie 	  sec = h->root.u.def.section->output_section;
2617b305b0f1Sespie 	  if (sec != NULL)
2618b305b0f1Sespie 	    {
2619b305b0f1Sespie 	      auxp->x_scn.x_scnlen = (sec->_cooked_size != 0
2620b305b0f1Sespie 				      ? sec->_cooked_size
2621b305b0f1Sespie 				      : sec->_raw_size);
2622b305b0f1Sespie 
2623b305b0f1Sespie 	      /* For PE, an overflow on the final link reportedly does
2624b305b0f1Sespie                  not matter.  FIXME: Why not?  */
2625b305b0f1Sespie 	      if (sec->reloc_count > 0xffff
2626b305b0f1Sespie 		  && (! obj_pe (output_bfd)
2627*007c2a45Smiod 		      || finfo->info->relocatable))
2628b305b0f1Sespie 		(*_bfd_error_handler)
2629b305b0f1Sespie 		  (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
2630b305b0f1Sespie 		   bfd_get_filename (output_bfd),
2631b305b0f1Sespie 		   bfd_get_section_name (output_bfd, sec),
2632b305b0f1Sespie 		   sec->reloc_count);
2633b305b0f1Sespie 
2634b305b0f1Sespie 	      if (sec->lineno_count > 0xffff
2635b305b0f1Sespie 		  && (! obj_pe (output_bfd)
2636*007c2a45Smiod 		      || finfo->info->relocatable))
2637b305b0f1Sespie 		(*_bfd_error_handler)
2638b305b0f1Sespie 		  (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
2639b305b0f1Sespie 		   bfd_get_filename (output_bfd),
2640b305b0f1Sespie 		   bfd_get_section_name (output_bfd, sec),
2641b305b0f1Sespie 		   sec->lineno_count);
2642b305b0f1Sespie 
2643b305b0f1Sespie 	      auxp->x_scn.x_nreloc = sec->reloc_count;
2644b305b0f1Sespie 	      auxp->x_scn.x_nlinno = sec->lineno_count;
2645b305b0f1Sespie 	      auxp->x_scn.x_checksum = 0;
2646b305b0f1Sespie 	      auxp->x_scn.x_associated = 0;
2647b305b0f1Sespie 	      auxp->x_scn.x_comdat = 0;
2648b305b0f1Sespie 	    }
2649b305b0f1Sespie 	}
2650b305b0f1Sespie 
2651*007c2a45Smiod       bfd_coff_swap_aux_out (output_bfd, auxp, isym.n_type,
2652c074d1c9Sdrahn 			     isym.n_sclass, (int) i, isym.n_numaux,
2653*007c2a45Smiod 			     finfo->outsyms);
2654c074d1c9Sdrahn       if (bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz)
26552159047fSniklas 	{
2656c074d1c9Sdrahn 	  finfo->failed = TRUE;
2657c074d1c9Sdrahn 	  return FALSE;
26582159047fSniklas 	}
26592159047fSniklas       ++obj_raw_syment_count (output_bfd);
26602159047fSniklas     }
26612159047fSniklas 
2662c074d1c9Sdrahn   return TRUE;
26632159047fSniklas }
26642159047fSniklas 
2665b305b0f1Sespie /* Write out task global symbols, converting them to statics.  Called
2666b305b0f1Sespie    via coff_link_hash_traverse.  Calls bfd_coff_write_global_sym to do
2667b305b0f1Sespie    the dirty work, if the symbol we are processing needs conversion.  */
2668b305b0f1Sespie 
2669c074d1c9Sdrahn bfd_boolean
_bfd_coff_write_task_globals(struct coff_link_hash_entry * h,void * data)2670*007c2a45Smiod _bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data)
2671b305b0f1Sespie {
2672b305b0f1Sespie   struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
2673c074d1c9Sdrahn   bfd_boolean rtnval = TRUE;
2674c074d1c9Sdrahn   bfd_boolean save_global_to_static;
2675c074d1c9Sdrahn 
2676c074d1c9Sdrahn   if (h->root.type == bfd_link_hash_warning)
2677c074d1c9Sdrahn     h = (struct coff_link_hash_entry *) h->root.u.i.link;
2678b305b0f1Sespie 
2679b305b0f1Sespie   if (h->indx < 0)
2680b305b0f1Sespie     {
2681b305b0f1Sespie       switch (h->root.type)
2682b305b0f1Sespie 	{
2683b305b0f1Sespie 	case bfd_link_hash_defined:
2684b305b0f1Sespie 	case bfd_link_hash_defweak:
2685b305b0f1Sespie 	  save_global_to_static = finfo->global_to_static;
2686c074d1c9Sdrahn 	  finfo->global_to_static = TRUE;
2687b305b0f1Sespie 	  rtnval = _bfd_coff_write_global_sym (h, data);
2688b305b0f1Sespie 	  finfo->global_to_static = save_global_to_static;
2689b305b0f1Sespie 	  break;
2690b305b0f1Sespie 	default:
2691b305b0f1Sespie 	  break;
2692b305b0f1Sespie 	}
2693b305b0f1Sespie     }
2694b305b0f1Sespie   return (rtnval);
2695b305b0f1Sespie }
2696b305b0f1Sespie 
26972159047fSniklas /* Handle a link order which is supposed to generate a reloc.  */
26982159047fSniklas 
2699c074d1c9Sdrahn bfd_boolean
_bfd_coff_reloc_link_order(bfd * output_bfd,struct coff_final_link_info * finfo,asection * output_section,struct bfd_link_order * link_order)2700*007c2a45Smiod _bfd_coff_reloc_link_order (bfd *output_bfd,
2701*007c2a45Smiod 			    struct coff_final_link_info *finfo,
2702*007c2a45Smiod 			    asection *output_section,
2703*007c2a45Smiod 			    struct bfd_link_order *link_order)
27042159047fSniklas {
27052159047fSniklas   reloc_howto_type *howto;
27062159047fSniklas   struct internal_reloc *irel;
27072159047fSniklas   struct coff_link_hash_entry **rel_hash_ptr;
27082159047fSniklas 
27092159047fSniklas   howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
27102159047fSniklas   if (howto == NULL)
27112159047fSniklas     {
27122159047fSniklas       bfd_set_error (bfd_error_bad_value);
2713c074d1c9Sdrahn       return FALSE;
27142159047fSniklas     }
27152159047fSniklas 
27162159047fSniklas   if (link_order->u.reloc.p->addend != 0)
27172159047fSniklas     {
27182159047fSniklas       bfd_size_type size;
27192159047fSniklas       bfd_byte *buf;
27202159047fSniklas       bfd_reloc_status_type rstat;
2721c074d1c9Sdrahn       bfd_boolean ok;
2722c074d1c9Sdrahn       file_ptr loc;
27232159047fSniklas 
27242159047fSniklas       size = bfd_get_reloc_size (howto);
2725*007c2a45Smiod       buf = bfd_zmalloc (size);
27262159047fSniklas       if (buf == NULL)
2727c074d1c9Sdrahn 	return FALSE;
27282159047fSniklas 
27292159047fSniklas       rstat = _bfd_relocate_contents (howto, output_bfd,
2730c074d1c9Sdrahn 				      (bfd_vma) link_order->u.reloc.p->addend,\
2731c074d1c9Sdrahn 				      buf);
27322159047fSniklas       switch (rstat)
27332159047fSniklas 	{
27342159047fSniklas 	case bfd_reloc_ok:
27352159047fSniklas 	  break;
27362159047fSniklas 	default:
27372159047fSniklas 	case bfd_reloc_outofrange:
27382159047fSniklas 	  abort ();
27392159047fSniklas 	case bfd_reloc_overflow:
27402159047fSniklas 	  if (! ((*finfo->info->callbacks->reloc_overflow)
27412159047fSniklas 		 (finfo->info,
27422159047fSniklas 		  (link_order->type == bfd_section_reloc_link_order
27432159047fSniklas 		   ? bfd_section_name (output_bfd,
27442159047fSniklas 				       link_order->u.reloc.p->u.section)
27452159047fSniklas 		   : link_order->u.reloc.p->u.name),
27462159047fSniklas 		  howto->name, link_order->u.reloc.p->addend,
27472159047fSniklas 		  (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
27482159047fSniklas 	    {
27492159047fSniklas 	      free (buf);
2750c074d1c9Sdrahn 	      return FALSE;
27512159047fSniklas 	    }
27522159047fSniklas 	  break;
27532159047fSniklas 	}
2754c074d1c9Sdrahn       loc = link_order->offset * bfd_octets_per_byte (output_bfd);
2755*007c2a45Smiod       ok = bfd_set_section_contents (output_bfd, output_section, buf,
2756c074d1c9Sdrahn                                      loc, size);
27572159047fSniklas       free (buf);
27582159047fSniklas       if (! ok)
2759c074d1c9Sdrahn 	return FALSE;
27602159047fSniklas     }
27612159047fSniklas 
27622159047fSniklas   /* Store the reloc information in the right place.  It will get
27632159047fSniklas      swapped and written out at the end of the final_link routine.  */
27642159047fSniklas   irel = (finfo->section_info[output_section->target_index].relocs
27652159047fSniklas 	  + output_section->reloc_count);
27662159047fSniklas   rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes
27672159047fSniklas 		  + output_section->reloc_count);
27682159047fSniklas 
27692159047fSniklas   memset (irel, 0, sizeof (struct internal_reloc));
27702159047fSniklas   *rel_hash_ptr = NULL;
27712159047fSniklas 
27722159047fSniklas   irel->r_vaddr = output_section->vma + link_order->offset;
27732159047fSniklas 
27742159047fSniklas   if (link_order->type == bfd_section_reloc_link_order)
27752159047fSniklas     {
27762159047fSniklas       /* We need to somehow locate a symbol in the right section.  The
27772159047fSniklas          symbol must either have a value of zero, or we must adjust
27782159047fSniklas          the addend by the value of the symbol.  FIXME: Write this
27792159047fSniklas          when we need it.  The old linker couldn't handle this anyhow.  */
27802159047fSniklas       abort ();
27812159047fSniklas       *rel_hash_ptr = NULL;
27822159047fSniklas       irel->r_symndx = 0;
27832159047fSniklas     }
27842159047fSniklas   else
27852159047fSniklas     {
27862159047fSniklas       struct coff_link_hash_entry *h;
27872159047fSniklas 
2788c88b1d6cSniklas       h = ((struct coff_link_hash_entry *)
2789c88b1d6cSniklas 	   bfd_wrapped_link_hash_lookup (output_bfd, finfo->info,
27902159047fSniklas 					 link_order->u.reloc.p->u.name,
2791c074d1c9Sdrahn 					 FALSE, FALSE, TRUE));
27922159047fSniklas       if (h != NULL)
27932159047fSniklas 	{
27942159047fSniklas 	  if (h->indx >= 0)
27952159047fSniklas 	    irel->r_symndx = h->indx;
27962159047fSniklas 	  else
27972159047fSniklas 	    {
27982159047fSniklas 	      /* Set the index to -2 to force this symbol to get
27992159047fSniklas 		 written out.  */
28002159047fSniklas 	      h->indx = -2;
28012159047fSniklas 	      *rel_hash_ptr = h;
28022159047fSniklas 	      irel->r_symndx = 0;
28032159047fSniklas 	    }
28042159047fSniklas 	}
28052159047fSniklas       else
28062159047fSniklas 	{
28072159047fSniklas 	  if (! ((*finfo->info->callbacks->unattached_reloc)
28082159047fSniklas 		 (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL,
28092159047fSniklas 		  (asection *) NULL, (bfd_vma) 0)))
2810c074d1c9Sdrahn 	    return FALSE;
28112159047fSniklas 	  irel->r_symndx = 0;
28122159047fSniklas 	}
28132159047fSniklas     }
28142159047fSniklas 
28152159047fSniklas   /* FIXME: Is this always right?  */
28162159047fSniklas   irel->r_type = howto->type;
28172159047fSniklas 
28182159047fSniklas   /* r_size is only used on the RS/6000, which needs its own linker
28192159047fSniklas      routines anyhow.  r_extern is only used for ECOFF.  */
28202159047fSniklas 
28212159047fSniklas   /* FIXME: What is the right value for r_offset?  Is zero OK?  */
28222159047fSniklas   ++output_section->reloc_count;
28232159047fSniklas 
2824c074d1c9Sdrahn   return TRUE;
28252159047fSniklas }
28262159047fSniklas 
28272159047fSniklas /* A basic reloc handling routine which may be used by processors with
28282159047fSniklas    simple relocs.  */
28292159047fSniklas 
2830c074d1c9Sdrahn bfd_boolean
_bfd_coff_generic_relocate_section(bfd * output_bfd,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,struct internal_reloc * relocs,struct internal_syment * syms,asection ** sections)2831*007c2a45Smiod _bfd_coff_generic_relocate_section (bfd *output_bfd,
2832*007c2a45Smiod 				    struct bfd_link_info *info,
2833*007c2a45Smiod 				    bfd *input_bfd,
2834*007c2a45Smiod 				    asection *input_section,
2835*007c2a45Smiod 				    bfd_byte *contents,
2836*007c2a45Smiod 				    struct internal_reloc *relocs,
2837*007c2a45Smiod 				    struct internal_syment *syms,
2838*007c2a45Smiod 				    asection **sections)
28392159047fSniklas {
28402159047fSniklas   struct internal_reloc *rel;
28412159047fSniklas   struct internal_reloc *relend;
28422159047fSniklas 
28432159047fSniklas   rel = relocs;
28442159047fSniklas   relend = rel + input_section->reloc_count;
28452159047fSniklas   for (; rel < relend; rel++)
28462159047fSniklas     {
28472159047fSniklas       long symndx;
28482159047fSniklas       struct coff_link_hash_entry *h;
28492159047fSniklas       struct internal_syment *sym;
28502159047fSniklas       bfd_vma addend;
28512159047fSniklas       bfd_vma val;
28522159047fSniklas       reloc_howto_type *howto;
28532159047fSniklas       bfd_reloc_status_type rstat;
28542159047fSniklas 
28552159047fSniklas       symndx = rel->r_symndx;
28562159047fSniklas 
28572159047fSniklas       if (symndx == -1)
28582159047fSniklas 	{
28592159047fSniklas 	  h = NULL;
28602159047fSniklas 	  sym = NULL;
28612159047fSniklas 	}
2862b305b0f1Sespie       else if (symndx < 0
2863b305b0f1Sespie 	       || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
2864b305b0f1Sespie 	{
2865b305b0f1Sespie 	  (*_bfd_error_handler)
2866b305b0f1Sespie 	    ("%s: illegal symbol index %ld in relocs",
2867c074d1c9Sdrahn 	     bfd_archive_filename (input_bfd), symndx);
2868c074d1c9Sdrahn 	  return FALSE;
2869b305b0f1Sespie 	}
28702159047fSniklas       else
28712159047fSniklas 	{
28722159047fSniklas 	  h = obj_coff_sym_hashes (input_bfd)[symndx];
28732159047fSniklas 	  sym = syms + symndx;
28742159047fSniklas 	}
28752159047fSniklas 
28762159047fSniklas       /* COFF treats common symbols in one of two ways.  Either the
28772159047fSniklas          size of the symbol is included in the section contents, or it
28782159047fSniklas          is not.  We assume that the size is not included, and force
28792159047fSniklas          the rtype_to_howto function to adjust the addend as needed.  */
28802159047fSniklas       if (sym != NULL && sym->n_scnum != 0)
28812159047fSniklas 	addend = - sym->n_value;
28822159047fSniklas       else
28832159047fSniklas 	addend = 0;
28842159047fSniklas 
28852159047fSniklas       howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
28862159047fSniklas 				       sym, &addend);
28872159047fSniklas       if (howto == NULL)
2888c074d1c9Sdrahn 	return FALSE;
28892159047fSniklas 
2890*007c2a45Smiod       /* If we are doing a relocatable link, then we can just ignore
2891b305b0f1Sespie          a PC relative reloc that is pcrel_offset.  It will already
2892*007c2a45Smiod          have the correct value.  If this is not a relocatable link,
2893b305b0f1Sespie          then we should ignore the symbol value.  */
2894b305b0f1Sespie       if (howto->pc_relative && howto->pcrel_offset)
2895b305b0f1Sespie 	{
2896*007c2a45Smiod 	  if (info->relocatable)
2897b305b0f1Sespie 	    continue;
2898b305b0f1Sespie 	  if (sym != NULL && sym->n_scnum != 0)
2899b305b0f1Sespie 	    addend += sym->n_value;
2900b305b0f1Sespie 	}
2901b305b0f1Sespie 
29022159047fSniklas       val = 0;
29032159047fSniklas 
29042159047fSniklas       if (h == NULL)
29052159047fSniklas 	{
29062159047fSniklas 	  asection *sec;
29072159047fSniklas 
29082159047fSniklas 	  if (symndx == -1)
29092159047fSniklas 	    {
29102159047fSniklas 	      sec = bfd_abs_section_ptr;
29112159047fSniklas 	      val = 0;
29122159047fSniklas 	    }
29132159047fSniklas 	  else
29142159047fSniklas 	    {
29152159047fSniklas 	      sec = sections[symndx];
29162159047fSniklas               val = (sec->output_section->vma
29172159047fSniklas 		     + sec->output_offset
2918b305b0f1Sespie 		     + sym->n_value);
2919b305b0f1Sespie 	      if (! obj_pe (input_bfd))
2920b305b0f1Sespie 		val -= sec->vma;
29212159047fSniklas 	    }
29222159047fSniklas 	}
29232159047fSniklas       else
29242159047fSniklas 	{
29252159047fSniklas 	  if (h->root.type == bfd_link_hash_defined
29262159047fSniklas 	      || h->root.type == bfd_link_hash_defweak)
29272159047fSniklas 	    {
29282159047fSniklas 	      asection *sec;
29292159047fSniklas 
29302159047fSniklas 	      sec = h->root.u.def.section;
29312159047fSniklas 	      val = (h->root.u.def.value
29322159047fSniklas 		     + sec->output_section->vma
29332159047fSniklas 		     + sec->output_offset);
29342159047fSniklas 	      }
29352159047fSniklas 
2936b55d4692Sfgsch 	  else if (h->root.type == bfd_link_hash_undefweak)
2937b55d4692Sfgsch 	    val = 0;
2938b55d4692Sfgsch 
2939*007c2a45Smiod 	  else if (! info->relocatable)
29402159047fSniklas 	    {
29412159047fSniklas 	      if (! ((*info->callbacks->undefined_symbol)
29422159047fSniklas 		     (info, h->root.root.string, input_bfd, input_section,
2943c074d1c9Sdrahn 		      rel->r_vaddr - input_section->vma, TRUE)))
2944c074d1c9Sdrahn 		return FALSE;
29452159047fSniklas 	    }
29462159047fSniklas 	}
29472159047fSniklas 
29482159047fSniklas       if (info->base_file)
29492159047fSniklas 	{
29502159047fSniklas 	  /* Emit a reloc if the backend thinks it needs it.  */
29512159047fSniklas 	  if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto))
29522159047fSniklas 	    {
2953b305b0f1Sespie 	      /* Relocation to a symbol in a section which isn't
2954b305b0f1Sespie 		 absolute.  We output the address here to a file.
2955b305b0f1Sespie 		 This file is then read by dlltool when generating the
2956b305b0f1Sespie 		 reloc section.  Note that the base file is not
2957b305b0f1Sespie 		 portable between systems.  We write out a long here,
2958b305b0f1Sespie 		 and dlltool reads in a long.  */
2959b305b0f1Sespie 	      long addr = (rel->r_vaddr
29602159047fSniklas 			   - input_section->vma
29612159047fSniklas 			   + input_section->output_offset
2962b305b0f1Sespie 			   + input_section->output_section->vma);
29632159047fSniklas 	      if (coff_data (output_bfd)->pe)
29642159047fSniklas 		addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
2965b305b0f1Sespie 	      if (fwrite (&addr, 1, sizeof (long), (FILE *) info->base_file)
2966b305b0f1Sespie 		  != sizeof (long))
2967b305b0f1Sespie 		{
2968b305b0f1Sespie 		  bfd_set_error (bfd_error_system_call);
2969c074d1c9Sdrahn 		  return FALSE;
2970b305b0f1Sespie 		}
29712159047fSniklas 	    }
29722159047fSniklas 	}
29732159047fSniklas 
29742159047fSniklas       rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
29752159047fSniklas 					contents,
29762159047fSniklas 					rel->r_vaddr - input_section->vma,
29772159047fSniklas 					val, addend);
29782159047fSniklas 
29792159047fSniklas       switch (rstat)
29802159047fSniklas 	{
29812159047fSniklas 	default:
29822159047fSniklas 	  abort ();
29832159047fSniklas 	case bfd_reloc_ok:
29842159047fSniklas 	  break;
2985b305b0f1Sespie 	case bfd_reloc_outofrange:
2986b305b0f1Sespie 	  (*_bfd_error_handler)
2987b305b0f1Sespie 	    (_("%s: bad reloc address 0x%lx in section `%s'"),
2988c074d1c9Sdrahn 	     bfd_archive_filename (input_bfd),
2989b305b0f1Sespie 	     (unsigned long) rel->r_vaddr,
2990b305b0f1Sespie 	     bfd_get_section_name (input_bfd, input_section));
2991c074d1c9Sdrahn 	  return FALSE;
29922159047fSniklas 	case bfd_reloc_overflow:
29932159047fSniklas 	  {
29942159047fSniklas 	    const char *name;
29952159047fSniklas 	    char buf[SYMNMLEN + 1];
29962159047fSniklas 
29972159047fSniklas 	    if (symndx == -1)
29982159047fSniklas 	      name = "*ABS*";
29992159047fSniklas 	    else if (h != NULL)
30002159047fSniklas 	      name = h->root.root.string;
30012159047fSniklas 	    else
30022159047fSniklas 	      {
30032159047fSniklas 		name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
30042159047fSniklas 		if (name == NULL)
3005c074d1c9Sdrahn 		  return FALSE;
30062159047fSniklas 	      }
30072159047fSniklas 
30082159047fSniklas 	    if (! ((*info->callbacks->reloc_overflow)
30092159047fSniklas 		   (info, name, howto->name, (bfd_vma) 0, input_bfd,
30102159047fSniklas 		    input_section, rel->r_vaddr - input_section->vma)))
3011c074d1c9Sdrahn 	      return FALSE;
30122159047fSniklas 	  }
30132159047fSniklas 	}
30142159047fSniklas     }
3015c074d1c9Sdrahn   return TRUE;
30162159047fSniklas }
3017