Message ID | d95b6a05-624f-02eb-1ffe-ade077cd94e2@redhat.com |
---|---|
State | Not applicable |
Headers |
Received: (qmail 37951 invoked by alias); 27 Jul 2017 16:34:51 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 37927 invoked by uid 89); 27 Jul 2017 16:34:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7103E4483F Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=fweimer@redhat.com Subject: Re: ppc64le: expected localentry:0 `pthread_condattr_destroy' From: Florian Weimer <fweimer@redhat.com> To: Alan Modra <amodra@gmail.com>, Carlos O'Donell <carlos@redhat.com> Cc: Josh Stone <jistone@redhat.com>, libc-alpha@sourceware.org, binutils@sourceware.org References: <00ac3cbe-47f4-ccf0-3017-c1f2ab43db20@redhat.com> <30946d0a-a095-f5cb-bf0b-d3897712cdab@redhat.com> <ef3da09f-5e98-223c-8e77-68c724c12df7@redhat.com> <be439468-44fe-6cf1-0519-d03e50dd8432@redhat.com> <20170727040411.GX14520@bubble.grove.modra.org> <598f4b24-976e-cc28-177c-4e01e8c7467c@redhat.com> Message-ID: <d95b6a05-624f-02eb-1ffe-ade077cd94e2@redhat.com> Date: Thu, 27 Jul 2017 18:34:33 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-Version: 1.0 In-Reply-To: <598f4b24-976e-cc28-177c-4e01e8c7467c@redhat.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit |
Commit Message
Florian Weimer
July 27, 2017, 4:34 p.m. UTC
On 07/27/2017 11:55 AM, Florian Weimer wrote: > On 07/27/2017 06:04 AM, Alan Modra wrote: >>>>> On 07/25/2017 09:11 PM, Josh Stone wrote: >>>>>> ./bin/rustc: error while loading shared libraries: >>>>>> ./lib/libstd-c3a1748e15265da7.so: expected localentry:0 >>>>>> `pthread_condattr_destroy' >> >> You will get this error if the link-time version of a function symbol >> is seen as localentry:0 (ie. not needing a global entry point due to >> not needing a valid r2 toc pointer), but the run-time version does. >> >> The most likely thing is that your library was linked against a stub >> version of pthread_condattr_destroy. Making the stub weak will >> disable the generation of the optimized localentry:0 plt call code. >> So will linking with -Wl,--no-plt-localentry > > The common theme seems to be that this only affects symbols which live > both in libpthread and libc. Do you suggest that we have to make the > implementation in libc a weak symbol? > > Why isn't this a plain regression break ELF symbol interposition? > > I filed a glibc bug for this: > > https://sourceware.org/bugzilla/show_bug.cgi?id=21847 > > I think we need to sort this out before the release. That does not mean > we have to fix it, we just need a better understanding what is going on. I injected -Wl,--no-plt-localentry into the build, using this patch: But the issue persists afterwards. I'm afraid we'll need a real fix. Thanks, Florian
Comments
On Thu, Jul 27, 2017 at 06:34:33PM +0200, Florian Weimer wrote: > On 07/27/2017 11:55 AM, Florian Weimer wrote: > > On 07/27/2017 06:04 AM, Alan Modra wrote: > >>>>> On 07/25/2017 09:11 PM, Josh Stone wrote: > >>>>>> ./bin/rustc: error while loading shared libraries: > >>>>>> ./lib/libstd-c3a1748e15265da7.so: expected localentry:0 > >>>>>> `pthread_condattr_destroy' > >> > >> You will get this error if the link-time version of a function symbol > >> is seen as localentry:0 (ie. not needing a global entry point due to > >> not needing a valid r2 toc pointer), but the run-time version does. > >> > >> The most likely thing is that your library was linked against a stub > >> version of pthread_condattr_destroy. Making the stub weak will > >> disable the generation of the optimized localentry:0 plt call code. > >> So will linking with -Wl,--no-plt-localentry > > > > The common theme seems to be that this only affects symbols which live > > both in libpthread and libc. Do you suggest that we have to make the > > implementation in libc a weak symbol? Right, the stub symbols in libpthread.so should be make weak. See my comment in pr21847. We're getting a mismatch between ld symbol resolution and ld.so resolution. > > Why isn't this a plain regression break ELF symbol interposition? > > > > I filed a glibc bug for this: > > > > https://sourceware.org/bugzilla/show_bug.cgi?id=21847 > > > > I think we need to sort this out before the release. That does not mean > > we have to fix it, we just need a better understanding what is going on. > > I injected -Wl,--no-plt-localentry into the build, using this patch: > > --- a/sysdeps/powerpc/powerpc64le/Makefile > +++ b/sysdeps/powerpc/powerpc64le/Makefile > @@ -6,6 +6,10 @@ > # linked executables, forcing to link the loader after libgcc link. > f128-loader-link = $(as-needed) $(elf-objpfx)ld.so $(no-as-needed) > > +sysdep-LDFLAGS += -Wl,--no-plt-localentry > +# Linking libc_pic.os ignores sysdep-LDFLAGS. > +LDFLAGS-c_pic.os += -Wl,--no-plt-localentry > + > ifeq ($(subdir),math) > # sqrtf128 requires emulation before POWER9. > CPPFLAGS += -I../soft-fp > > But the issue persists afterwards. I'm afraid we'll need a real fix. No, you misunderstood my comment about --no-plt-localentry. The *user* library would need to be built with that option, which isn't a good solution.
On 07/28/2017 12:07 PM, Alan Modra wrote: > No, you misunderstood my comment about --no-plt-localentry. The > *user* library would need to be built with that option, which isn't a > good solution. Could you clarify how this optimization works? Is the following description accurate? At static link time, when processing a relocation to a function, the static link editor looks at the implementation of the called function (which can live in a different DSO). If the current implementation does not use the TOC register, the caller is adjusted to call an optimized PLT stub which does not set the TOC. Otherwise, a full PLT stub which sets the TOC is used. If the link edit chose to apply the optimization, there is no way to go back, and future implementations of the called function must never require a TOC pointer. The dynamic linker cannot recover and thus bails out with the localentry error message. Thanks, Florian
On Fri, Jul 28, 2017 at 02:39:13PM +0200, Florian Weimer wrote: > On 07/28/2017 12:07 PM, Alan Modra wrote: > > No, you misunderstood my comment about --no-plt-localentry. The > > *user* library would need to be built with that option, which isn't a > > good solution. > > Could you clarify how this optimization works? Is the following > description accurate? > > At static link time, when processing a relocation to a function, the > static link editor looks at the implementation of the called function > (which can live in a different DSO). If the current implementation does > not use the TOC register, the caller is adjusted to call an optimized > PLT stub which does not set the TOC. Otherwise, a full PLT stub which > sets the TOC is used. If the link edit chose to apply the optimization, > there is no way to go back, and future implementations of the called > function must never require a TOC pointer. The dynamic linker cannot > recover and thus bails out with the localentry error message. Yes, that's correct. If the linker doesn't see a definition, or if the definition is weak, then the optimization does not apply.
On Jul 28 2017, Alan Modra <amodra@gmail.com> wrote: > On Fri, Jul 28, 2017 at 02:39:13PM +0200, Florian Weimer wrote: >> At static link time, when processing a relocation to a function, the >> static link editor looks at the implementation of the called function >> (which can live in a different DSO). If the current implementation does >> not use the TOC register, the caller is adjusted to call an optimized >> PLT stub which does not set the TOC. Otherwise, a full PLT stub which >> sets the TOC is used. If the link edit chose to apply the optimization, >> there is no way to go back, and future implementations of the called >> function must never require a TOC pointer. The dynamic linker cannot >> recover and thus bails out with the localentry error message. > > Yes, that's correct. If the linker doesn't see a definition, or if > the definition is weak, then the optimization does not apply. That looks like a design bug. The link-time object will almost never exactly match the run-time object. Andreas.
On 07/28/2017 02:52 PM, Alan Modra wrote: > On Fri, Jul 28, 2017 at 02:39:13PM +0200, Florian Weimer wrote: >> On 07/28/2017 12:07 PM, Alan Modra wrote: >>> No, you misunderstood my comment about --no-plt-localentry. The >>> *user* library would need to be built with that option, which isn't a >>> good solution. >> >> Could you clarify how this optimization works? Is the following >> description accurate? >> >> At static link time, when processing a relocation to a function, the >> static link editor looks at the implementation of the called function >> (which can live in a different DSO). If the current implementation does >> not use the TOC register, the caller is adjusted to call an optimized >> PLT stub which does not set the TOC. Otherwise, a full PLT stub which >> sets the TOC is used. If the link edit chose to apply the optimization, >> there is no way to go back, and future implementations of the called >> function must never require a TOC pointer. The dynamic linker cannot >> recover and thus bails out with the localentry error message. > > Yes, that's correct. If the linker doesn't see a definition, or if > the definition is weak, then the optimization does not apply. Ugh. This absolutely has to be disabled by default. No one is prepared for an ABI change because a global variable access has been added to a function (or the compiler has decided to inline a function with a global variable access). In fact, I'm *extremely* reluctant to ship a distribution which as support for this in the link editor and dynamic linker, even as an optional feature, because developers will see this option and use it, without realizing the full consequences (that they lose ABI forward compatibility). The optimization is only possible if it is source-directed, that is, the compiler can take measures to preserve ABI in the presence of implementation changes. This would have to be encoded in the DSO (as a promise “this function will never use the TOC pointer”), and static link editor could pick up that flag and skip setting that TOC. But we can't do that automatically just because the current implementation has some convenient property. Nobody knows if future library upgrades will preserve this property. Thanks, Florian
--- a/sysdeps/powerpc/powerpc64le/Makefile +++ b/sysdeps/powerpc/powerpc64le/Makefile @@ -6,6 +6,10 @@ # linked executables, forcing to link the loader after libgcc link. f128-loader-link = $(as-needed) $(elf-objpfx)ld.so $(no-as-needed) +sysdep-LDFLAGS += -Wl,--no-plt-localentry +# Linking libc_pic.os ignores sysdep-LDFLAGS. +LDFLAGS-c_pic.os += -Wl,--no-plt-localentry + ifeq ($(subdir),math) # sqrtf128 requires emulation before POWER9. CPPFLAGS += -I../soft-fp