cannot build mainline GCC with mainline binutils

Bob Wilson bwilson@tensilica.com
Tue Nov 30 01:35:00 GMT 2004


I discovered a problem while trying to build mainline GCC with mainline binutils 
for an xtensa-elf target.  It looks like some of the recent comdat patches 
require the assembler's DIFF_EXPR_OK macro to be defined.  This is not true for 
Xtensa or MIPS.

I'm seeing the problem when building libstdc++-v3/src/locale-inst.cc.  The 
generated assembly looks like this:

.section
   .gnu.linkonce.t.long_mangled_name,"axG",@progbits,long_mangled_name,comdat
long_mangled_name:
	....CODE....

.section
   .gnu.linkonce.r.long_mangled_name,"aG",@progbits,long_mangled_name,comdat
	....DATA....

.section
   .gnu.linkonce.t.long_mangled_name,"axG",@progbits,long_mangled_name,comdat
long_mangled_name:
	....MORE CODE....

.size	long_mangled_name, .-long_mangled_name

(The "long_mangled_name" here is: 
_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb0EEES3_S3_RSt8ios_basecRKSs.)

The problem is the ".-long_mangled_name" expression in the .size directive. 
This does not assemble unless DIFF_EXPR_OK is defined.  (Either that or 
something else is wrong in the Xtensa port of GAS, which is always a 
possibility.)  The error message is: "Error: operation combines symbols in 
different segments".  The data in the middle of the function apparently makes 
the assembler think that "." is in a different segment than the start of the 
function.

I'm not sure how to resolve this.  Some possibilities and questions:

* Perhaps GCC ought to be emitting .pushsection/.popsection around the data in 
the middle of the function.  I tried that out (by hand-editing the assembly 
source) and it does indeed solve the problem.

* Why does DIFF_EXPR_OK have anything to do with the expression in a .size 
directive?  I thought DIFF_EXPR_OK was related to using PC-relative relocations, 
and I don't think the assembler will allow a relocation in the ELF symbol table. 
   I.E., even if DIFF_EXPR_OK is defined, I think the assembler is resolving 
this expression to a constant.  Perhaps the expr() function ought to always 
allow difference expressions, i.e., as if DIFF_EXPR_OK is defined, with the 
check for valid difference expressions being handled when evaluating the "fix"es??

* Is there some other change that could be done in the assembler to handle this 
case where a function body is broken up by some data in another section?

Any other thoughts or suggestions?  I'm just not sure how to handle this one.

--Bob



More information about the Binutils mailing list