xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/interception/interception_linux.cc (revision 7c30b7e17f4454167eadd2991e8fa9e6536eacd8)
1a7c257b0Skamil //===-- interception_linux.cc -----------------------------------*- C++ -*-===//
2a7c257b0Skamil //
3a7c257b0Skamil //                     The LLVM Compiler Infrastructure
4a7c257b0Skamil //
5a7c257b0Skamil // This file is distributed under the University of Illinois Open Source
6a7c257b0Skamil // License. See LICENSE.TXT for details.
7a7c257b0Skamil //
8a7c257b0Skamil //===----------------------------------------------------------------------===//
9a7c257b0Skamil //
10a7c257b0Skamil // This file is a part of AddressSanitizer, an address sanity checker.
11a7c257b0Skamil //
12a7c257b0Skamil // Linux-specific interception methods.
13a7c257b0Skamil //===----------------------------------------------------------------------===//
14a7c257b0Skamil 
15a7c257b0Skamil #include "interception.h"
16a7c257b0Skamil 
17a7c257b0Skamil #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
18a7c257b0Skamil     SANITIZER_OPENBSD || SANITIZER_SOLARIS
19a7c257b0Skamil 
20a7c257b0Skamil #include <dlfcn.h>   // for dlsym() and dlvsym()
21a7c257b0Skamil 
22a7c257b0Skamil #if SANITIZER_NETBSD
23a7c257b0Skamil #include "sanitizer_common/sanitizer_libc.h"
24a7c257b0Skamil #endif
25a7c257b0Skamil 
26a7c257b0Skamil namespace __interception {
GetRealFunctionAddress(const char * func_name,uptr * func_addr,uptr real,uptr wrapper)27a7c257b0Skamil bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
28a7c257b0Skamil     uptr real, uptr wrapper) {
29a7c257b0Skamil #if SANITIZER_NETBSD
30a7c257b0Skamil   // XXX: Find a better way to handle renames
31*7c30b7e1Sthorpej   // XXX: Do we have to handle the old __sigaction14 name here too?
32*7c30b7e1Sthorpej   if (internal_strcmp(func_name, "sigaction") == 0) func_name = "__sigaction_siginfo";
33a7c257b0Skamil #endif
34a7c257b0Skamil   *func_addr = (uptr)dlsym(RTLD_NEXT, func_name);
35a7c257b0Skamil   if (!*func_addr) {
36a7c257b0Skamil     // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
37a7c257b0Skamil     // later in the library search order than the DSO that we are trying to
38a7c257b0Skamil     // intercept, which means that we cannot intercept this function. We still
39a7c257b0Skamil     // want the address of the real definition, though, so look it up using
40a7c257b0Skamil     // RTLD_DEFAULT.
41a7c257b0Skamil     *func_addr = (uptr)dlsym(RTLD_DEFAULT, func_name);
42a7c257b0Skamil   }
43a7c257b0Skamil   return real == wrapper;
44a7c257b0Skamil }
45a7c257b0Skamil 
46a7c257b0Skamil // Android and Solaris do not have dlvsym
47a7c257b0Skamil #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
GetFuncAddrVer(const char * func_name,const char * ver)48a7c257b0Skamil void *GetFuncAddrVer(const char *func_name, const char *ver) {
49a7c257b0Skamil   return dlvsym(RTLD_NEXT, func_name, ver);
50a7c257b0Skamil }
51a7c257b0Skamil #endif  // !SANITIZER_ANDROID
52a7c257b0Skamil 
53a7c257b0Skamil }  // namespace __interception
54a7c257b0Skamil 
55a7c257b0Skamil #endif  // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
56a7c257b0Skamil         // SANITIZER_OPENBSD || SANITIZER_SOLARIS
57