* cofflink.c (coff_link_add_symbols): Look for special MSVC string

constant symbols, and avoid multiple definition errors on them.
This commit is contained in:
Ian Lance Taylor 1999-09-12 16:28:20 +00:00
parent bb8fe706a0
commit 49147fca36
2 changed files with 45 additions and 0 deletions

View File

@ -1,3 +1,8 @@
1999-09-12 Ian Lance Taylor <ian@zembu.com>
* cofflink.c (coff_link_add_symbols): Look for special MSVC string
constant symbols, and avoid multiple definition errors on them.
1999-09-12 Donn Terry <donn@interix.com>
* libbfd.c (bfd_log2): Rewrite to avoid infinite loop if most

View File

@ -422,6 +422,46 @@ coff_link_add_symbols (abfd, info)
}
}
/* The Microsoft Visual C compiler does string pooling by
hashing the constants to an internal symbol name, and
relying on the the linker comdat support to discard
duplicate names. However, if one string is a literal and
one is a data initializer, one will end up in the .data
section and one will end up in the .rdata section. The
Microsoft linker will combine them into the .data
section, which seems to be wrong since it might cause the
literal to change.
As long as there are no external references to the
symbols, which there shouldn't be, we can treat the .data
and .rdata instances as separate symbols. The comdat
code in the linker will do the appropriate merging. Here
we avoid getting a multiple definition error for one of
these special symbols.
FIXME: I don't think this will work in the case where
there are two object files which use the constants as a
literal and two object files which use it as a data
initializer. One or the other of the second object files
is going to wind up with an inappropriate reference. */
if (obj_pe (abfd)
&& (classification == COFF_SYMBOL_GLOBAL
|| classification == COFF_SYMBOL_PE_SECTION)
&& section->comdat != NULL
&& strncmp (name, "??_", 3) == 0
&& strcmp (name, 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)
addit = false;
}
if (addit)
{
if (! (bfd_coff_link_add_one_symbol