[PATCH] PE-COFF: Fix link failure of C++ code with debug info after partial linking

Jan Beulich jbeulich@suse.com
Fri Mar 27 14:33:11 GMT 2026


On 25.03.2026 16:56, Eric Botcazou wrote:
> Hi,
> 
> if you apply the following recipe to the attached C/C++ files with a PE-COFF 
> toolchain, you get the specified output:
> 
> 1. g++ -c clib.cpp cpplib.cpp test.c -g
> 2. g++ -o pl.o clib.o cpplib.o -nostdlib -Wl,-r
> 3. objcopy pl.o
> objcopy.exe: pl.o: warning: COMDAT symbol 
> '.debug_frame$_ZNSt12_Vector_baseIiSaIiEE12_Vector_implD1Ev' does not match 
> section name '.debug_frame'
> 4. g++ -o test test.o pl.o
> ld.exe: pl.o: warning: COMDAT symbol 
> '.debug_frame$_ZNSt12_Vector_baseIiSaIiEE12_Vector_implD1Ev' does not match 
> section name '.debug_frame'
> pl.o:clib.cpp:(.pdata$_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPiy+0x0): 
> relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against 
> `.text$_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPiy'
> pl.o:clib.cpp:(.pdata$_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPiy+0x4): 
> relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against 
> `.text$_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPiy'
> pl.o:clib.cpp:(.pdata$_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv+0x0): 
> relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against 
> `.text$_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv'
> pl.o:clib.cpp:(.pdata$_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv+0x4): 
> relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against 
> `.text$_ZNSt12_Vector_baseIiSaIiEE19_M_get_Tp_allocatorEv'
> pl.o:clib.cpp:(.pdata$_ZNSt15__new_allocatorIiE10deallocateEPiy+0x0): 
> relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against 
> `.text$_ZNSt15__new_allocatorIiE10deallocateEPiy'
> pl.o:clib.cpp:(.pdata$_ZNSt15__new_allocatorIiE10deallocateEPiy+0x4): 
> relocation truncated to fit: IMAGE_REL_AMD64_ADDR32NB against 
> `.text$_ZNSt15__new_allocatorIiE10deallocateEPiy'
> collect2.exe: error: ld returned 1 exit status
> 
> The problem pertains to section symbols generated for COMDAT sections: they
> are marked as local symbols as per Microsoft's PE-COFF specification, but
> partial linking discards the duplicate COMDAT sections without being able
> to either merge them, or remove them when they are used in a relocation.
> 
> So they end up as undefined local symbols after the partial link, which in
> turn may cause the final link to fail (in practice you need e.g. a call to
> objcopy in between, because it moves them to the end of the symbol list).
> 
> This change instructs the linker to "relocate" them instead, that is to say
> to attach them to the one COMDAT section that is output among the multiple
> COMDAT sections that are duplicate.  It also prevents partial linking from
> prematurely globing the .[z]debug_frame* sections together, as already done
> for the .eh_frame* sections.
> 
> Tested on x86_64-w64-mingw32, OK for the mainline?

Yes, albeit preferably with a few small adjustments (can't comment very well
on a patch that comes only as attachment): The new variable wants to be
pointer-to-const (unless I'm overlooking a reason why it cannot be), and it
would likely help the code if the variable had *secpp as initializer, such
that in place of the three (*secpp) the local variable can then be used.

Jan


More information about the Binutils mailing list