On Mon, Mar 02, 2015 at 09:40:01AM +0100, Richard Biener wrote: > On Sat, Feb 28, 2015 at 5:42 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > > Ue copy relocation in PIE improves performance. But copy relocation > > can't be used to access protected symbols defined in shared libaries > > and linker in binutils 2.26 enforces doesn't allow it. GCC doesn't > > know if an external definition is protected or not. This option adds > > -mcopyreloc-in-pie to give user an option to turn it off to avoid problem > > at link-time. OK for trunk? > > I wonder if the linker can fix this up? That is, turn the relocation into > a valid one?
No it can't (*), nor can the dynamic linker. Copy relocs aren't really the issue. They are just a means of initializing a linker generated variable to be used in place of a variable in a shared library. The issue is the linker generated .dynbss variable itself. Consider an ELF executable linked against a shared library, with the executable referencing (but not defining) a variable defined in the shared library. You'd expect that the executable and shared library would both use the same location for the variable. Indeed, that is true. Both executable and shared library use the shared library's variable. Except there is a wrinkle. If the executable is non-PIC, code in the executable will require dynamic text relocations as the variable's address isn't known until run time. To avoid that, some clever person thought: "Why not have the linker define the variable in the executable? ELF run time linking semantics mean the shared library will now use the linker defined copy, so we'll still just be using one copy of the variable". Any everyone was happy. At least until ELF visibility was invented. When ELF visibility comes into play, a variable defined in a shared library with non-default visibility is *not* overridden by another definition in the executable, be it an actual definition or a linker generated one. There is no problem of course if there is an actual definition in the executable. In that case the programmer would expect to see two different variables used. However, if the shared library contains a protected visibility variable, and the linker introduces a copy, then it has changed the meaning of the program. At the source level we only had one definition of the variable, but at run time we'd end up using two different locations. *) Except by avoiding .dynbss copies and hence requiring dynamic text relocations. -- Alan Modra Australia Development Lab, IBM