M
> Hi,
> 
> On 08/29/2013 10:11 AM, Jan Hubicka wrote:
> >Paolo,
> >there seems to be one extra issue about this patch. It causes quite a twist 
> >in libstdc++ exported symbols.
> >It is purpose of the patch to remove those that are going to be generated in 
> >user programs, too.
> >I am however bit confused about bad array. Perhaps it is an optimization 
> >difference dragging it in?
> I'm also confused because your patch isn't already in (at least I
> can't find such a ChangeLog in svn) and what you attached, as long
> as bad_array_* is concerned is just what we currently have, before
> the patch. Check point: 21 added symbols.

I see, I tought that adding a symbol will make ABI check to fail, so I got
sidetracked by trying to understand why we need the bad array.
> 
> In general, of course, inlining alone can make a difference, if for
> example you inline less and a pattern in the linker map isn't tight
> enough some symbols can become inadvertently exported.
> 
> *But*, outside bad_array* I can see a lot of SUBTRACTED, those would
> be very bad regressions of course. check_abi cannot pass.

I see, it is purpose of the patch to cause regressions like this :)
What I am tracking is the following testcase:

jan@linux-9ure:~> cat t.C
__attribute__ ((noinline))
inline void t(void)
{
 asm("fsin");
}
void q(void);

main()
{
  q();
  t();
}
jan@linux-9ure:~> cat t2.C
__attribute__ ((noinline))
inline void t(void)
{
 asm("fsin");
}

void q(void)
{
  t();
}
jan@linux-9ure:~> gcc -O2 t2.C -fPIC --shared -o libt.so 
jan@linux-9ure:~> gcc -O2 t.C -lt -L.

Now I have a shared library and main binary but defining function t():

jan@linux-9ure:~> objdump -d a.out | grep fsin
  400720:       d9 fe                   fsin   
jan@linux-9ure:~> objdump -d libt.so | grep fsin
 720:   d9 fe                   fsin   

Both define it in dynamic symbol table:

jan@linux-9ure:~> objdump -t a.out | grep _Z1tv
0000000000400720  w    F .text  0000000000000003              _Z1tv
jan@linux-9ure:~> objdump -t libt.so | grep _Z1tv
0000000000000720  w    F .text  0000000000000003              _Z1tv

and libt has dynamic relocation on call to the function:
jan@linux-9ure:~> objdump -R libt.so | grep _Z1tv
0000000000201020 R_X86_64_JUMP_SLOT  _Z1tv
jan@linux-9ure:~> objdump -R a.out | grep _Z1tv
jan@linux-9ure:~> 

Both versions of t() (in libt and a.out) are known to be semantically
equivalent.  My patch makes an observation that is does not matter to what copy
of t() we call.  So it makes both symbols hidden.  This makes them resovled at
link-time rather than at dynamic link-time.  Thinks should still work as
previously, just we will dispatch at runtime into both copies. I believe it is
little cost to pay for getting cheaper dynamic linking and better codegen (for
locally bound calls).

The symbol disappear from the external symbol table, but this transformation
ought to be valid since the same would happen if the symbol was fully inlined
or its uses optimized out.

This optimization will disable itself when you take address of t() so 
comparing addresses works as expected. Also the optimization won't take
place when you key a template since then the users of the library do not
necesarily need to emit their own copy of the code.

My longer term vision is to turn as many relocations as possible from external
to IP relative. This by itself will help (i.e. from libreoffice, this patch
cuts down important percentage of symbols). If something like Mike Homey's 
elfhack
http://glandium.org/blog/?p=1177
ever land into official dynamic linker (I think it should), we will see a lot
smaller binaries.
> 
> In the past, when we (library people) had special issues with
> versioning, like we had to patch a mistake we made, Jakub promptly
> helped, I would recommend referring to him too, if you are seeing
> something weird, but the general rule as far as testing is concerned
> is very simple: *never* ignore check_abi failures, make sure
> additional symbols are exported only at the current ABI version,
> never add symbols at older versions, never remove symbols.

So my belief is that it is safe to drop those symbols from libstdc++. Every
program/DSO using them have to define its own copy of those symbols, so I
believe removing them from libstdc++ won't cause issues.

Honza
> 
> Paolo.
> 

Reply via email to