diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-04-07 20:26:28 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-04-07 20:26:28 +0000 |
commit | 8d93681f5878604d6f36035c9f1d6006538f5ed3 (patch) | |
tree | 7a36d117e61590e48be56ae43f485d2228888cf5 /test | |
parent | b138bb6af7ea73abe78b006013114cda7b52c657 (diff) |
[sanitizer] Fix sem_init_glibc.cc test on __HAVE_64B_ATOMIC arches.
glibc can use one of 2 layouts for semaphores: architectures that
don't HAVE_64B_ATOMIC use an uint32_t field with semaphore value,
then a private field, then a waiting thread count field - this is
the layout currently assumed by the test. However, HAVE_64B_ATOMIC
arches use a fused uint64_t field that contains the value in low bits
and waiting thread count in high bits, followed by a private field.
This resulted in taking private field from the wrong offset on 64-bit
atomic platforms (the test still passed, but didn't actually test
the private field). On big-endian platforms, this resulted in a fail,
since the first 4 bytes overlay the thread count field, and not
the value field.
Found while porting ASan to s390x.
Patch by Marcin KoĆcielnicki.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@265715 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc b/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc index f17453b2d..193b33d79 100644 --- a/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc +++ b/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc @@ -2,24 +2,35 @@ // This test depends on the glibc layout of struct sem_t and checks that we // don't leave sem_t::private uninitialized. // UNSUPPORTED: android +#include <features.h> #include <assert.h> #include <semaphore.h> #include <string.h> +#include <stdint.h> -void my_sem_init(bool priv, int value, unsigned *a, unsigned char *b) { +// This condition needs to correspond to __HAVE_64B_ATOMICS macro in glibc. +#if (defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ + defined(__s390x__) || defined(__sparc64__) || defined(__alpha__) || \ + defined(__ia64__) || defined(__m68k__)) && __GLIBC_PREREQ(2, 21) +typedef uint64_t semval_t; +#else +typedef unsigned semval_t; +#endif + +void my_sem_init(bool priv, int value, semval_t *a, unsigned char *b) { sem_t sem; memset(&sem, 0xAB, sizeof(sem)); sem_init(&sem, priv, value); char *p = (char *)&sem; - memcpy(a, p, sizeof(unsigned)); - memcpy(b, p + sizeof(unsigned), sizeof(char)); + memcpy(a, p, sizeof(semval_t)); + memcpy(b, p + sizeof(semval_t), sizeof(char)); sem_destroy(&sem); } int main() { - unsigned a; + semval_t a; unsigned char b; my_sem_init(false, 42, &a, &b); |