]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
powerpc: Move cache line size to rtld_global_ro
authorTulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Fri, 10 Jan 2020 22:14:56 +0000 (19:14 -0300)
committerTulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Fri, 17 Jan 2020 12:05:03 +0000 (09:05 -0300)
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.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
20 files changed:
elf/dl-support.c
elf/dl-sysdep.c
sysdeps/generic/dl-auxv.h [new file with mode: 0644]
sysdeps/powerpc/Makefile
sysdeps/powerpc/dl-procinfo.c
sysdeps/powerpc/mod-cache-ppc.c [new file with mode: 0644]
sysdeps/powerpc/powerpc32/a2/memcpy.S
sysdeps/powerpc/powerpc32/dl-machine.c
sysdeps/powerpc/powerpc32/memset.S
sysdeps/powerpc/powerpc32/sysdep.h
sysdeps/powerpc/powerpc64/a2/memcpy.S
sysdeps/powerpc/powerpc64/memset.S
sysdeps/powerpc/powerpc64/sysdep.h
sysdeps/powerpc/rtld-global-offsets.sym
sysdeps/powerpc/tst-cache-ppc-static-dlopen.c [new file with mode: 0644]
sysdeps/powerpc/tst-cache-ppc-static.c [new file with mode: 0644]
sysdeps/powerpc/tst-cache-ppc.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/dl-auxv.h [moved from sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c with 60% similarity]
sysdeps/unix/sysv/linux/powerpc/dl-static.c
sysdeps/unix/sysv/linux/powerpc/libc-start.c

index ad791ab6abe6612a20ab1d7e39b7d7683424e2a7..7704c101c5a543a1b43215381a4d2f0514dbaa2b 100644 (file)
@@ -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)
     {
index 53bbee14f4a9af4afa6e1615f56a9e26a9c73061..854570821c77919d7f89ab1fd19a02bf563f2de8 100644 (file)
@@ -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 (file)
index 0000000..bf3c011
--- /dev/null
@@ -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
index df45d348d2791a0d837c27b163c832f0f00dae46..d1c71a0ca4e83bcf8bbdd8c3bd3854de570bf246 100644 (file)
@@ -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
index 2ae68c41f1a8be91a177bb265a0545d0438b5ad0..7a7d93dd0a3fb299057f84ce34dbdf24c831fe10 100644 (file)
@@ -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 (file)
index 0000000..81fad52
--- /dev/null
@@ -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;
+}
index fe5dab847abbc3f40822f4a28a054f97a6209115..6f4d8a7b34f7702376275b63df10a9283a60648e 100644 (file)
@@ -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.  */
index d5ea4b97f41b6facdf441fa09b8fb801f1b496bc..6090e60d3c3da31bf8c660527978712eed317780 100644 (file)
 #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)
index 5f614c07d7fdf736eb8007ec257005d84b05bb21..26c37f8a17f51ea674af83fd7faef3ab73c60601 100644 (file)
    <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.  */
index ceed9ef1585e10133055da2b71e5cb197a8916ff..0dee5f2757c1c2c2bafd6fb4fe6942fcca0f2056 100644 (file)
@@ -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__ */
index 0e3c435f3c78625ea4c9207a9b61a8ed36f6f6bd..1162cc22077b5ea5425b63d410eb61a3a378adb5 100644 (file)
@@ -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 */
index 857c023755272705992d4e222237a6dda47c3e08..2fa98e6e2d3ed8c3bf51e6191ab4c440ad98dd9f 100644 (file)
    <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
index aefd29a14da91fb526e5b1f0265039bf7f6e6e1b..d6616ac905b9f8deeebfd351825b5ba9ca8e79fd 100644 (file)
@@ -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
index f5ea5a1466c1a4f777ce0070f83c33a66e8ace21..6b348fd5221d0903e2e39a71d79aa1c512bef0ef 100644 (file)
@@ -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 (file)
index 0000000..296d0f4
--- /dev/null
@@ -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 (file)
index 0000000..b0c417e
--- /dev/null
@@ -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 (file)
index 0000000..86c7117
--- /dev/null
@@ -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>
similarity index 60%
rename from sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
rename to sysdeps/unix/sysv/linux/powerpc/dl-auxv.h
index 5d65bc63037d29fc5c57393e9b40512597e8976b..be2189732ae66a5dc15aaff572ac40bc572879ce 100644 (file)
@@ -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
    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>
index 59ce4e89726ab31a840ae5c08228866967f4727c..a77e07b5034f90b8aca0462cc133cf0d22438da3 100644 (file)
@@ -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
index 93f8659fa628616bf0b6a3aea9cb095f1c0e4f51..fc86d6e23481d89b2523a95e2ea5518f3a667d4b 100644 (file)
@@ -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;