summaryrefslogtreecommitdiff
path: root/bfd/cofflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/cofflink.c')
-rw-r--r--bfd/cofflink.c109
1 files changed, 64 insertions, 45 deletions
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 4ad566cc22e..ca144cc4929 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -1,6 +1,6 @@
/* 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 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -96,7 +96,7 @@ _bfd_coff_link_hash_table_init (struct coff_link_hash_table *table,
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);
}
@@ -435,18 +435,19 @@ coff_link_add_symbols (bfd *abfd,
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;
}
@@ -503,9 +504,8 @@ coff_link_add_symbols (bfd *abfd,
&& (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
@@ -551,8 +551,8 @@ coff_link_add_symbols (bfd *abfd,
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
@@ -714,8 +714,10 @@ _bfd_coff_final_link (bfd *abfd,
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)
@@ -1080,7 +1082,7 @@ _bfd_coff_final_link (bfd *abfd,
}
/* 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;
@@ -1208,21 +1210,18 @@ process_embedded_commands (bfd *output_bfd,
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, &copy))
{
- free (copy);
+ if (copy != NULL)
+ free (copy);
return 0;
}
- e = copy + sec->_raw_size;
+ e = copy + sec->size;
for (s = copy; s < e ; )
{
@@ -2283,16 +2282,18 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd)
/* 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;
}
@@ -2305,8 +2306,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd)
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;
}
@@ -2431,10 +2432,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd)
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
@@ -2616,9 +2615,7 @@ _bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data)
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? */
@@ -2863,8 +2860,7 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
|| (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
@@ -2925,16 +2921,41 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
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
+ * characteristics IMAGE_WEAK_EXTERN_SEARCH_LIBRARY (2).
+ * There are no known uses of the other two types of
+ * weak externals.
+ */
+ asection *sec;
+ struct coff_link_hash_entry *h2 =
+ input_bfd->tdata.coff_obj_data->sym_hashes[
+ h->aux->x_sym.x_tagndx.l];
+
+ 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)
{
@@ -2984,10 +3005,8 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
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:
{