Bug 37520 - NO_DOLLAR_IN_LABEL should be defined on x86 targets
Summary: NO_DOLLAR_IN_LABEL should be defined on x86 targets
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords:
Depends on:
Blocks:
 
Reported: 2008-09-14 20:46 UTC by Gerald Pfeifer
Modified: 2009-03-07 01:48 UTC (History)
4 users (show)

See Also:
Host:
Target: x86-*-*
Build:
Known to work: 4.3.1
Known to fail:
Last reconfirmed: 2009-03-01 20:20:05


Attachments
init-list.ii (34.42 KB, application/x-gzip)
2008-09-14 20:47 UTC, Gerald Pfeifer
Details
init-list.s (46.08 KB, application/x-gzip)
2008-09-14 20:47 UTC, Gerald Pfeifer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Gerald Pfeifer 2008-09-14 20:46:21 UTC
Looking at my testsuite runs on i386-unknown-freebsd6.3 I noticed the
following testsuite failure.

FAIL: 23_containers/deque/init-list.cc (test for excess errors)
Excess errors:
/var/tmp//ccHEu2Vp.s:5429: Error: junk `(,%eax,4)' after expression
/var/tmp//ccHEu2Vp.s:5429: Error: suffix or operands invalid for `lea'

I'll attach *.ii and *.s files in a minute.
Comment 1 Gerald Pfeifer 2008-09-14 20:47:22 UTC
Created attachment 16319 [details]
init-list.ii
Comment 2 Gerald Pfeifer 2008-09-14 20:47:54 UTC
Created attachment 16320 [details]
init-list.s
Comment 3 Andrew Pinski 2008-09-14 22:24:13 UTC
        leal    $_48(,%eax,4), %eax
...
        subl    $$_48, %eax

Hmm

Looks like someone forgot a $ encoding in some cases.
Comment 4 Uroš Bizjak 2008-09-15 09:01:38 UTC
IMO, you need to define NO_DOLLAR_IN_LABEL in your configuration files.
Comment 5 Gerald Pfeifer 2008-09-21 10:15:27 UTC
Uros, looking at this again, after manually changing
  leal    $_48(,%eax,4), %eax
to
  leal    _48(,%eax,4), %eax
things build again with the label being defined as
        .type   $_48, @object
        .size   $_48, 12
  $_48:
and used like
  cmpl    $$_48+12, %eax
without problems.

Do you believe this is a bug for leal in the older version of binutils
(2.15) FreeBSD ships?  I am surprised that it works when I remove the $.


I am not a gcc/config expert but can give NO_DOLLAR_IN_LABEL a try.

However, will this change ABI?  That is, if I know enable this in GCC, how
will this interact with an existing (FreeBSD) system where libraries likely
have been built with a system compiler that does not have this set?
Comment 6 Benjamin Kosnik 2009-01-05 20:01:49 UTC
Adding 4.4.x reported against, as this testcase is not in 4.3.x.
Comment 7 Benjamin Kosnik 2009-01-05 20:23:06 UTC
The other kind of freebsd6.3 fail in libstdc++ is:

testsuite/25_algorithms/max/3.cc

/sw/test/GCC/trunk/libstdc++-v3/testsuite/25_algorithms/max/3.cc:26: undefined reference to `_47'

/var/tmp//ccInT4La.o(.text._Z6test01v+0xb):/sw/test/GCC/trunk/libstdc++-v3/testsuite/25_algorithms/max/3.cc:26: undefined reference to `_47'


On linux I see these in the linked binary:

0000000000600b58 d ._65
0000000000600b64 d ._66
0000000000600b70 d ._67
0000000000600b7c d ._68
0000000000600b88 d ._69
0000000000600b94 d ._70

So assuming this would be ._48 or '.' used instead of '$'. Does BSD already define NO_DOT_IN_LABEL? Although I am not quite sure what is going on it appears as if the freebsd config (and or assember) for correct linking of some of these C++ entities is off.

Anyway. I thought NO_DOT_IN_LABEL/NO_DOLLAR_IN_LABEL will change the name of exported symbols and is ABI-breaking.

IMHO figuring this out before the 4.4.0 release seems advisable. 
Comment 8 Benjamin Kosnik 2009-02-02 18:26:38 UTC
This looks like it happens on FreeBSD 7.1 as well:
http://gcc.gnu.org/ml/gcc-testresults/2009-02/msg00142.html

Any news on what is going on here? 

Please note that i386-bsd is a primary platform for a release, as per:
http://gcc.gnu.org/gcc-4.4/criteria.html

Thus, this should really be a higher priority than P3.
Comment 9 Benjamin Kosnik 2009-02-24 17:56:25 UTC
Changed title for 4.4 regression.
Comment 10 Uroš Bizjak 2009-02-25 07:33:36 UTC
Confirmed.
Comment 11 Richard Biener 2009-02-25 08:57:43 UTC
Let's make this P1 until we are sure it is not an ABI problem.
Comment 12 Gerald Pfeifer 2009-03-01 13:03:41 UTC
(In reply to comment #8)
> This looks like it happens on FreeBSD 7.1 as well:
> http://gcc.gnu.org/ml/gcc-testresults/2009-02/msg00142.html
> 
> Any news on what is going on here? 

Yes, I have updated my nightly tester to see whether this may be specific
to that older versions.  Alas, no difference.

I also built GNU binutils 2.19, alas this does not seem to make a difference
either.

If anyone has any ideas / patches to verify, I will be happy to do my best.
Comment 13 Uroš Bizjak 2009-03-01 19:16:39 UTC
(In reply to comment #12)

> If anyone has any ideas / patches to verify, I will be happy to do my best.

Is there an ABI documentation that says which prefixes are correct for certain cases? It is easy to fix this issue by setting a bunch of macros, but until some document clearly says, which approach is correct, I think that we will be just shooting in the dark.

Looking at Comment #5 and Comment #7, it is not clear even if we want to follow some published ABI or we want to be compatible with existing system libraries.
Comment 14 Uroš Bizjak 2009-03-01 20:13:05 UTC
(In reply to comment #5)
> Uros, looking at this again, after manually changing
>   leal    $_48(,%eax,4), %eax
> to
>   leal    _48(,%eax,4), %eax
> things build again with the label being defined as
>         .type   $_48, @object
>         .size   $_48, 12
>   $_48:
> and used like
>   cmpl    $$_48+12, %eax
> without problems.
> 
> Do you believe this is a bug for leal in the older version of binutils
> (2.15) FreeBSD ships?  I am surprised that it works when I remove the $.

It works only because "_48" will create a relocation to an external object. You can see this by using 'objdump -dr init-list.o", where init-list.o is created with "gcc -O2 -m32 -c -std=gnu++0x"

When this part is assembled (on linux!):

	ja	.L306
	leal	._48(,%eax,4), %eax
	movl	%eax, 44(%esp)
	subl	$._48, %eax
	sarl	$2, %eax

An offset to an object in .data section is calculated at assembly time, so you will get:

...
 579:	0f 87 01 02 00 00    	ja     780 <main+0x780>
 57f:	8d 04 85 18 00 00 00 	lea    0x18(,%eax,4),%eax
			582: R_386_32	.data
 586:	89 44 24 2c          	mov    %eax,0x2c(%esp)
 58a:	2d 18 00 00 00       	sub    $0x18,%eax
			58b: R_386_32	.data
 58f:	c1 f8 02             	sar    $0x2,%eax
...

while removing "." (equivalent to removing "$" on BSD) from the lea operand leaves an relocation to external symbol:

...
 579:	0f 87 01 02 00 00    	ja     780 <main+0x780>
 57f:	8d 04 85 00 00 00 00 	lea    0x0(,%eax,4),%eax
			582: R_386_32	_48
 586:	89 44 24 2c          	mov    %eax,0x2c(%esp)
 58a:	2d 18 00 00 00       	sub    $0x18,%eax
			58b: R_386_32	.data
 58f:	c1 f8 02             	sar    $0x2,%eax

I found much more interesting the fact, that both:

	subl	._48, %eax
and
	subl	$._48, %eax

produce the same result, while changing:

	leal	._48(,%eax,4), %eax
to
	leal	$._48(,%eax,4), %eax

produces:

init-list.s: Assembler messages:
init-list.s:2664: Error: junk `(,%eax,4)' after expression
init-list.s:2664: Error: suffix or operands invalid for `lea'

I think that H.J. can explain the reason for this inconsistency in the assembler.
Comment 15 H.J. Lu 2009-03-01 20:20:05 UTC
(In reply to comment #14)
> I think that H.J. can explain the reason for this inconsistency in the
> assembler.
> 

LOCAL_LABELS_DOLLAR never really works completely for x86 assembler.
When assembler sees $foo, it can't tell if $foo is a label or the value
of symbol foo. I do have a hack for x86 assembler, which assumes $_XXX
is a local label if LOCAL_LABELS_DOLLAR is defined. But it won't work
when _XXX is a real label.
Comment 16 H.J. Lu 2009-03-01 20:23:04 UTC
I posted a patch at:

http://gcc.gnu.org/ml/gcc-patches/2009-03/msg00049.html

It may breaks ABI for platforms where NO_DOLLAR_IN_LABEL
is undefined:

bash-3.2$ grep NO_DOLLAR_IN_LABEL *.h */*.h | grep undef
freebsd.h:#undef NO_DOLLAR_IN_LABEL
vx-common.h:#undef NO_DOLLAR_IN_LABEL
i386/openbsdelf.h:#undef NO_DOLLAR_IN_LABEL
xtensa/elf.h:#undef NO_DOLLAR_IN_LABEL
Comment 17 H.J. Lu 2009-03-01 20:40:20 UTC
I opened an assembler bug:

http://sourceware.org/bugzilla/show_bug.cgi?id=9915

I believe it is a mistake to define LOCAL_LABELS_DOLLAR for any
x86 targets where '$' is used as the immediate prefix. If it worked
on such a x86 target before, it was a pure luck.
Comment 18 H.J. Lu 2009-03-01 21:53:52 UTC
I will check in a patch:

http://sourceware.org/ml/binutils/2009-03/msg00008.html

to undefine LOCAL_LABELS_DOLLAR for x86 assembler. I suggest that
gcc should define NO_DOLLAR_IN_LABEL for all x86 targets.
Comment 19 H.J. Lu 2009-03-02 03:20:45 UTC
A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2009-03/msg00061.html
Comment 20 hjl@gcc.gnu.org 2009-03-07 01:47:39 UTC
Subject: Bug 37520

Author: hjl
Date: Sat Mar  7 01:47:25 2009
New Revision: 144692

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=144692
Log:
2009-03-06  H.J. Lu  <hongjiu.lu@intel.com>

	PR c++/37520
	* cp-tree.h: Check NO_DOT_IN_LABEL before NO_DOLLAR_IN_LABEL
	when mangling symbols.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h

Comment 21 H.J. Lu 2009-03-07 01:48:47 UTC
Fixed.