Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/interception/interception_linux.cpp
35262 views
1
//===-- interception_linux.cpp ----------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file is a part of AddressSanitizer, an address sanity checker.
10
//
11
// Linux-specific interception methods.
12
//===----------------------------------------------------------------------===//
13
14
#include "interception.h"
15
16
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
17
SANITIZER_SOLARIS
18
19
#include <dlfcn.h> // for dlsym() and dlvsym()
20
21
namespace __interception {
22
23
#if SANITIZER_NETBSD
24
static int StrCmp(const char *s1, const char *s2) {
25
while (true) {
26
if (*s1 != *s2)
27
return false;
28
if (*s1 == 0)
29
return true;
30
s1++;
31
s2++;
32
}
33
}
34
#endif
35
36
static void *GetFuncAddr(const char *name, uptr trampoline) {
37
#if SANITIZER_NETBSD
38
// FIXME: Find a better way to handle renames
39
if (StrCmp(name, "sigaction"))
40
name = "__sigaction14";
41
#endif
42
void *addr = dlsym(RTLD_NEXT, name);
43
if (!addr) {
44
// If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
45
// later in the library search order than the DSO that we are trying to
46
// intercept, which means that we cannot intercept this function. We still
47
// want the address of the real definition, though, so look it up using
48
// RTLD_DEFAULT.
49
addr = dlsym(RTLD_DEFAULT, name);
50
51
// In case `name' is not loaded, dlsym ends up finding the actual wrapper.
52
// We don't want to intercept the wrapper and have it point to itself.
53
if ((uptr)addr == trampoline)
54
addr = nullptr;
55
}
56
return addr;
57
}
58
59
bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
60
uptr trampoline) {
61
void *addr = GetFuncAddr(name, trampoline);
62
*ptr_to_real = (uptr)addr;
63
return addr && (func == trampoline);
64
}
65
66
// dlvsym is a GNU extension supported by some other platforms.
67
#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
68
static void *GetFuncAddr(const char *name, const char *ver) {
69
return dlvsym(RTLD_NEXT, name, ver);
70
}
71
72
bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
73
uptr func, uptr trampoline) {
74
void *addr = GetFuncAddr(name, ver);
75
*ptr_to_real = (uptr)addr;
76
return addr && (func == trampoline);
77
}
78
# endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
79
80
} // namespace __interception
81
82
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
83
// SANITIZER_SOLARIS
84
85