Skip to content

[interception] Implement interception on AIX (3/3) #138608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler-rt/lib/interception/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Build for the runtime interception helper library.

set(INTERCEPTION_SOURCES
interception_aix.cpp
interception_linux.cpp
interception_mac.cpp
interception_win.cpp
Expand All @@ -9,6 +10,7 @@ set(INTERCEPTION_SOURCES

set(INTERCEPTION_HEADERS
interception.h
interception_aix.h
interception_linux.h
interception_mac.h
interception_win.h
Expand Down
25 changes: 20 additions & 5 deletions compiler-rt/lib/interception/interception.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \
!SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
!SANITIZER_SOLARIS && !SANITIZER_HAIKU
!SANITIZER_SOLARIS && !SANITIZER_HAIKU && !SANITIZER_AIX
# error "Interception doesn't work on this operating system."
#endif

Expand Down Expand Up @@ -168,6 +168,16 @@ const interpose_substitution substitution_##func_name[] \
extern "C" ret_type func(__VA_ARGS__);
# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
#elif SANITIZER_AIX
# define WRAP(x) __interceptor_##x
# define TRAMPOLINE(x) WRAP(x)
// # define WRAPPER_NAME(x) "__interceptor_" #x
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
// AIX's linker will not select the weak symbol, so don't use weak for the
// interceptors.
# define DECLARE_WRAPPER(ret_type, func, ...) \
extern "C" ret_type func(__VA_ARGS__) \
__attribute__((alias("__interceptor_" #func), visibility("default")));
#elif !SANITIZER_FUCHSIA // LINUX, FREEBSD, NETBSD, SOLARIS
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
# if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
Expand Down Expand Up @@ -367,12 +377,17 @@ inline void DoesNotSupportStaticLinking() {}

#define INCLUDED_FROM_INTERCEPTION_LIB

#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
#if SANITIZER_AIX
# include "interception_aix.h"
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_AIX(func)
# define INTERCEPT_FUNCTION_VER(func, symver) INTERCEPT_FUNCTION_AIX(func)

#elif SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
SANITIZER_SOLARIS || SANITIZER_HAIKU

# include "interception_linux.h"
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
# define INTERCEPT_FUNCTION_VER(func, symver) \
# include "interception_linux.h"
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
# define INTERCEPT_FUNCTION_VER(func, symver) \
INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver)
#elif SANITIZER_APPLE
# include "interception_mac.h"
Expand Down
45 changes: 45 additions & 0 deletions compiler-rt/lib/interception/interception_aix.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===-- interception_aix.cpp ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// AIX-specific interception methods.
//===----------------------------------------------------------------------===//

#include "interception.h"
#include "sanitizer_common/sanitizer_common.h"

#if SANITIZER_AIX

# include <dlfcn.h> // for dlsym()

namespace __interception {

static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
// AIX dlsym can only defect the functions that are exported, so
// on AIX, we can not intercept some basic functions like memcpy.
// FIXME: if we are going to ship dynamic asan library, we may need to search
// all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
void *addr = dlsym(RTLD_NEXT, name);

// In case `name' is not loaded, dlsym ends up finding the actual wrapper.
// We don't want to intercept the wrapper and have it point to itself.
if ((uptr)addr == wrapper_addr)
addr = nullptr;
return addr;
}

bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
uptr wrapper) {
void *addr = GetFuncAddr(name, wrapper);
*ptr_to_real = (uptr)addr;
return addr && (func == wrapper);
}

} // namespace __interception
#endif // SANITIZER_AIX
36 changes: 36 additions & 0 deletions compiler-rt/lib/interception/interception_aix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===-- interception_aix.h --------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// AIX-specific interception methods.
//===----------------------------------------------------------------------===//

#if SANITIZER_AIX

# if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
# error \
"interception_aix.h should be included from interception library only"
# endif

# ifndef INTERCEPTION_AIX_H
# define INTERCEPTION_AIX_H

namespace __interception {
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
uptr wrapper);
} // namespace __interception

# define INTERCEPT_FUNCTION_AIX(func) \
::__interception::InterceptFunction( \
#func, (::__interception::uptr *)&REAL(func), \
(::__interception::uptr) & (func), \
(::__interception::uptr) & WRAP(func))

# endif // INTERCEPTION_AIX_H
#endif // SANITIZER_AIX
Loading