Bug 23304 - ARM linker fails to combine identical typeinfo sections
Summary: ARM linker fails to combine identical typeinfo sections
Status: RESOLVED INVALID
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.31
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-06-18 12:10 UTC by Nick Clifton
Modified: 2018-06-19 11:35 UTC (History)
3 users (show)

See Also:
Host:
Target: ARM
Build:
Last reconfirmed:


Attachments
testcase. (582 bytes, application/zip)
2018-06-18 12:10 UTC, Nick Clifton
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Clifton 2018-06-18 12:10:37 UTC
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
Comment 1 Cary Coutant 2018-06-18 15:24:34 UTC
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.
Comment 2 Nick Clifton 2018-06-19 10:25:32 UTC
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.
Comment 3 Nick Clifton 2018-06-19 11:05:39 UTC
(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...
Comment 4 Nick Clifton 2018-06-19 11:35:10 UTC
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.