Skip to content

Commit 1c2952c

Browse files
committed
[sanitizer_common] Implement interceptors for AIX
1 parent 8e6fa15 commit 1c2952c

9 files changed

+178
-34
lines changed

compiler-rt/lib/interception/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Build for the runtime interception helper library.
22

33
set(INTERCEPTION_SOURCES
4+
interception_aix.cpp
45
interception_linux.cpp
56
interception_mac.cpp
67
interception_win.cpp
@@ -9,6 +10,7 @@ set(INTERCEPTION_SOURCES
910

1011
set(INTERCEPTION_HEADERS
1112
interception.h
13+
interception_aix.h
1214
interception_linux.h
1315
interception_mac.h
1416
interception_win.h

compiler-rt/lib/interception/interception.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \
2121
!SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
22-
!SANITIZER_SOLARIS
22+
!SANITIZER_SOLARIS && !SANITIZER_AIX
2323
# error "Interception doesn't work on this operating system."
2424
#endif
2525

@@ -168,6 +168,16 @@ const interpose_substitution substitution_##func_name[] \
168168
extern "C" ret_type func(__VA_ARGS__);
169169
# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
170170
extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
171+
#elif SANITIZER_AIX
172+
# define WRAP(x) __interceptor_##x
173+
# define TRAMPOLINE(x) WRAP(x)
174+
// # define WRAPPER_NAME(x) "__interceptor_" #x
175+
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
176+
// AIX's linker will not select the weak symbol, so don't use weak for the
177+
// interceptors.
178+
# define DECLARE_WRAPPER(ret_type, func, ...) \
179+
extern "C" ret_type func(__VA_ARGS__) \
180+
__attribute__((alias("__interceptor_" #func), visibility("default")));
171181
#elif !SANITIZER_FUCHSIA // LINUX, FREEBSD, NETBSD, SOLARIS
172182
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
173183
# if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
@@ -367,7 +377,12 @@ inline void DoesNotSupportStaticLinking() {}
367377

368378
#define INCLUDED_FROM_INTERCEPTION_LIB
369379

370-
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
380+
#if SANITIZER_AIX
381+
# include "interception_aix.h"
382+
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_AIX(func)
383+
# define INTERCEPT_FUNCTION_VER(func, symver) INTERCEPT_FUNCTION_AIX(func)
384+
385+
#elif SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
371386
SANITIZER_SOLARIS
372387

373388
# include "interception_linux.h"
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===-- interception_aix.cpp ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a part of AddressSanitizer, an address sanity checker.
10+
//
11+
// AIX-specific interception methods.
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "interception.h"
15+
#include "sanitizer_common/sanitizer_common.h"
16+
17+
#if SANITIZER_AIX
18+
19+
# include <dlfcn.h> // for dlsym()
20+
21+
namespace __interception {
22+
23+
static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
24+
// AIX dlsym can only defect the functions that are exported, so
25+
// on AIX, we can not intercept some basic functions like memcpy.
26+
// FIXME: if we are going to ship dynamic asan library, we may need to search
27+
// all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
28+
void *addr = dlsym(RTLD_NEXT, name);
29+
30+
// In case `name' is not loaded, dlsym ends up finding the actual wrapper.
31+
// We don't want to intercept the wrapper and have it point to itself.
32+
if ((uptr)addr == wrapper_addr)
33+
addr = nullptr;
34+
return addr;
35+
}
36+
37+
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
38+
uptr wrapper) {
39+
void *addr = GetFuncAddr(name, wrapper);
40+
*ptr_to_real = (uptr)addr;
41+
return addr && (func == wrapper);
42+
}
43+
44+
} // namespace __interception
45+
#endif // SANITIZER_AIX
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===-- interception_aix.h --------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a part of AddressSanitizer, an address sanity checker.
10+
//
11+
// AIX-specific interception methods.
12+
//===----------------------------------------------------------------------===//
13+
14+
#if SANITIZER_AIX
15+
16+
# if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
17+
# error \
18+
"interception_aix.h should be included from interception library only"
19+
# endif
20+
21+
# ifndef INTERCEPTION_AIX_H
22+
# define INTERCEPTION_AIX_H
23+
24+
namespace __interception {
25+
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
26+
uptr wrapper);
27+
} // namespace __interception
28+
29+
# define INTERCEPT_FUNCTION_AIX(func) \
30+
::__interception::InterceptFunction( \
31+
#func, (::__interception::uptr *)&REAL(func), \
32+
(::__interception::uptr) & (func), \
33+
(::__interception::uptr)&WRAP(func))
34+
35+
# endif // INTERCEPTION_AIX_H
36+
#endif // SANITIZER_AIX

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ INTERCEPTOR(char*, textdomain, const char *domainname) {
480480
#define INIT_TEXTDOMAIN
481481
#endif
482482

483-
#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP
483+
#if SANITIZER_INTERCEPT_MEMCMP
484484
static inline int CharCmpX(unsigned char c1, unsigned char c2) {
485485
return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
486486
}
@@ -953,7 +953,7 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
953953
#define INIT_FREXP
954954
#endif // SANITIZER_INTERCEPT_FREXP
955955

956-
#if SANITIZER_INTERCEPT_FREXPF_FREXPL
956+
#if SANITIZER_INTERCEPT_FREXPF
957957
INTERCEPTOR(float, frexpf, float x, int *exp) {
958958
void *ctx;
959959
COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
@@ -963,6 +963,12 @@ INTERCEPTOR(float, frexpf, float x, int *exp) {
963963
return res;
964964
}
965965

966+
#define INIT_FREXPF COMMON_INTERCEPT_FUNCTION(frexpf);
967+
#else
968+
#define INIT_FREXPF
969+
#endif
970+
971+
#if SANITIZER_INTERCEPT_FREXPL
966972
INTERCEPTOR(long double, frexpl, long double x, int *exp) {
967973
void *ctx;
968974
COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
@@ -972,12 +978,10 @@ INTERCEPTOR(long double, frexpl, long double x, int *exp) {
972978
return res;
973979
}
974980

975-
#define INIT_FREXPF_FREXPL \
976-
COMMON_INTERCEPT_FUNCTION(frexpf); \
977-
COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
981+
#define INIT_FREXPL COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
978982
#else
979-
#define INIT_FREXPF_FREXPL
980-
#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
983+
#define INIT_FREXPL
984+
#endif
981985

982986
#if SI_POSIX
983987
static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
@@ -1346,7 +1350,8 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) {
13461350
#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
13471351
static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
13481352
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1349-
#if !SANITIZER_SOLARIS
1353+
// AIX tm struct does not have tm_zone field.
1354+
#if !SANITIZER_SOLARIS && !SANITIZER_AIX
13501355
if (tm->tm_zone) {
13511356
// Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
13521357
// can point to shared memory and tsan would report a data race.
@@ -1731,8 +1736,10 @@ INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
17311736
VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
17321737
#endif
17331738

1739+
#if SANITIZER_INTERCEPT_VASPRINTF
17341740
INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
17351741
VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1742+
#endif
17361743

17371744
#if SANITIZER_INTERCEPT_ISOC99_PRINTF
17381745
INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
@@ -1783,8 +1790,10 @@ INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
17831790
FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
17841791
#endif
17851792

1793+
#if SANITIZER_INTERCEPT_ASPRINTF
17861794
INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
17871795
FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1796+
#endif
17881797

17891798
#if SANITIZER_INTERCEPT_ISOC99_PRINTF
17901799
INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
@@ -1807,17 +1816,29 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
18071816
#endif // SANITIZER_INTERCEPT_PRINTF
18081817

18091818
#if SANITIZER_INTERCEPT_PRINTF
1819+
#if SANITIZER_AIX
1820+
#define INIT_PRINTF \
1821+
COMMON_INTERCEPT_FUNCTION_LDBL(printf); \
1822+
COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \
1823+
COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \
1824+
COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \
1825+
COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \
1826+
COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \
1827+
COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
1828+
COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
1829+
#else
18101830
#define INIT_PRINTF \
18111831
COMMON_INTERCEPT_FUNCTION_LDBL(printf); \
18121832
COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \
18131833
COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \
1814-
COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \
18151834
COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \
18161835
COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \
18171836
COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \
18181837
COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
1838+
COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \
18191839
COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
18201840
COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
1841+
#endif
18211842
#else
18221843
#define INIT_PRINTF
18231844
#endif
@@ -3901,7 +3922,10 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
39013922
if (res != ((SIZE_T)-1)) {
39023923
CHECK_LE(res, sizeof(local_dest));
39033924
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3904-
REAL(memcpy)(dest, local_dest, res);
3925+
if (!SANITIZER_AIX)
3926+
REAL(memcpy)(dest, local_dest, res);
3927+
else
3928+
internal_memcpy(dest, local_dest, res);
39053929
}
39063930
return res;
39073931
}
@@ -3923,7 +3947,10 @@ INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
39233947
if (res != -1) {
39243948
CHECK_LE(res, sizeof(local_dest));
39253949
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3926-
REAL(memcpy)(dest, local_dest, res);
3950+
if (!SANITIZER_AIX)
3951+
REAL(memcpy)(dest, local_dest, res);
3952+
else
3953+
internal_memcpy(dest, local_dest, res);
39273954
}
39283955
return res;
39293956
}
@@ -10329,7 +10356,8 @@ static void InitializeCommonInterceptors() {
1032910356
INIT_PRINTF_L;
1033010357
INIT_ISOC99_PRINTF;
1033110358
INIT_FREXP;
10332-
INIT_FREXPF_FREXPL;
10359+
INIT_FREXPF;
10360+
INIT_FREXPL;
1033310361
INIT_GETPWNAM_AND_FRIENDS;
1033410362
INIT_GETPWNAM_R_AND_FRIENDS;
1033510363
INIT_GETPWENT;

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ static void ioctl_table_fill() {
7373
_(TIOCNXCL, NONE, 0);
7474
_(TIOCOUTQ, WRITE, sizeof(int));
7575
_(TIOCPKT, READ, sizeof(int));
76+
#if !SANITIZER_AIX
7677
_(TIOCSCTTY, NONE, 0);
78+
#endif
7779
_(TIOCSETD, READ, sizeof(int));
7880
_(TIOCSPGRP, READ, pid_t_sz);
7981
_(TIOCSTI, READ, sizeof(char));

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
3737
#elif SANITIZER_WINDOWS64
3838
#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
39+
#elif SANITIZER_AIX
40+
#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
3941
#else
4042
#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
4143
#endif // SANITIZER_APPLE

0 commit comments

Comments
 (0)