Created attachment 11078 [details]
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:
This is old, but may still be relevant:
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.
> 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
.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:
.type _ZTS13test_templateIlLl2EE, %object
whereas the x86_64 compiler produces:
.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 184.108.40.206 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.