Skip to content

Conversation

@jakeegan
Copy link
Member

@jakeegan jakeegan commented May 5, 2025

Implement AIX specific interception functions.

Issue: #138916

@jakeegan jakeegan changed the title interceptors [interception] Implement address sanitizer on AIX: interceptors May 6, 2025
@jakeegan jakeegan changed the title [interception] Implement address sanitizer on AIX: interceptors [interception] Implement interception on AIX (3/3) May 7, 2025
@jakeegan jakeegan marked this pull request as ready for review May 7, 2025 17:38
@llvmbot
Copy link
Member

llvmbot commented May 7, 2025

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Jake Egan (jakeegan)

Changes

Implement AIX specific interception functions.


Full diff: https://github.com/llvm/llvm-project/pull/138608.diff

4 Files Affected:

  • (modified) compiler-rt/lib/interception/CMakeLists.txt (+2)
  • (modified) compiler-rt/lib/interception/interception.h (+20-5)
  • (added) compiler-rt/lib/interception/interception_aix.cpp (+45)
  • (added) compiler-rt/lib/interception/interception_aix.h (+36)
diff --git a/compiler-rt/lib/interception/CMakeLists.txt b/compiler-rt/lib/interception/CMakeLists.txt index fe7fa27fbc78b..57c8c8ba20141 100644 --- a/compiler-rt/lib/interception/CMakeLists.txt +++ b/compiler-rt/lib/interception/CMakeLists.txt @@ -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 diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index 25480120e7ad6..9fe7d3db308bf 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -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" diff --git a/compiler-rt/lib/interception/interception_aix.cpp b/compiler-rt/lib/interception/interception_aix.cpp new file mode 100644 index 0000000000000..953bbad96eb47 --- /dev/null +++ b/compiler-rt/lib/interception/interception_aix.cpp @@ -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 diff --git a/compiler-rt/lib/interception/interception_aix.h b/compiler-rt/lib/interception/interception_aix.h new file mode 100644 index 0000000000000..b86ae89f50461 --- /dev/null +++ b/compiler-rt/lib/interception/interception_aix.h @@ -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 
@vitalybuka
Copy link
Collaborator

Can you please instead of counter, like (3/3), just create an issue, and mention that issue in every PR?

@jakeegan jakeegan changed the title [interception] Implement interception on AIX (3/3) [interception] Implement interception on AIX May 12, 2025
@jakeegan jakeegan merged commit 75e6133 into llvm:main May 26, 2025
14 checks passed
@jakeegan jakeegan deleted the asan_common10 branch May 26, 2025 15:40
@llvm-ci
Copy link
Collaborator

llvm-ci commented May 26, 2025

LLVM Buildbot has detected a new failure on builder clang-ppc64-aix running on aix-ppc64 while building compiler-rt at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/64/builds/3841

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure) ******************** TEST 'lit :: timeout-hang.py' FAILED ******************** Exit Code: 1 Command Output (stdout): -- # RUN: at line 13 not env -u FILECHECK_OPTS "/home/llvm/llvm-external-buildbots/workers/env/bin/python3.11" /home/llvm/llvm-external-buildbots/workers/aix-ppc64/clang-ppc64-aix/llvm-project/llvm/utils/lit/lit.py -j1 --order=lexical Inputs/timeout-hang/run-nonexistent.txt --timeout=1 --param external=0 | "/home/llvm/llvm-external-buildbots/workers/env/bin/python3.11" /home/llvm/llvm-external-buildbots/workers/aix-ppc64/clang-ppc64-aix/build/utils/lit/tests/timeout-hang.py 1 # executed command: not env -u FILECHECK_OPTS /home/llvm/llvm-external-buildbots/workers/env/bin/python3.11 /home/llvm/llvm-external-buildbots/workers/aix-ppc64/clang-ppc64-aix/llvm-project/llvm/utils/lit/lit.py -j1 --order=lexical Inputs/timeout-hang/run-nonexistent.txt --timeout=1 --param external=0 # .---command stderr------------ # | lit.py: /home/llvm/llvm-external-buildbots/workers/aix-ppc64/clang-ppc64-aix/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 1 seconds was requested on the command line. Forcing timeout to be 1 seconds. # `----------------------------- # executed command: /home/llvm/llvm-external-buildbots/workers/env/bin/python3.11 /home/llvm/llvm-external-buildbots/workers/aix-ppc64/clang-ppc64-aix/build/utils/lit/tests/timeout-hang.py 1 # .---command stdout------------ # | Testing took as long or longer than timeout # `----------------------------- # error: command failed with exit status: 1 -- ******************** 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment