[compiler-rt] r265715 - [sanitizer] Fix sem_init_glibc.cc test on __HAVE_64B_ATOMIC arches.

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 7 13:26:28 PDT 2016


Author: eugenis
Date: Thu Apr  7 15:26:28 2016
New Revision: 265715

URL: http://llvm.org/viewvc/llvm-project?rev=265715&view=rev
Log:
[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.

Modified:
    compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc

Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc?rev=265715&r1=265714&r2=265715&view=diff
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc (original)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc Thu Apr  7 15:26:28 2016
@@ -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);




More information about the llvm-commits mailing list