Discussion:
64bit: weak symbols
Yaakov (Cygwin/X)
2013-03-31 03:32:08 UTC
Permalink
The following code links behaves on i686 and x86_64:

/* from gcc config/weakref.m4, used in libitm */
extern void fNotToBeFound(void) __attribute__((weak));
int main ()
{
if (fNotToBeFound)
return 1;
else
return 0;
}

On i686 with gcc-4.5.3, this links and returns 0. On x86_64 with
gcc-4.8.0, this produces an error:

/tmp/ccPWiz9s.o:test.c:(.rdata$.refptr.fNotToBeFound[.refptr.fNotToBeFound]+0x0):
undefined reference to `fNotToBeFound'
collect2: error: ld returned 1 exit status


--
Yaakov
Corinna Vinschen
2013-03-31 10:32:08 UTC
Permalink
Post by Yaakov (Cygwin/X)
/* from gcc config/weakref.m4, used in libitm */
extern void fNotToBeFound(void) __attribute__((weak));
int main ()
{
if (fNotToBeFound)
return 1;
else
return 0;
}
On i686 with gcc-4.5.3, this links and returns 0. On x86_64 with
undefined reference to `fNotToBeFound'
collect2: error: ld returned 1 exit status
There's a recent discussion aboout this very problem on the gcc mailing
list. Kai claims that weak symbols cannot work this way on PE/COFF
targets, and the fact that they worked on i686 is kind of a coincidence,
Dave Korn thinks everything's ok as is. IIUC, the symbol is an absolute
reference to the 0 address on i686, but a pc-relative reference with
undefined displacement on x86_64. Personally I think the x86_64 gcc
should create absolute references for weak symbols as well, but I'm not
fluent enough in the bowels of gcc to have a say in the matter.

Kai? Dave?


Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
Earnie Boyd
2013-03-31 17:26:59 UTC
Permalink
Post by Corinna Vinschen
Post by Yaakov (Cygwin/X)
/* from gcc config/weakref.m4, used in libitm */
extern void fNotToBeFound(void) __attribute__((weak));
int main ()
{
if (fNotToBeFound)
return 1;
else
return 0;
}
On i686 with gcc-4.5.3, this links and returns 0. On x86_64 with
undefined reference to `fNotToBeFound'
collect2: error: ld returned 1 exit status
There's a recent discussion aboout this very problem on the gcc mailing
list. Kai claims that weak symbols cannot work this way on PE/COFF
targets, and the fact that they worked on i686 is kind of a coincidence,
Dave Korn thinks everything's ok as is. IIUC, the symbol is an absolute
reference to the 0 address on i686, but a pc-relative reference with
undefined displacement on x86_64. Personally I think the x86_64 gcc
should create absolute references for weak symbols as well, but I'm not
fluent enough in the bowels of gcc to have a say in the matter.
Regardless, IMO, the result should be the same for either i686 or x86_64.

--
Earnie
-- https://sites.google.com/site/earnieboyd
Kai Tietz
2013-04-02 09:05:37 UTC
Permalink
----- Original Message -----
Sent: Sunday, March 31, 2013 12:32:08 PM
Subject: Re: 64bit: weak symbols
Post by Yaakov (Cygwin/X)
/* from gcc config/weakref.m4, used in libitm */
extern void fNotToBeFound(void) __attribute__((weak));
int main ()
{
if (fNotToBeFound)
return 1;
else
return 0;
}
On i686 with gcc-4.5.3, this links and returns 0. On x86_64 with
undefined reference to `fNotToBeFound'
collect2: error: ld returned 1 exit status
There's a recent discussion aboout this very problem on the gcc mailing
list. Kai claims that weak symbols cannot work this way on PE/COFF
targets, and the fact that they worked on i686 is kind of a coincidence,
Dave Korn thinks everything's ok as is. IIUC, the symbol is an absolute
reference to the 0 address on i686, but a pc-relative reference with
undefined displacement on x86_64. Personally I think the x86_64 gcc
should create absolute references for weak symbols as well, but I'm not
fluent enough in the bowels of gcc to have a say in the matter.
Kai? Dave?
This issue is a bit tricky. The only way to solve this for 64-bit is by making weak-symbols always using indirect access. The issue is that symbols for x64 are pc-relative in instructions. So a NULL-address isn't necessarily possible for an image-base >2GB as address because instruction-relocations are 32-bit signed.
By using indirect-access (as done for large-code-model also for functions) an absolute symbol to zero-address would be possible. One weakness I see about this approach because the extern symbol is just known to be weak in the TU(s) where it is prototyped as external weak-symbol. Otherwise it is treated as a standard symbol and for none-large-code-model a direct pc-relative-addressing is used.
So I would suggest to use instead here only none-external weak-symbols. Means that the a weak-implementation is provided which might get overriden by a none-weak implementation on link. This is the way I used for the crtbegin.c patch I posted to gcc's ML, where Dave was commenting to.

Dave said that he wanted to look into that, so I would like to hear his findings about that subject.

Regards,
Kai

PS: Sorry for the spamming. Gmail changed mail-encoding and seems not to provide a working switch to reset it to old text-only format (as specified in configuration), I had to switch to different account for anwsering.
Dave Korn
2013-04-09 06:02:04 UTC
Permalink
Post by Kai Tietz
This issue is a bit tricky. The only way to solve this for 64-bit is by
making weak-symbols always using indirect access. The issue is that
symbols for x64 are pc-relative in instructions. So a NULL-address isn't
necessarily possible for an image-base >2GB as address because
instruction-relocations are 32-bit signed. By using indirect-access (as
done for large-code-model also for functions) an absolute symbol to
zero-address would be possible. One weakness I see about this approach
because the extern symbol is just known to be weak in the TU(s) where it is
prototyped as external weak-symbol. Otherwise it is treated as a standard
symbol and for none-large-code-model a direct pc-relative-addressing is
used. So I would suggest to use instead here only none-external
weak-symbols. Means that the a weak-implementation is provided which might
get overriden by a none-weak implementation on link. This is the way I
used for the crtbegin.c patch I posted to gcc's ML, where Dave was
commenting to.
Dave said that he wanted to look into that, so I would like to hear his
findings about that subject.
Thanks for the explanation Kai, I wasn't aware of the problems w.r.t 64-bit
vs. memory models. I've replied over on the gcc-patches list, agreeing that
the patch is ok. (I suggested a couple of minor changes in formatting and no
longer testing the function pointers for NULL).

cheers,
DaveK

Loading...