If the lookup using RTLD_NEXT failed, the sanitizer runtime library is later in the library search order than the DSO that we are trying to intercept, which means that we cannot intercept this function. We still want the address of the real definition, though, so look it up using RTLD_DEFAULT. Differential Revision: https://reviews.llvm.org/D39779 llvm-svn: 317930
52 lines
1.8 KiB
C++
52 lines
1.8 KiB
C++
//===-- interception_linux.cc -----------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of AddressSanitizer, an address sanity checker.
|
|
//
|
|
// Linux-specific interception methods.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
|
#include "interception.h"
|
|
|
|
#include <dlfcn.h> // for dlsym() and dlvsym()
|
|
|
|
#ifdef __NetBSD__
|
|
#include "sanitizer_common/sanitizer_libc.h"
|
|
#endif
|
|
|
|
namespace __interception {
|
|
bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
|
|
uptr real, uptr wrapper) {
|
|
#ifdef __NetBSD__
|
|
// XXX: Find a better way to handle renames
|
|
if (internal_strcmp(func_name, "sigaction") == 0) func_name = "__sigaction14";
|
|
#endif
|
|
*func_addr = (uptr)dlsym(RTLD_NEXT, func_name);
|
|
if (!*func_addr) {
|
|
// If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
|
|
// later in the library search order than the DSO that we are trying to
|
|
// intercept, which means that we cannot intercept this function. We still
|
|
// want the address of the real definition, though, so look it up using
|
|
// RTLD_DEFAULT.
|
|
*func_addr = (uptr)dlsym(RTLD_DEFAULT, func_name);
|
|
}
|
|
return real == wrapper;
|
|
}
|
|
|
|
#if !defined(__ANDROID__) // android does not have dlvsym
|
|
void *GetFuncAddrVer(const char *func_name, const char *ver) {
|
|
return dlvsym(RTLD_NEXT, func_name, ver);
|
|
}
|
|
#endif // !defined(__ANDROID__)
|
|
|
|
} // namespace __interception
|
|
|
|
#endif // __linux__ || __FreeBSD__ || __NetBSD__
|