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