On Mon, Mar 2, 2015 at 5:39 AM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Mon, Mar 2, 2015 at 4:05 AM, Richard Biener > <richard.guent...@gmail.com> wrote: >> On Mon, Mar 2, 2015 at 11:09 AM, Alan Modra <amo...@gmail.com> wrote: >>> 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, > > ^^^^^^^^^^^^ > This is the key here. This optimization makes PIE behave like normal > executable. Is it good or bad? > >>> 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. >> >> Ah, I see (protected visibility has haunted us in the past...). >> >> So I think we need to turn the new option off by default. >>
By turning this optimization on by default, we make PIE behave the same as normal executable and provide a way to change PIE behavior. This is more consistent to users. -- H.J.