[interception] Implement interception on AIX (#138608)

Implement AIX specific interception functions.

Issue: https://github.com/llvm/llvm-project/issues/138916
This commit is contained in:
Jake Egan
2025-05-26 11:40:20 -04:00
committed by GitHub
parent e1328fd9ad
commit 75e61333f0
4 changed files with 103 additions and 5 deletions

View File

@@ -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
@@ -9,6 +10,7 @@ set(INTERCEPTION_SOURCES
set(INTERCEPTION_HEADERS
interception.h
interception_aix.h
interception_linux.h
interception_mac.h
interception_win.h

View File

@@ -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
@@ -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
@@ -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"

View File

@@ -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

View File

@@ -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