This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: LOCAL symbols discarded at link time


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 $@


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]