PE-COFF: Fix weak external symbol resolution when strong undef is seen first
Fixes an issue where weak external symbols in PE COFF are incorrectly resolved when a strong undefined reference is encountered first.
When linking PE-COFF objects, a weak external symbol may fail to resolve correctly if a strong undefined reference is encountered first. This patch fixes this issue by ensuring that the COFF-specific symbol class and auxiliary record are stored even when a strong undefined reference is seen first. The patch also extends the relocation handler to resolve the weak alias fallback for undefined symbols with a C_NT_WEAK class and an aux record.
- proposer
Fixes the incorrect resolution of weak external symbols when a strong undefined reference is encountered before the weak definition, updating symbol_class and aux records and extending the relocation handler.
“Fix by extending the condition in coff_link_add_symbols to also update symbol_class and aux when the incoming symbol is a PE weak external with aux and the existing hash is still undefined. Also extend the relocation handler to resolve the weak alias fallback for bfd_link_hash_undefined symbols that carry C_NT_WEAK class and have an aux record.”
In Details
The patch modifies coff_link_add_symbols in bfd/cofflink.c to store symbol_class and aux record when a PE weak external with aux meets an existing undefined hash entry. It also extends _bfd_coff_generic_relocate_section to resolve weak alias fallback for undefined symbols with C_NT_WEAK class and aux.
For Context
In PE COFF linking, 'weak externals' are symbols that can optionally fall back to a default definition if no strong definition is found. This patch fixes a bug where, if code first declares that a symbol MUST exist (a 'strong undefined reference'), then later provides a weak definition with a fallback, the linker would fail to use the fallback. This patch ensures that the linker correctly handles this case, which is important for C++ features like operator new, ensuring programs link correctly.