From 167d5ed5de0c6e587506b8a595fe0e4aa630bbb0 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 2 Jul 2009 04:33:12 -0700 Subject: [PATCH] Fix handling of xmm6 in ld.so audit hooks on x86-64. --- ChangeLog | 13 ++++ elf/Makefile | 11 ++- elf/tst-audit3.c | 20 ++++++ elf/tst-auditmod3a.c | 24 +++++++ elf/tst-auditmod3b.c | 156 +++++++++++++++++++++++++++++++++++++++++ sysdeps/x86_64/dl-trampoline.S | 6 +- 6 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 elf/tst-audit3.c create mode 100644 elf/tst-auditmod3a.c create mode 100644 elf/tst-auditmod3b.c diff --git a/ChangeLog b/ChangeLog index b3c403dc16..795d07ec48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2009-06-30 H.J. Lu + * elf/Makefile (distribute): Remove tst-audit.sh. Add + tst-audit2.c, tst-audit3.c, tst-auditmod3a.c, tst-auditmod3b.c. + (tests): Add tst-audit3 for x86_64. + (modules-names): Add tst-auditmod3a, tst-auditmod3b. + ($(objpfx)tst-audit3): Define. + ($(objpfx)tst-audit3.out): Define. + (tst-audit3-ENV): Define. + * elf/tst-audit3.c: New file. + * elf/tst-auditmod3a.c: New file. + * elf/tst-auditmod3b.c: New file. + * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Save + and restore xmm6. + * string/stpncpy.c (STPNCPY): New. Defined if not defined. (__stpncpy): Renamed to ... (STPNCPY): This. diff --git a/elf/Makefile b/elf/Makefile index 56935d5a1a..57febea483 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -89,7 +89,8 @@ distribute := rtld-Rules \ unload4mod1.c unload4mod2.c unload4mod3.c unload4mod4.c \ unload6mod1.c unload6mod2.c unload6mod3.c \ unload7mod1.c unload7mod2.c \ - tst-auditmod1.c tst-audit.sh \ + tst-audit1.c tst-audit2.c tst-audit3.c \ + tst-auditmod1.c tst-auditmod3a.c tst-auditmod3b.c \ order2mod1.c order2mod2.c order2mod3.c order2mod4.c \ tst-stackguard1.c tst-stackguard1-static.c \ tst-array5.c tst-array5-static.c tst-array5dep.c \ @@ -193,6 +194,9 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ # reldep9 test-srcs = tst-pathopt tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog +ifeq (x86_64,$(config-machine)) +tests += tst-audit3 +endif endif ifeq (yesyes,$(have-fpie)$(build-shared)) tests: $(objpfx)tst-pie1.out @@ -230,6 +234,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ $(modules-execstack-$(have-z-execstack)) \ tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \ tst-dlmopen1mod tst-auditmod1 \ + tst-auditmod3a tst-auditmod3b \ unload3mod1 unload3mod2 unload3mod3 unload3mod4 \ unload4mod1 unload4mod2 unload4mod3 unload4mod4 \ unload6mod1 unload6mod2 unload6mod3 \ @@ -959,6 +964,10 @@ tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so $(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so +$(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-global1: $(libdl) $(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so diff --git a/elf/tst-audit3.c b/elf/tst-audit3.c new file mode 100644 index 0000000000..ae86cc6b7d --- /dev/null +++ b/elf/tst-audit3.c @@ -0,0 +1,20 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include +#include + +#include + +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/elf/tst-auditmod3a.c b/elf/tst-auditmod3a.c new file mode 100644 index 0000000000..6019589e24 --- /dev/null +++ b/elf/tst-auditmod3a.c @@ -0,0 +1,24 @@ +/* Test case for x86-64 preserved registers in dynamic linker. */ + +#include +#include +#include + +__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/elf/tst-auditmod3b.c b/elf/tst-auditmod3b.c new file mode 100644 index 0000000000..388ed6e49c --- /dev/null +++ b/elf/tst-auditmod3b.c @@ -0,0 +1,156 @@ +/* Verify that changing xmm registers in audit library won't affect + function parameter passing/return. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} + +#define pltenter la_x86_64_gnu_pltenter +#define pltexit la_x86_64_gnu_pltexit +#define La_regs La_x86_64_regs +#define La_retval La_x86_64_retval +#define int_retval lrv_rax + +#include + +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, 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/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S index d8d9bc12a4..33e6115f7b 100644 --- a/sysdeps/x86_64/dl-trampoline.S +++ b/sysdeps/x86_64/dl-trampoline.S @@ -107,7 +107,8 @@ _dl_runtime_profile: movaps %xmm3, 112(%rsp) movaps %xmm4, 128(%rsp) movaps %xmm5, 144(%rsp) - movaps %xmm7, 160(%rsp) + movaps %xmm6, 160(%rsp) + movaps %xmm7, 176(%rsp) movq %rsp, %rcx # La_x86_64_regs pointer to %rcx. movq 48(%rbx), %rdx # Load return address if needed. @@ -128,7 +129,8 @@ _dl_runtime_profile: movaps 112(%rsp), %xmm3 movaps 128(%rsp), %xmm4 movaps 144(%rsp), %xmm5 - movaps 160(%rsp), %xmm7 + movaps 160(%rsp), %xmm6 + movaps 176(%rsp), %xmm7 movq 16(%rbx), %r10 # Anything in framesize? testq %r10, %r10 -- 2.11.4.GIT