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: PR 18167, Relax PR 15228 protected visibility restriction


On Fri, Mar 27, 2015 at 10:32:10AM +0000, Pedro Alves wrote:
> On 03/27/2015 05:43 AM, Alan Modra wrote:
> > Allows .dynbss copy of shared library protected visibility variables
> > if they are read-only.
> > 
> > To recap: Copying a variable from a shared library into an executable's
> > .dynbss is an old hack invented for non-PIC executables, to avoid the
> > text relocations you'd otherwise need to access a shared library
> > variable.  This works with ELF shared libraries because global
> > symbols can be overridden.  The trouble is that protected visibility
> > symbols can't be overridden.  A shared library will continue to access
> > it's own protected visibility variable while the executable accesses a
> > copy.  If either the shared library or the executable updates the
> > value then the copy diverges from the original.  This is wrong since
> > there is only one definition of the variable in the application.
> > 
> > So I made the linker report an error on attempting to copy protected
> > visibility variables into .dynbss.  However, you'll notice the above
> > paragraph contains an "If".  An application that does not modify the
> > variable value remains correct even though two copies of the variable
> > exist.  The linker can detect this situation if the variable was
> > defined in a read-only section.
> 
> Except pointer comparison won't be correct, right?  I mean,

True.

> lib:
> 
>   const int protected_var __attribute__ ((visibility ("protected")));
> 
>   void
>   library (int *var)
>   {
>      if (var != &protected_var)
>        abort ();
>   }
> 
> app:
> 
>   const int protected_var __attribute__ ((visibility ("protected")));
> 
>   library (&protected_var);
> 
> 
> Or is there something else that already makes it invalid to expect
> that the variable's address taken by program and library match?

Well your example has two definitions, so you'll hit the abort if
protected symbols are working as designed.  :)

Modifying app:
extern int protected_var;
extern void library (int *);

int main ()
{
  library (&protected_var);
  return 0;
}

Now if the app is compiled -fPIE you shouldn't have the .dynbss copy
and no abort, but if the app is non-PIC then yes, pointer comparisons
won't be correct.

HJ has gcc, glibc and ld patches to fix the mess by
a) modifying gcc to emit the same code for protected visibility
variables in shared libraries as default visibility, and
b) modifying ld.so to enforce proper protected semantics, and
c) disabling the linker checks.

They look reasonable to me except there is no provision to deal with
any mismatch in the toolchain components, which is a nasty problem.
For example if you have a new gcc but older glibc then gcc will
generate code that is quite wrong for protected variables.  (It's also
slower since access to a protected variable in a shared library uses a
GOT indirection with HJ's patch.)  Similarly with ld, and note that
current x86_64 ld already has (c) installed, effectively disabling my
pr15228 fix..

-- 
Alan Modra
Australia Development Lab, IBM


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