xref: /freebsd/contrib/llvm-project/compiler-rt/lib/interception/interception_aix.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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