PE-COFF linker prefers defined weak external over null fallback
Fixes PE-COFF weak external symbol resolution to prefer defined fallback aliases, preventing runtime crashes.
The PE-COFF linker now correctly prefers weak external symbols with defined fallback aliases over those with null fallbacks. Previously, if a weak declaration with a null fallback was linked before a weak definition with a valid fallback, the symbol would incorrectly resolve to address 0, leading to crashes. This change aligns binutils behavior with lld and ensures more robust symbol resolution for weak externals.
In Details
When linking PE COFF objects, two weak externals for the same symbol can be encountered. The bfd/cofflink.c logic for coff_link_add_symbols previously did not correctly differentiate between fallback aliases when a weak undefined symbol (NOACT) met an existing weak undefined symbol. This commit updates the logic to compare fallback targets, preferring a fallback that resolves to a defined symbol over a null fallback or an undefined symbol, thereby fixing a class of runtime crashes.
- PE-COFF
- Portable Executable - Common Object File Format. A file format used for executables, object code, and DLLs on 32-bit and 64-bit versions of Windows.
- weak external
- A symbol declaration that allows a linker to resolve it to a definition if one exists, but otherwise provides a default (fallback) implementation or resolves to NULL if no definition is found. This is indicated by
C_NT_WEAKwith an auxiliary record in PE-COFF files. - fallback alias
- In the context of weak external symbols, this is a mechanism where the linker can provide a default symbol or address to be used if no explicit definition is found for the symbol being linked. In PE-COFF, this is specified in the auxiliary record of a
C_NT_WEAKsymbol. - NOACT
- A linker action code indicating that no action should be taken when the current symbol being processed is weak and undefined, and it encounters an existing weak undefined symbol. The existing symbol's resolution is preserved.