[sanitizers] Get the proper symbol version when long double transition is involved.
On linux, some architectures had an ABI transition from 64-bit long double (ie. same as double) to 128-bit long double. On those, glibc symbols involving long doubles come in two versions, and we need to pass the correct one to dlvsym when intercepting them. A few more functions we intercept are also versioned (all printf, scanf, strtold variants), but there's no need to fix these, as the REAL() versions are never called. Differential Revision: http://reviews.llvm.org/D19555 llvm-svn: 267794
This commit is contained in:
parent
41939466d1
commit
66f0deacb5
|
@ -144,6 +144,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
|
|||
(void) ctx; \
|
||||
|
||||
#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
|
||||
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
|
||||
ASAN_INTERCEPT_FUNC_VER(name, ver)
|
||||
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
|
||||
ASAN_WRITE_RANGE(ctx, ptr, size)
|
||||
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
|
||||
|
|
|
@ -43,6 +43,8 @@ using namespace __esan; // NOLINT
|
|||
#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!EsanIsInitialized)
|
||||
|
||||
#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
|
||||
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
|
||||
INTERCEPT_FUNCTION_VER(name, ver)
|
||||
|
||||
// We currently do not use ctx.
|
||||
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
|
||||
|
|
|
@ -1327,7 +1327,16 @@ int OnExit() {
|
|||
VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \
|
||||
} while (0)
|
||||
|
||||
#define MSAN_INTERCEPT_FUNC_VER(name, ver) \
|
||||
do { \
|
||||
if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \
|
||||
VReport( \
|
||||
1, "MemorySanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
|
||||
} while (0)
|
||||
|
||||
#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
|
||||
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
|
||||
MSAN_INTERCEPT_FUNC_VER(name, ver)
|
||||
#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) \
|
||||
UnpoisonParam(count)
|
||||
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
|
||||
|
@ -1573,8 +1582,13 @@ void InitializeInterceptors() {
|
|||
INTERCEPT_STRTO(wcstoul);
|
||||
INTERCEPT_STRTO(wcstoll);
|
||||
INTERCEPT_STRTO(wcstoull);
|
||||
#ifdef SANITIZER_NLDBL_VERSION
|
||||
INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION);
|
||||
INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION);
|
||||
#else
|
||||
INTERCEPT_FUNCTION(vswprintf);
|
||||
INTERCEPT_FUNCTION(swprintf);
|
||||
#endif
|
||||
INTERCEPT_FUNCTION(strxfrm);
|
||||
INTERCEPT_FUNCTION(strxfrm_l);
|
||||
INTERCEPT_FUNCTION(strftime);
|
||||
|
|
|
@ -155,6 +155,14 @@
|
|||
#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
|
||||
#endif
|
||||
|
||||
#ifdef SANITIZER_NLDBL_VERSION
|
||||
#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \
|
||||
COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
|
||||
#else
|
||||
#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \
|
||||
COMMON_INTERCEPT_FUNCTION(fn)
|
||||
#endif
|
||||
|
||||
struct FileMetadata {
|
||||
// For open_memstream().
|
||||
char **addr;
|
||||
|
@ -670,7 +678,7 @@ INTERCEPTOR(long double, frexpl, long double x, int *exp) {
|
|||
|
||||
#define INIT_FREXPF_FREXPL \
|
||||
COMMON_INTERCEPT_FUNCTION(frexpf); \
|
||||
COMMON_INTERCEPT_FUNCTION(frexpl)
|
||||
COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
|
||||
#else
|
||||
#define INIT_FREXPF_FREXPL
|
||||
#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
|
||||
|
@ -2449,7 +2457,7 @@ INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
|
|||
#define INIT_MODF \
|
||||
COMMON_INTERCEPT_FUNCTION(modf); \
|
||||
COMMON_INTERCEPT_FUNCTION(modff); \
|
||||
COMMON_INTERCEPT_FUNCTION(modfl);
|
||||
COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
|
||||
#else
|
||||
#define INIT_MODF
|
||||
#endif
|
||||
|
@ -4110,7 +4118,7 @@ INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
|
|||
#define INIT_SINCOS \
|
||||
COMMON_INTERCEPT_FUNCTION(sincos); \
|
||||
COMMON_INTERCEPT_FUNCTION(sincosf); \
|
||||
COMMON_INTERCEPT_FUNCTION(sincosl);
|
||||
COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
|
||||
#else
|
||||
#define INIT_SINCOS
|
||||
#endif
|
||||
|
@ -4149,7 +4157,7 @@ INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
|
|||
#define INIT_REMQUO \
|
||||
COMMON_INTERCEPT_FUNCTION(remquo); \
|
||||
COMMON_INTERCEPT_FUNCTION(remquof); \
|
||||
COMMON_INTERCEPT_FUNCTION(remquol);
|
||||
COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
|
||||
#else
|
||||
#define INIT_REMQUO
|
||||
#endif
|
||||
|
@ -4180,7 +4188,7 @@ INTERCEPTOR(long double, lgammal, long double x) {
|
|||
#define INIT_LGAMMA \
|
||||
COMMON_INTERCEPT_FUNCTION(lgamma); \
|
||||
COMMON_INTERCEPT_FUNCTION(lgammaf); \
|
||||
COMMON_INTERCEPT_FUNCTION(lgammal);
|
||||
COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
|
||||
#else
|
||||
#define INIT_LGAMMA
|
||||
#endif
|
||||
|
@ -4224,7 +4232,7 @@ INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
|
|||
if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
|
||||
return res;
|
||||
}
|
||||
#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION(lgammal_r);
|
||||
#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
|
||||
#else
|
||||
#define INIT_LGAMMAL_R
|
||||
#endif
|
||||
|
|
|
@ -231,4 +231,12 @@
|
|||
# define SANITIZER_NON_UNIQUE_TYPEINFO 0
|
||||
#endif
|
||||
|
||||
// On linux, some architectures had an ABI transition from 64-bit long double
|
||||
// (ie. same as double) to 128-bit long double. On those, glibc symbols
|
||||
// involving long doubles come in two versions, and we need to pass the
|
||||
// correct one to dlvsym when intercepting them.
|
||||
#if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1)
|
||||
#define SANITIZER_NLDBL_VERSION "GLIBC_2.4"
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_PLATFORM_H
|
||||
|
|
|
@ -2281,6 +2281,8 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
|
|||
#undef SANITIZER_INTERCEPT_TLS_GET_ADDR
|
||||
|
||||
#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
|
||||
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
|
||||
INTERCEPT_FUNCTION_VER(name, ver)
|
||||
|
||||
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
|
||||
MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \
|
||||
|
|
Loading…
Reference in New Issue