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