From patchwork Wed Jun 29 13:24:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lu, Hongjiu" X-Patchwork-Id: 13474 Received: (qmail 48252 invoked by alias); 29 Jun 2016 13:24:54 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 46644 invoked by uid 89); 29 Jun 2016 13:24:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=EOF, eof, 1888, 188, 8 X-HELO: mga09.intel.com X-ExtLoop1: 1 Date: Wed, 29 Jun 2016 06:24:11 -0700 From: "H.J. Lu" To: GNU C Library Subject: [PATCH] [BZ #20309] X86-64: Properly align stack in _dl_tlsdesc_dynamic Message-ID: <20160629132411.GA18302@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.6.1 (2016-04-27) Since _dl_tlsdesc_dynamic is called via PLT, we need to add 8 bytes for for push in the PLT entry to align the stack. Tested on i686 and x86-64. OK for trunk? H.J. --- [BZ #20309] * configure.ac (have-mtls-dialect-gnu2): Set to yes if -mtls-dialect=gnu2 works. * configure: Regenerated. * elf/Makefile [have-mtls-dialect-gnu2 = yes] (tests): Add tst-gnu2-tls1. (modules-names): Add tst-gnu2-tls1mod. ($(objpfx)tst-gnu2-tls1): New. (tst-gnu2-tls1mod.so-no-z-defs): Likewise. (CFLAGS-tst-gnu2-tls1mod.c): Likewise. * elf/tst-gnu2-tls1.c: New file. * elf/tst-gnu2-tls1mod.c: Likewise. * sysdeps/x86_64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Add 8 bytes for push in the PLT entry to align the stack. --- configure | 33 ++++++++++++++++++++++++++ configure.ac | 20 ++++++++++++++++ elf/Makefile | 7 ++++++ elf/tst-gnu2-tls1.c | 52 +++++++++++++++++++++++++++++++++++++++++ elf/tst-gnu2-tls1mod.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ sysdeps/x86_64/dl-tlsdesc.S | 13 ++++++----- 6 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 elf/tst-gnu2-tls1.c create mode 100644 elf/tst-gnu2-tls1mod.c diff --git a/configure.ac b/configure.ac index 123f0d2..33bcd62 100644 --- a/configure.ac +++ b/configure.ac @@ -1412,6 +1412,26 @@ elif test "$libc_cv_ssp" = "yes"; then fi AC_SUBST(stack_protector) +AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, +[dnl +cat > conftest.c <&AS_MESSAGE_LOG_FD]) +then + libc_cv_mtls_dialect_gnu2=yes +else + libc_cv_mtls_dialect_gnu2=no +fi +rm -f conftest*]) +AC_SUBST(libc_cv_mtls_dialect_gnu2) +LIBC_CONFIG_VAR([have-mtls-dialect-gnu2], [$libc_cv_mtls_dialect_gnu2]) + AC_CACHE_CHECK(whether cc puts quotes around section names, libc_cv_have_section_quotes, [cat > conftest.c <. */ + +#include +#include + +extern int * get_gd (void); +extern void set_gd (int); +extern int test_gd (int); +extern int * get_ld (void); +extern void set_ld (int); +extern int test_ld (int); + +__thread int gd = 1; + +static int +do_test (void) +{ + int *p; + + p = get_gd (); + set_gd (3); + if (*p != 3 || !test_gd (3)) + abort (); + + p = get_ld (); + set_ld (4); + if (*p != 4 || !test_ld (4)) + abort (); + + printf ("PASS\n"); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/elf/tst-gnu2-tls1mod.c b/elf/tst-gnu2-tls1mod.c new file mode 100644 index 0000000..45c4816 --- /dev/null +++ b/elf/tst-gnu2-tls1mod.c @@ -0,0 +1,56 @@ +/* DSO used by tst-gnu2-tls1. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +static __thread int ld; + +int * +get_ld (void) +{ + return &ld; +} + +void +set_ld (int i) +{ + ld = i; +} + +int +test_ld (int i) +{ + return ld == i; +} +extern __thread int gd; + +int * +get_gd (void) +{ + return &gd; +} + +void +set_gd (int i) +{ + gd = i; +} + +int +test_gd (int i) +{ + return gd == i; +} diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S index 3cb7c3d..777f30b 100644 --- a/sysdeps/x86_64/dl-tlsdesc.S +++ b/sysdeps/x86_64/dl-tlsdesc.S @@ -163,14 +163,15 @@ _dl_tlsdesc_dynamic: /* The PLT entry will have pushed the link_map pointer. */ _dl_tlsdesc_resolve_rela: cfi_adjust_cfa_offset (8) - /* Save all call-clobbered registers. */ - subq $72, %rsp - cfi_adjust_cfa_offset (72) + /* Save all call-clobbered registers. Add 8 bytes for push in + the PLT entry to align the stack. */ + subq $80, %rsp + cfi_adjust_cfa_offset (80) movq %rax, (%rsp) movq %rdi, 8(%rsp) movq %rax, %rdi /* Pass tlsdesc* in %rdi. */ movq %rsi, 16(%rsp) - movq 72(%rsp), %rsi /* Pass link_map* in %rsi. */ + movq 80(%rsp), %rsi /* Pass link_map* in %rsi. */ movq %r8, 24(%rsp) movq %r9, 32(%rsp) movq %r10, 40(%rsp) @@ -187,8 +188,8 @@ _dl_tlsdesc_resolve_rela: movq 48(%rsp), %r11 movq 56(%rsp), %rdx movq 64(%rsp), %rcx - addq $80, %rsp - cfi_adjust_cfa_offset (-80) + addq $88, %rsp + cfi_adjust_cfa_offset (-88) jmp *(%rax) cfi_endproc .size _dl_tlsdesc_resolve_rela, .-_dl_tlsdesc_resolve_rela