/* COFF specific linker code.
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004, 2005 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* This file contains the COFF backend linker code. */
#include "libbfd.h"
#include "coff/internal.h"
#include "libcoff.h"
+#include "safe-ctype.h"
-static bfd_boolean coff_link_add_object_symbols
- PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean coff_link_check_archive_element
- PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *));
-static bfd_boolean coff_link_check_ar_symbols
- PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *));
-static bfd_boolean coff_link_add_symbols
- PARAMS ((bfd *, struct bfd_link_info *));
-static char *dores_com
- PARAMS ((char *, bfd *, int));
-static char *get_name
- PARAMS ((char *, char **));
-static int process_embedded_commands
- PARAMS ((bfd *, struct bfd_link_info *, bfd *));
-static void mark_relocs
- PARAMS ((struct coff_final_link_info *, bfd *));
+static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info);
+static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded);
+static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info);
/* Return TRUE if SYM is a weak, external symbol. */
#define IS_WEAK_EXTERNAL(abfd, sym) \
/* Create an entry in a COFF linker hash table. */
struct bfd_hash_entry *
-_bfd_coff_link_hash_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
+_bfd_coff_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
{
struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry;
/* Initialize a COFF linker hash table. */
bfd_boolean
-_bfd_coff_link_hash_table_init (table, abfd, newfunc)
- struct coff_link_hash_table *table;
- bfd *abfd;
- struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
- struct bfd_hash_table *,
- const char *));
+_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 *))
{
- table->stab_info = NULL;
+ memset (&table->stab_info, 0, sizeof (table->stab_info));
return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
}
/* Create a COFF linker hash table. */
struct bfd_link_hash_table *
-_bfd_coff_link_hash_table_create (abfd)
- bfd *abfd;
+_bfd_coff_link_hash_table_create (bfd *abfd)
{
struct coff_link_hash_table *ret;
bfd_size_type amt = sizeof (struct coff_link_hash_table);
- ret = (struct coff_link_hash_table *) bfd_malloc (amt);
+ ret = bfd_malloc (amt);
if (ret == NULL)
return NULL;
+
if (! _bfd_coff_link_hash_table_init (ret, abfd,
_bfd_coff_link_hash_newfunc))
{
/* Create an entry in a COFF debug merge hash table. */
struct bfd_hash_entry *
-_bfd_coff_debug_merge_hash_newfunc (entry, table, string)
- struct bfd_hash_entry *entry;
- struct bfd_hash_table *table;
- const char *string;
+_bfd_coff_debug_merge_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
{
struct coff_debug_merge_hash_entry *ret =
(struct coff_debug_merge_hash_entry *) entry;
appropriate. */
bfd_boolean
-_bfd_coff_link_add_symbols (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
+_bfd_coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
switch (bfd_get_format (abfd))
{
case bfd_object:
return coff_link_add_object_symbols (abfd, info);
case bfd_archive:
- return (_bfd_generic_link_add_archive_symbols
- (abfd, info, coff_link_check_archive_element));
+ return _bfd_generic_link_add_archive_symbols
+ (abfd, info, coff_link_check_archive_element);
default:
bfd_set_error (bfd_error_wrong_format);
return FALSE;
/* Add symbols from a COFF object file. */
static bfd_boolean
-coff_link_add_object_symbols (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
+coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
{
if (! _bfd_coff_get_external_symbols (abfd))
return FALSE;
if (! coff_link_add_symbols (abfd, info))
return FALSE;
- if (! info->keep_memory)
- {
- if (! _bfd_coff_free_symbols (abfd))
- return FALSE;
- }
- return TRUE;
-}
-
-/* Check a single archive element to see if we need to include it in
- the link. *PNEEDED is set according to whether this element is
- needed in the link or not. This is called via
- _bfd_generic_link_add_archive_symbols. */
-
-static bfd_boolean
-coff_link_check_archive_element (abfd, info, pneeded)
- bfd *abfd;
- struct bfd_link_info *info;
- bfd_boolean *pneeded;
-{
- if (! _bfd_coff_get_external_symbols (abfd))
- return FALSE;
-
- if (! coff_link_check_ar_symbols (abfd, info, pneeded))
+ if (! info->keep_memory
+ && ! _bfd_coff_free_symbols (abfd))
return FALSE;
- if (*pneeded)
- {
- if (! coff_link_add_symbols (abfd, info))
- return FALSE;
- }
-
- if (! info->keep_memory || ! *pneeded)
- {
- if (! _bfd_coff_free_symbols (abfd))
- return FALSE;
- }
-
return TRUE;
}
included in the link. */
static bfd_boolean
-coff_link_check_ar_symbols (abfd, info, pneeded)
- bfd *abfd;
- struct bfd_link_info *info;
- bfd_boolean *pneeded;
+coff_link_check_ar_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean *pneeded)
{
bfd_size_type symesz;
bfd_byte *esym;
struct internal_syment sym;
enum coff_symbol_classification classification;
- bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+ bfd_coff_swap_sym_in (abfd, esym, &sym);
classification = bfd_coff_classify_symbol (abfd, &sym);
if (classification == COFF_SYMBOL_GLOBAL
/* This symbol is externally visible, and is defined by this
object file. */
-
name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
if (name == NULL)
return FALSE;
h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
- /* auto import */
- if (!h && info->pei386_auto_import)
- {
- if (!strncmp (name,"__imp_", 6))
- {
- h =
- bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE,
- TRUE);
- }
- }
+ /* Auto import. */
+ if (!h
+ && info->pei386_auto_import
+ && !strncmp (name,"__imp_", 6))
+ h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE);
+
/* We are only interested in symbols that are currently
undefined. If a symbol is currently known to be common,
COFF linkers do not bring in an object file which defines
return TRUE;
}
+/* Check a single archive element to see if we need to include it in
+ the link. *PNEEDED is set according to whether this element is
+ needed in the link or not. This is called via
+ _bfd_generic_link_add_archive_symbols. */
+
+static bfd_boolean
+coff_link_check_archive_element (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean *pneeded)
+{
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return FALSE;
+
+ if (! coff_link_check_ar_symbols (abfd, info, pneeded))
+ return FALSE;
+
+ if (*pneeded
+ && ! coff_link_add_symbols (abfd, info))
+ return FALSE;
+
+ if ((! info->keep_memory || ! *pneeded)
+ && ! _bfd_coff_free_symbols (abfd))
+ return FALSE;
+
+ return TRUE;
+}
+
/* Add all the symbols from an object file to the hash table. */
static bfd_boolean
-coff_link_add_symbols (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
+coff_link_add_symbols (bfd *abfd,
+ struct bfd_link_info *info)
{
unsigned int n_tmask = coff_data (abfd)->local_n_tmask;
unsigned int n_btshft = coff_data (abfd)->local_n_btshft;
/* We keep a list of the linker hash table entries that correspond
to particular symbols. */
amt = symcount * sizeof (struct coff_link_hash_entry *);
- sym_hash = (struct coff_link_hash_entry **) bfd_zalloc (abfd, amt);
+ sym_hash = bfd_zalloc (abfd, amt);
if (sym_hash == NULL && symcount != 0)
goto error_return;
obj_coff_sym_hashes (abfd) = sym_hash;
enum coff_symbol_classification classification;
bfd_boolean copy;
- bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+ bfd_coff_swap_sym_in (abfd, esym, &sym);
classification = bfd_coff_classify_symbol (abfd, &sym);
if (classification != COFF_SYMBOL_LOCAL)
if (obj_pe (abfd)
&& (classification == COFF_SYMBOL_GLOBAL
|| classification == COFF_SYMBOL_PE_SECTION)
- && section->comdat != NULL
+ && coff_section_data (abfd, section) != NULL
+ && coff_section_data (abfd, section)->comdat != NULL
&& strncmp (name, "??_", 3) == 0
- && strcmp (name, section->comdat->name) == 0)
+ && strcmp (name, coff_section_data (abfd, section)->comdat->name) == 0)
{
if (*sym_hash == NULL)
*sym_hash = coff_link_hash_lookup (coff_hash_table (info),
name, FALSE, copy, FALSE);
if (*sym_hash != NULL
&& (*sym_hash)->root.type == bfd_link_hash_defined
- && (*sym_hash)->root.u.def.section->comdat != NULL
- && strcmp ((*sym_hash)->root.u.def.section->comdat->name,
- section->comdat->name) == 0)
+ && coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat != NULL
+ && strcmp (coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat->name,
+ coff_section_data (abfd, section)->comdat->name) == 0)
addit = FALSE;
}
&& (BTYPE ((*sym_hash)->type) == T_NULL
|| BTYPE (sym.n_type) == T_NULL)))
(*_bfd_error_handler)
- (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
- name, (*sym_hash)->type, sym.n_type,
- bfd_archive_filename (abfd));
+ (_("Warning: type of symbol `%s' changed from %d to %d in %B"),
+ abfd, name, (*sym_hash)->type, sym.n_type);
/* We don't want to change from a meaningful
base type to a null one, but if we know
for (i = 0, eaux = esym + symesz, iaux = alloc;
i < sym.n_numaux;
i++, eaux += symesz, iaux++)
- bfd_coff_swap_aux_in (abfd, (PTR) eaux, sym.n_type,
+ bfd_coff_swap_aux_in (abfd, eaux, sym.n_type,
sym.n_sclass, (int) i,
- sym.n_numaux, (PTR) iaux);
+ sym.n_numaux, iaux);
(*sym_hash)->aux = alloc;
}
}
FIXME: This is not at all the right place to do this.
For example, it won't help objdump. This needs to be
done when we swap in the section header. */
-
BFD_ASSERT ((*sym_hash)->numaux == 1);
- if (section->_raw_size == 0)
- section->_raw_size = (*sym_hash)->aux[0].x_scn.x_scnlen;
+ if (section->size == 0)
+ section->size = (*sym_hash)->aux[0].x_scn.x_scnlen;
/* FIXME: We could test whether the section sizes
matches the size in the aux entry, but apparently
&& info->hash->creator->flavour == bfd_get_flavour (abfd)
&& (info->strip != strip_all && info->strip != strip_debugger))
{
- asection *stab, *stabstr;
+ asection *stabstr;
- stab = bfd_get_section_by_name (abfd, ".stab");
- if (stab != NULL)
- {
- stabstr = bfd_get_section_by_name (abfd, ".stabstr");
+ stabstr = bfd_get_section_by_name (abfd, ".stabstr");
- if (stabstr != NULL)
+ if (stabstr != NULL)
+ {
+ bfd_size_type string_offset = 0;
+ asection *stab;
+
+ for (stab = abfd->sections; stab; stab = stab->next)
+ if (strncmp (".stab", stab->name, 5) == 0
+ && (!stab->name[5]
+ || (stab->name[5] == '.' && ISDIGIT (stab->name[6]))))
{
struct coff_link_hash_table *table;
- struct coff_section_tdata *secdata;
-
- secdata = coff_section_data (abfd, stab);
+ struct coff_section_tdata *secdata
+ = coff_section_data (abfd, stab);
+
if (secdata == NULL)
{
amt = sizeof (struct coff_section_tdata);
- stab->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
+ stab->used_by_bfd = bfd_zalloc (abfd, amt);
if (stab->used_by_bfd == NULL)
goto error_return;
secdata = coff_section_data (abfd, stab);
if (! _bfd_link_section_stabs (abfd, &table->stab_info,
stab, stabstr,
- &secdata->stab_info))
+ &secdata->stab_info,
+ &string_offset))
goto error_return;
}
}
/* Do the final link step. */
bfd_boolean
-_bfd_coff_final_link (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
+_bfd_coff_final_link (bfd *abfd,
+ struct bfd_link_info *info)
{
bfd_size_type symesz;
struct coff_final_link_info finfo;
{
o->reloc_count = 0;
o->lineno_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order)
{
if (info->relocatable)
o->reloc_count += sec->reloc_count;
- if (sec->_raw_size > max_contents_size)
- max_contents_size = sec->_raw_size;
+ if (sec->rawsize > max_contents_size)
+ max_contents_size = sec->rawsize;
+ if (sec->size > max_contents_size)
+ max_contents_size = sec->size;
if (sec->lineno_count > max_lineno_count)
max_lineno_count = sec->lineno_count;
if (sec->reloc_count > max_reloc_count)
the target_index fields are 1 based. */
amt = abfd->section_count + 1;
amt *= sizeof (struct coff_link_section_info);
- finfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt);
+ finfo.section_info = bfd_malloc (amt);
if (finfo.section_info == NULL)
goto error_return;
for (i = 0; i <= abfd->section_count; i++)
BFD_ASSERT (info->relocatable);
amt = o->reloc_count;
amt *= sizeof (struct internal_reloc);
- finfo.section_info[o->target_index].relocs =
- (struct internal_reloc *) bfd_malloc (amt);
+ finfo.section_info[o->target_index].relocs = bfd_malloc (amt);
amt = o->reloc_count;
amt *= sizeof (struct coff_link_hash_entry *);
- finfo.section_info[o->target_index].rel_hashes =
- (struct coff_link_hash_entry **) bfd_malloc (amt);
+ finfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt);
if (finfo.section_info[o->target_index].relocs == NULL
|| finfo.section_info[o->target_index].rel_hashes == NULL)
goto error_return;
/* Allocate some buffers used while linking. */
amt = max_sym_count * sizeof (struct internal_syment);
- finfo.internal_syms = (struct internal_syment *) bfd_malloc (amt);
+ finfo.internal_syms = bfd_malloc (amt);
amt = max_sym_count * sizeof (asection *);
- finfo.sec_ptrs = (asection **) bfd_malloc (amt);
+ finfo.sec_ptrs = bfd_malloc (amt);
amt = max_sym_count * sizeof (long);
- finfo.sym_indices = (long *) bfd_malloc (amt);
- finfo.outsyms = (bfd_byte *) bfd_malloc ((max_sym_count + 1) * symesz);
+ finfo.sym_indices = bfd_malloc (amt);
+ finfo.outsyms = bfd_malloc ((max_sym_count + 1) * symesz);
amt = max_lineno_count * bfd_coff_linesz (abfd);
- finfo.linenos = (bfd_byte *) bfd_malloc (amt);
- finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ finfo.linenos = bfd_malloc (amt);
+ finfo.contents = bfd_malloc (max_contents_size);
amt = max_reloc_count * relsz;
- finfo.external_relocs = (bfd_byte *) bfd_malloc (amt);
+ finfo.external_relocs = bfd_malloc (amt);
if (! info->relocatable)
{
amt = max_reloc_count * sizeof (struct internal_reloc);
- finfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
+ finfo.internal_relocs = bfd_malloc (amt);
}
if ((finfo.internal_syms == NULL && max_sym_count > 0)
|| (finfo.sec_ptrs == NULL && max_sym_count > 0)
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order
&& bfd_family_coff (p->u.indirect.section->owner))
file_ptr pos;
finfo.last_file.n_value = obj_raw_syment_count (abfd);
- bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
- (PTR) finfo.outsyms);
+ bfd_coff_swap_sym_out (abfd, &finfo.last_file,
+ finfo.outsyms);
pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz;
if (bfd_seek (abfd, pos, SEEK_SET) != 0
{
finfo.failed = FALSE;
coff_link_hash_traverse (coff_hash_table (info),
- _bfd_coff_write_task_globals,
- (PTR) &finfo);
+ _bfd_coff_write_task_globals, &finfo);
if (finfo.failed)
goto error_return;
}
/* Write out the global symbols. */
finfo.failed = FALSE;
coff_link_hash_traverse (coff_hash_table (info),
- _bfd_coff_write_global_sym,
- (PTR) &finfo);
+ _bfd_coff_write_global_sym, &finfo);
if (finfo.failed)
goto error_return;
the symbol indices to use for relocs against them, and we can
finally write out the relocs. */
amt = max_output_reloc_count * relsz;
- external_relocs = (bfd_byte *) bfd_malloc (amt);
+ external_relocs = bfd_malloc (amt);
if (external_relocs == NULL)
goto error_return;
BFD_ASSERT ((*rel_hash)->indx >= 0);
irel->r_symndx = (*rel_hash)->indx;
}
- bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
+ bfd_coff_swap_reloc_out (abfd, irel, erel);
}
- if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
- || (bfd_bwrite ((PTR) external_relocs,
- (bfd_size_type) relsz * o->reloc_count, abfd)
- != (bfd_size_type) relsz * o->reloc_count))
+ if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
+ goto error_return;
+ if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+ {
+ /* In PE COFF, write the count of relocs as the first
+ reloc. The header overflow bit will be set
+ elsewhere. */
+ struct internal_reloc incount;
+ bfd_byte *excount = (bfd_byte *)bfd_malloc (relsz);
+
+ memset (&incount, 0, sizeof (incount));
+ incount.r_vaddr = o->reloc_count + 1;
+ bfd_coff_swap_reloc_out (abfd, (PTR) &incount, (PTR) excount);
+ if (bfd_bwrite (excount, relsz, abfd) != relsz)
+ /* We'll leak, but it's an error anyway. */
+ goto error_return;
+ free (excount);
+ }
+ if (bfd_bwrite (external_relocs,
+ (bfd_size_type) relsz * o->reloc_count, abfd)
+ != (bfd_size_type) relsz * o->reloc_count)
goto error_return;
}
}
/* If we have optimized stabs strings, output them. */
- if (coff_hash_table (info)->stab_info != NULL)
+ if (coff_hash_table (info)->stab_info.stabstr != NULL)
{
if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
return FALSE;
return FALSE;
}
-/* parse out a -heap <reserved>,<commit> line */
+/* Parse out a -heap <reserved>,<commit> line. */
static char *
-dores_com (ptr, output_bfd, heap)
- char *ptr;
- bfd *output_bfd;
- int heap;
+dores_com (char *ptr, bfd *output_bfd, int heap)
{
if (coff_data(output_bfd)->pe)
{
int val = strtoul (ptr, &ptr, 0);
+
if (heap)
pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve = val;
else
return ptr;
}
-static char *get_name(ptr, dst)
-char *ptr;
-char **dst;
+static char *
+get_name (char *ptr, char **dst)
{
while (*ptr == ' ')
ptr++;
return ptr+1;
}
-/* Process any magic embedded commands in a section called .drectve */
+/* Process any magic embedded commands in a section called .drectve. */
static int
-process_embedded_commands (output_bfd, info, abfd)
- bfd *output_bfd;
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- bfd *abfd;
+process_embedded_commands (bfd *output_bfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bfd *abfd)
{
asection *sec = bfd_get_section_by_name (abfd, ".drectve");
char *s;
char *e;
- char *copy;
+ bfd_byte *copy;
+
if (!sec)
return 1;
- copy = bfd_malloc (sec->_raw_size);
- if (!copy)
- return 0;
- if (! bfd_get_section_contents(abfd, sec, copy, (bfd_vma) 0, sec->_raw_size))
+ if (!bfd_malloc_and_get_section (abfd, sec, ©))
{
- free (copy);
+ if (copy != NULL)
+ free (copy);
return 0;
}
- e = copy + sec->_raw_size;
- for (s = copy; s < e ; )
+ e = (char *) copy + sec->size;
+
+ for (s = (char *) copy; s < e ; )
{
- if (s[0]!= '-') {
- s++;
- continue;
- }
- if (strncmp (s,"-attr", 5) == 0)
+ if (s[0] != '-')
+ {
+ s++;
+ continue;
+ }
+ if (strncmp (s, "-attr", 5) == 0)
{
char *name;
char *attribs;
asection *asec;
-
int loop = 1;
int had_write = 0;
int had_read = 0;
int had_exec= 0;
int had_shared= 0;
+
s += 5;
- s = get_name(s, &name);
- s = get_name(s, &attribs);
- while (loop) {
- switch (*attribs++)
- {
- case 'W':
- had_write = 1;
- break;
- case 'R':
- had_read = 1;
- break;
- case 'S':
- had_shared = 1;
- break;
- case 'X':
- had_exec = 1;
- break;
- default:
- loop = 0;
- }
- }
+ s = get_name (s, &name);
+ s = get_name (s, &attribs);
+
+ while (loop)
+ {
+ switch (*attribs++)
+ {
+ case 'W':
+ had_write = 1;
+ break;
+ case 'R':
+ had_read = 1;
+ break;
+ case 'S':
+ had_shared = 1;
+ break;
+ case 'X':
+ had_exec = 1;
+ break;
+ default:
+ loop = 0;
+ }
+ }
asec = bfd_get_section_by_name (abfd, name);
- if (asec) {
- if (had_exec)
- asec->flags |= SEC_CODE;
- if (!had_write)
- asec->flags |= SEC_READONLY;
- }
+ if (asec)
+ {
+ if (had_exec)
+ asec->flags |= SEC_CODE;
+ if (!had_write)
+ asec->flags |= SEC_READONLY;
+ }
}
else if (strncmp (s,"-heap", 5) == 0)
- {
- s = dores_com (s+5, output_bfd, 1);
- }
+ s = dores_com (s+5, output_bfd, 1);
+
else if (strncmp (s,"-stack", 6) == 0)
- {
- s = dores_com (s+6, output_bfd, 0);
- }
+ s = dores_com (s+6, output_bfd, 0);
+
else
s++;
}
/* Place a marker against all symbols which are used by relocations.
This marker can be picked up by the 'do we skip this symbol ?'
loop in _bfd_coff_link_input_bfd() and used to prevent skipping
- that symbol.
- */
+ that symbol. */
static void
-mark_relocs (finfo, input_bfd)
- struct coff_final_link_info * finfo;
- bfd * input_bfd;
+mark_relocs (struct coff_final_link_info *finfo, bfd *input_bfd)
{
asection * a;
/* Place a mark in the sym_indices array (whose entries have
been initialised to 0) for all of the symbols that are used
in the relocation table. This will then be picked up in the
- skip/don't pass */
-
+ skip/don't-skip pass. */
for (; irel < irelend; irel++)
- {
- finfo->sym_indices[ irel->r_symndx ] = -1;
- }
+ finfo->sym_indices[ irel->r_symndx ] = -1;
}
}
handles all the sections and relocations of the input file at once. */
bfd_boolean
-_bfd_coff_link_input_bfd (finfo, input_bfd)
- struct coff_final_link_info *finfo;
- bfd *input_bfd;
+_bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd)
{
unsigned int n_tmask = coff_data (input_bfd)->local_n_tmask;
unsigned int n_btshft = coff_data (input_bfd)->local_n_btshft;
-#if 0
- unsigned int n_btmask = coff_data (input_bfd)->local_n_btmask;
-#endif
bfd_boolean (*adjust_symndx)
- PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
- struct internal_reloc *, bfd_boolean *));
+ (bfd *, struct bfd_link_info *, bfd *, asection *,
+ struct internal_reloc *, bfd_boolean *);
bfd *output_bfd;
const char *strings;
bfd_size_type syment_base;
output_index = syment_base;
outsym = finfo->outsyms;
- if (coff_data (output_bfd)->pe)
- {
- if (! process_embedded_commands (output_bfd, finfo->info, input_bfd))
- return FALSE;
- }
+ if (coff_data (output_bfd)->pe
+ && ! process_embedded_commands (output_bfd, finfo->info, input_bfd))
+ return FALSE;
- /* If we are going to perform relocations and also strip/discard some symbols
- then we must make sure that we do not strip/discard those symbols that are
- going to be involved in the relocations */
+ /* If we are going to perform relocations and also strip/discard some
+ symbols then we must make sure that we do not strip/discard those
+ symbols that are going to be involved in the relocations. */
if (( finfo->info->strip != strip_none
|| finfo->info->discard != discard_none)
&& finfo->info->relocatable)
{
- /* mark the symbol array as 'not-used' */
+ /* Mark the symbol array as 'not-used'. */
memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
mark_relocs (finfo, input_bfd);
bfd_boolean dont_skip_symbol;
int add;
- bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp);
+ bfd_coff_swap_sym_in (input_bfd, esym, isymp);
/* Make a copy of *isymp so that the relocate_section function
always sees the original values. This is more reliable than
/* Skip section symbols for sections which are not going to be
emitted. */
if (!skip
+ && dont_skip_symbol == 0
&& isym.n_sclass == C_STAT
&& isym.n_type == T_NULL
- && isym.n_numaux > 0)
- {
- if ((*secpp)->output_section == bfd_abs_section_ptr)
- skip = TRUE;
- }
+ && isym.n_numaux > 0
+ && (*secpp)->output_section == bfd_abs_section_ptr)
+ skip = TRUE;
#endif
/* If we stripping debugging symbols, and this is a debugging
out to be a duplicate, we pass this address to
bfd_release. */
amt = sizeof (struct coff_debug_merge_type);
- mt = (struct coff_debug_merge_type *) bfd_alloc (input_bfd, amt);
+ mt = bfd_alloc (input_bfd, amt);
if (mt == NULL)
return FALSE;
mt->class = isym.n_sclass;
/* Pick up the aux entry, which points to the end of the tag
entries. */
- bfd_coff_swap_aux_in (input_bfd, (PTR) (esym + isymesz),
+ bfd_coff_swap_aux_in (input_bfd, (esym + isymesz),
isym.n_type, isym.n_sclass, 0, isym.n_numaux,
- (PTR) &aux);
+ &aux);
/* Gather the elements. */
epp = &mt->elements;
char elebuf[SYMNMLEN + 1];
char *name_copy;
- bfd_coff_swap_sym_in (input_bfd, (PTR) esl, (PTR) islp);
+ bfd_coff_swap_sym_in (input_bfd, esl, islp);
amt = sizeof (struct coff_debug_merge_element);
- *epp = ((struct coff_debug_merge_element *)
- bfd_alloc (input_bfd, amt));
+ *epp = bfd_alloc (input_bfd, amt);
if (*epp == NULL)
return FALSE;
return FALSE;
amt = strlen (elename) + 1;
- name_copy = (char *) bfd_alloc (input_bfd, amt);
+ name_copy = bfd_alloc (input_bfd, amt);
if (name_copy == NULL)
return FALSE;
strcpy (name_copy, elename);
union internal_auxent eleaux;
long indx;
- bfd_coff_swap_aux_in (input_bfd, (PTR) (esl + isymesz),
+ bfd_coff_swap_aux_in (input_bfd, (esl + isymesz),
islp->n_type, islp->n_sclass, 0,
- islp->n_numaux, (PTR) &eleaux);
+ islp->n_numaux, &eleaux);
indx = eleaux.x_sym.x_tagndx.l;
/* FIXME: If this tagndx entry refers to a symbol
defined later in this file, we just ignore it.
Handling this correctly would be tedious, and may
not be required. */
-
if (indx > 0
&& (indx
< ((esym -
type. We always output the type if it has no elements,
for simplicity. */
if (mt->elements == NULL)
- bfd_release (input_bfd, (PTR) mt);
+ bfd_release (input_bfd, mt);
else
{
struct coff_debug_merge_type *mtl;
else
{
/* This is a redefinition which can be merged. */
- bfd_release (input_bfd, (PTR) mt);
+ bfd_release (input_bfd, mt);
*indexp = mtl->indx;
add = (eslend - esym) / isymesz;
skip = TRUE;
bfd_coff_symname_in_debug. That is only true for
XCOFF, and XCOFF requires different linking code
anyhow. */
- name = _bfd_coff_internal_syment_name (input_bfd, &isym,
- (char *) NULL);
+ name = _bfd_coff_internal_syment_name (input_bfd, &isym, NULL);
if (name == NULL)
return FALSE;
indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy);
it). We try to get this right, below, just before we
write the symbols out, but in the general case we may
have to write the symbol out twice. */
-
if (finfo->last_file_index != -1
&& finfo->last_file.n_value != (bfd_vma) output_index)
{
{
/* The last C_FILE symbol is in this input file. */
bfd_coff_swap_sym_out (output_bfd,
- (PTR) &finfo->last_file,
- (PTR) (finfo->outsyms
- + ((finfo->last_file_index
- - syment_base)
- * osymesz)));
+ &finfo->last_file,
+ (finfo->outsyms
+ + ((finfo->last_file_index
+ - syment_base)
+ * osymesz)));
}
else
{
symbol. We need to write it out again. We
borrow *outsym temporarily. */
bfd_coff_swap_sym_out (output_bfd,
- (PTR) &finfo->last_file,
- (PTR) outsym);
+ &finfo->last_file, outsym);
pos = obj_sym_filepos (output_bfd);
pos += finfo->last_file_index * osymesz;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
isym.n_sclass = C_STAT;
/* Output the symbol. */
-
- bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
+ bfd_coff_swap_sym_out (output_bfd, &isym, outsym);
*indexp = output_index;
/* Fix up the aux entries. This must be done in a separate pass,
because we don't know the correct symbol indices until we have
already decided which symbols we are going to keep. */
-
esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
isymp = finfo->internal_syms;
indexp = finfo->sym_indices;
sym_hash = obj_coff_sym_hashes (input_bfd);
outsym = finfo->outsyms;
+
while (esym < esym_end)
{
int add;
auxp = h->aux + i;
else
{
- bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type,
- isymp->n_sclass, i, isymp->n_numaux,
- (PTR) &aux);
+ bfd_coff_swap_aux_in (input_bfd, esym, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux, &aux);
auxp = &aux;
}
auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
}
}
- else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
+ else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
+ && isymp->n_sclass != C_NT_WEAK)
{
unsigned long indx;
if ((bfd_size_type) finfo->last_bf_index
>= syment_base)
{
- PTR auxout;
+ void *auxout;
/* The last .bf symbol is in this input
file. This will only happen if the
assembler did not set up the .bf
endndx symbols correctly. */
- auxout = (PTR) (finfo->outsyms
- + ((finfo->last_bf_index
- - syment_base)
- * osymesz));
+ auxout = (finfo->outsyms
+ + ((finfo->last_bf_index
+ - syment_base)
+ * osymesz));
+
bfd_coff_swap_aux_out (output_bfd,
- (PTR) &finfo->last_bf,
+ &finfo->last_bf,
isymp->n_type,
isymp->n_sclass,
0, isymp->n_numaux,
temporarily. FIXME: This case should
be made faster. */
bfd_coff_swap_aux_out (output_bfd,
- (PTR) &finfo->last_bf,
+ &finfo->last_bf,
isymp->n_type,
isymp->n_sclass,
0, isymp->n_numaux,
- (PTR) outsym);
+ outsym);
pos = obj_sym_filepos (output_bfd);
pos += finfo->last_bf_index * osymesz;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
if (h == NULL)
{
- bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isymp->n_type,
+ bfd_coff_swap_aux_out (output_bfd, auxp, isymp->n_type,
isymp->n_sclass, i, isymp->n_numaux,
- (PTR) outsym);
+ outsym);
outsym += osymesz;
}
{
struct internal_lineno iline;
- bfd_coff_swap_lineno_in (input_bfd, (PTR) eline, (PTR) &iline);
+ bfd_coff_swap_lineno_in (input_bfd, eline, &iline);
if (iline.l_lnno != 0)
iline.l_addr.l_paddr += offset;
of the line numbers rather than an absolute
file index. */
bfd_coff_swap_sym_in (output_bfd,
- (PTR) (finfo->outsyms
- + ((indx - syment_base)
- * osymesz)),
- (PTR) &is);
+ (finfo->outsyms
+ + ((indx - syment_base)
+ * osymesz)), &is);
if ((ISFCN (is.n_type)
|| is.n_sclass == C_BLOCK)
&& is.n_numaux >= 1)
{
- PTR auxptr;
+ void *auxptr;
- auxptr = (PTR) (finfo->outsyms
- + ((indx - syment_base + 1)
- * osymesz));
+ auxptr = (finfo->outsyms
+ + ((indx - syment_base + 1)
+ * osymesz));
bfd_coff_swap_aux_in (output_bfd, auxptr,
is.n_type, is.n_sclass,
- 0, is.n_numaux, (PTR) &ia);
+ 0, is.n_numaux, &ia);
ia.x_sym.x_fcnary.x_fcn.x_lnnoptr =
(o->output_section->line_filepos
+ o->output_section->lineno_count * linesz
+ eline - finfo->linenos);
- bfd_coff_swap_aux_out (output_bfd, (PTR) &ia,
+ bfd_coff_swap_aux_out (output_bfd, &ia,
is.n_type, is.n_sclass, 0,
is.n_numaux, auxptr);
}
if (!skipping)
{
- bfd_coff_swap_lineno_out (output_bfd, (PTR) &iline,
- (PTR) oeline);
+ bfd_coff_swap_lineno_out (output_bfd, &iline, oeline);
oeline += linesz;
}
}
&& (bfd_size_type) finfo->last_file_index >= syment_base)
{
finfo->last_file.n_value = output_index;
- bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file,
- (PTR) (finfo->outsyms
- + ((finfo->last_file_index - syment_base)
- * osymesz)));
+ bfd_coff_swap_sym_out (output_bfd, &finfo->last_file,
+ (finfo->outsyms
+ + ((finfo->last_file_index - syment_base)
+ * osymesz)));
}
/* Write the modified symbols to the output file. */
struct coff_section_tdata *secdata;
if (! o->linker_mark)
- {
- /* This section was omitted from the link. */
- continue;
- }
+ /* This section was omitted from the link. */
+ continue;
+
+ if ((o->flags & SEC_LINKER_CREATED) != 0)
+ continue;
if ((o->flags & SEC_HAS_CONTENTS) == 0
- || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
+ || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
{
if ((o->flags & SEC_RELOC) != 0
&& o->reloc_count != 0)
{
- ((*_bfd_error_handler)
- (_("%s: relocs in section `%s', but it has no contents"),
- bfd_archive_filename (input_bfd),
- bfd_get_section_name (input_bfd, o)));
+ (*_bfd_error_handler)
+ (_("%B: relocs in section `%A', but it has no contents"),
+ input_bfd, o);
bfd_set_error (bfd_error_no_contents);
return FALSE;
}
contents = secdata->contents;
else
{
- if (! bfd_get_section_contents (input_bfd, o, finfo->contents,
- (file_ptr) 0, o->_raw_size))
+ bfd_size_type x = o->rawsize ? o->rawsize : o->size;
+ if (! bfd_get_section_contents (input_bfd, o, finfo->contents, 0, x))
return FALSE;
contents = finfo->contents;
}
*rel_hash = NULL;
/* Adjust the reloc address and symbol index. */
-
irel->r_vaddr += offset;
if (irel->r_symndx == -1)
stripping. This should have been handled
by the 'dont_skip_symbol' code in the while
loop at the top of this function. */
-
is = finfo->internal_syms + irel->r_symndx;
name = (_bfd_coff_internal_syment_name
if (secdata == NULL || secdata->stab_info == NULL)
{
file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd);
- bfd_size_type amt = (o->_cooked_size != 0
- ? o->_cooked_size : o->_raw_size);
if (! bfd_set_section_contents (output_bfd, o->output_section,
- contents, loc, amt))
+ contents, loc, o->size))
return FALSE;
}
else
}
}
- if (! finfo->info->keep_memory)
- {
- if (! _bfd_coff_free_symbols (input_bfd))
- return FALSE;
- }
+ if (! finfo->info->keep_memory
+ && ! _bfd_coff_free_symbols (input_bfd))
+ return FALSE;
return TRUE;
}
/* Write out a global symbol. Called via coff_link_hash_traverse. */
bfd_boolean
-_bfd_coff_write_global_sym (h, data)
- struct coff_link_hash_entry *h;
- PTR data;
+_bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data)
{
struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
bfd *output_bfd;
isym.n_sclass = C_STAT;
}
- /* When a weak symbol is not overriden by a strong one,
+ /* When a weak symbol is not overridden by a strong one,
turn it into an external symbol when not building a
shared or relocatable object. */
if (! finfo->info->shared
isym.n_numaux = h->numaux;
- bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms);
+ bfd_coff_swap_sym_out (output_bfd, &isym, finfo->outsyms);
symesz = bfd_coff_symesz (output_bfd);
sec = h->root.u.def.section->output_section;
if (sec != NULL)
{
- auxp->x_scn.x_scnlen = (sec->_cooked_size != 0
- ? sec->_cooked_size
- : sec->_raw_size);
+ auxp->x_scn.x_scnlen = sec->size;
/* For PE, an overflow on the final link reportedly does
not matter. FIXME: Why not? */
-
if (sec->reloc_count > 0xffff
&& (! obj_pe (output_bfd)
|| finfo->info->relocatable))
}
}
- bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isym.n_type,
+ bfd_coff_swap_aux_out (output_bfd, auxp, isym.n_type,
isym.n_sclass, (int) i, isym.n_numaux,
- (PTR) finfo->outsyms);
+ finfo->outsyms);
if (bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz)
{
finfo->failed = TRUE;
the dirty work, if the symbol we are processing needs conversion. */
bfd_boolean
-_bfd_coff_write_task_globals (h, data)
- struct coff_link_hash_entry *h;
- PTR data;
+_bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data)
{
struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
bfd_boolean rtnval = TRUE;
/* Handle a link order which is supposed to generate a reloc. */
bfd_boolean
-_bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
- bfd *output_bfd;
- struct coff_final_link_info *finfo;
- asection *output_section;
- struct bfd_link_order *link_order;
+_bfd_coff_reloc_link_order (bfd *output_bfd,
+ struct coff_final_link_info *finfo,
+ asection *output_section,
+ struct bfd_link_order *link_order)
{
reloc_howto_type *howto;
struct internal_reloc *irel;
file_ptr loc;
size = bfd_get_reloc_size (howto);
- buf = (bfd_byte *) bfd_zmalloc (size);
+ buf = bfd_zmalloc (size);
if (buf == NULL)
return FALSE;
abort ();
case bfd_reloc_overflow:
if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info,
+ (finfo->info, NULL,
(link_order->type == bfd_section_reloc_link_order
? bfd_section_name (output_bfd,
link_order->u.reloc.p->u.section)
break;
}
loc = link_order->offset * bfd_octets_per_byte (output_bfd);
- ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
+ ok = bfd_set_section_contents (output_bfd, output_section, buf,
loc, size);
free (buf);
if (! ok)
/* Store the reloc information in the right place. It will get
swapped and written out at the end of the final_link routine. */
-
irel = (finfo->section_info[output_section->target_index].relocs
+ output_section->reloc_count);
rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes
routines anyhow. r_extern is only used for ECOFF. */
/* FIXME: What is the right value for r_offset? Is zero OK? */
-
++output_section->reloc_count;
return TRUE;
simple relocs. */
bfd_boolean
-_bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
- input_section, contents, relocs, syms,
- sections)
- 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;
+_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)
{
struct internal_reloc *rel;
struct internal_reloc *relend;
|| (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
{
(*_bfd_error_handler)
- ("%s: illegal symbol index %ld in relocs",
- bfd_archive_filename (input_bfd), symndx);
+ ("%B: illegal symbol index %ld in relocs", input_bfd, symndx);
return FALSE;
}
else
size of the symbol is included in the section contents, or it
is not. We assume that the size is not included, and force
the rtype_to_howto function to adjust the addend as needed. */
-
if (sym != NULL && sym->n_scnum != 0)
addend = - sym->n_value;
else
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
+ /* Defined weak symbols are a GNU extension. */
asection *sec;
sec = h->root.u.def.section;
val = (h->root.u.def.value
+ sec->output_section->vma
+ sec->output_offset);
- }
+ }
else if (h->root.type == bfd_link_hash_undefweak)
- val = 0;
+ {
+ if (h->class == C_NT_WEAK && h->numaux == 1)
+ {
+ /* See _Microsoft Portable Executable and Common Object
+ File Format Specification_, section 5.5.3.
+ Note that weak symbols without aux records are a GNU
+ extension.
+ FIXME: All weak externals are treated as having
+ characteristic IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY (1).
+ These behave as per SVR4 ABI: A library member
+ will resolve a weak external only if a normal
+ external causes the library member to be linked.
+ See also linker.c: generic_link_check_archive_element. */
+ asection *sec;
+ struct coff_link_hash_entry *h2 =
+ input_bfd->tdata.coff_obj_data->sym_hashes[
+ h->aux->x_sym.x_tagndx.l];
+
+ if (!h2 || h2->root.type == bfd_link_hash_undefined)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = h2->root.u.def.section;
+ val = h2->root.u.def.value
+ + sec->output_section->vma + sec->output_offset;
+ }
+ }
+ else
+ /* This is a GNU extension. */
+ val = 0;
+ }
else if (! info->relocatable)
{
break;
case bfd_reloc_outofrange:
(*_bfd_error_handler)
- (_("%s: bad reloc address 0x%lx in section `%s'"),
- bfd_archive_filename (input_bfd),
- (unsigned long) rel->r_vaddr,
- bfd_get_section_name (input_bfd, input_section));
+ (_("%B: bad reloc address 0x%lx in section `%A'"),
+ input_bfd, input_section, (unsigned long) rel->r_vaddr);
return FALSE;
case bfd_reloc_overflow:
{
if (symndx == -1)
name = "*ABS*";
else if (h != NULL)
- name = h->root.root.string;
+ name = NULL;
else
{
name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
}
if (! ((*info->callbacks->reloc_overflow)
- (info, name, howto->name, (bfd_vma) 0, input_bfd,
- input_section, rel->r_vaddr - input_section->vma)))
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
return FALSE;
}
}