Message ID | 20200110222743.79551-2-tuliom@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | [1/2] powerpc: Initialize rtld_global_ro for static dlopen [BZ #20802] | expand |
On 1/10/20 5:27 PM, Tulio Magno Quites Machado Filho wrote: > Changes since v1: > - Updated copyright dates > - Added tests > - Fixed coding style issues > - Added macros __GLRO_DEF and __GLRO in the 64-bit case. > - Removed sysdeps/unix/sysv/linux/powerpc/dl-support.c in favor of > sysdeps/generic/dl-auxv.h which is included by elf/dl-support.c and > elf/dl-sysdep.c > - Removed sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c > OK for master. This is probably the smallest change you can make to fix all of this up. This needs approval again by Siddhesh. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > ----8<---- > > GCC 10.0 enabled -fno-common by default and this started to point that > __cache_line_size had been implemented in 2 different places: loader and > libc. > > In order to avoid this duplication, the libc variable has been removed > and the loader variable is moved to rtld_global_ro. > > File sysdeps/unix/sysv/linux/powerpc/dl-auxv.h has been added in order > to reuse code for both static and dynamic linking scenarios. > --- > elf/dl-support.c | 3 +- > elf/dl-sysdep.c | 3 +- > sysdeps/generic/dl-auxv.h | 21 ++++++++ > sysdeps/powerpc/Makefile | 17 ++++++ > sysdeps/powerpc/dl-procinfo.c | 17 ++++++ > sysdeps/powerpc/mod-cache-ppc.c | 45 ++++++++++++++++ > sysdeps/powerpc/powerpc32/a2/memcpy.S | 23 ++++---- > sysdeps/powerpc/powerpc32/dl-machine.c | 11 ++-- > sysdeps/powerpc/powerpc32/memset.S | 29 +++++----- > sysdeps/powerpc/powerpc32/sysdep.h | 26 +++++++++ > sysdeps/powerpc/powerpc64/a2/memcpy.S | 13 +++-- > sysdeps/powerpc/powerpc64/memset.S | 11 ++-- > sysdeps/powerpc/powerpc64/sysdep.h | 24 +++++++++ > sysdeps/powerpc/rtld-global-offsets.sym | 1 + > sysdeps/powerpc/tst-cache-ppc-static-dlopen.c | 54 +++++++++++++++++++ > sysdeps/powerpc/tst-cache-ppc-static.c | 20 +++++++ > sysdeps/powerpc/tst-cache-ppc.c | 29 ++++++++++ > .../linux/powerpc/{dl-sysdep.c => dl-auxv.h} | 19 +++---- > sysdeps/unix/sysv/linux/powerpc/dl-static.c | 3 ++ > sysdeps/unix/sysv/linux/powerpc/libc-start.c | 10 ++-- > 20 files changed, 312 insertions(+), 67 deletions(-) > create mode 100644 sysdeps/generic/dl-auxv.h > create mode 100644 sysdeps/powerpc/mod-cache-ppc.c > create mode 100644 sysdeps/powerpc/tst-cache-ppc-static-dlopen.c > create mode 100644 sysdeps/powerpc/tst-cache-ppc-static.c > create mode 100644 sysdeps/powerpc/tst-cache-ppc.c > rename sysdeps/unix/sysv/linux/powerpc/{dl-sysdep.c => dl-auxv.h} (60%) > > diff --git a/elf/dl-support.c b/elf/dl-support.c > index ad791ab6ab..7704c101c5 100644 > --- a/elf/dl-support.c > +++ b/elf/dl-support.c > @@ -36,6 +36,7 @@ > #include <stackinfo.h> > #include <dl-vdso.h> > #include <dl-vdso-setup.h> > +#include <dl-auxv.h> OK. > > extern char *__progname; > char **_dl_argv = &__progname; /* This is checked for some error messages. */ > @@ -293,9 +294,7 @@ _dl_aux_init (ElfW(auxv_t) *av) > case AT_RANDOM: > _dl_random = (void *) av->a_un.a_val; > break; > -# ifdef DL_PLATFORM_AUXV > DL_PLATFORM_AUXV > -# endif OK. Because DL_PLATFORM_AUXV is always defined now. > } > if (seen == 0xf) > { > diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c > index 53bbee14f4..854570821c 100644 > --- a/elf/dl-sysdep.c > +++ b/elf/dl-sysdep.c > @@ -45,6 +45,7 @@ > #include <tls.h> > > #include <dl-tunables.h> > +#include <dl-auxv.h> OK. > > extern char **_environ attribute_hidden; > extern char _end[] attribute_hidden; > @@ -180,9 +181,7 @@ _dl_sysdep_start (void **start_argptr, > case AT_RANDOM: > _dl_random = (void *) av->a_un.a_val; > break; > -#ifdef DL_PLATFORM_AUXV > DL_PLATFORM_AUXV > -#endif OK. Because DL_PLATFORM_AUXV is always defined now. > } > > #ifndef HAVE_AUX_SECURE > diff --git a/sysdeps/generic/dl-auxv.h b/sysdeps/generic/dl-auxv.h > new file mode 100644 > index 0000000000..bf3c01182e > --- /dev/null > +++ b/sysdeps/generic/dl-auxv.h > @@ -0,0 +1,21 @@ > +/* Auxiliary vector processing. Generic version. > + Copyright (C) 2020 Free Software Foundation, Inc. OK. > + 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 > + <https://www.gnu.org/licenses/>. */ > + > +/* Define DL_PLATFORM_AUXV in order to process platform-specific AUXV entries > + during the initialization of the loader or of a static libc. */ > +#define DL_PLATFORM_AUXV OK. Default version does nothing. > diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile > index df45d348d2..d1c71a0ca4 100644 > --- a/sysdeps/powerpc/Makefile > +++ b/sysdeps/powerpc/Makefile > @@ -14,6 +14,23 @@ mod-tlsopt-powerpc.so-no-z-defs = yes > tests += tst-tlsopt-powerpc > $(objpfx)tst-tlsopt-powerpc: $(objpfx)mod-tlsopt-powerpc.so > > +tests-static += tst-cache-ppc-static > +tests-internal += tst-cache-ppc-static OK. Add one test. > + > +ifeq (yes,$(build-shared)) > +modules-names += mod-cache-ppc > +tests += tst-cache-ppc tst-cache-ppc-static-dlopen > +tests-static += tst-cache-ppc-static-dlopen > +test-internal-extras += mod-cache-ppc > + > +mod-cache-ppc.so-no-z-defs = yes > +tst-cache-ppc-static-dlopen-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf > +$(objpfx)tst-cache-ppc-static-dlopen: $(common-objpfx)dlfcn/libdl.a > +$(objpfx)tst-cache-ppc-static-dlopen.out: $(objpfx)mod-cache-ppc.so > + > +$(objpfx)tst-cache-ppc: $(objpfx)mod-cache-ppc.so > +endif OK. Add two tests and modules. > + > ifneq (no,$(multi-arch)) > tests-static += tst-tlsifunc-static > tests-internal += tst-tlsifunc-static > diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c > index 2ae68c41f1..7a7d93dd0a 100644 > --- a/sysdeps/powerpc/dl-procinfo.c > +++ b/sysdeps/powerpc/dl-procinfo.c > @@ -89,5 +89,22 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][15] > , > #endif > > +#if !IS_IN (ldconfig) > +# if !defined PROCINFO_DECL && defined SHARED > + ._dl_cache_line_size OK. Define cache line size. > +# else > +PROCINFO_CLASS int _dl_cache_line_size > +# endif > +# ifndef PROCINFO_DECL > + = 0 > +# endif > +# if !defined SHARED || defined PROCINFO_DECL > +; > +# else > +, > +# endif > +#endif > + > + > #undef PROCINFO_DECL > #undef PROCINFO_CLASS > diff --git a/sysdeps/powerpc/mod-cache-ppc.c b/sysdeps/powerpc/mod-cache-ppc.c > new file mode 100644 > index 0000000000..81fad52078 > --- /dev/null > +++ b/sysdeps/powerpc/mod-cache-ppc.c > @@ -0,0 +1,45 @@ > +/* Test if an executable can read from rtld_global_ro._dl_cache_line_size. > + Copyright (C) 2020 Free Software Foundation, Inc. OK. > + 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <stdio.h> > +#include <stdint.h> > +#include <inttypes.h> > +#include <sys/auxv.h> > +#include <ldsodefs.h> > +#include <errno.h> > + > +/* errnop is required in order to work around BZ #20802. */ > +int > +test_cache (int *errnop) > +{ > + int cls1 = GLRO (dl_cache_line_size); OK. > + errno = *errnop; > + uint64_t cls2 = getauxval (AT_DCACHEBSIZE); OK. > + *errnop = errno; OK. Copy back errno. > + > + printf ("AT_DCACHEBSIZE = %" PRIu64 " B\n", cls2); > + printf ("_dl_cache_line_size = %d B\n", cls1); > + > + if (cls1 != cls2) > + { > + printf ("error: _dl_cache_line_size != AT_DCACHEBSIZE\n"); > + return 1; > + } > + > + return 0; > +} > diff --git a/sysdeps/powerpc/powerpc32/a2/memcpy.S b/sysdeps/powerpc/powerpc32/a2/memcpy.S > index fe5dab847a..6f4d8a7b34 100644 > --- a/sysdeps/powerpc/powerpc32/a2/memcpy.S > +++ b/sysdeps/powerpc/powerpc32/a2/memcpy.S > @@ -18,6 +18,7 @@ > <https://www.gnu.org/licenses/>. */ > > #include <sysdep.h> > +#include <rtld-global-offsets.h> OK. > > #define PREFETCH_AHEAD 4 /* no cache lines SRC prefetching ahead */ > #define ZERO_AHEAD 2 /* no cache lines DST zeroing ahead */ > @@ -106,25 +107,23 @@ EALIGN (memcpy, 5, 0) > L(dst_aligned): > > > -#ifdef SHARED > +#ifdef PIC > mflr r0 > -/* Establishes GOT addressability so we can load __cache_line_size > - from static. This value was set from the aux vector during startup. */ > +/* Establishes GOT addressability so we can load the cache line size > + from rtld_global_ro. This value was set from the aux vector during > + startup. */ OK. > SETUP_GOT_ACCESS(r9,got_label) > - addis r9,r9,__cache_line_size-got_label@ha > - lwz r9,__cache_line_size-got_label@l(r9) > - mtlr r0 > -#else > -/* Load __cache_line_size from static. This value was set from the > - aux vector during startup. */ > - lis r9,__cache_line_size@ha > - lwz r9,__cache_line_size@l(r9) > + addis r9,r9,_GLOBAL_OFFSET_TABLE_-got_label@ha > + addi r9,r9,_GLOBAL_OFFSET_TABLE_-got_label@l > + mtlr r0 OK. > #endif > + __GLRO(r9, r9, _dl_cache_line_size, > + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) OK. > > cmplwi cr5, r9, 0 > bne+ cr5,L(cachelineset) > > -/* __cache_line_size not set: generic byte copy without much optimization */ > +/* Cache line size not set: generic byte copy without much optimization */ OK. > andi. r0,r5,1 /* If length is odd copy one byte. */ > beq L(cachelinenotset_align) > lbz r7,0(r4) /* Read one byte from source. */ > diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c > index d5ea4b97f4..6090e60d3c 100644 > --- a/sysdeps/powerpc/powerpc32/dl-machine.c > +++ b/sysdeps/powerpc/powerpc32/dl-machine.c > @@ -25,11 +25,6 @@ > #include <dl-machine.h> > #include <_itoa.h> > > -/* The value __cache_line_size is defined in dl-sysdep.c and is initialised > - by _dl_sysdep_start via DL_PLATFORM_INIT. */ > -extern int __cache_line_size attribute_hidden; OK. Remove the use of __cache_line_size. > - > - > /* Stuff for the PLT. */ > #define PLT_INITIAL_ENTRY_WORDS 18 > #define PLT_LONGBRANCH_ENTRY_WORDS 0 > @@ -309,14 +304,14 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile) > > Assumes that dcbst and icbi apply to lines of 16 bytes or > more. Current known line sizes are 16, 32, and 128 bytes. > - The following gets the __cache_line_size, when available. */ > + The following gets the cache line size, when available. */ OK. > > /* Default minimum 4 words per cache line. */ > int line_size_words = 4; > > - if (lazy && __cache_line_size != 0) > + if (lazy && GLRO(dl_cache_line_size) != 0) OK. > /* Convert bytes to words. */ > - line_size_words = __cache_line_size / 4; > + line_size_words = GLRO(dl_cache_line_size) / 4; OK. > > size_modified = lazy ? rel_offset_words : 6; > for (i = 0; i < size_modified; i += line_size_words) > diff --git a/sysdeps/powerpc/powerpc32/memset.S b/sysdeps/powerpc/powerpc32/memset.S > index 5f614c07d7..26c37f8a17 100644 > --- a/sysdeps/powerpc/powerpc32/memset.S > +++ b/sysdeps/powerpc/powerpc32/memset.S > @@ -17,12 +17,13 @@ > <https://www.gnu.org/licenses/>. */ > > #include <sysdep.h> > +#include <rtld-global-offsets.h> OK. > > /* void * [r3] memset (void *s [r3], int c [r4], size_t n [r5])); > Returns 's'. > > The memset is done in four sizes: byte (8 bits), word (32 bits), > - 32-byte blocks (256 bits) and __cache_line_size (128, 256, 1024 bits). > + 32-byte blocks (256 bits) and cache line size (128, 256, 1024 bits). OK. > There is a special case for setting whole cache lines to 0, which > takes advantage of the dcbz instruction. */ > > @@ -95,7 +96,7 @@ L(caligned): > > /* Check if we can use the special case for clearing memory using dcbz. > This requires that we know the correct cache line size for this > - processor. Getting the __cache_line_size may require establishing GOT > + processor. Getting the cache line size may require establishing GOT OK. > addressability, so branch out of line to set this up. */ > beq cr1, L(checklinesize) > > @@ -230,26 +231,22 @@ L(medium_28t): > blr > > L(checklinesize): > -#ifdef SHARED > - mflr rTMP > /* If the remaining length is less the 32 bytes then don't bother getting > the cache line size. */ > beq L(medium) > -/* Establishes GOT addressability so we can load __cache_line_size > - from static. This value was set from the aux vector during startup. */ > +#ifdef PIC > + mflr rTMP > +/* Establishes GOT addressability so we can load the cache line size > + from rtld_global_ro. This value was set from the aux vector during > + startup. */ > SETUP_GOT_ACCESS(rGOT,got_label) > - addis rGOT,rGOT,__cache_line_size-got_label@ha > - lwz rCLS,__cache_line_size-got_label@l(rGOT) > + addis rGOT,rGOT,_GLOBAL_OFFSET_TABLE_-got_label@ha > + addi rGOT,rGOT,_GLOBAL_OFFSET_TABLE_-got_label@l OK. > mtlr rTMP > -#else > -/* Load __cache_line_size from static. This value was set from the > - aux vector during startup. */ > - lis rCLS,__cache_line_size@ha > -/* If the remaining length is less the 32 bytes then don't bother getting > - the cache line size. */ > - beq L(medium) > - lwz rCLS,__cache_line_size@l(rCLS) > #endif > +/* Load rtld_global_ro._dl_cache_line_size. */ > + __GLRO(rCLS, rGOT, _dl_cache_line_size, > + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) OK. > > /* If the cache line size was not set then goto to L(nondcbz), which is > safe for any cache line size. */ > diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h > index ceed9ef158..0dee5f2757 100644 > --- a/sysdeps/powerpc/powerpc32/sysdep.h > +++ b/sysdeps/powerpc/powerpc32/sysdep.h > @@ -157,4 +157,30 @@ GOT_LABEL: ; \ > /* Label in text section. */ > #define C_TEXT(name) name > > +/* Read the value of member from rtld_global_ro. */ > +#ifdef PIC > +# ifdef SHARED > +# if IS_IN (rtld) > +/* Inside ld.so we use the local alias to avoid runtime GOT > + relocations. */ > +# define __GLRO(rOUT, rGOT, member, offset) \ > + lwz rOUT,_rtld_local_ro@got(rGOT); \ > + lwz rOUT,offset(rOUT) OK. Within rtld use local. > +# else > +# define __GLRO(rOUT, rGOT, member, offset) \ > + lwz rOUT,_rtld_global_ro@got(rGOT); \ > + lwz rOUT,offset(rOUT) OK. > +# endif > +# else > +# define __GLRO(rOUT, rGOT, member, offset) \ > + lwz rOUT,member@got(rGOT); \ > + lwz rOUT,0(rOUT) OK. > +# endif > +#else > +/* Position-dependent code does not require access to the GOT. */ > +# define __GLRO(rOUT, rGOT, member, offset) \ > + lis rOUT,(member+LOWORD)@ha \ > + lwz rOUT,(member+LOWORD)@l(rOUT) OK. > +#endif /* PIC */ > + > #endif /* __ASSEMBLER__ */ > diff --git a/sysdeps/powerpc/powerpc64/a2/memcpy.S b/sysdeps/powerpc/powerpc64/a2/memcpy.S > index 0e3c435f3c..1162cc2207 100644 > --- a/sysdeps/powerpc/powerpc64/a2/memcpy.S > +++ b/sysdeps/powerpc/powerpc64/a2/memcpy.S > @@ -18,6 +18,7 @@ > <https://www.gnu.org/licenses/>. */ > > #include <sysdep.h> > +#include <rtld-global-offsets.h> OK. > > #ifndef MEMCPY > # define MEMCPY memcpy > @@ -27,8 +28,9 @@ > #define ZERO_AHEAD 2 /* no cache lines DST zeroing ahead */ > > .section ".toc","aw" > -.LC0: > - .tc __cache_line_size[TC],__cache_line_size > +__GLRO_DEF(dl_cache_line_size) > + > + OK. > .section ".text" > .align 2 > > @@ -55,10 +57,11 @@ ENTRY (MEMCPY, 5) > */ > > neg r8,r3 /* LS 4 bits = # bytes to 8-byte dest bdry */ > - ld r9,.LC0@toc(r2) /* Get cache line size (part 1) */ > + /* Get the cache line size. */ > + __GLRO (r9, dl_cache_line_size, > + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) OK. > clrldi r8,r8,64-4 /* align to 16byte boundary */ > sub r7,r4,r3 /* compute offset to src from dest */ > - lwz r9,0(r9) /* Get cache line size (part 2) */ > cmpldi cr0,r8,0 /* Were we aligned on a 16 byte bdy? */ > addi r10,r9,-1 /* Cache line mask */ > beq+ L(dst_aligned) > @@ -121,7 +124,7 @@ L(dst_aligned): > cmpdi cr0,r9,0 /* Cache line size set? */ > bne+ cr0,L(cachelineset) > > -/* __cache_line_size not set: generic byte copy without much optimization */ > +/* Cache line size not set: generic byte copy without much optimization */ OK. > clrldi. r0,r5,63 /* If length is odd copy one byte */ > beq L(cachelinenotset_align) > lbz r7,0(r4) /* Read one byte from source */ > diff --git a/sysdeps/powerpc/powerpc64/memset.S b/sysdeps/powerpc/powerpc64/memset.S > index 857c023755..2fa98e6e2d 100644 > --- a/sysdeps/powerpc/powerpc64/memset.S > +++ b/sysdeps/powerpc/powerpc64/memset.S > @@ -17,10 +17,11 @@ > <https://www.gnu.org/licenses/>. */ > > #include <sysdep.h> > +#include <rtld-global-offsets.h> OK. > > .section ".toc","aw" > -.LC0: > - .tc __cache_line_size[TC],__cache_line_size > +__GLRO_DEF(dl_cache_line_size) > + OK. > .section ".text" > .align 2 > > @@ -146,8 +147,10 @@ L(zloopstart): > /* If the remaining length is less the 32 bytes, don't bother getting > the cache line size. */ > beq L(medium) > - ld rCLS,.LC0@toc(r2) > - lwz rCLS,0(rCLS) > + /* Read the cache line size. */ > + __GLRO (rCLS, dl_cache_line_size, > + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) > + OK. > /* If the cache line size was not set just goto to L(nondcbz) which is > safe for any cache line size. */ > cmpldi cr1,rCLS,0 > diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h > index aefd29a14d..d6616ac905 100644 > --- a/sysdeps/powerpc/powerpc64/sysdep.h > +++ b/sysdeps/powerpc/powerpc64/sysdep.h > @@ -342,6 +342,30 @@ LT_LABELSUFFIX(name,_name_end): ; \ > #define PSEUDO_END_ERRVAL(name) \ > END (name) > > +#ifdef SHARED > +# if IS_IN (rtld) > + /* Inside ld.so we use the local alias to avoid runtime GOT > + relocations. */ > +# define __GLRO_DEF(var) \ > +.LC__ ## var: \ > + .tc _rtld_local_ro[TC],_rtld_local_ro OK. > +# else > +# define __GLRO_DEF(var) \ > +.LC__ ## var: \ > + .tc _rtld_global_ro[TC],_rtld_global_ro > +# endif > +# define __GLRO(rOUT, var, offset) \ > + ld rOUT,.LC__ ## var@toc(r2); \ > + lwz rOUT,offset(rOUT) > +#else > +# define __GLRO_DEF(var) \ > +.LC__ ## var: \ > + .tc _ ## var[TC],_ ## var > +# define __GLRO(rOUT, var, offset) \ > + ld rOUT,.LC__ ## var@toc(r2); \ > + lwz rOUT,0(rOUT) > +#endif OK. > + > #else /* !__ASSEMBLER__ */ > > #if _CALL_ELF != 2 > diff --git a/sysdeps/powerpc/rtld-global-offsets.sym b/sysdeps/powerpc/rtld-global-offsets.sym > index f5ea5a1466..6b348fd522 100644 > --- a/sysdeps/powerpc/rtld-global-offsets.sym > +++ b/sysdeps/powerpc/rtld-global-offsets.sym > @@ -6,3 +6,4 @@ > > RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap) > RTLD_GLOBAL_RO_DL_HWCAP2_OFFSET rtld_global_ro_offsetof (_dl_hwcap2) > +RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET rtld_global_ro_offsetof (_dl_cache_line_size) Ok. > diff --git a/sysdeps/powerpc/tst-cache-ppc-static-dlopen.c b/sysdeps/powerpc/tst-cache-ppc-static-dlopen.c > new file mode 100644 > index 0000000000..296d0f4397 > --- /dev/null > +++ b/sysdeps/powerpc/tst-cache-ppc-static-dlopen.c > @@ -0,0 +1,54 @@ > +/* Test dl_cache_line_size from a dlopen'ed DSO from a static executable. > + Copyright (C) 2020 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <dlfcn.h> > +#include <stdio.h> > +#include <errno.h> > + > +int test_cache(int *); > + > +static int > +do_test (void) > +{ > + int ret; > + void *handle; > + int (*test_cache) (int *); > + > + handle = dlopen ("mod-cache-ppc.so", RTLD_LAZY | RTLD_LOCAL); > + if (handle == NULL) > + { > + printf ("dlopen (mod-cache-ppc.so): %s\n", dlerror ()); > + return 1; > + } > + > + test_cache = dlsym (handle, "test_cache"); > + if (test_cache == NULL) > + { > + printf ("dlsym (test_cache): %s\n", dlerror ()); > + return 1; > + } > + > + ret = test_cache(&errno); > + > + test_cache = NULL; > + dlclose (handle); OK. > + > + return ret; > +} > + > +#include <support/test-driver.c> > diff --git a/sysdeps/powerpc/tst-cache-ppc-static.c b/sysdeps/powerpc/tst-cache-ppc-static.c > new file mode 100644 > index 0000000000..b0c417e822 > --- /dev/null > +++ b/sysdeps/powerpc/tst-cache-ppc-static.c > @@ -0,0 +1,20 @@ > +/* Test if an executable can read from _dl_cache_line_size. > + Copyright (C) 2020 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include "tst-cache-ppc.c" > +#include "mod-cache-ppc.c" OK. > diff --git a/sysdeps/powerpc/tst-cache-ppc.c b/sysdeps/powerpc/tst-cache-ppc.c > new file mode 100644 > index 0000000000..86c7117c43 > --- /dev/null > +++ b/sysdeps/powerpc/tst-cache-ppc.c > @@ -0,0 +1,29 @@ > +/* Test if an executable can read from rtld_global_ro._dl_cache_line_size. > + Copyright (C) 2020 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <errno.h> > + > +int test_cache(int *); > + > +static int > +do_test (void) > +{ > + return test_cache(&errno); > +} OK. > + > +#include <support/test-driver.c> > diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h > similarity index 60% > rename from sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c > rename to sysdeps/unix/sysv/linux/powerpc/dl-auxv.h > index 5d65bc6303..be2189732a 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c > +++ b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h > @@ -1,5 +1,5 @@ > -/* Operating system support for run-time dynamic linker. Linux/PPC version. > - Copyright (C) 1997-2020 Free Software Foundation, Inc. > +/* Auxiliary vector processing. Linux/PPC version. > + Copyright (C) 2020 Free Software Foundation, Inc. OK. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > @@ -16,18 +16,15 @@ > License along with the GNU C Library; if not, see > <https://www.gnu.org/licenses/>. */ > > -#include <config.h> > #include <ldsodefs.h> > > -int __cache_line_size attribute_hidden; > +#if IS_IN (libc) && !defined SHARED > +int GLRO(dl_cache_line_size); > +#endif > > -/* Scan the Aux Vector for the "Data Cache Block Size" entry. If found > - verify that the static extern __cache_line_size is defined by checking > - for not NULL. If it is defined then assign the cache block size > - value to __cache_line_size. */ > +/* Scan the Aux Vector for the "Data Cache Block Size" entry and assign it > + to dl_cache_line_size. */ > #define DL_PLATFORM_AUXV \ > case AT_DCACHEBSIZE: \ > - __cache_line_size = av->a_un.a_val; \ > + GLRO(dl_cache_line_size) = av->a_un.a_val; \ OK. > break; > - > -#include <sysdeps/unix/sysv/linux/dl-sysdep.c> > diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-static.c b/sysdeps/unix/sysv/linux/powerpc/dl-static.c > index 59ce4e8972..a77e07b503 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/dl-static.c > +++ b/sysdeps/unix/sysv/linux/powerpc/dl-static.c > @@ -30,12 +30,14 @@ _dl_var_init (void *array[]) > DL_AUXV = 1, > DL_HWCAP = 2, > DL_HWCAP2 = 3, > + DL_CACHE_LINE_SIZE = 4 OK. > }; > > GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); > GLRO(dl_auxv) = (ElfW(auxv_t) *) *((size_t *) array[DL_AUXV]); > GLRO(dl_hwcap) = *((unsigned long int *) array[DL_HWCAP]); > GLRO(dl_hwcap2) = *((unsigned long int *) array[DL_HWCAP2]); > + GLRO(dl_cache_line_size) = (int) *((int *) array[DL_CACHE_LINE_SIZE]); OK. > } > > #else > @@ -46,6 +48,7 @@ static void *variables[] = > &GLRO(dl_auxv), > &GLRO(dl_hwcap), > &GLRO(dl_hwcap2), > + &GLRO(dl_cache_line_size) OK. > }; > > static void > diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c > index 93f8659fa6..fc86d6e234 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c > +++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c > @@ -24,7 +24,6 @@ > #include <hwcapinfo.h> > #endif > > -int __cache_line_size attribute_hidden; OK. > /* The main work is done in the generic function. */ > #define LIBC_START_MAIN generic_start_main > #define LIBC_START_DISABLE_INLINE > @@ -71,15 +70,12 @@ __libc_start_main (int argc, char **argv, > rtld_fini = NULL; > } > > - /* Initialize the __cache_line_size variable from the aux vector. For the > - static case, we also need _dl_hwcap, _dl_hwcap2 and _dl_platform, so we > - can call __tcb_parse_hwcap_and_convert_at_platform (). */ OK. > for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av) > switch (av->a_type) > { > - case AT_DCACHEBSIZE: > - __cache_line_size = av->a_un.a_val; > - break; > + /* For the static case, we also need _dl_hwcap, _dl_hwcap2 and > + _dl_platform, so we can call > + __tcb_parse_hwcap_and_convert_at_platform (). */ OK. > #ifndef SHARED > case AT_HWCAP: > _dl_hwcap = (unsigned long int) av->a_un.a_val; >
On 16/01/20 10:07 pm, Carlos O'Donell wrote: > On 1/10/20 5:27 PM, Tulio Magno Quites Machado Filho wrote: >> Changes since v1: >> - Updated copyright dates >> - Added tests >> - Fixed coding style issues >> - Added macros __GLRO_DEF and __GLRO in the 64-bit case. >> - Removed sysdeps/unix/sysv/linux/powerpc/dl-support.c in favor of >> sysdeps/generic/dl-auxv.h which is included by elf/dl-support.c and >> elf/dl-sysdep.c >> - Removed sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c >> > > OK for master. This is probably the smallest change you can make to fix > all of this up. > > This needs approval again by Siddhesh. > > Reviewed-by: Carlos O'Donell <carlos@redhat.com> > This is fine. Siddhesh
Siddhesh Poyarekar <siddhesh@gotplt.org> writes: > On 16/01/20 10:07 pm, Carlos O'Donell wrote: >> On 1/10/20 5:27 PM, Tulio Magno Quites Machado Filho wrote: >>> Changes since v1: >>> - Updated copyright dates >>> - Added tests >>> - Fixed coding style issues >>> - Added macros __GLRO_DEF and __GLRO in the 64-bit case. >>> - Removed sysdeps/unix/sysv/linux/powerpc/dl-support.c in favor of >>> sysdeps/generic/dl-auxv.h which is included by elf/dl-support.c and >>> elf/dl-sysdep.c >>> - Removed sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c >>> >> >> OK for master. This is probably the smallest change you can make to fix >> all of this up. >> >> This needs approval again by Siddhesh. >> >> Reviewed-by: Carlos O'Donell <carlos@redhat.com> > > This is fine. I've just pushed both patches to master. Thanks!
* Tulio Magno Quites Machado Filho: > Siddhesh Poyarekar <siddhesh@gotplt.org> writes: > >> On 16/01/20 10:07 pm, Carlos O'Donell wrote: >>> On 1/10/20 5:27 PM, Tulio Magno Quites Machado Filho wrote: >>>> Changes since v1: >>>> - Updated copyright dates >>>> - Added tests >>>> - Fixed coding style issues >>>> - Added macros __GLRO_DEF and __GLRO in the 64-bit case. >>>> - Removed sysdeps/unix/sysv/linux/powerpc/dl-support.c in favor of >>>> sysdeps/generic/dl-auxv.h which is included by elf/dl-support.c and >>>> elf/dl-sysdep.c >>>> - Removed sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c >>>> >>> >>> OK for master. This is probably the smallest change you can make to fix >>> all of this up. >>> >>> This needs approval again by Siddhesh. >>> >>> Reviewed-by: Carlos O'Donell <carlos@redhat.com> >> >> This is fine. > > I've just pushed both patches to master. This appears to have caused (on powerpc-linux-gnu): ../sysdeps/powerpc/powerpc32/memset.S: Assembler messages: ../sysdeps/powerpc/powerpc32/memset.S:248: Error: syntax error; found ` ', expected `,' ../sysdeps/powerpc/powerpc32/memset.S:248: Error: junk at end of line: `lwz 8,(_dl_cache_line_size+4)@l(8)' Thanks, Florian
One of these changes appears to have broken the build for 32-bit powerpc (all the 32-bit configurations in build-many-glibcs.py), at least with GCC 8 / binutils 2.33. https://sourceware.org/ml/libc-testresults/2020-q1/msg00077.html ../sysdeps/powerpc/powerpc32/memset.S: Assembler messages: ../sysdeps/powerpc/powerpc32/memset.S:248: Error: syntax error; found ` ', expected `,' ../sysdeps/powerpc/powerpc32/memset.S:248: Error: junk at end of line: `lwz 8,(_dl_cache_line_size+4)@l(8)'
Joseph Myers <joseph@codesourcery.com> writes: > One of these changes appears to have broken the build for 32-bit powerpc > (all the 32-bit configurations in build-many-glibcs.py), at least with > GCC 8 / binutils 2.33. > > https://sourceware.org/ml/libc-testresults/2020-q1/msg00077.html > > ../sysdeps/powerpc/powerpc32/memset.S: Assembler messages: > ../sysdeps/powerpc/powerpc32/memset.S:248: Error: syntax error; found ` ', expected `,' > ../sysdeps/powerpc/powerpc32/memset.S:248: Error: junk at end of line: `lwz 8,(_dl_cache_line_size+4)@l(8)' I've just reproduced this. Interestingly, I can't reproduce it from outside a build-many-glibcs.py with Binutils 2.33.1 (Debian 10). I tried with GCC 7, 8 and 9. I'll continue to investigate it. Thanks!
I'm seeing all the statically linked glibc tests fail for 32-bit powerpc when built with GCC 10: malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. Aborted (A statically linked program with empty main produces that error on startup.) If I build glibc with -fcommon, at least a trivial statically linked binary no longer fails. So I think there may have been something missing from the fixes to build with -fno-common; they got glibc building again, but not working in the statically linked case.
On Jul 23 2020, Joseph Myers wrote: > I'm seeing all the statically linked glibc tests fail for 32-bit powerpc > when built with GCC 10: > > malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. > Aborted I don't see that here. https://build.opensuse.org/package/live_build_log/home:Andreas_Schwab:glibc/glibc:testsuite/p/ppc Andreas.
* Joseph Myers: > I'm seeing all the statically linked glibc tests fail for 32-bit powerpc > when built with GCC 10: > > malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. > Aborted > > (A statically linked program with empty main produces that error on > startup.) > > If I build glibc with -fcommon, at least a trivial statically linked > binary no longer fails. So I think there may have been something missing > from the fixes to build with -fno-common; they got glibc building again, > but not working in the statically linked case. What's your binutils version? Does this affect the statically linked test binaries built by build-many-glibcs.py? Thanks, Florian
On Fri, 31 Jul 2020, Florian Weimer via Libc-alpha wrote: > * Joseph Myers: > > > I'm seeing all the statically linked glibc tests fail for 32-bit powerpc > > when built with GCC 10: > > > > malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. > > Aborted > > > > (A statically linked program with empty main produces that error on > > startup.) > > > > If I build glibc with -fcommon, at least a trivial statically linked > > binary no longer fails. So I think there may have been something missing > > from the fixes to build with -fno-common; they got glibc building again, > > but not working in the statically linked case. > > What's your binutils version? This testing was with 2.35.50.20200720. > Does this affect the statically linked test binaries built by > build-many-glibcs.py? Yes. I tested build-many-glibcs.py for powerpc-linux-gnu with current default versions of everything (so binutils 2.35 branch in this case); running the math/atest-exp binary left from a --keep=all build produces that same assertion failure.
* Joseph Myers: >> Does this affect the statically linked test binaries built by >> build-many-glibcs.py? > > Yes. I tested build-many-glibcs.py? for powerpc-linux-gnu with current > default versions of everything (so binutils 2.35 branch in this case); > running the math/atest-exp binary left from a --keep=all build produces > that same assertion failure. I can reproduce it: (gdb) bt #0 0x10007d74 in __libc_signal_restore_set (set=0xfffed708) at ../sysdeps/unix/sysv/linux/internal-signals.h:104 #1 raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:47 #2 0x10000268 in abort () at abort.c:79 #3 0x1001c7b8 in __malloc_assert ( assertion=assertion@entry=0x10081ec4 "(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)", file=file@entry=0x10081690 "malloc.c", line=line@entry=2394, function=function@entry=0x100828b8 <__PRETTY_FUNCTION__.3> "sysmalloc") at malloc.c:298 #4 0x1001ee1c in sysmalloc (nb=nb@entry=64, av=av@entry=0x100c03d4 <main_arena>) at malloc.c:2394 #5 0x10020614 in _int_malloc (av=av@entry=0x100c03d4 <main_arena>, bytes=bytes@entry=53) at malloc.c:4169 #6 0x10021804 in __libc_malloc (bytes=53) at malloc.c:3078 #7 0x10060f44 in _dl_get_origin () at ../sysdeps/unix/sysv/linux/dl-origin.c:49 #8 0x100302f4 in _dl_non_dynamic_init () at dl-support.c:311 #9 0x10031908 in __libc_init_first (argc=argc@entry=2, argv=argv@entry=0xfffeecd4, envp=0xfffeece0) at init-first.c:72 #10 0x100024dc in generic_start_main (main=0x100003d4 <main>, argc=argc@entry=2, argv=argv@entry=0xfffeecd4, auxvec=auxvec@entry=0xfffeed9c, init=0x10002be0 <__libc_csu_init>, fini=0x10002d58 <__libc_csu_fini>, rtld_fini=rtld_fini@entry=0x0, stack_end=stack_end@entry=0xfffeecd0) at ../csu/libc-start.c:250 #11 0x10002774 in __libc_start_main (argc=2, argv=0xfffeecd4, ev=<optimized out>, auxvec=0xfffeed9c, rtld_fini=0x0, stinfo=0x1007f3e0, stack_on_entry=0xfffeecd0) at ../sysdeps/unix/sysv/linux/powerpc/libc-start.c:98 #12 0x00000000 in ?? () main_arena.top->mchunk_size gets overwritten during tcache_init: #0 memset () at ../sysdeps/powerpc/powerpc32/memset.S:291 #1 0x10021660 in tcache_init () at malloc.c:3021 #2 0x10021af4 in __libc_malloc (bytes=bytes@entry=53) at malloc.c:3064 #3 0x10021d80 in malloc_hook_ini (sz=53, caller=<optimized out>) at hooks.c:32 #4 0x10021aa0 in __libc_malloc (bytes=53) at malloc.c:3053 #5 0x100614c4 in _dl_get_origin () at ../sysdeps/unix/sysv/linux/dl-origin.c:49 #6 0x10030874 in _dl_non_dynamic_init () at dl-support.c:311 #7 0x10031e88 in __libc_init_first (argc=argc@entry=2, argv=argv@entry=0xfffeecd4, envp=0xfffeece0) at init-first.c:72 #8 0x100024dc in generic_start_main (main=0x100003d4 <main>, argc=argc@entry=2, argv=argv@entry=0xfffeecd4, auxvec=auxvec@entry=0xfffeed9c, init=0x10002be0 <__libc_csu_init>, fini=0x10002d58 <__libc_csu_fini>, rtld_fini=rtld_fini@entry=0x0, stack_end=stack_end@entry=0xfffeecd0) at ../csu/libc-start.c:250 #9 0x10002774 in __libc_start_main (argc=2, argv=0xfffeecd4, ev=<optimized out>, auxvec=0xfffeed9c, rtld_fini=0x0, stinfo=0x1007f960, stack_on_entry=0xfffeecd0) at ../sysdeps/unix/sysv/linux/powerpc/libc-start.c:98 #10 0x00000000 in ?? () The memset goes wrong because it loads the cache line size as 1 here: /* Load rtld_global_ro._dl_cache_line_size. */ __GLRO(rCLS, rGOT, _dl_cache_line_size, RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) 0x100259e4 <+576>: lis r8,4108 => 0x100259e8 <+580>: lwz r8,3912(r8) (gdb) print (void*)($r8 + 3912) $24 = (void *) 0x100c0f48 <__libc_enable_secure_decided> This is not the address that is seen by the debugger for _dl_cache_line_size: (gdb) print &_dl_cache_line_size $26 = (int *) 0x100c0f44 <_dl_cache_line_size> The symbol table looks pretty reasonable: 1461: 100c0f44 4 OBJECT GLOBAL DEFAULT 23 _dl_cache_line_size 1495: 100c0f40 4 OBJECT GLOBAL DEFAULT 23 _dl_platform 1512: 100c0f48 4 OBJECT GLOBAL DEFAULT 23 __libc_enable_secure_decided 2135: 100c0f4c 4 OBJECT GLOBAL DEFAULT 23 __libc_argv For some reason, we have relocations with displacements in string/memset.o: 244: 3d 00 00 00 lis r8,0 246: R_PPC_ADDR16_HA _dl_cache_line_size+0x4 248: 81 08 00 00 lwz r8,0(r8) 24a: R_PPC_ADDR16_LO _dl_cache_line_size+0x4 This is due to the definition of __GLRO: #else /* Position-dependent code does not require access to the GOT. */ # define __GLRO(rOUT, rGOT, member, offset) \ lis rOUT,(member+LOWORD)@ha; \ lwz rOUT,(member+LOWORD)@l(rOUT) #endif /* PIC */ And LOWORD is 4 on big-endian PowerPC: /* The 32-bit words of a 64-bit dword are at these offsets in memory. */ #if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN # define LOWORD 0 # define HIWORD 4 #else # define LOWORD 4 # define HIWORD 0 #endif I believe we should remove the “+LOWORD” part here: diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index 2ba009e9..829eec26 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -179,8 +179,8 @@ GOT_LABEL: ; \ #else /* Position-dependent code does not require access to the GOT. */ # define __GLRO(rOUT, rGOT, member, offset) \ - lis rOUT,(member+LOWORD)@ha; \ - lwz rOUT,(member+LOWORD)@l(rOUT) + lis rOUT,(member)@ha; \ + lwz rOUT,(member)@l(rOUT) #endif /* PIC */ #endif /* __ASSEMBLER__ */ It fixes math/atest-exp for me. Tulio, I believe you constructed this macro from sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S, where it is needed because we are loading the lower 32 bits of a 64-bit value. It's not correct for loading a 32-bit quantity. Technically, this bug is not a release blocker. It's not a regression, it's present in 2.31 as well. I will file a bug and post a proper patch. Thanks, Florian
On 8/3/20 4:15 AM, Florian Weimer wrote: > Technically, this bug is not a release blocker. It's not a regression, > it's present in 2.31 as well. I will file a bug and post a proper patch. I just ack'd your patch for inclusion in 2.32. Please commit for 2.32 so the release goes out without the bug. Tulio, please review ASAP to double check our results here.
diff --git a/elf/dl-support.c b/elf/dl-support.c index ad791ab6ab..7704c101c5 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -36,6 +36,7 @@ #include <stackinfo.h> #include <dl-vdso.h> #include <dl-vdso-setup.h> +#include <dl-auxv.h> extern char *__progname; char **_dl_argv = &__progname; /* This is checked for some error messages. */ @@ -293,9 +294,7 @@ _dl_aux_init (ElfW(auxv_t) *av) case AT_RANDOM: _dl_random = (void *) av->a_un.a_val; break; -# ifdef DL_PLATFORM_AUXV DL_PLATFORM_AUXV -# endif } if (seen == 0xf) { diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c index 53bbee14f4..854570821c 100644 --- a/elf/dl-sysdep.c +++ b/elf/dl-sysdep.c @@ -45,6 +45,7 @@ #include <tls.h> #include <dl-tunables.h> +#include <dl-auxv.h> extern char **_environ attribute_hidden; extern char _end[] attribute_hidden; @@ -180,9 +181,7 @@ _dl_sysdep_start (void **start_argptr, case AT_RANDOM: _dl_random = (void *) av->a_un.a_val; break; -#ifdef DL_PLATFORM_AUXV DL_PLATFORM_AUXV -#endif } #ifndef HAVE_AUX_SECURE diff --git a/sysdeps/generic/dl-auxv.h b/sysdeps/generic/dl-auxv.h new file mode 100644 index 0000000000..bf3c01182e --- /dev/null +++ b/sysdeps/generic/dl-auxv.h @@ -0,0 +1,21 @@ +/* Auxiliary vector processing. Generic version. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +/* Define DL_PLATFORM_AUXV in order to process platform-specific AUXV entries + during the initialization of the loader or of a static libc. */ +#define DL_PLATFORM_AUXV diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile index df45d348d2..d1c71a0ca4 100644 --- a/sysdeps/powerpc/Makefile +++ b/sysdeps/powerpc/Makefile @@ -14,6 +14,23 @@ mod-tlsopt-powerpc.so-no-z-defs = yes tests += tst-tlsopt-powerpc $(objpfx)tst-tlsopt-powerpc: $(objpfx)mod-tlsopt-powerpc.so +tests-static += tst-cache-ppc-static +tests-internal += tst-cache-ppc-static + +ifeq (yes,$(build-shared)) +modules-names += mod-cache-ppc +tests += tst-cache-ppc tst-cache-ppc-static-dlopen +tests-static += tst-cache-ppc-static-dlopen +test-internal-extras += mod-cache-ppc + +mod-cache-ppc.so-no-z-defs = yes +tst-cache-ppc-static-dlopen-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf +$(objpfx)tst-cache-ppc-static-dlopen: $(common-objpfx)dlfcn/libdl.a +$(objpfx)tst-cache-ppc-static-dlopen.out: $(objpfx)mod-cache-ppc.so + +$(objpfx)tst-cache-ppc: $(objpfx)mod-cache-ppc.so +endif + ifneq (no,$(multi-arch)) tests-static += tst-tlsifunc-static tests-internal += tst-tlsifunc-static diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c index 2ae68c41f1..7a7d93dd0a 100644 --- a/sysdeps/powerpc/dl-procinfo.c +++ b/sysdeps/powerpc/dl-procinfo.c @@ -89,5 +89,22 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][15] , #endif +#if !IS_IN (ldconfig) +# if !defined PROCINFO_DECL && defined SHARED + ._dl_cache_line_size +# else +PROCINFO_CLASS int _dl_cache_line_size +# endif +# ifndef PROCINFO_DECL + = 0 +# endif +# if !defined SHARED || defined PROCINFO_DECL +; +# else +, +# endif +#endif + + #undef PROCINFO_DECL #undef PROCINFO_CLASS diff --git a/sysdeps/powerpc/mod-cache-ppc.c b/sysdeps/powerpc/mod-cache-ppc.c new file mode 100644 index 0000000000..81fad52078 --- /dev/null +++ b/sysdeps/powerpc/mod-cache-ppc.c @@ -0,0 +1,45 @@ +/* Test if an executable can read from rtld_global_ro._dl_cache_line_size. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdint.h> +#include <inttypes.h> +#include <sys/auxv.h> +#include <ldsodefs.h> +#include <errno.h> + +/* errnop is required in order to work around BZ #20802. */ +int +test_cache (int *errnop) +{ + int cls1 = GLRO (dl_cache_line_size); + errno = *errnop; + uint64_t cls2 = getauxval (AT_DCACHEBSIZE); + *errnop = errno; + + printf ("AT_DCACHEBSIZE = %" PRIu64 " B\n", cls2); + printf ("_dl_cache_line_size = %d B\n", cls1); + + if (cls1 != cls2) + { + printf ("error: _dl_cache_line_size != AT_DCACHEBSIZE\n"); + return 1; + } + + return 0; +} diff --git a/sysdeps/powerpc/powerpc32/a2/memcpy.S b/sysdeps/powerpc/powerpc32/a2/memcpy.S index fe5dab847a..6f4d8a7b34 100644 --- a/sysdeps/powerpc/powerpc32/a2/memcpy.S +++ b/sysdeps/powerpc/powerpc32/a2/memcpy.S @@ -18,6 +18,7 @@ <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <rtld-global-offsets.h> #define PREFETCH_AHEAD 4 /* no cache lines SRC prefetching ahead */ #define ZERO_AHEAD 2 /* no cache lines DST zeroing ahead */ @@ -106,25 +107,23 @@ EALIGN (memcpy, 5, 0) L(dst_aligned): -#ifdef SHARED +#ifdef PIC mflr r0 -/* Establishes GOT addressability so we can load __cache_line_size - from static. This value was set from the aux vector during startup. */ +/* Establishes GOT addressability so we can load the cache line size + from rtld_global_ro. This value was set from the aux vector during + startup. */ SETUP_GOT_ACCESS(r9,got_label) - addis r9,r9,__cache_line_size-got_label@ha - lwz r9,__cache_line_size-got_label@l(r9) - mtlr r0 -#else -/* Load __cache_line_size from static. This value was set from the - aux vector during startup. */ - lis r9,__cache_line_size@ha - lwz r9,__cache_line_size@l(r9) + addis r9,r9,_GLOBAL_OFFSET_TABLE_-got_label@ha + addi r9,r9,_GLOBAL_OFFSET_TABLE_-got_label@l + mtlr r0 #endif + __GLRO(r9, r9, _dl_cache_line_size, + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) cmplwi cr5, r9, 0 bne+ cr5,L(cachelineset) -/* __cache_line_size not set: generic byte copy without much optimization */ +/* Cache line size not set: generic byte copy without much optimization */ andi. r0,r5,1 /* If length is odd copy one byte. */ beq L(cachelinenotset_align) lbz r7,0(r4) /* Read one byte from source. */ diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c index d5ea4b97f4..6090e60d3c 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.c +++ b/sysdeps/powerpc/powerpc32/dl-machine.c @@ -25,11 +25,6 @@ #include <dl-machine.h> #include <_itoa.h> -/* The value __cache_line_size is defined in dl-sysdep.c and is initialised - by _dl_sysdep_start via DL_PLATFORM_INIT. */ -extern int __cache_line_size attribute_hidden; - - /* Stuff for the PLT. */ #define PLT_INITIAL_ENTRY_WORDS 18 #define PLT_LONGBRANCH_ENTRY_WORDS 0 @@ -309,14 +304,14 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile) Assumes that dcbst and icbi apply to lines of 16 bytes or more. Current known line sizes are 16, 32, and 128 bytes. - The following gets the __cache_line_size, when available. */ + The following gets the cache line size, when available. */ /* Default minimum 4 words per cache line. */ int line_size_words = 4; - if (lazy && __cache_line_size != 0) + if (lazy && GLRO(dl_cache_line_size) != 0) /* Convert bytes to words. */ - line_size_words = __cache_line_size / 4; + line_size_words = GLRO(dl_cache_line_size) / 4; size_modified = lazy ? rel_offset_words : 6; for (i = 0; i < size_modified; i += line_size_words) diff --git a/sysdeps/powerpc/powerpc32/memset.S b/sysdeps/powerpc/powerpc32/memset.S index 5f614c07d7..26c37f8a17 100644 --- a/sysdeps/powerpc/powerpc32/memset.S +++ b/sysdeps/powerpc/powerpc32/memset.S @@ -17,12 +17,13 @@ <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <rtld-global-offsets.h> /* void * [r3] memset (void *s [r3], int c [r4], size_t n [r5])); Returns 's'. The memset is done in four sizes: byte (8 bits), word (32 bits), - 32-byte blocks (256 bits) and __cache_line_size (128, 256, 1024 bits). + 32-byte blocks (256 bits) and cache line size (128, 256, 1024 bits). There is a special case for setting whole cache lines to 0, which takes advantage of the dcbz instruction. */ @@ -95,7 +96,7 @@ L(caligned): /* Check if we can use the special case for clearing memory using dcbz. This requires that we know the correct cache line size for this - processor. Getting the __cache_line_size may require establishing GOT + processor. Getting the cache line size may require establishing GOT addressability, so branch out of line to set this up. */ beq cr1, L(checklinesize) @@ -230,26 +231,22 @@ L(medium_28t): blr L(checklinesize): -#ifdef SHARED - mflr rTMP /* If the remaining length is less the 32 bytes then don't bother getting the cache line size. */ beq L(medium) -/* Establishes GOT addressability so we can load __cache_line_size - from static. This value was set from the aux vector during startup. */ +#ifdef PIC + mflr rTMP +/* Establishes GOT addressability so we can load the cache line size + from rtld_global_ro. This value was set from the aux vector during + startup. */ SETUP_GOT_ACCESS(rGOT,got_label) - addis rGOT,rGOT,__cache_line_size-got_label@ha - lwz rCLS,__cache_line_size-got_label@l(rGOT) + addis rGOT,rGOT,_GLOBAL_OFFSET_TABLE_-got_label@ha + addi rGOT,rGOT,_GLOBAL_OFFSET_TABLE_-got_label@l mtlr rTMP -#else -/* Load __cache_line_size from static. This value was set from the - aux vector during startup. */ - lis rCLS,__cache_line_size@ha -/* If the remaining length is less the 32 bytes then don't bother getting - the cache line size. */ - beq L(medium) - lwz rCLS,__cache_line_size@l(rCLS) #endif +/* Load rtld_global_ro._dl_cache_line_size. */ + __GLRO(rCLS, rGOT, _dl_cache_line_size, + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) /* If the cache line size was not set then goto to L(nondcbz), which is safe for any cache line size. */ diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index ceed9ef158..0dee5f2757 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -157,4 +157,30 @@ GOT_LABEL: ; \ /* Label in text section. */ #define C_TEXT(name) name +/* Read the value of member from rtld_global_ro. */ +#ifdef PIC +# ifdef SHARED +# if IS_IN (rtld) +/* Inside ld.so we use the local alias to avoid runtime GOT + relocations. */ +# define __GLRO(rOUT, rGOT, member, offset) \ + lwz rOUT,_rtld_local_ro@got(rGOT); \ + lwz rOUT,offset(rOUT) +# else +# define __GLRO(rOUT, rGOT, member, offset) \ + lwz rOUT,_rtld_global_ro@got(rGOT); \ + lwz rOUT,offset(rOUT) +# endif +# else +# define __GLRO(rOUT, rGOT, member, offset) \ + lwz rOUT,member@got(rGOT); \ + lwz rOUT,0(rOUT) +# endif +#else +/* Position-dependent code does not require access to the GOT. */ +# define __GLRO(rOUT, rGOT, member, offset) \ + lis rOUT,(member+LOWORD)@ha \ + lwz rOUT,(member+LOWORD)@l(rOUT) +#endif /* PIC */ + #endif /* __ASSEMBLER__ */ diff --git a/sysdeps/powerpc/powerpc64/a2/memcpy.S b/sysdeps/powerpc/powerpc64/a2/memcpy.S index 0e3c435f3c..1162cc2207 100644 --- a/sysdeps/powerpc/powerpc64/a2/memcpy.S +++ b/sysdeps/powerpc/powerpc64/a2/memcpy.S @@ -18,6 +18,7 @@ <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <rtld-global-offsets.h> #ifndef MEMCPY # define MEMCPY memcpy @@ -27,8 +28,9 @@ #define ZERO_AHEAD 2 /* no cache lines DST zeroing ahead */ .section ".toc","aw" -.LC0: - .tc __cache_line_size[TC],__cache_line_size +__GLRO_DEF(dl_cache_line_size) + + .section ".text" .align 2 @@ -55,10 +57,11 @@ ENTRY (MEMCPY, 5) */ neg r8,r3 /* LS 4 bits = # bytes to 8-byte dest bdry */ - ld r9,.LC0@toc(r2) /* Get cache line size (part 1) */ + /* Get the cache line size. */ + __GLRO (r9, dl_cache_line_size, + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) clrldi r8,r8,64-4 /* align to 16byte boundary */ sub r7,r4,r3 /* compute offset to src from dest */ - lwz r9,0(r9) /* Get cache line size (part 2) */ cmpldi cr0,r8,0 /* Were we aligned on a 16 byte bdy? */ addi r10,r9,-1 /* Cache line mask */ beq+ L(dst_aligned) @@ -121,7 +124,7 @@ L(dst_aligned): cmpdi cr0,r9,0 /* Cache line size set? */ bne+ cr0,L(cachelineset) -/* __cache_line_size not set: generic byte copy without much optimization */ +/* Cache line size not set: generic byte copy without much optimization */ clrldi. r0,r5,63 /* If length is odd copy one byte */ beq L(cachelinenotset_align) lbz r7,0(r4) /* Read one byte from source */ diff --git a/sysdeps/powerpc/powerpc64/memset.S b/sysdeps/powerpc/powerpc64/memset.S index 857c023755..2fa98e6e2d 100644 --- a/sysdeps/powerpc/powerpc64/memset.S +++ b/sysdeps/powerpc/powerpc64/memset.S @@ -17,10 +17,11 @@ <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <rtld-global-offsets.h> .section ".toc","aw" -.LC0: - .tc __cache_line_size[TC],__cache_line_size +__GLRO_DEF(dl_cache_line_size) + .section ".text" .align 2 @@ -146,8 +147,10 @@ L(zloopstart): /* If the remaining length is less the 32 bytes, don't bother getting the cache line size. */ beq L(medium) - ld rCLS,.LC0@toc(r2) - lwz rCLS,0(rCLS) + /* Read the cache line size. */ + __GLRO (rCLS, dl_cache_line_size, + RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET) + /* If the cache line size was not set just goto to L(nondcbz) which is safe for any cache line size. */ cmpldi cr1,rCLS,0 diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h index aefd29a14d..d6616ac905 100644 --- a/sysdeps/powerpc/powerpc64/sysdep.h +++ b/sysdeps/powerpc/powerpc64/sysdep.h @@ -342,6 +342,30 @@ LT_LABELSUFFIX(name,_name_end): ; \ #define PSEUDO_END_ERRVAL(name) \ END (name) +#ifdef SHARED +# if IS_IN (rtld) + /* Inside ld.so we use the local alias to avoid runtime GOT + relocations. */ +# define __GLRO_DEF(var) \ +.LC__ ## var: \ + .tc _rtld_local_ro[TC],_rtld_local_ro +# else +# define __GLRO_DEF(var) \ +.LC__ ## var: \ + .tc _rtld_global_ro[TC],_rtld_global_ro +# endif +# define __GLRO(rOUT, var, offset) \ + ld rOUT,.LC__ ## var@toc(r2); \ + lwz rOUT,offset(rOUT) +#else +# define __GLRO_DEF(var) \ +.LC__ ## var: \ + .tc _ ## var[TC],_ ## var +# define __GLRO(rOUT, var, offset) \ + ld rOUT,.LC__ ## var@toc(r2); \ + lwz rOUT,0(rOUT) +#endif + #else /* !__ASSEMBLER__ */ #if _CALL_ELF != 2 diff --git a/sysdeps/powerpc/rtld-global-offsets.sym b/sysdeps/powerpc/rtld-global-offsets.sym index f5ea5a1466..6b348fd522 100644 --- a/sysdeps/powerpc/rtld-global-offsets.sym +++ b/sysdeps/powerpc/rtld-global-offsets.sym @@ -6,3 +6,4 @@ RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap) RTLD_GLOBAL_RO_DL_HWCAP2_OFFSET rtld_global_ro_offsetof (_dl_hwcap2) +RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET rtld_global_ro_offsetof (_dl_cache_line_size) diff --git a/sysdeps/powerpc/tst-cache-ppc-static-dlopen.c b/sysdeps/powerpc/tst-cache-ppc-static-dlopen.c new file mode 100644 index 0000000000..296d0f4397 --- /dev/null +++ b/sysdeps/powerpc/tst-cache-ppc-static-dlopen.c @@ -0,0 +1,54 @@ +/* Test dl_cache_line_size from a dlopen'ed DSO from a static executable. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +#include <dlfcn.h> +#include <stdio.h> +#include <errno.h> + +int test_cache(int *); + +static int +do_test (void) +{ + int ret; + void *handle; + int (*test_cache) (int *); + + handle = dlopen ("mod-cache-ppc.so", RTLD_LAZY | RTLD_LOCAL); + if (handle == NULL) + { + printf ("dlopen (mod-cache-ppc.so): %s\n", dlerror ()); + return 1; + } + + test_cache = dlsym (handle, "test_cache"); + if (test_cache == NULL) + { + printf ("dlsym (test_cache): %s\n", dlerror ()); + return 1; + } + + ret = test_cache(&errno); + + test_cache = NULL; + dlclose (handle); + + return ret; +} + +#include <support/test-driver.c> diff --git a/sysdeps/powerpc/tst-cache-ppc-static.c b/sysdeps/powerpc/tst-cache-ppc-static.c new file mode 100644 index 0000000000..b0c417e822 --- /dev/null +++ b/sysdeps/powerpc/tst-cache-ppc-static.c @@ -0,0 +1,20 @@ +/* Test if an executable can read from _dl_cache_line_size. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +#include "tst-cache-ppc.c" +#include "mod-cache-ppc.c" diff --git a/sysdeps/powerpc/tst-cache-ppc.c b/sysdeps/powerpc/tst-cache-ppc.c new file mode 100644 index 0000000000..86c7117c43 --- /dev/null +++ b/sysdeps/powerpc/tst-cache-ppc.c @@ -0,0 +1,29 @@ +/* Test if an executable can read from rtld_global_ro._dl_cache_line_size. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> + +int test_cache(int *); + +static int +do_test (void) +{ + return test_cache(&errno); +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h similarity index 60% rename from sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c rename to sysdeps/unix/sysv/linux/powerpc/dl-auxv.h index 5d65bc6303..be2189732a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c +++ b/sysdeps/unix/sysv/linux/powerpc/dl-auxv.h @@ -1,5 +1,5 @@ -/* Operating system support for run-time dynamic linker. Linux/PPC version. - Copyright (C) 1997-2020 Free Software Foundation, Inc. +/* Auxiliary vector processing. Linux/PPC version. + Copyright (C) 2020 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 @@ -16,18 +16,15 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#include <config.h> #include <ldsodefs.h> -int __cache_line_size attribute_hidden; +#if IS_IN (libc) && !defined SHARED +int GLRO(dl_cache_line_size); +#endif -/* Scan the Aux Vector for the "Data Cache Block Size" entry. If found - verify that the static extern __cache_line_size is defined by checking - for not NULL. If it is defined then assign the cache block size - value to __cache_line_size. */ +/* Scan the Aux Vector for the "Data Cache Block Size" entry and assign it + to dl_cache_line_size. */ #define DL_PLATFORM_AUXV \ case AT_DCACHEBSIZE: \ - __cache_line_size = av->a_un.a_val; \ + GLRO(dl_cache_line_size) = av->a_un.a_val; \ break; - -#include <sysdeps/unix/sysv/linux/dl-sysdep.c> diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-static.c b/sysdeps/unix/sysv/linux/powerpc/dl-static.c index 59ce4e8972..a77e07b503 100644 --- a/sysdeps/unix/sysv/linux/powerpc/dl-static.c +++ b/sysdeps/unix/sysv/linux/powerpc/dl-static.c @@ -30,12 +30,14 @@ _dl_var_init (void *array[]) DL_AUXV = 1, DL_HWCAP = 2, DL_HWCAP2 = 3, + DL_CACHE_LINE_SIZE = 4 }; GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); GLRO(dl_auxv) = (ElfW(auxv_t) *) *((size_t *) array[DL_AUXV]); GLRO(dl_hwcap) = *((unsigned long int *) array[DL_HWCAP]); GLRO(dl_hwcap2) = *((unsigned long int *) array[DL_HWCAP2]); + GLRO(dl_cache_line_size) = (int) *((int *) array[DL_CACHE_LINE_SIZE]); } #else @@ -46,6 +48,7 @@ static void *variables[] = &GLRO(dl_auxv), &GLRO(dl_hwcap), &GLRO(dl_hwcap2), + &GLRO(dl_cache_line_size) }; static void diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c index 93f8659fa6..fc86d6e234 100644 --- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c +++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c @@ -24,7 +24,6 @@ #include <hwcapinfo.h> #endif -int __cache_line_size attribute_hidden; /* The main work is done in the generic function. */ #define LIBC_START_MAIN generic_start_main #define LIBC_START_DISABLE_INLINE @@ -71,15 +70,12 @@ __libc_start_main (int argc, char **argv, rtld_fini = NULL; } - /* Initialize the __cache_line_size variable from the aux vector. For the - static case, we also need _dl_hwcap, _dl_hwcap2 and _dl_platform, so we - can call __tcb_parse_hwcap_and_convert_at_platform (). */ for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av) switch (av->a_type) { - case AT_DCACHEBSIZE: - __cache_line_size = av->a_un.a_val; - break; + /* For the static case, we also need _dl_hwcap, _dl_hwcap2 and + _dl_platform, so we can call + __tcb_parse_hwcap_and_convert_at_platform (). */ #ifndef SHARED case AT_HWCAP: _dl_hwcap = (unsigned long int) av->a_un.a_val;