This is the mail archive of the
mailing list for the binutils project.
Re: gold vs ld-bfd mismatch on --wrap=
- From: Cary Coutant <ccoutant at gmail dot com>
- To: Tristan Gingold <gingold at adacore dot com>
- Cc: binutils <binutils at sourceware dot org>
- Date: Fri, 16 Sep 2016 08:03:11 -0700
- Subject: Re: gold vs ld-bfd mismatch on --wrap=
- Authentication-results: sourceware.org; auth=none
- References: <3894AB92-FBE6-4367-972E-2369FED1006E@adacore.com>
> an incompatibility between gold and ld-bfd is visible on this stackoverflow hack:
> (in a short:
> asm (".symver memcpy, memcpy@GLIBC_2.2.5");
> void *__wrap_memcpy(void *dest, const void *src, size_t n)
> return memcpy(dest, src, n);
> and link with --wrap=memcpy)
> This works with ld-bfd, but not with gold. The reason is that gold wraps the symbols for all versions, so the call to memcpy becomes a call to __wrap_memcpy which results in an infinite recursion.
> The presence of a comment in symtab.cc:add_from_object looks like this is an intentional decision.
> Is it really the case ?
> Does it make sense to follow more closely ld-bfd and to wrap only symbols without version ?
The following works for gold, but not for ld:
extern void *__real_memcpy(void *, const void *, size_t);
asm (".symver __real_memcpy, __real_memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n)
return __real_memcpy(dest, src, n);
As I understand it, this is how --wrap is supposed to be used, but ld
fails to translate __real_memcpy back to memcpy (presumably because it
has a version).
I see nothing in the ld manual about not wrapping symbols with
versions. If we don't wrap versioned symbols, wouldn't the example in
the manual (which uses malloc) fail?
To my eyes, gold is doing the right thing here. Sure, we like to match
BFD ld behavior as much as possible, but not when ld behavior looks
like a bug.
[Update] After I accidentally sent this reply privately yesterday,
Tristan noticed that, while the example no longer crashes, gold still
drops the version number from the final reference to memcpy, with the
result that gold binds the reference to the default version
(GLIBC_2.14). I think that dropping the version number from the
wrapped references is still the right thing to do, per the comment
that Tristan referred to, but we shouldn't drop it when translating
the __real_memcpy reference.