Created attachment 11078 [details] testcase. The ARM linker fails to combine identical typeinfo sections from different compilation units. To see this compile the source files in the attached testcase with: g++ -c inst1.cpp inst2.cpp main.cpp g++ inst1.o inst2.o main.o For the ARM target this will produce messages like this: ld-new: inst2.o:(.rodata+0x0): multiple definition of `typeinfo for test_template<long, 2l>'; inst1.o:(.rodata+0x0): first defined here Other targets, eg AArch64 and x86_64, do not have this problem. This bug was originally reported alongside a memory exhaustion problem in the Fedora version of the linker: https://bugzilla.redhat.com/show_bug.cgi?id=1584711
This is old, but may still be relevant: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=608029 Given the error message, it sure looks like arm-g++ is still failing to mark the typeinfo symbols as weak definitions. Back when that bug report was filed, duplicate explicit instantiations were not allowed, but if C++11 now allows them, the arm compiler should have been changed. The x86 g++ does in fact make them weak, so we don't get the duplicate symbol warnings. (I'm surprised that the target makes a difference -- I'd expect the decision to make those symbols weak would be in common code, independent of the target architecture.) The linker will not combine the identical typeinfo sections, though, since they're not in COMDAT groups. It'll allocate space for both copies, but all references will resolve to the first copy, and the second copy will just be wasted space.
Hi Cary, > Given the error message, it sure looks like arm-g++ is still failing to mark > the typeinfo symbols as weak definitions. Actually I think that the compiler is doing the right thing now, but the assembler is messing up. For example: % arm-g++ inst2.cpp -c --save-temps % cat inst2.s [...] .weak _ZTV13test_templateIlLl2EE .section .rodata._ZTV13test_templateIlLl2EE,"aG",%progbits,_ZTV13test_templateIlLl2EE,comdat .align 2 .type _ZTV13test_templateIlLl2EE, %object [...] % readelf --wide --syms inst2.o [...] 123: 00000008 23 OBJECT GLOBAL DEFAULT 84 _ZTS13test_templateIlLl2EE [...] Note how the symbol is GLOBAL not WEAK... This is with a very recent version of gcc: xg++ (GCC) 9.0.0 20180618 (experimental) [trunk revision 261696] I am investigating further.
(In reply to Nick Clifton from comment #2) Darn C++ name mangling. I was looking at the wrong symbol. It should have been _ZTS13test_templateIlLl2EE and it does look like the compiler is wrong: .word _ZTS13test_templateIlLl2EE .global _ZTS13test_templateIlLl2EE .align 2 .type _ZTS13test_templateIlLl2EE, %object whereas the x86_64 compiler produces: .quad _ZTS13test_templateIlLl2EE .weak _ZTS13test_templateIlLl2EE .section .rodata._ZTS13test_templateIlLl2EE,"aG",@progbits,_ZTS13test_templateIlLl2EE,comdat .align 16 .type _ZTS13test_templateIlLl2EE, @object More investigation to follow...
Right - this is an ARM API issue. If you compile with the default API for ARM (the AAPCS) then you get global typeinfo symbols because: /* \S 3.2.5.4 of the ARM C++ ABI says that class data only have vague linkage if the class has no key function. */ This is from gcc/config/arm/arm.c:arm_cxx_class_data_always_comdat(). If you compile with a different API, eg apcs-gnu, then you get weak linkage for typeinfo symbols. Either way this is not a binutils bug, so I am closing this BZ.