Message ID | 20140514203250.GK26038@redacted.bos.redhat.com |
---|---|
State | Superseded |
Headers |
Return-Path: <x14307373@homiemail-mx23.g.dreamhost.com> X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx23.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 234F436007B for <siddhesh@wilcox.dreamhost.com>; Wed, 14 May 2014 13:33:00 -0700 (PDT) Received: by homiemail-mx23.g.dreamhost.com (Postfix, from userid 14307373) id AB8CA63ABAB56; Wed, 14 May 2014 13:32:59 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx23.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx23.g.dreamhost.com (Postfix) with ESMTPS id 7C4E663ABAB50 for <glibc@patchwork.siddhesh.in>; Wed, 14 May 2014 13:32:59 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; q=dns; s=default; b=LXFtVk9paT7J3S0hQz4BvTnqlkIbF mpE2n5A7K7D/wVr41mE0jy0uSz09PHL3FthC7DAFtACSZztkceKuuU1lyHtTnO3B 6MiuUO470n3hexyIyEJMyqRiiM8Tezo6Br6ONDFXR9BuLw380U8IDNvs2FJ64VfW ApGcaYnD1uTFc8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; s=default; bh=dAJIz/JeBAdwmPSVHZLYqjNrV+E=; b=kQq UmMIZLSRwiwC30owf4ZpGKJPtQV85xb+9lb3ntlODzq2uxgJ0QoCKSjNkHQIwmLR DkPjIE9euaocM0Kya/WDlcTmGEGUU2rLzbCICnY0lVBI9vluw26m/hICzFekn9Ss K7JBc7MZWQvrTgw2kNNUgESMc1/q3pUpYFHuaI70= Received: (qmail 13992 invoked by alias); 14 May 2014 20:32:57 -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-glibc=patchwork.siddhesh.in@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 13979 invoked by uid 89); 14 May 2014 20:32:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Date: Wed, 14 May 2014 16:32:51 -0400 From: Kyle McMartin <kmcmarti@redhat.com> To: libc-alpha@sourceware.org Subject: [PATCH] fix static TLS consumption by TLS descriptors Message-ID: <20140514203250.GK26038@redacted.bos.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-DH-Original-To: glibc@patchwork.siddhesh.in |
Commit Message
Kyle McMartin
May 14, 2014, 8:32 p.m. UTC
AArch64 presently defaults to use TLS descriptors, as opposed to traditional dynamic TLS relocations, and has hit a bug in the copy-pasta used in elf_machine_rel{,a} for all TLS descriptor implementations. When a program calls dlopen() with R_AARCH64_TLSDESC relocs, we're consuming static TLS until it's exhausted (presumably as an optimisation.) However, this means that once our static TLS space is consumed, attempting to dlopen() any shared object which contain an R_AARCH64_TPREL reloc will fail, since we've exhausted all the space. Instead, always use dynamic TLS for TLS descriptors, which lets us load arbitrarily many proper dynamic TLS using shared objects, and allow the static TLS fallback only in the non-SHARED case. This issue is reproducible on x86_64, by specifying -ftls-dialect=gnu2 when building with gcc. I've written a test for this: https://github.com/jkkm/test-tls_desc.git Tweak DIALECT to be appropriate, and run ./test-tls_desc.sh, ./main and it should fail with: % ./test-tls_desc.sh; ./main ./tmp16.so: cannot allocate memory in static TLS block ./test-tls_desc.sh: line 18: 10141 Aborted (core dumped) ./main 2014-05-14 Kyle McMartin <kyle@redhat.com> * sysdeps/aarch64/dl-machine.h (elf_machine_rela): always allocate dynamic TLS space for TLS descriptors. * sysdeps/x86_64/dl-machine.h (elf_machine_rela): ditto. * sysdeps/arm/dl-machine.h (elf_machine_rel): ditto. * sysdeps/i386/dl-machine.h (elf_machine_rel): ditto.
Comments
On 14 May 2014 21:32, Kyle McMartin <kmcmarti@redhat.com> wrote: > AArch64 presently defaults to use TLS descriptors, as opposed to > traditional dynamic TLS relocations, and has hit a bug in the copy-pasta > used in elf_machine_rel{,a} for all TLS descriptor implementations. When > a program calls dlopen() with R_AARCH64_TLSDESC relocs, we're consuming > static TLS until it's exhausted (presumably as an optimisation.) > However, this means that once our static TLS space is consumed, > attempting to dlopen() any shared object which contain an > R_AARCH64_TPREL reloc will fail, since we've exhausted all the space. > > Instead, always use dynamic TLS for TLS descriptors, which lets us load > arbitrarily many proper dynamic TLS using shared objects, and allow the > static TLS fallback only in the non-SHARED case. > > This issue is reproducible on x86_64, by specifying -ftls-dialect=gnu2 > when building with gcc. I've written a test for this: > https://github.com/jkkm/test-tls_desc.git > Tweak DIALECT to be appropriate, and run ./test-tls_desc.sh, ./main > and it should fail with: > % ./test-tls_desc.sh; ./main > ./tmp16.so: cannot allocate memory in static TLS block > ./test-tls_desc.sh: line 18: 10141 Aborted (core dumped) ./main > > 2014-05-14 Kyle McMartin <kyle@redhat.com> > > * sysdeps/aarch64/dl-machine.h (elf_machine_rela): always > allocate dynamic TLS space for TLS descriptors. > * sysdeps/x86_64/dl-machine.h (elf_machine_rela): ditto. > * sysdeps/arm/dl-machine.h (elf_machine_rel): ditto. > * sysdeps/i386/dl-machine.h (elf_machine_rel): ditto. ChangeLog entries should be sentences, so start with a capital letter. > --- a/sysdeps/aarch64/dl-machine.h > +++ b/sysdeps/aarch64/dl-machine.h > @@ -295,13 +295,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->arg = _dl_make_tlsdesc_dynamic > (sym_map, sym->st_value + reloc->r_addend); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > #endif > { > diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h > index 899b256..dcb2127 100644 > --- a/sysdeps/arm/dl-machine.h > +++ b/sysdeps/arm/dl-machine.h > @@ -458,13 +458,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->argument.pointer > = _dl_make_tlsdesc_dynamic (sym_map, value); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > # endif > { > diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h > index 368bee2..64cf74c 100644 > --- a/sysdeps/i386/dl-machine.h > +++ b/sysdeps/i386/dl-machine.h > @@ -394,13 +394,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->arg = _dl_make_tlsdesc_dynamic > (sym_map, sym->st_value + (ElfW(Word))td->arg); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > # endif > { > diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h > index 8df04a9..67e98d1 100644 > --- a/sysdeps/x86_64/dl-machine.h > +++ b/sysdeps/x86_64/dl-machine.h > @@ -359,13 +359,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->arg = _dl_make_tlsdesc_dynamic > (sym_map, sym->st_value + reloc->r_addend); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > # endif > {
On Wed, May 14, 2014 at 1:33 PM Kyle McMartin <kmcmarti@redhat.com> wrote: > > AArch64 presently defaults to use TLS descriptors, as opposed to > traditional dynamic TLS relocations, and has hit a bug in the copy-pasta > used in elf_machine_rel{,a} for all TLS descriptor implementations. When > a program calls dlopen() with R_AARCH64_TLSDESC relocs, we're consuming > static TLS until it's exhausted (presumably as an optimisation.) > However, this means that once our static TLS space is consumed, > attempting to dlopen() any shared object which contain an > R_AARCH64_TPREL reloc will fail, since we've exhausted all the space. > > Instead, always use dynamic TLS for TLS descriptors, which lets us load > arbitrarily many proper dynamic TLS using shared objects, and allow the > static TLS fallback only in the non-SHARED case. > > This issue is reproducible on x86_64, by specifying -ftls-dialect=gnu2 > when building with gcc. I've written a test for this: > https://github.com/jkkm/test-tls_desc.git > Tweak DIALECT to be appropriate, and run ./test-tls_desc.sh, ./main > and it should fail with: > % ./test-tls_desc.sh; ./main > ./tmp16.so: cannot allocate memory in static TLS block > ./test-tls_desc.sh: line 18: 10141 Aborted (core dumped) ./main This or a variant of this patch never went in it seems and VPP folks had run into this similar thing: https://jira.fd.io/browse/VPP-1284 Thanks, Andrew Pinski > > 2014-05-14 Kyle McMartin <kyle@redhat.com> > > * sysdeps/aarch64/dl-machine.h (elf_machine_rela): always > allocate dynamic TLS space for TLS descriptors. > * sysdeps/x86_64/dl-machine.h (elf_machine_rela): ditto. > * sysdeps/arm/dl-machine.h (elf_machine_rel): ditto. > * sysdeps/i386/dl-machine.h (elf_machine_rel): ditto. > > --- a/sysdeps/aarch64/dl-machine.h > +++ b/sysdeps/aarch64/dl-machine.h > @@ -295,13 +295,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->arg = _dl_make_tlsdesc_dynamic > (sym_map, sym->st_value + reloc->r_addend); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > #endif > { > diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h > index 899b256..dcb2127 100644 > --- a/sysdeps/arm/dl-machine.h > +++ b/sysdeps/arm/dl-machine.h > @@ -458,13 +458,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->argument.pointer > = _dl_make_tlsdesc_dynamic (sym_map, value); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > # endif > { > diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h > index 368bee2..64cf74c 100644 > --- a/sysdeps/i386/dl-machine.h > +++ b/sysdeps/i386/dl-machine.h > @@ -394,13 +394,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->arg = _dl_make_tlsdesc_dynamic > (sym_map, sym->st_value + (ElfW(Word))td->arg); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > # endif > { > diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h > index 8df04a9..67e98d1 100644 > --- a/sysdeps/x86_64/dl-machine.h > +++ b/sysdeps/x86_64/dl-machine.h > @@ -359,13 +359,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, > # ifndef SHARED > CHECK_STATIC_TLS (map, sym_map); > # else > - if (!TRY_STATIC_TLS (map, sym_map)) > { > td->arg = _dl_make_tlsdesc_dynamic > (sym_map, sym->st_value + reloc->r_addend); > td->entry = _dl_tlsdesc_dynamic; > } > - else > + if (0) > # endif > # endif > {
* Andrew Pinski via Libc-alpha: > On Wed, May 14, 2014 at 1:33 PM Kyle McMartin <kmcmarti@redhat.com> wrote: >> >> AArch64 presently defaults to use TLS descriptors, as opposed to >> traditional dynamic TLS relocations, and has hit a bug in the copy-pasta >> used in elf_machine_rel{,a} for all TLS descriptor implementations. When >> a program calls dlopen() with R_AARCH64_TLSDESC relocs, we're consuming >> static TLS until it's exhausted (presumably as an optimisation.) >> However, this means that once our static TLS space is consumed, >> attempting to dlopen() any shared object which contain an >> R_AARCH64_TPREL reloc will fail, since we've exhausted all the space. >> >> Instead, always use dynamic TLS for TLS descriptors, which lets us load >> arbitrarily many proper dynamic TLS using shared objects, and allow the >> static TLS fallback only in the non-SHARED case. >> >> This issue is reproducible on x86_64, by specifying -ftls-dialect=gnu2 >> when building with gcc. I've written a test for this: >> https://github.com/jkkm/test-tls_desc.git >> Tweak DIALECT to be appropriate, and run ./test-tls_desc.sh, ./main >> and it should fail with: >> % ./test-tls_desc.sh; ./main >> ./tmp16.so: cannot allocate memory in static TLS block >> ./test-tls_desc.sh: line 18: 10141 Aborted (core dumped) ./main > > This or a variant of this patch never went in it seems and VPP folks > had run into this similar thing: > https://jira.fd.io/browse/VPP-1284 There isn't really enough information in the JIRA ticket. It could also be the race fixed in: commit b7cf203b5c17dd6d9878537d41e0c7cc3d270a67 Author: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Wed Sep 27 16:55:14 2017 +0100 aarch64: Disable lazy symbol binding of TLSDESC The allocation issue should be fixed in: commit ffb17e7ba3a5ba9632cee97330b325072fbe41dd Author: Szabolcs Nagy <szabolcs.nagy@arm.com> Date: Wed Jun 10 13:40:40 2020 +0100 rtld: Avoid using up static TLS surplus for optimizations [BZ #25051] Thanks, Florian
--- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -295,13 +295,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, # ifndef SHARED CHECK_STATIC_TLS (map, sym_map); # else - if (!TRY_STATIC_TLS (map, sym_map)) { td->arg = _dl_make_tlsdesc_dynamic (sym_map, sym->st_value + reloc->r_addend); td->entry = _dl_tlsdesc_dynamic; } - else + if (0) # endif #endif { diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index 899b256..dcb2127 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -458,13 +458,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, # ifndef SHARED CHECK_STATIC_TLS (map, sym_map); # else - if (!TRY_STATIC_TLS (map, sym_map)) { td->argument.pointer = _dl_make_tlsdesc_dynamic (sym_map, value); td->entry = _dl_tlsdesc_dynamic; } - else + if (0) # endif # endif { diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 368bee2..64cf74c 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -394,13 +394,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, # ifndef SHARED CHECK_STATIC_TLS (map, sym_map); # else - if (!TRY_STATIC_TLS (map, sym_map)) { td->arg = _dl_make_tlsdesc_dynamic (sym_map, sym->st_value + (ElfW(Word))td->arg); td->entry = _dl_tlsdesc_dynamic; } - else + if (0) # endif # endif { diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index 8df04a9..67e98d1 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -359,13 +359,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, # ifndef SHARED CHECK_STATIC_TLS (map, sym_map); # else - if (!TRY_STATIC_TLS (map, sym_map)) { td->arg = _dl_make_tlsdesc_dynamic (sym_map, sym->st_value + reloc->r_addend); td->entry = _dl_tlsdesc_dynamic; } - else + if (0) # endif # endif {