/* COFF specific linker code.
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
size_t sz;
sub->output_has_begun = FALSE;
- sz = obj_raw_syment_count (sub);
+ sz = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
if (sz > max_sym_count)
max_sym_count = sz;
}
}
}
+ if (finfo.info->strip != strip_all && finfo.info->discard != discard_all)
+ {
+ /* Add local symbols from foreign inputs. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ unsigned int i;
+
+ if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
+ continue;
+ for (i = 0; i < bfd_get_symcount (sub); ++i)
+ {
+ asymbol *sym = bfd_get_outsymbols (sub) [i];
+ file_ptr pos;
+ struct internal_syment isym;
+ bfd_size_type string_size = 0;
+ bfd_vma written = 0;
+ bfd_boolean rewrite = FALSE;
+
+ if (! (sym->flags & BSF_LOCAL)
+ || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+ | BSF_SYNTHETIC))
+ || ((sym->flags & BSF_DEBUGGING)
+ && ! (sym->flags & BSF_FILE)))
+ continue;
+
+ /* See if we are discarding symbols with this name. */
+ if ((finfo.info->strip == strip_some
+ && (bfd_hash_lookup (finfo.info->keep_hash,
+ bfd_asymbol_name(sym), FALSE, FALSE)
+ == NULL))
+ || (((finfo.info->discard == discard_sec_merge
+ && (bfd_get_section (sym)->flags & SEC_MERGE)
+ && ! finfo.info->relocatable)
+ || finfo.info->discard == discard_l)
+ && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
+ continue;
+
+ pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
+ * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ goto error_return;
+ if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+ &string_size, NULL, NULL))
+ goto error_return;
+
+ if (string_size)
+ {
+ bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
+ bfd_size_type indx;
+
+ indx = _bfd_stringtab_add (finfo.strtab,
+ bfd_asymbol_name (sym), hash,
+ FALSE);
+ if (indx == (bfd_size_type) -1)
+ goto error_return;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ bfd_coff_swap_sym_out (abfd, &isym, finfo.outsyms);
+ rewrite = TRUE;
+ }
+
+ if (isym.n_sclass == C_FILE)
+ {
+ if (finfo.last_file_index != -1)
+ {
+ finfo.last_file.n_value = obj_raw_syment_count (abfd);
+ bfd_coff_swap_sym_out (abfd, &finfo.last_file,
+ finfo.outsyms);
+ pos = obj_sym_filepos (abfd) + finfo.last_file_index
+ * symesz;
+ rewrite = TRUE;
+ }
+ finfo.last_file_index = obj_raw_syment_count (abfd);
+ finfo.last_file = isym;
+ }
+
+ if (rewrite
+ && (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz))
+ goto error_return;
+
+ obj_raw_syment_count (abfd) += written;
+ }
+ }
+ }
+
if (! bfd_coff_final_link_postscript (abfd, & finfo))
goto error_return;
/* Write out the global symbols. */
finfo.failed = FALSE;
- coff_link_hash_traverse (coff_hash_table (info),
- _bfd_coff_write_global_sym, &finfo);
+ bfd_hash_traverse (&info->hash->table, _bfd_coff_write_global_sym, &finfo);
if (finfo.failed)
goto error_return;
return TRUE;
}
-/* Write out a global symbol. Called via coff_link_hash_traverse. */
+/* Write out a global symbol. Called via bfd_hash_traverse. */
bfd_boolean
-_bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data)
+_bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
{
+ struct coff_link_hash_entry *h = (struct coff_link_hash_entry *) bh;
struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
bfd *output_bfd;
struct internal_syment isym;
case bfd_link_hash_defweak:
save_global_to_static = finfo->global_to_static;
finfo->global_to_static = TRUE;
- rtnval = _bfd_coff_write_global_sym (h, data);
+ rtnval = _bfd_coff_write_global_sym (&h->root.root, data);
finfo->global_to_static = save_global_to_static;
break;
default: