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