Message ID | 20160629132411.GA18302@intel.com |
---|---|
State | New |
Headers | show |
On Wed, Jun 29, 2016 at 6:24 AM, H.J. Lu <hongjiu.lu@intel.com> wrote: > 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? If there is no objection by the end of today, I will check it tomorrow. > 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 <<EOF > +__thread int i; > +void foo (void) > +{ > + i = 10; > +} > +EOF > +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -fPIC -mtls-dialect=gnu2 > + conftest.c 1>&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 <<EOF > diff --git a/elf/Makefile b/elf/Makefile > index 210dde9..593403c 100644 > --- a/elf/Makefile > +++ b/elf/Makefile > @@ -224,6 +224,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ > tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \ > tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \ > tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 > +ifeq (yes,$(have-mtls-dialect-gnu2)) > +tests += tst-gnu2-tls1 > +modules-names += tst-gnu2-tls1mod > +$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so > +tst-gnu2-tls1mod.so-no-z-defs = yes > +CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 > +endif > ifeq (yes,$(have-protected-data)) > modules-names += tst-protected1moda tst-protected1modb > tests += tst-protected1a tst-protected1b > diff --git a/elf/tst-gnu2-tls1.c b/elf/tst-gnu2-tls1.c > new file mode 100644 > index 0000000..f55de59 > --- /dev/null > +++ b/elf/tst-gnu2-tls1.c > @@ -0,0 +1,52 @@ > +/* Test local and global dynamic models for GNU2 TLS. > + 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 > + <http://www.gnu.org/licenses/>. */ > + > +#include <stdio.h> > +#include <stdlib.h> > + > +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 > + <http://www.gnu.org/licenses/>. */ > + > +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 > -- > 2.7.4 >
On 11/07/16 16:55, H.J. Lu wrote: > On Wed, Jun 29, 2016 at 6:24 AM, H.J. Lu <hongjiu.lu@intel.com> wrote: >> 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? > > If there is no objection by the end of today, I will check it tomorrow. ... >> +AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, >> +[dnl >> +cat > conftest.c <<EOF >> +__thread int i; >> +void foo (void) >> +{ >> + i = 10; >> +} >> +EOF >> +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -fPIC -mtls-dialect=gnu2 >> + conftest.c 1>&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]) >> + on aarch64 the flag is -mtls-dialect=desc (it's the default dialect though) >> --- a/elf/Makefile >> +++ b/elf/Makefile >> @@ -224,6 +224,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ >> tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \ >> tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \ >> tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 >> +ifeq (yes,$(have-mtls-dialect-gnu2)) >> +tests += tst-gnu2-tls1 >> +modules-names += tst-gnu2-tls1mod >> +$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so >> +tst-gnu2-tls1mod.so-no-z-defs = yes >> +CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 >> +endif so this new test won't run on aarch64. i don't object to the patch, but i think testing with different tls-dialects may eventually need a better approach.
On Mon, Jul 11, 2016 at 9:53 AM, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote: > On 11/07/16 16:55, H.J. Lu wrote: >> On Wed, Jun 29, 2016 at 6:24 AM, H.J. Lu <hongjiu.lu@intel.com> wrote: >>> 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? >> >> If there is no objection by the end of today, I will check it tomorrow. > ... >>> +AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, >>> +[dnl >>> +cat > conftest.c <<EOF >>> +__thread int i; >>> +void foo (void) >>> +{ >>> + i = 10; >>> +} >>> +EOF >>> +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -fPIC -mtls-dialect=gnu2 >>> + conftest.c 1>&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]) >>> + > > on aarch64 the flag is -mtls-dialect=desc > (it's the default dialect though) > >>> --- a/elf/Makefile >>> +++ b/elf/Makefile >>> @@ -224,6 +224,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ >>> tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \ >>> tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \ >>> tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 >>> +ifeq (yes,$(have-mtls-dialect-gnu2)) >>> +tests += tst-gnu2-tls1 >>> +modules-names += tst-gnu2-tls1mod >>> +$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so >>> +tst-gnu2-tls1mod.so-no-z-defs = yes >>> +CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 >>> +endif > > so this new test won't run on aarch64. > > i don't object to the patch, but i think > testing with different tls-dialects may > eventually need a better approach. > I can move -mtls-dialect=gnu2 test to sysdep/x86 if it is x86 specific. Or we can leave it as is and adapt it to different targets later.
On 11/07/16 18:32, H.J. Lu wrote: > I can move -mtls-dialect=gnu2 test to sysdep/x86 if it is x86 specific. > Or we can leave it as is and adapt it to different targets later. > arm also has -mtls-dialect=gnu2 so i think it's fine for now.
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 <<EOF +__thread int i; +void foo (void) +{ + i = 10; +} +EOF +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -fPIC -mtls-dialect=gnu2 + conftest.c 1>&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 <<EOF diff --git a/elf/Makefile b/elf/Makefile index 210dde9..593403c 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -224,6 +224,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \ tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \ tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 +ifeq (yes,$(have-mtls-dialect-gnu2)) +tests += tst-gnu2-tls1 +modules-names += tst-gnu2-tls1mod +$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so +tst-gnu2-tls1mod.so-no-z-defs = yes +CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 +endif ifeq (yes,$(have-protected-data)) modules-names += tst-protected1moda tst-protected1modb tests += tst-protected1a tst-protected1b diff --git a/elf/tst-gnu2-tls1.c b/elf/tst-gnu2-tls1.c new file mode 100644 index 0000000..f55de59 --- /dev/null +++ b/elf/tst-gnu2-tls1.c @@ -0,0 +1,52 @@ +/* Test local and global dynamic models for GNU2 TLS. + 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 + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> + +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 + <http://www.gnu.org/licenses/>. */ + +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