diff options
Diffstat (limited to 'sysdeps/x86_64')
-rw-r--r-- | sysdeps/x86_64/Makefile | 44 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-audit3.c | 20 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-audit4.c | 49 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-audit5.c | 21 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-audit6.c | 42 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-audit7.c | 1 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod3a.c | 24 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod3b.c | 151 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod4a.c | 48 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod4b.c | 201 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod5a.c | 46 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod5b.c | 173 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod6a.c | 46 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod6b.c | 215 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod6c.c | 220 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod7a.c | 1 | ||||
-rw-r--r-- | sysdeps/x86_64/tst-auditmod7b.c | 213 |
17 files changed, 1515 insertions, 0 deletions
diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile index 78c98e7c5e..08db331923 100644 --- a/sysdeps/x86_64/Makefile +++ b/sysdeps/x86_64/Makefile @@ -37,6 +37,50 @@ tests-pie += $(quad-pie-test) $(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o $(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o + +tests += tst-audit3 tst-audit4 tst-audit5 +ifeq (yes,$(config-cflags-avx)) +tests += tst-audit6 tst-audit7 +endif +modules-names += tst-auditmod3a tst-auditmod3b \ + tst-auditmod4a tst-auditmod4b \ + tst-auditmod5a tst-auditmod5b \ + tst-auditmod6a tst-auditmod6b tst-auditmod6c \ + tst-auditmod7a tst-auditmod7b + +$(objpfx)tst-audit3: $(objpfx)tst-auditmod3a.so +$(objpfx)tst-audit3.out: $(objpfx)tst-auditmod3b.so +tst-audit3-ENV = LD_AUDIT=$(objpfx)tst-auditmod3b.so + +$(objpfx)tst-audit4: $(objpfx)tst-auditmod4a.so +$(objpfx)tst-audit4.out: $(objpfx)tst-auditmod4b.so +tst-audit4-ENV = LD_AUDIT=$(objpfx)tst-auditmod4b.so + +$(objpfx)tst-audit5: $(objpfx)tst-auditmod5a.so +$(objpfx)tst-audit5.out: $(objpfx)tst-auditmod5b.so +tst-audit5-ENV = LD_AUDIT=$(objpfx)tst-auditmod5b.so + +$(objpfx)tst-audit6: $(objpfx)tst-auditmod6a.so +$(objpfx)tst-audit6.out: $(objpfx)tst-auditmod6b.so \ + $(objpfx)tst-auditmod6c.so +tst-audit6-ENV = LD_AUDIT=$(objpfx)tst-auditmod6b.so:$(objpfx)tst-auditmod6c.so + +$(objpfx)tst-audit7: $(objpfx)tst-auditmod7a.so +$(objpfx)tst-audit7.out: $(objpfx)tst-auditmod7b.so +tst-audit7-ENV = LD_AUDIT=$(objpfx)tst-auditmod7b.so + +ifeq (yes,$(config-cflags-avx)) +AVX-CFLAGS=-mavx +ifeq (yes,$(config-cflags-novzeroupper)) +AVX-CFLAGS+=-mno-vzeroupper +endif +CFLAGS-tst-audit4.c += $(AVX-CFLAGS) +CFLAGS-tst-auditmod4a.c += $(AVX-CFLAGS) +CFLAGS-tst-auditmod4b.c += $(AVX-CFLAGS) +CFLAGS-tst-auditmod6b.c += $(AVX-CFLAGS) +CFLAGS-tst-auditmod6c.c += $(AVX-CFLAGS) +CFLAGS-tst-auditmod7b.c += $(AVX-CFLAGS) +endif endif ifeq ($(subdir),csu) diff --git a/sysdeps/x86_64/tst-audit3.c b/sysdeps/x86_64/tst-audit3.c new file mode 100644 index 0000000000..d00db9972b --- /dev/null +++ b/sysdeps/x86_64/tst-audit3.c @@ -0,0 +1,20 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include <stdlib.h> +#include <string.h> + +#include <emmintrin.h> + +extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i, + __m128i, __m128i, __m128i, __m128i); +int +main (void) +{ + __m128i xmm = _mm_setzero_si128 (); + __m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm); + + if (memcmp (&xmm, &ret, sizeof (ret))) + abort (); + + return 0; +} diff --git a/sysdeps/x86_64/tst-audit4.c b/sysdeps/x86_64/tst-audit4.c new file mode 100644 index 0000000000..c4f1d5bdb9 --- /dev/null +++ b/sysdeps/x86_64/tst-audit4.c @@ -0,0 +1,49 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#ifdef __AVX__ +#include <stdlib.h> +#include <string.h> +#include <cpuid.h> +#include <immintrin.h> + + +static int +avx_enabled (void) +{ + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 + || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) + return 0; + + /* Check the OS has AVX and SSE saving enabled. */ + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + + return (eax & 6) == 6; +} + + +extern __m256i audit_test (__m256i, __m256i, __m256i, __m256i, + __m256i, __m256i, __m256i, __m256i); +int +main (void) +{ + /* Run AVX test only if AVX is supported. */ + if (avx_enabled ()) + { + __m256i ymm = _mm256_setzero_si256 (); + __m256i ret = audit_test (ymm, ymm, ymm, ymm, ymm, ymm, ymm, ymm); + + ymm = _mm256_set1_epi32 (0x12349876); + if (memcmp (&ymm, &ret, sizeof (ret))) + abort (); + } + return 0; +} +#else +int +main (void) +{ + return 0; +} +#endif diff --git a/sysdeps/x86_64/tst-audit5.c b/sysdeps/x86_64/tst-audit5.c new file mode 100644 index 0000000000..0094fee61f --- /dev/null +++ b/sysdeps/x86_64/tst-audit5.c @@ -0,0 +1,21 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include <stdlib.h> +#include <string.h> + +#include <emmintrin.h> + +extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i, + __m128i, __m128i, __m128i, __m128i); +int +main (void) +{ + __m128i xmm = _mm_setzero_si128 (); + __m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm); + + xmm = _mm_set1_epi32 (0x12349876); + if (memcmp (&xmm, &ret, sizeof (ret))) + abort (); + + return 0; +} diff --git a/sysdeps/x86_64/tst-audit6.c b/sysdeps/x86_64/tst-audit6.c new file mode 100644 index 0000000000..64209a152e --- /dev/null +++ b/sysdeps/x86_64/tst-audit6.c @@ -0,0 +1,42 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include <stdlib.h> +#include <string.h> +#include <cpuid.h> +#include <emmintrin.h> + +extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i, + __m128i, __m128i, __m128i, __m128i); + + +static int +avx_enabled (void) +{ + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 + || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) + return 0; + + /* Check the OS has AVX and SSE saving enabled. */ + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + + return (eax & 6) == 6; +} + + +int +main (void) +{ + /* Run AVX test only if AVX is supported. */ + if (avx_enabled ()) + { + __m128i xmm = _mm_setzero_si128 (); + __m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm); + + xmm = _mm_set1_epi32 (0x98abcdef); + if (memcmp (&xmm, &ret, sizeof (ret))) + abort (); + } + return 0; +} diff --git a/sysdeps/x86_64/tst-audit7.c b/sysdeps/x86_64/tst-audit7.c new file mode 100644 index 0000000000..1d2a7de439 --- /dev/null +++ b/sysdeps/x86_64/tst-audit7.c @@ -0,0 +1 @@ +#include "tst-audit6.c" diff --git a/sysdeps/x86_64/tst-auditmod3a.c b/sysdeps/x86_64/tst-auditmod3a.c new file mode 100644 index 0000000000..9514aba505 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod3a.c @@ -0,0 +1,24 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include <stdlib.h> +#include <string.h> +#include <emmintrin.h> + +__m128i +audit_test (__m128i x0, __m128i x1, __m128i x2, __m128i x3, + __m128i x4, __m128i x5, __m128i x6, __m128i x7) +{ + __m128i xmm = _mm_setzero_si128 (); + + if (memcmp (&xmm, &x0, sizeof (xmm)) + || memcmp (&xmm, &x1, sizeof (xmm)) + || memcmp (&xmm, &x2, sizeof (xmm)) + || memcmp (&xmm, &x3, sizeof (xmm)) + || memcmp (&xmm, &x4, sizeof (xmm)) + || memcmp (&xmm, &x5, sizeof (xmm)) + || memcmp (&xmm, &x6, sizeof (xmm)) + || memcmp (&xmm, &x7, sizeof (xmm))) + abort (); + + return xmm; +} diff --git a/sysdeps/x86_64/tst-auditmod3b.c b/sysdeps/x86_64/tst-auditmod3b.c new file mode 100644 index 0000000000..1a41ca80c0 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod3b.c @@ -0,0 +1,151 @@ +/* Verify that changing xmm registers in audit library won't affect + function parameter passing/return. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <bits/wordsize.h> +#include <gnu/lib-names.h> +#include <emmintrin.h> + +unsigned int +la_version (unsigned int v) +{ + setlinebuf (stdout); + + printf ("version: %u\n", v); + + char buf[20]; + sprintf (buf, "%u", v); + + return v; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + if (flag == LA_ACT_CONSISTENT) + printf ("activity: consistent\n"); + else if (flag == LA_ACT_ADD) + printf ("activity: add\n"); + else if (flag == LA_ACT_DELETE) + printf ("activity: delete\n"); + else + printf ("activity: unknown activity %u\n", flag); +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + char buf[100]; + const char *flagstr; + if (flag == LA_SER_ORIG) + flagstr = "LA_SET_ORIG"; + else if (flag == LA_SER_LIBPATH) + flagstr = "LA_SER_LIBPATH"; + else if (flag == LA_SER_RUNPATH) + flagstr = "LA_SER_RUNPATH"; + else if (flag == LA_SER_CONFIG) + flagstr = "LA_SER_CONFIG"; + else if (flag == LA_SER_DEFAULT) + flagstr = "LA_SER_DEFAULT"; + else if (flag == LA_SER_SECURE) + flagstr = "LA_SER_SECURE"; + else + { + sprintf (buf, "unknown flag %d", flag); + flagstr = buf; + } + printf ("objsearch: %s, %s\n", name, flagstr); + + return (char *) name; +} + +unsigned int +la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie) +{ + printf ("objopen: %ld, %s\n", lmid, l->l_name); + + return 3; +} + +void +la_preinit (uintptr_t *cookie) +{ + printf ("preinit\n"); +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + printf ("objclose\n"); + return 0; +} + +uintptr_t +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +{ + printf ("symbind32: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +{ + printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +#include <tst-audit.h> + +ElfW(Addr) +pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + __m128i xmm = _mm_set1_epi32 (-1); + asm volatile ("movdqa %0, %%xmm0" : : "x" (xmm) : "xmm0" ); + asm volatile ("movdqa %0, %%xmm1" : : "x" (xmm) : "xmm1" ); + asm volatile ("movdqa %0, %%xmm2" : : "x" (xmm) : "xmm2" ); + asm volatile ("movdqa %0, %%xmm3" : : "x" (xmm) : "xmm3" ); + asm volatile ("movdqa %0, %%xmm4" : : "x" (xmm) : "xmm4" ); + asm volatile ("movdqa %0, %%xmm5" : : "x" (xmm) : "xmm5" ); + asm volatile ("movdqa %0, %%xmm6" : : "x" (xmm) : "xmm6" ); + asm volatile ("movdqa %0, %%xmm7" : : "x" (xmm) : "xmm7" ); + + return sym->st_value; +} + +unsigned int +pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, + const char *symname) +{ + printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", + symname, (long int) sym->st_value, ndx, + (ptrdiff_t) outregs->int_retval); + + __m128i xmm = _mm_set1_epi32 (-1); + asm volatile ("movdqa %0, %%xmm0" : : "x" (xmm) : "xmm0" ); + asm volatile ("movdqa %0, %%xmm1" : : "x" (xmm) : "xmm1" ); + asm volatile ("movdqa %0, %%xmm2" : : "x" (xmm) : "xmm2" ); + asm volatile ("movdqa %0, %%xmm3" : : "x" (xmm) : "xmm3" ); + asm volatile ("movdqa %0, %%xmm4" : : "x" (xmm) : "xmm4" ); + asm volatile ("movdqa %0, %%xmm5" : : "x" (xmm) : "xmm5" ); + asm volatile ("movdqa %0, %%xmm6" : : "x" (xmm) : "xmm6" ); + asm volatile ("movdqa %0, %%xmm7" : : "x" (xmm) : "xmm7" ); + + return 0; +} diff --git a/sysdeps/x86_64/tst-auditmod4a.c b/sysdeps/x86_64/tst-auditmod4a.c new file mode 100644 index 0000000000..c9c24c04a8 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod4a.c @@ -0,0 +1,48 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#ifdef __AVX__ +#include <stdlib.h> +#include <string.h> +#include <immintrin.h> + +__m256i +audit_test (__m256i x0, __m256i x1, __m256i x2, __m256i x3, + __m256i x4, __m256i x5, __m256i x6, __m256i x7) +{ + __m256i ymm; + + ymm = _mm256_set1_epi32 (1); + if (memcmp (&ymm, &x0, sizeof (ymm))) + abort (); + + ymm = _mm256_set1_epi32 (2); + if (memcmp (&ymm, &x1, sizeof (ymm))) + abort (); + + ymm = _mm256_set1_epi32 (3); + if (memcmp (&ymm, &x2, sizeof (ymm))) + abort (); + + ymm = _mm256_set1_epi32 (4); + if (memcmp (&ymm, &x3, sizeof (ymm))) + abort (); + + ymm = _mm256_set1_epi32 (5); + if (memcmp (&ymm, &x4, sizeof (ymm))) + abort (); + + ymm = _mm256_set1_epi32 (6); + if (memcmp (&ymm, &x5, sizeof (ymm))) + abort (); + + ymm = _mm256_set1_epi32 (7); + if (memcmp (&ymm, &x6, sizeof (ymm))) + abort (); + + ymm = _mm256_set1_epi32 (8); + if (memcmp (&ymm, &x7, sizeof (ymm))) + abort (); + + return _mm256_setzero_si256 (); +} +#endif diff --git a/sysdeps/x86_64/tst-auditmod4b.c b/sysdeps/x86_64/tst-auditmod4b.c new file mode 100644 index 0000000000..80aaedcd3e --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod4b.c @@ -0,0 +1,201 @@ +/* Verify that changing AVX registers in audit library won't affect + function parameter passing/return. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <bits/wordsize.h> +#include <gnu/lib-names.h> + +unsigned int +la_version (unsigned int v) +{ + setlinebuf (stdout); + + printf ("version: %u\n", v); + + char buf[20]; + sprintf (buf, "%u", v); + + return v; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + if (flag == LA_ACT_CONSISTENT) + printf ("activity: consistent\n"); + else if (flag == LA_ACT_ADD) + printf ("activity: add\n"); + else if (flag == LA_ACT_DELETE) + printf ("activity: delete\n"); + else + printf ("activity: unknown activity %u\n", flag); +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + char buf[100]; + const char *flagstr; + if (flag == LA_SER_ORIG) + flagstr = "LA_SET_ORIG"; + else if (flag == LA_SER_LIBPATH) + flagstr = "LA_SER_LIBPATH"; + else if (flag == LA_SER_RUNPATH) + flagstr = "LA_SER_RUNPATH"; + else if (flag == LA_SER_CONFIG) + flagstr = "LA_SER_CONFIG"; + else if (flag == LA_SER_DEFAULT) + flagstr = "LA_SER_DEFAULT"; + else if (flag == LA_SER_SECURE) + flagstr = "LA_SER_SECURE"; + else + { + sprintf (buf, "unknown flag %d", flag); + flagstr = buf; + } + printf ("objsearch: %s, %s\n", name, flagstr); + + return (char *) name; +} + +unsigned int +la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie) +{ + printf ("objopen: %ld, %s\n", lmid, l->l_name); + + return 3; +} + +void +la_preinit (uintptr_t *cookie) +{ + printf ("preinit\n"); +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + printf ("objclose\n"); + return 0; +} + +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +{ + printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +#include <tst-audit.h> + +#ifdef __AVX__ +#include <immintrin.h> +#include <cpuid.h> + +static int avx = -1; + +static inline int +__attribute ((always_inline)) +check_avx (void) +{ + if (avx == -1) + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) + && (ecx & bit_AVX)) + avx = 1; + else + avx = 0; + } + return avx; +} +#else +#include <emmintrin.h> +#endif + +ElfW(Addr) +pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + __m256i zero = _mm256_setzero_si256 (); + if (memcmp (®s->lr_vector[0], &zero, sizeof (zero)) + || memcmp (®s->lr_vector[1], &zero, sizeof (zero)) + || memcmp (®s->lr_vector[2], &zero, sizeof (zero)) + || memcmp (®s->lr_vector[3], &zero, sizeof (zero)) + || memcmp (®s->lr_vector[4], &zero, sizeof (zero)) + || memcmp (®s->lr_vector[5], &zero, sizeof (zero)) + || memcmp (®s->lr_vector[6], &zero, sizeof (zero)) + || memcmp (®s->lr_vector[7], &zero, sizeof (zero))) + abort (); + + for (int i = 0; i < 8; i++) + regs->lr_vector[i].ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (i + 1); + + __m256i ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + asm volatile ("vmovdqa %0, %%ymm2" : : "x" (ymm) : "xmm2" ); + asm volatile ("vmovdqa %0, %%ymm3" : : "x" (ymm) : "xmm3" ); + asm volatile ("vmovdqa %0, %%ymm4" : : "x" (ymm) : "xmm4" ); + asm volatile ("vmovdqa %0, %%ymm5" : : "x" (ymm) : "xmm5" ); + asm volatile ("vmovdqa %0, %%ymm6" : : "x" (ymm) : "xmm6" ); + asm volatile ("vmovdqa %0, %%ymm7" : : "x" (ymm) : "xmm7" ); + + *framesizep = 1024; + } +#endif + + return sym->st_value; +} + +unsigned int +pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, + const char *symname) +{ + printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", + symname, (long int) sym->st_value, ndx, + (ptrdiff_t) outregs->int_retval); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + __m256i zero = _mm256_setzero_si256 (); + if (memcmp (&outregs->lrv_vector0, &zero, sizeof (zero))) + abort (); + + for (int i = 0; i < 8; i++) + { + __m256i ymm = _mm256_set1_epi32 (i + 1); + if (memcmp (&inregs->lr_vector[i], &ymm, sizeof (ymm)) != 0) + abort (); + } + + outregs->lrv_vector0.ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (0x12349876); + + __m256i ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + } +#endif + + return 0; +} diff --git a/sysdeps/x86_64/tst-auditmod5a.c b/sysdeps/x86_64/tst-auditmod5a.c new file mode 100644 index 0000000000..8511a70747 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod5a.c @@ -0,0 +1,46 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include <stdlib.h> +#include <string.h> +#include <emmintrin.h> + +__m128i +audit_test (__m128i x0, __m128i x1, __m128i x2, __m128i x3, + __m128i x4, __m128i x5, __m128i x6, __m128i x7) +{ + __m128i xmm; + + xmm = _mm_set1_epi32 (1); + if (memcmp (&xmm, &x0, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (2); + if (memcmp (&xmm, &x1, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (3); + if (memcmp (&xmm, &x2, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (4); + if (memcmp (&xmm, &x3, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (5); + if (memcmp (&xmm, &x4, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (6); + if (memcmp (&xmm, &x5, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (7); + if (memcmp (&xmm, &x6, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (8); + if (memcmp (&xmm, &x7, sizeof (xmm))) + abort (); + + return _mm_setzero_si128 (); +} diff --git a/sysdeps/x86_64/tst-auditmod5b.c b/sysdeps/x86_64/tst-auditmod5b.c new file mode 100644 index 0000000000..576183d722 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod5b.c @@ -0,0 +1,173 @@ +/* Verify that changing xmm registers in audit library won't affect + function parameter passing/return. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <bits/wordsize.h> +#include <gnu/lib-names.h> +#include <emmintrin.h> + +unsigned int +la_version (unsigned int v) +{ + setlinebuf (stdout); + + printf ("version: %u\n", v); + + char buf[20]; + sprintf (buf, "%u", v); + + return v; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + if (flag == LA_ACT_CONSISTENT) + printf ("activity: consistent\n"); + else if (flag == LA_ACT_ADD) + printf ("activity: add\n"); + else if (flag == LA_ACT_DELETE) + printf ("activity: delete\n"); + else + printf ("activity: unknown activity %u\n", flag); +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + char buf[100]; + const char *flagstr; + if (flag == LA_SER_ORIG) + flagstr = "LA_SET_ORIG"; + else if (flag == LA_SER_LIBPATH) + flagstr = "LA_SER_LIBPATH"; + else if (flag == LA_SER_RUNPATH) + flagstr = "LA_SER_RUNPATH"; + else if (flag == LA_SER_CONFIG) + flagstr = "LA_SER_CONFIG"; + else if (flag == LA_SER_DEFAULT) + flagstr = "LA_SER_DEFAULT"; + else if (flag == LA_SER_SECURE) + flagstr = "LA_SER_SECURE"; + else + { + sprintf (buf, "unknown flag %d", flag); + flagstr = buf; + } + printf ("objsearch: %s, %s\n", name, flagstr); + + return (char *) name; +} + +unsigned int +la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie) +{ + printf ("objopen: %ld, %s\n", lmid, l->l_name); + + return 3; +} + +void +la_preinit (uintptr_t *cookie) +{ + printf ("preinit\n"); +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + printf ("objclose\n"); + return 0; +} + +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +{ + printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +#include <tst-audit.h> + +ElfW(Addr) +pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + __m128i minusone = _mm_set1_epi32 (-1); + + if (strcmp (symname, "audit_test") == 0) + { + __m128i zero = _mm_setzero_si128 (); + if (memcmp (®s->lr_xmm[0], &zero, sizeof (zero)) + || memcmp (®s->lr_xmm[1], &zero, sizeof (zero)) + || memcmp (®s->lr_xmm[2], &zero, sizeof (zero)) + || memcmp (®s->lr_xmm[3], &zero, sizeof (zero)) + || memcmp (®s->lr_xmm[4], &zero, sizeof (zero)) + || memcmp (®s->lr_xmm[5], &zero, sizeof (zero)) + || memcmp (®s->lr_xmm[6], &zero, sizeof (zero)) + || memcmp (®s->lr_xmm[7], &zero, sizeof (zero))) + abort (); + + for (int i = 0; i < 8; i++) + regs->lr_xmm[i] = (La_x86_64_xmm) _mm_set1_epi32 (i + 1); + + *framesizep = 1024; + } + + asm volatile ("movdqa %0, %%xmm0" : : "x" (minusone) : "xmm0" ); + asm volatile ("movdqa %0, %%xmm1" : : "x" (minusone) : "xmm1" ); + asm volatile ("movdqa %0, %%xmm2" : : "x" (minusone) : "xmm2" ); + asm volatile ("movdqa %0, %%xmm3" : : "x" (minusone) : "xmm3" ); + asm volatile ("movdqa %0, %%xmm4" : : "x" (minusone) : "xmm4" ); + asm volatile ("movdqa %0, %%xmm5" : : "x" (minusone) : "xmm5" ); + asm volatile ("movdqa %0, %%xmm6" : : "x" (minusone) : "xmm6" ); + asm volatile ("movdqa %0, %%xmm7" : : "x" (minusone) : "xmm7" ); + + return sym->st_value; +} + +unsigned int +pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, + const char *symname) +{ + printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", + symname, (long int) sym->st_value, ndx, + (ptrdiff_t) outregs->int_retval); + + __m128i xmm; + + if (strcmp (symname, "audit_test") == 0) + { + __m128i zero = _mm_setzero_si128 (); + if (memcmp (&outregs->lrv_xmm0, &zero, sizeof (zero))) + abort (); + + for (int i = 0; i < 8; i++) + { + xmm = _mm_set1_epi32 (i + 1); + if (memcmp (&inregs->lr_xmm[i], &xmm, sizeof (xmm)) != 0) + abort (); + } + + outregs->lrv_xmm0 = (La_x86_64_xmm) _mm_set1_epi32 (0x12349876); + } + + xmm = _mm_set1_epi32 (-1); + asm volatile ("movdqa %0, %%xmm0" : : "x" (xmm) : "xmm0" ); + asm volatile ("movdqa %0, %%xmm1" : : "x" (xmm) : "xmm1" ); + + return 0; +} diff --git a/sysdeps/x86_64/tst-auditmod6a.c b/sysdeps/x86_64/tst-auditmod6a.c new file mode 100644 index 0000000000..c3a850ce98 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod6a.c @@ -0,0 +1,46 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include <stdlib.h> +#include <string.h> +#include <emmintrin.h> + +__m128i +audit_test (__m128i x0, __m128i x1, __m128i x2, __m128i x3, + __m128i x4, __m128i x5, __m128i x6, __m128i x7) +{ + __m128i xmm; + + xmm = _mm_set1_epi32 (0x100); + if (memcmp (&xmm, &x0, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (0x101); + if (memcmp (&xmm, &x1, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (0x102); + if (memcmp (&xmm, &x2, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (0x103); + if (memcmp (&xmm, &x3, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (0x104); + if (memcmp (&xmm, &x4, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (0x105); + if (memcmp (&xmm, &x5, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (0x106); + if (memcmp (&xmm, &x6, sizeof (xmm))) + abort (); + + xmm = _mm_set1_epi32 (0x107); + if (memcmp (&xmm, &x7, sizeof (xmm))) + abort (); + + return _mm_setzero_si128 (); +} diff --git a/sysdeps/x86_64/tst-auditmod6b.c b/sysdeps/x86_64/tst-auditmod6b.c new file mode 100644 index 0000000000..b1c155a26e --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod6b.c @@ -0,0 +1,215 @@ +/* Verify that changing AVX registers in audit library won't affect + function parameter passing/return. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <bits/wordsize.h> +#include <gnu/lib-names.h> + +unsigned int +la_version (unsigned int v) +{ + setlinebuf (stdout); + + printf ("version: %u\n", v); + + char buf[20]; + sprintf (buf, "%u", v); + + return v; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + if (flag == LA_ACT_CONSISTENT) + printf ("activity: consistent\n"); + else if (flag == LA_ACT_ADD) + printf ("activity: add\n"); + else if (flag == LA_ACT_DELETE) + printf ("activity: delete\n"); + else + printf ("activity: unknown activity %u\n", flag); +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + char buf[100]; + const char *flagstr; + if (flag == LA_SER_ORIG) + flagstr = "LA_SET_ORIG"; + else if (flag == LA_SER_LIBPATH) + flagstr = "LA_SER_LIBPATH"; + else if (flag == LA_SER_RUNPATH) + flagstr = "LA_SER_RUNPATH"; + else if (flag == LA_SER_CONFIG) + flagstr = "LA_SER_CONFIG"; + else if (flag == LA_SER_DEFAULT) + flagstr = "LA_SER_DEFAULT"; + else if (flag == LA_SER_SECURE) + flagstr = "LA_SER_SECURE"; + else + { + sprintf (buf, "unknown flag %d", flag); + flagstr = buf; + } + printf ("objsearch: %s, %s\n", name, flagstr); + + return (char *) name; +} + +unsigned int +la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie) +{ + printf ("objopen: %ld, %s\n", lmid, l->l_name); + + return 3; +} + +void +la_preinit (uintptr_t *cookie) +{ + printf ("preinit\n"); +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + printf ("objclose\n"); + return 0; +} + +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +{ + printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +#include <tst-audit.h> + +#ifdef __AVX__ +#include <immintrin.h> +#include <cpuid.h> + +static int avx = -1; + +static inline int +__attribute ((always_inline)) +check_avx (void) +{ + if (avx == -1) + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) + && (ecx & bit_AVX)) + avx = 1; + else + avx = 0; + } + return avx; +} +#else +#include <emmintrin.h> +#endif + +ElfW(Addr) +pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + int i; + + __m128i xmm = _mm_setzero_si128 (); + for (i = 0; i < 8; i++) + if (memcmp (®s->lr_xmm[i], &xmm, sizeof (xmm)) + || memcmp (®s->lr_vector[i], &xmm, sizeof (xmm))) + abort (); + + for (i = 0; i < 8; i += 2) + { + regs->lr_xmm[i] = (La_x86_64_xmm) _mm_set1_epi32 (i + 1); + regs->lr_vector[i].xmm[0] = regs->lr_xmm[i]; + regs->lr_vector[i + 1].ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (i + 2); + regs->lr_xmm[i + 1] = regs->lr_vector[i + 1].xmm[0]; + } + + __m256i ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + asm volatile ("vmovdqa %0, %%ymm2" : : "x" (ymm) : "xmm2" ); + asm volatile ("vmovdqa %0, %%ymm3" : : "x" (ymm) : "xmm3" ); + asm volatile ("vmovdqa %0, %%ymm4" : : "x" (ymm) : "xmm4" ); + asm volatile ("vmovdqa %0, %%ymm5" : : "x" (ymm) : "xmm5" ); + asm volatile ("vmovdqa %0, %%ymm6" : : "x" (ymm) : "xmm6" ); + asm volatile ("vmovdqa %0, %%ymm7" : : "x" (ymm) : "xmm7" ); + + *framesizep = 1024; + } +#endif + + return sym->st_value; +} + +unsigned int +pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, + const char *symname) +{ + printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", + symname, (long int) sym->st_value, ndx, + (ptrdiff_t) outregs->int_retval); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + int i; + + __m128i xmm = _mm_setzero_si128 (); + if (memcmp (&outregs->lrv_xmm0, &xmm, sizeof (xmm)) + || memcmp (&outregs->lrv_vector0, &xmm, sizeof (xmm))) + abort (); + + __m256i ymm; + + for (i = 0; i < 8; i += 2) + { + xmm = _mm_set1_epi32 (i + 0x100); + if (memcmp (&inregs->lr_xmm[i], &xmm, sizeof (xmm)) + || memcmp (&inregs->lr_vector[i], &xmm, sizeof (xmm))) + abort (); + + ymm = _mm256_set1_epi32 (i + 0x101); + if (memcmp (&inregs->lr_xmm[i + 1], + &inregs->lr_vector[i + 1].xmm[0], sizeof (xmm)) + || memcmp (&inregs->lr_vector[i + 1], &ymm, sizeof (ymm))) + abort (); + } + + outregs->lrv_vector0.ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (0x12349876); + + ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + } +#endif + + return 0; +} diff --git a/sysdeps/x86_64/tst-auditmod6c.c b/sysdeps/x86_64/tst-auditmod6c.c new file mode 100644 index 0000000000..88adb21aa1 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod6c.c @@ -0,0 +1,220 @@ +/* Verify that changing AVX registers in audit library won't affect + function parameter passing/return. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <bits/wordsize.h> +#include <gnu/lib-names.h> + +unsigned int +la_version (unsigned int v) +{ + setlinebuf (stdout); + + printf ("version: %u\n", v); + + char buf[20]; + sprintf (buf, "%u", v); + + return v; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + if (flag == LA_ACT_CONSISTENT) + printf ("activity: consistent\n"); + else if (flag == LA_ACT_ADD) + printf ("activity: add\n"); + else if (flag == LA_ACT_DELETE) + printf ("activity: delete\n"); + else + printf ("activity: unknown activity %u\n", flag); +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + char buf[100]; + const char *flagstr; + if (flag == LA_SER_ORIG) + flagstr = "LA_SET_ORIG"; + else if (flag == LA_SER_LIBPATH) + flagstr = "LA_SER_LIBPATH"; + else if (flag == LA_SER_RUNPATH) + flagstr = "LA_SER_RUNPATH"; + else if (flag == LA_SER_CONFIG) + flagstr = "LA_SER_CONFIG"; + else if (flag == LA_SER_DEFAULT) + flagstr = "LA_SER_DEFAULT"; + else if (flag == LA_SER_SECURE) + flagstr = "LA_SER_SECURE"; + else + { + sprintf (buf, "unknown flag %d", flag); + flagstr = buf; + } + printf ("objsearch: %s, %s\n", name, flagstr); + + return (char *) name; +} + +unsigned int +la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie) +{ + printf ("objopen: %ld, %s\n", lmid, l->l_name); + + return 3; +} + +void +la_preinit (uintptr_t *cookie) +{ + printf ("preinit\n"); +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + printf ("objclose\n"); + return 0; +} + +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +{ + printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +#include <tst-audit.h> + +#ifdef __AVX__ +#include <immintrin.h> +#include <cpuid.h> + +static int avx = -1; + +static inline int +__attribute ((always_inline)) +check_avx (void) +{ + if (avx == -1) + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) + && (ecx & bit_AVX)) + avx = 1; + else + avx = 0; + } + return avx; +} +#else +#include <emmintrin.h> +#endif + +ElfW(Addr) +pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + int i; + __m128i xmm; + __m256i ymm; + + for (i = 0; i < 8; i += 2) + { + xmm = _mm_set1_epi32 (i + 1); + if (memcmp (®s->lr_xmm[i], &xmm, sizeof (xmm)) + || memcmp (®s->lr_vector[i], &xmm, sizeof (xmm))) + abort (); + regs->lr_xmm[i] = (La_x86_64_xmm) _mm_set1_epi32 (i + 0x100); + regs->lr_vector[i].xmm[0] = regs->lr_xmm[i]; + + ymm = _mm256_set1_epi32 (i + 2); + if (memcmp (®s->lr_xmm[i + 1], + ®s->lr_vector[i + 1].xmm[0], sizeof (xmm)) + || memcmp (®s->lr_vector[i + 1], &ymm, sizeof (ymm))) + abort (); + regs->lr_vector[i + 1].ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (i + 0x101); + regs->lr_xmm[i + 1] = regs->lr_vector[i + 1].xmm[0]; + } + + ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + asm volatile ("vmovdqa %0, %%ymm2" : : "x" (ymm) : "xmm2" ); + asm volatile ("vmovdqa %0, %%ymm3" : : "x" (ymm) : "xmm3" ); + asm volatile ("vmovdqa %0, %%ymm4" : : "x" (ymm) : "xmm4" ); + asm volatile ("vmovdqa %0, %%ymm5" : : "x" (ymm) : "xmm5" ); + asm volatile ("vmovdqa %0, %%ymm6" : : "x" (ymm) : "xmm6" ); + asm volatile ("vmovdqa %0, %%ymm7" : : "x" (ymm) : "xmm7" ); + + *framesizep = 1024; + } +#endif + + return sym->st_value; +} + +unsigned int +pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, + const char *symname) +{ + printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", + symname, (long int) sym->st_value, ndx, + (ptrdiff_t) outregs->int_retval); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + int i; + + __m256i ymm = _mm256_set1_epi32 (0x12349876);; + if (memcmp (&outregs->lrv_vector0, &ymm, sizeof (ymm))) + abort (); + + __m128i xmm; + + for (i = 0; i < 8; i += 2) + { + xmm = _mm_set1_epi32 (i + 0x100); + if (memcmp (&inregs->lr_xmm[i], &xmm, sizeof (xmm)) + || memcmp (&inregs->lr_vector[i], &xmm, sizeof (xmm))) + abort (); + + ymm = _mm256_set1_epi32 (i + 0x101); + if (memcmp (&inregs->lr_xmm[i + 1], + &inregs->lr_vector[i + 1].xmm[0], sizeof (xmm)) + || memcmp (&inregs->lr_vector[i + 1], &ymm, sizeof (ymm))) + abort (); + } + + outregs->lrv_vector0.ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (0x98abcdef); + + ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + } +#endif + + return 0; +} diff --git a/sysdeps/x86_64/tst-auditmod7a.c b/sysdeps/x86_64/tst-auditmod7a.c new file mode 100644 index 0000000000..b379df75d6 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod7a.c @@ -0,0 +1 @@ +#include "tst-auditmod6a.c" diff --git a/sysdeps/x86_64/tst-auditmod7b.c b/sysdeps/x86_64/tst-auditmod7b.c new file mode 100644 index 0000000000..68052efe97 --- /dev/null +++ b/sysdeps/x86_64/tst-auditmod7b.c @@ -0,0 +1,213 @@ +/* Verify that changing AVX registers in audit library won't affect + function parameter passing/return. */ + +#include <dlfcn.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <bits/wordsize.h> +#include <gnu/lib-names.h> + +unsigned int +la_version (unsigned int v) +{ + setlinebuf (stdout); + + printf ("version: %u\n", v); + + char buf[20]; + sprintf (buf, "%u", v); + + return v; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + if (flag == LA_ACT_CONSISTENT) + printf ("activity: consistent\n"); + else if (flag == LA_ACT_ADD) + printf ("activity: add\n"); + else if (flag == LA_ACT_DELETE) + printf ("activity: delete\n"); + else + printf ("activity: unknown activity %u\n", flag); +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + char buf[100]; + const char *flagstr; + if (flag == LA_SER_ORIG) + flagstr = "LA_SET_ORIG"; + else if (flag == LA_SER_LIBPATH) + flagstr = "LA_SER_LIBPATH"; + else if (flag == LA_SER_RUNPATH) + flagstr = "LA_SER_RUNPATH"; + else if (flag == LA_SER_CONFIG) + flagstr = "LA_SER_CONFIG"; + else if (flag == LA_SER_DEFAULT) + flagstr = "LA_SER_DEFAULT"; + else if (flag == LA_SER_SECURE) + flagstr = "LA_SER_SECURE"; + else + { + sprintf (buf, "unknown flag %d", flag); + flagstr = buf; + } + printf ("objsearch: %s, %s\n", name, flagstr); + + return (char *) name; +} + +unsigned int +la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie) +{ + printf ("objopen: %ld, %s\n", lmid, l->l_name); + + return 3; +} + +void +la_preinit (uintptr_t *cookie) +{ + printf ("preinit\n"); +} + +unsigned int +la_objclose (uintptr_t *cookie) +{ + printf ("objclose\n"); + return 0; +} + +uintptr_t +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +{ + printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +#include <tst-audit.h> + +#ifdef __AVX__ +#include <immintrin.h> +#include <cpuid.h> + +static int avx = -1; + +static inline int +__attribute ((always_inline)) +check_avx (void) +{ + if (avx == -1) + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) + && (ecx & bit_AVX)) + avx = 1; + else + avx = 0; + } + return avx; +} +#else +#include <emmintrin.h> +#endif + +ElfW(Addr) +pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + int i; + + __m128i xmm = _mm_setzero_si128 (); + for (i = 0; i < 8; i++) + if (memcmp (®s->lr_xmm[i], &xmm, sizeof (xmm)) + || memcmp (®s->lr_vector[i], &xmm, sizeof (xmm))) + abort (); + + for (i = 0; i < 8; i += 2) + { + regs->lr_xmm[i] = (La_x86_64_xmm) _mm_set1_epi32 (i + 0x100); + regs->lr_vector[i + 1].ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (i + 0x101); + } + + __m256i ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + asm volatile ("vmovdqa %0, %%ymm2" : : "x" (ymm) : "xmm2" ); + asm volatile ("vmovdqa %0, %%ymm3" : : "x" (ymm) : "xmm3" ); + asm volatile ("vmovdqa %0, %%ymm4" : : "x" (ymm) : "xmm4" ); + asm volatile ("vmovdqa %0, %%ymm5" : : "x" (ymm) : "xmm5" ); + asm volatile ("vmovdqa %0, %%ymm6" : : "x" (ymm) : "xmm6" ); + asm volatile ("vmovdqa %0, %%ymm7" : : "x" (ymm) : "xmm7" ); + + *framesizep = 1024; + } +#endif + + return sym->st_value; +} + +unsigned int +pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, + const char *symname) +{ + printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", + symname, (long int) sym->st_value, ndx, + (ptrdiff_t) outregs->int_retval); + +#ifdef __AVX__ + if (check_avx () && strcmp (symname, "audit_test") == 0) + { + int i; + + __m128i xmm = _mm_setzero_si128 (); + if (memcmp (&outregs->lrv_xmm0, &xmm, sizeof (xmm)) + || memcmp (&outregs->lrv_vector0, &xmm, sizeof (xmm))) + abort (); + + __m256i ymm; + + for (i = 0; i < 8; i += 2) + { + xmm = _mm_set1_epi32 (i + 0x100); + if (memcmp (&inregs->lr_xmm[i], &xmm, sizeof (xmm)) + || memcmp (&inregs->lr_vector[i], &xmm, sizeof (xmm))) + abort (); + + ymm = _mm256_set1_epi32 (i + 0x101); + if (memcmp (&inregs->lr_xmm[i + 1], + &inregs->lr_vector[i + 1].xmm[0], sizeof (xmm)) + || memcmp (&inregs->lr_vector[i + 1], &ymm, sizeof (ymm))) + abort (); + } + + outregs->lrv_vector0.ymm[0] + = (La_x86_64_ymm) _mm256_set1_epi32 (0x98abcdef); + + ymm = _mm256_set1_epi32 (-1); + asm volatile ("vmovdqa %0, %%ymm0" : : "x" (ymm) : "xmm0" ); + asm volatile ("vmovdqa %0, %%ymm1" : : "x" (ymm) : "xmm1" ); + } +#endif + + return 0; +} |