forked from OSchip/llvm-project
[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. llvm-svn: 265715
This commit is contained in:
parent
87b30a0ef2
commit
eb37fcbc87
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue