mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
powerpc: Move cache line size to rtld_global_ro
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>
This commit is contained in:
parent
c908ae0492
commit
18363b4f01
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
21
sysdeps/generic/dl-auxv.h
Normal file
21
sysdeps/generic/dl-auxv.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
45
sysdeps/powerpc/mod-cache-ppc.c
Normal file
45
sysdeps/powerpc/mod-cache-ppc.c
Normal file
@ -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;
|
||||
}
|
@ -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. */
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
/* If the remaining length is less the 32 bytes then don't bother getting
|
||||
the cache line size. */
|
||||
beq L(medium)
|
||||
#ifdef PIC
|
||||
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. */
|
||||
/* 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. */
|
||||
|
@ -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__ */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
54
sysdeps/powerpc/tst-cache-ppc-static-dlopen.c
Normal file
54
sysdeps/powerpc/tst-cache-ppc-static-dlopen.c
Normal file
@ -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>
|
20
sysdeps/powerpc/tst-cache-ppc-static.c
Normal file
20
sysdeps/powerpc/tst-cache-ppc-static.c
Normal file
@ -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"
|
29
sysdeps/powerpc/tst-cache-ppc.c
Normal file
29
sysdeps/powerpc/tst-cache-ppc.c
Normal file
@ -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>
|
@ -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>
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user