121495Sjmacd# Copyright (c) 2018 The NetBSD Foundation, Inc.
221495Sjmacd# All rights reserved.
321495Sjmacd#
421495Sjmacd# This code is derived from software contributed to The NetBSD Foundation
521495Sjmacd# by Yang Zheng.
621495Sjmacd#
721495Sjmacd# Redistribution and use in source and binary forms, with or without
821495Sjmacd# modification, are permitted provided that the following conditions
921495Sjmacd# are met:
1021495Sjmacd# 1. Redistributions of source code must retain the above copyright
1121495Sjmacd#    notice, this list of conditions and the following disclaimer.
1221495Sjmacd# 2. Redistributions in binary form must reproduce the above copyright
1321495Sjmacd#    notice, this list of conditions and the following disclaimer in the
1421495Sjmacd#    documentation and/or other materials provided with the distribution.
1521495Sjmacd#
1621495Sjmacd# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1721495Sjmacd# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1821495Sjmacd# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1921495Sjmacd# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2021495Sjmacd# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2121495Sjmacd# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2221495Sjmacd# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2321495Sjmacd# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2421495Sjmacd# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2521495Sjmacd# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2621495Sjmacd# POSSIBILITY OF SUCH DAMAGE.
2721495Sjmacd#
2821495Sjmacd
2921495Sjmacdtsan_available_archs()
3021495Sjmacd{
3121495Sjmacd	atf_set "require.arch" "x86_64"
3221495Sjmacd}
3321495Sjmacd
3421495Sjmacdatf_test_case locked_mutex_destroy
3521495Sjmacdlocked_mutex_destroy_head() {
3621495Sjmacd	atf_set "descr" "Test thread sanitizer for destroying locked mutex condition"
3721495Sjmacd	atf_set "require.progs" "cc paxctl"
3821495Sjmacd	tsan_available_archs
3921495Sjmacd}
4021495Sjmacd
4121495Sjmacdatf_test_case locked_mutex_destroy_profile
4221495Sjmacdlocked_mutex_destroy_profile_head() {
4321495Sjmacd	atf_set "descr" "Test thread sanitizer for destroying locked mutex with profiling option"
4421495Sjmacd	atf_set "require.progs" "cc paxctl"
4521495Sjmacd	tsan_available_archs
4621495Sjmacd}
4721495Sjmacdatf_test_case locked_mutex_destroy_pic
4821495Sjmacdlocked_mutex_destroy_pic_head() {
4921495Sjmacd	atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent code (PIC) flag"
5021495Sjmacd	atf_set "require.progs" "cc paxctl"
5121495Sjmacd	tsan_available_archs
5221495Sjmacd}
5321495Sjmacdatf_test_case locked_mutex_destroy_pie
5421495Sjmacdlocked_mutex_destroy_pie_head() {
5521495Sjmacd	atf_set "descr" "Test thread sanitizer for destroying locked mutex with position independent execution (PIE) flag"
5621495Sjmacd	atf_set "require.progs" "cc paxctl"
5721495Sjmacd	tsan_available_archs
5821495Sjmacd}
5921495Sjmacd
6021495Sjmacdlocked_mutex_destroy_body(){
6121495Sjmacd	cat > test.c << EOF
6221495Sjmacd#include <pthread.h>
6321495Sjmacd#include <stdlib.h>
6421495Sjmacd
6521495Sjmacdpthread_mutex_t mutex;
6621495Sjmacdpthread_barrier_t barrier;
6721495Sjmacdvoid *Thread(void *a) {
6821495Sjmacd  pthread_mutex_lock(&mutex);
6921495Sjmacd  pthread_barrier_wait(&barrier);
7021495Sjmacd  return 0;
7121495Sjmacd}
7221495Sjmacd
7321495Sjmacdint main() {
7421495Sjmacd  pthread_t t;
7521495Sjmacd  pthread_barrier_init(&barrier, NULL, 2);
7621495Sjmacd  pthread_mutex_init(&mutex, NULL);
7721495Sjmacd  pthread_create(&t, NULL, Thread, NULL);
7821495Sjmacd  pthread_barrier_wait(&barrier);
7921495Sjmacd  pthread_mutex_destroy(&mutex);
8021495Sjmacd  pthread_join(t, NULL);
8121495Sjmacd  return 0;
8221495Sjmacd}
8321495SjmacdEOF
8421495Sjmacd
8521495Sjmacd	cc -fsanitize=thread -o test test.c
8621495Sjmacd	paxctl +a test
8721495Sjmacd	atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test
8821495Sjmacd}
8921495Sjmacd
9021495Sjmacdlocked_mutex_destroy_profile_body(){
9121495Sjmacd	atf_expect_fail "PR toolchain/55760"
9221495Sjmacd	cat > test.c << EOF
9321495Sjmacd#include <pthread.h>
9421495Sjmacd#include <stdlib.h>
9521495Sjmacd
9621495Sjmacdpthread_mutex_t mutex;
9721495Sjmacdpthread_barrier_t barrier;
9821495Sjmacdvoid *Thread(void *a) {
9921495Sjmacd  pthread_mutex_lock(&mutex);
10021495Sjmacd  pthread_barrier_wait(&barrier);
10121495Sjmacd  return 0;
10221495Sjmacd}
10321495Sjmacd
10421495Sjmacdint main() {
10521495Sjmacd  pthread_t t;
10621495Sjmacd  pthread_barrier_init(&barrier, NULL, 2);
10721495Sjmacd  pthread_mutex_init(&mutex, NULL);
10821495Sjmacd  pthread_create(&t, NULL, Thread, NULL);
10921495Sjmacd  pthread_barrier_wait(&barrier);
11021495Sjmacd  pthread_mutex_destroy(&mutex);
11121495Sjmacd  pthread_join(t, NULL);
11221495Sjmacd  return 0;
11321495Sjmacd}
11421495SjmacdEOF
11521495Sjmacd
11621495Sjmacd	cc -fsanitize=thread -static -o test -pg test.c
11721495Sjmacd	paxctl +a test
11821495Sjmacd	atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test
11921495Sjmacd}
12021495Sjmacd
12121495Sjmacdlocked_mutex_destroy_pic_body(){
12221495Sjmacd	cat > test.c << EOF
12321495Sjmacd#include <stdio.h>
12421495Sjmacd#include <stdlib.h>
12521495Sjmacdint help(int);
12621495Sjmacdint main(int argc, char **argv) {return help(argc);}
12721495SjmacdEOF
12821495Sjmacd
12921495Sjmacd	cat > pic.c << EOF
13021495Sjmacd#include <pthread.h>
13121495Sjmacd#include <stdlib.h>
13221495Sjmacd
13321495Sjmacdpthread_mutex_t mutex;
13421495Sjmacdpthread_barrier_t barrier;
13521495Sjmacdvoid *Thread(void *a) {
13621495Sjmacd  pthread_mutex_lock(&mutex);
13721495Sjmacd  pthread_barrier_wait(&barrier);
13821495Sjmacd  return 0;
13921495Sjmacd}
14021495Sjmacd
14121495Sjmacdint help(int argc) {
14221495Sjmacd  pthread_t t;
14321495Sjmacd  pthread_barrier_init(&barrier, NULL, 2);
14421495Sjmacd  pthread_mutex_init(&mutex, NULL);
14521495Sjmacd  pthread_create(&t, NULL, Thread, NULL);
14621495Sjmacd  pthread_barrier_wait(&barrier);
14721495Sjmacd  pthread_mutex_destroy(&mutex);
14821495Sjmacd  pthread_join(t, NULL);
14921495Sjmacd  return 0;
15021495Sjmacd}
15121495SjmacdEOF
15221495Sjmacd
15321495Sjmacd	cc -fsanitize=thread -fPIC -shared -o libtest.so pic.c
15421495Sjmacd	cc -o test test.c -fsanitize=thread -L. -ltest
15521495Sjmacd	paxctl +a test
15621495Sjmacd
15721495Sjmacd	export LD_LIBRARY_PATH=.
15821495Sjmacd	atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test
15921495Sjmacd}
16021495Sjmacdlocked_mutex_destroy_pie_body(){
16121495Sjmacd
16221495Sjmacd	#check whether -pie flag is supported on this architecture
16321495Sjmacd	if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
16421495Sjmacd		atf_set_skip "cc -pie not supported on this architecture"
16521495Sjmacd	fi
16621495Sjmacd	cat > test.c << EOF
16721495Sjmacd#include <pthread.h>
16821495Sjmacd#include <stdlib.h>
16921495Sjmacd
17021495Sjmacdpthread_mutex_t mutex;
17121495Sjmacdpthread_barrier_t barrier;
17221495Sjmacdvoid *Thread(void *a) {
17321495Sjmacd  pthread_mutex_lock(&mutex);
17421495Sjmacd  pthread_barrier_wait(&barrier);
17521495Sjmacd  return 0;
17621495Sjmacd}
17721495Sjmacd
17821495Sjmacdint main() {
17921495Sjmacd  pthread_t t;
18021495Sjmacd  pthread_barrier_init(&barrier, NULL, 2);
18121495Sjmacd  pthread_mutex_init(&mutex, NULL);
18221495Sjmacd  pthread_create(&t, NULL, Thread, NULL);
18321495Sjmacd  pthread_barrier_wait(&barrier);
18421495Sjmacd  pthread_mutex_destroy(&mutex);
18521495Sjmacd  pthread_join(t, NULL);
18621495Sjmacd  return 0;
18721495Sjmacd}
18821495SjmacdEOF
18921495Sjmacd
19021495Sjmacd	cc -fsanitize=thread -o test -fpie -pie test.c
19121495Sjmacd	paxctl +a test
19221495Sjmacd	atf_check -s ignore -o ignore -e match:"WARNING: ThreadSanitizer: destroy of a locked mutex" ./test
19321495Sjmacd}
19421495Sjmacd
19521495Sjmacdatf_init_test_cases()
19621495Sjmacd{
19721495Sjmacd	atf_add_test_case locked_mutex_destroy
19821495Sjmacd	atf_add_test_case locked_mutex_destroy_profile
19921495Sjmacd	atf_add_test_case locked_mutex_destroy_pie
20021495Sjmacd	atf_add_test_case locked_mutex_destroy_pic
20121495Sjmacd}
20221495Sjmacd