This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: LOCAL symbols discarded at link time
- From: Mark Hills <mark dot hills at framestore dot com>
- To: Alan Modra <amodra at gmail dot com>, binutils at sourceware dot org
- Cc: Christophe MONAT <christophe dot monat at st dot com>
- Date: Tue, 29 Mar 2016 18:16:08 +0100 (BST)
- Subject: Re: LOCAL symbols discarded at link time
- Authentication-results: sourceware.org; auth=none
- References: <1603021534350 dot 14549 at sys953 dot ldn dot framestore dot com> <20160311114042 dot GA16812 at bubble dot grove dot modra dot org>
On Fri, 11 Mar 2016, Alan Modra wrote:
> On Wed, Mar 02, 2016 at 04:34:59PM +0000, Mark Hills wrote:
> > I'm am experiencing interactions at link time, despite "LOCAL" symbols and
> > applying careful use of 'visibility':
>
> By converting weak symbols to locals you are subverting the mechanism
> used by the toolchain to provide just one instance of a C++ class that
> appears in multiple object files. Don't expect this to work.
Thanks Alan, and Christophe.
Yes, and I suppose a description of what I am trying to do actually /is/
to subvert mechanisms for sharing between object files.
I want to achieve a "safe" partial link step, where only the truly
exported symbols are visible outside a new object file.
> See "C++ one definition rule".
Thanks, was a lead which I was able to follow.
The phrase 'comdat groups' was also mentioned in a reply off-list, which
allowed me to pin down the difference between my two symbols and answer my
own question, which is:
> - Why the difference in behaviour for the two symbols? More likely my
> understanding is not correct, but otherwise could this be a linker bug?
Both symbols appear to have the same attributes:
12: 0000000000000000 11 FUNC LOCAL HIDDEN 4 _ZN3Bad15this_will_clashE
13: 0000000000000000 7 FUNC LOCAL HIDDEN 2 _Z12this_is_finev
but "this_will_clash" differs as it is mentioned in this comdat group.
COMDAT group section [ 1] `.group' [_ZN3Bad15this_will_clashEv] contains 1 sections:
[Index] Name
[ 4] .text._ZN3Bad15this_will_clashEv
So, when localising the symbols I assume I must also update this data
appropriately. In my case, removing this information should be enough, so:
objcopy --localize-hidden $@
became
objcopy -R .group --localize-hidden $@
And this /appears/ to work! It means my full compile and "partial link"
steps are (see full Makefile below)
g++ -c -o $@ $^ -fvisibility=hidden -Wall -fPIC
...
ld -r -o $@ $^
objcopy -R .group --localize-hidden $@
The program output is also, as expected. Despite multiple definitions of
the vague symbols (one in the 'apple' module of the project, the other in
'banana'), the correct one is used in each module courtesy of the partial
link step:
apple will clash
apple is fine
banana will clash
banana is fine
This 'appears' to solve my problem but that is, of course, a very
different thing to a correct solution.
I can't be the only person who wishes to statically link larger projects
of other, competing sub-modules; perhaps even a "hierarchy" of link steps.
Am I doing something here that is useful to share, and what problems can I
expect to encounter further down the line?
(apologies for the delay in reply, I have been unwell)
Many thanks
--
Mark
==> Makefile <==
%.o: %.cc
g++ -std=c++11 -c -o $@ $^ -fvisibility=hidden -Wall -fPIC
main: main.o apple.o banana.o
g++ -o $@ $^
apple.o: apple1.o apple2.o
ld -r -o $@ $^
objcopy -R .group --localize-hidden $@
banana.o: banana1.o banana2.o
ld -r -o $@ $^
objcopy -R .group --localize-hidden $@