* emultempl/pe.em (gld_*_after_open): detect case where there two

import libraries for same dll; rename one to ensure proper link
order.

* pe-dll.c (process_def_file): compare ordinals to -1, not 0; fix
typo
(generate_edata): fix typo
This commit is contained in:
DJ Delorie 2000-10-02 14:39:46 +00:00
parent 65420b22d1
commit 486e80e2d5
3 changed files with 89 additions and 3 deletions

View File

@ -1,3 +1,13 @@
2000-10-02 DJ Delorie <dj@redhat.com>
* emultempl/pe.em (gld_*_after_open): detect case where there two
import libraries for same dll; rename one to ensure proper link
order.
* pe-dll.c (process_def_file): compare ordinals to -1, not 0; fix
typo
(generate_edata): fix typo
2000-09-29 Hans-Peter Nilsson <hp@axis.com>
* scripttempl/crisaout.sc (ENTRY): Now __start.

View File

@ -813,6 +813,82 @@ gld_${EMULATION_NAME}_after_open ()
}
#endif
{
lang_input_statement_type *is2;
/* This next chunk of code tries to detect the case where you have
two import libraries for the same DLL (specifically,
symbolically linking libm.a and libc.a in cygwin to
libcygwin.a). In those cases, it's possible for function
thunks from the second implib to be used but without the
head/tail objects, causing an improper import table. We detect
those cases and rename the "other" import libraries to match
the one the head/tail come from, so that the linker will sort
things nicely and produce a valid import table. */
LANG_FOR_EACH_INPUT_STATEMENT (is)
{
if (is->the_bfd->my_archive)
{
int idata2 = 0, reloc_count=0, is_imp = 0;
asection *sec;
/* See if this is an import library thunk */
for (sec = is->the_bfd->sections; sec; sec = sec->next)
{
if (strcmp (sec->name, ".idata\$2") == 0)
idata2 = 1;
if (strncmp (sec->name, ".idata\$", 7) == 0)
is_imp = 1;
reloc_count += sec->reloc_count;
}
if (is_imp && !idata2 && reloc_count)
{
/* it is, look for the reference to head and see if it's
from our own library */
for (sec = is->the_bfd->sections; sec; sec = sec->next)
{
int i;
int symsize = bfd_get_symtab_upper_bound (is->the_bfd);
asymbol **symbols = (asymbol **) xmalloc (symsize);
int nsyms = bfd_canonicalize_symtab (is->the_bfd, symbols);
int relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec);
arelent **relocs = (arelent **) xmalloc ((size_t) relsize);
int nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec,
relocs, symbols);
for (i=0; i<nrelocs; i++)
{
struct symbol_cache_entry *s;
s = (relocs[i]->sym_ptr_ptr)[0];
if (!s->flags & BSF_LOCAL)
{
/* thunk section with reloc to another bfd... */
struct bfd_link_hash_entry *blhe;
blhe = bfd_link_hash_lookup (link_info.hash,
s->name,
false, false, true);
if (blhe && blhe->type == bfd_link_hash_defined)
{
bfd *other_bfd = blhe->u.def.section->owner;
if (strcmp (is->the_bfd->my_archive->filename,
other_bfd->my_archive->filename))
{
/* Rename this implib to match the other */
char *n = (char *) xmalloc (strlen (other_bfd->my_archive->filename) + 1);
strcpy (n, other_bfd->my_archive->filename);
is->the_bfd->my_archive->filename = n;
}
}
}
}
free (relocs);
}
}
}
}
}
{
int is_ms_arch = 0;
bfd *cur_arch = 0;

View File

@ -378,7 +378,7 @@ process_def_file (abfd, info)
{
if (pe_dll_warn_dup_exports)
/* xgettext:c-format */
einfo (_("%XError, duplicate EXPORT with oridinals: %s (%d vs %d)\n"),
einfo (_("%XError, duplicate EXPORT with ordinals: %s (%d vs %d)\n"),
e[j - 1].name, e[j - 1].ordinal, e[i].ordinal);
}
else
@ -388,7 +388,7 @@ process_def_file (abfd, info)
einfo (_("Warning, duplicate EXPORT: %s\n"),
e[j - 1].name);
}
if (e[i].ordinal)
if (e[i].ordinal != -1)
e[j - 1].ordinal = e[i].ordinal;
e[j - 1].flag_private |= e[i].flag_private;
e[j - 1].flag_constant |= e[i].flag_constant;
@ -585,7 +585,7 @@ generate_edata (abfd, info)
if (pi != -1)
{
/* xgettext:c-format */
einfo (_("%XError, oridinal used twice: %d (%s vs %s)\n"),
einfo (_("%XError, ordinal used twice: %d (%s vs %s)\n"),
pe_def_file->exports[i].ordinal,
pe_def_file->exports[i].name,
pe_def_file->exports[pi].name);