AdityaK 46cb8d9a32
[TSAN] add support for riscv64 (#68735)
Implements for sv39 and sv48 VMA layout.

Userspace only has access to the bottom half of vma range. The top half
is used by kernel. There is no dedicated vsyscall or heap segment.
PIE program is allocated to start at TASK_SIZE/3*2. Maximum ASLR is
ARCH_MMAP_RND_BITS_MAX+PAGE_SHIFT=24+12=36 Loader, vdso and other
libraries are allocated below stack from the top.

Also change RestoreAddr to use 4 bits to accommodate MappingRiscv64_48

Reviewed by: MaskRay, dvyukov, asb, StephenFan, luismarques, jrtc27,
hiraditya, vitalybuka

Differential Revision: https://reviews.llvm.org/D145214

D145214 was reverted because one file was missing in the latest commit.
Luckily the file was there in the previous commit, probably the author
missed uploading that file with latest commit.

Co-authored-by: Alex Fan <alex.fan.q@gmail.com>
2023-10-12 16:03:07 -07:00

143 lines
4.3 KiB
C

#ifndef __TSAN_TEST_H__
#define __TSAN_TEST_H__
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <stddef.h>
#include <sched.h>
#include <stdarg.h>
#include "sanitizer_common/print_address.h"
#include <sanitizer/tsan_interface.h>
#ifdef __APPLE__
#include <mach/mach_time.h>
#endif
#ifndef TSAN_VECTORIZE
# define TSAN_VECTORIZE __SSE4_2__
#endif
#if TSAN_VECTORIZE
# include <emmintrin.h>
# include <smmintrin.h>
#else
struct __m128i {
unsigned long long x[2];
};
#endif
// TSan-invisible barrier.
// Tests use it to establish necessary execution order in a way that does not
// interfere with tsan (does not establish synchronization between threads).
typedef unsigned invisible_barrier_t;
#ifdef __cplusplus
extern "C" {
#endif
void __tsan_testonly_barrier_init(invisible_barrier_t *barrier,
unsigned count);
void __tsan_testonly_barrier_wait(invisible_barrier_t *barrier);
unsigned long __tsan_testonly_shadow_stack_current_size();
#ifdef __cplusplus
}
#endif
static inline void barrier_init(invisible_barrier_t *barrier, unsigned count) {
__tsan_testonly_barrier_init(barrier, count);
}
static inline void barrier_wait(invisible_barrier_t *barrier) {
__tsan_testonly_barrier_wait(barrier);
}
// Default instance of the barrier, but a test can declare more manually.
invisible_barrier_t barrier;
#ifdef __APPLE__
unsigned long long monotonic_clock_ns() {
static mach_timebase_info_data_t timebase_info;
if (timebase_info.denom == 0) mach_timebase_info(&timebase_info);
return (mach_absolute_time() * timebase_info.numer) / timebase_info.denom;
}
#else
unsigned long long monotonic_clock_ns() {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return (unsigned long long)t.tv_sec * 1000000000ull + t.tv_nsec;
}
#endif
//The const kPCInc must be in sync with StackTrace::GetPreviousInstructionPc
#if defined(__s390__) || defined(__i386__) || defined(__x86_64__)
const int kPCInc = 1;
#elif defined(__sparc__) || defined(__mips__)
const int kPCInc = 8;
#elif defined(__riscv) && __riscv_xlen == 64
const int kPCInc = 2;
#else
const int kPCInc = 4;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void AnnotateThreadName(const char *f, int l, const char *name);
void AnnotateRWLockCreate(const char *f, int l, void *m);
void AnnotateRWLockCreateStatic(const char *f, int l, void *m);
void AnnotateRWLockDestroy(const char *f, int l, void *m);
void AnnotateRWLockAcquired(const char *f, int l, void *m, long is_w);
void AnnotateRWLockReleased(const char *f, int l, void *m, long is_w);
void AnnotateIgnoreReadsBegin(const char *f, int l);
void AnnotateIgnoreReadsEnd(const char *f, int l);
void AnnotateIgnoreWritesBegin(const char *f, int l);
void AnnotateIgnoreWritesEnd(const char *f, int l);
void AnnotateIgnoreSyncBegin(const char *f, int l);
void AnnotateIgnoreSyncEnd(const char *f, int l);
void AnnotateHappensBefore(const char *f, int l, void *addr);
void AnnotateHappensAfter(const char *f, int l, void *addr);
void AnnotateBenignRaceSized(const char *f, int l, const volatile void *mem,
unsigned int size, const char *desc);
void WTFAnnotateBenignRaceSized(const char *f, int l, const volatile void *mem,
unsigned int size, const char *desc);
#ifdef __cplusplus
}
#endif
#define ANNOTATE_RWLOCK_CREATE(m) \
AnnotateRWLockCreate(__FILE__, __LINE__, m)
#define ANNOTATE_RWLOCK_CREATE_STATIC(m) \
AnnotateRWLockCreateStatic(__FILE__, __LINE__, m)
#define ANNOTATE_RWLOCK_DESTROY(m) \
AnnotateRWLockDestroy(__FILE__, __LINE__, m)
#define ANNOTATE_RWLOCK_ACQUIRED(m, is_w) \
AnnotateRWLockAcquired(__FILE__, __LINE__, m, is_w)
#define ANNOTATE_RWLOCK_RELEASED(m, is_w) \
AnnotateRWLockReleased(__FILE__, __LINE__, m, is_w)
#define ANNOTATE_HAPPENS_BEFORE(addr) \
AnnotateHappensBefore(__FILE__, __LINE__, (void *)(addr))
#define ANNOTATE_HAPPENS_AFTER(addr) \
AnnotateHappensAfter(__FILE__, __LINE__, (void *)(addr))
#define ANNOTATE_BENIGN_RACE(var) \
AnnotateBenignRaceSized(__FILE__, __LINE__, &(var), sizeof(var), #var)
#define WTF_ANNOTATE_BENIGN_RACE(var) \
WTFAnnotateBenignRaceSized(__FILE__, __LINE__, &(var), sizeof(var), #var)
#ifdef __APPLE__
#define ASM_SYMBOL(symbol) "_" #symbol
#else
#define ASM_SYMBOL(symbol) #symbol
#endif
#endif // __TSAN_TEST_H__