Skip to content

Commit 39100c8

Browse files
committed
[NFC][sanitizer] Swap qsort_r and qsort code
To simplify future review.
1 parent f640c31 commit 39100c8

File tree

1 file changed

+51
-51
lines changed

1 file changed

+51
-51
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9949,6 +9949,57 @@ INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {
99499949
#define INIT_GETENTROPY
99509950
#endif
99519951

9952+
#if SANITIZER_INTERCEPT_QSORT_R
9953+
typedef int (*qsort_r_compar_f)(const void *, const void *, void *);
9954+
static THREADLOCAL qsort_r_compar_f qsort_r_compar;
9955+
static THREADLOCAL SIZE_T qsort_r_size;
9956+
static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {
9957+
COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9958+
COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_r_size);
9959+
COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_r_size);
9960+
return qsort_r_compar(a, b, arg);
9961+
}
9962+
9963+
INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
9964+
qsort_r_compar_f compar, void *arg) {
9965+
void *ctx;
9966+
COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);
9967+
// Run the comparator over all array elements to detect any memory issues.
9968+
if (nmemb > 1) {
9969+
for (SIZE_T i = 0; i < nmemb - 1; ++i) {
9970+
void *p = (void *)((char *)base + i * size);
9971+
void *q = (void *)((char *)base + (i + 1) * size);
9972+
COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9973+
compar(p, q, arg);
9974+
}
9975+
}
9976+
qsort_r_compar_f old_compar = qsort_r_compar;
9977+
SIZE_T old_size = qsort_r_size;
9978+
// Handle qsort_r() implementations that recurse using an
9979+
// interposable function call:
9980+
bool already_wrapped = compar == wrapped_qsort_r_compar;
9981+
if (already_wrapped) {
9982+
// This case should only happen if the qsort() implementation calls itself
9983+
// using a preemptible function call (e.g. the FreeBSD libc version).
9984+
// Check that the size and comparator arguments are as expected.
9985+
CHECK_NE(compar, qsort_r_compar);
9986+
CHECK_EQ(qsort_r_size, size);
9987+
} else {
9988+
qsort_r_compar = compar;
9989+
qsort_r_size = size;
9990+
}
9991+
REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, arg);
9992+
if (!already_wrapped) {
9993+
qsort_r_compar = old_compar;
9994+
qsort_r_size = old_size;
9995+
}
9996+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
9997+
}
9998+
# define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)
9999+
#else
10000+
# define INIT_QSORT_R
10001+
#endif
10002+
995210003
#if SANITIZER_INTERCEPT_QSORT
995310004
// Glibc qsort uses a temporary buffer allocated either on stack or on heap.
995410005
// Poisoned memory from there may get copied into the comparator arguments,
@@ -10011,57 +10062,6 @@ INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
1001110062
#define INIT_QSORT
1001210063
#endif
1001310064

10014-
#if SANITIZER_INTERCEPT_QSORT_R
10015-
typedef int (*qsort_r_compar_f)(const void *, const void *, void *);
10016-
static THREADLOCAL qsort_r_compar_f qsort_r_compar;
10017-
static THREADLOCAL SIZE_T qsort_r_size;
10018-
static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {
10019-
COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10020-
COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_r_size);
10021-
COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_r_size);
10022-
return qsort_r_compar(a, b, arg);
10023-
}
10024-
10025-
INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
10026-
qsort_r_compar_f compar, void *arg) {
10027-
void *ctx;
10028-
COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);
10029-
// Run the comparator over all array elements to detect any memory issues.
10030-
if (nmemb > 1) {
10031-
for (SIZE_T i = 0; i < nmemb - 1; ++i) {
10032-
void *p = (void *)((char *)base + i * size);
10033-
void *q = (void *)((char *)base + (i + 1) * size);
10034-
COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10035-
compar(p, q, arg);
10036-
}
10037-
}
10038-
qsort_r_compar_f old_compar = qsort_r_compar;
10039-
SIZE_T old_size = qsort_r_size;
10040-
// Handle qsort_r() implementations that recurse using an
10041-
// interposable function call:
10042-
bool already_wrapped = compar == wrapped_qsort_r_compar;
10043-
if (already_wrapped) {
10044-
// This case should only happen if the qsort() implementation calls itself
10045-
// using a preemptible function call (e.g. the FreeBSD libc version).
10046-
// Check that the size and comparator arguments are as expected.
10047-
CHECK_NE(compar, qsort_r_compar);
10048-
CHECK_EQ(qsort_r_size, size);
10049-
} else {
10050-
qsort_r_compar = compar;
10051-
qsort_r_size = size;
10052-
}
10053-
REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, arg);
10054-
if (!already_wrapped) {
10055-
qsort_r_compar = old_compar;
10056-
qsort_r_size = old_size;
10057-
}
10058-
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
10059-
}
10060-
#define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)
10061-
#else
10062-
#define INIT_QSORT_R
10063-
#endif
10064-
1006510065
#if SANITIZER_INTERCEPT_BSEARCH
1006610066
typedef int (*bsearch_compar_f)(const void *, const void *);
1006710067
static THREADLOCAL bsearch_compar_f bsearch_compar;

0 commit comments

Comments
 (0)