diff options
| author | maxim-yurchuk <[email protected]> | 2025-09-11 18:10:35 +0300 |
|---|---|---|
| committer | maxim-yurchuk <[email protected]> | 2025-09-11 18:29:46 +0300 |
| commit | f4413504c29db8e1e7cce3a2103e89ecb4073271 (patch) | |
| tree | 1bf7e20cd558f17fc8ec8c18f73efda775fc447a /contrib/libs/clang20-rt/lib/interception/interception_linux.cpp | |
| parent | 542e74eb48caba00fb12eef75125e376ab12c0c9 (diff) | |
Add clang20-rt into ydb sync config
commit_hash:a644e6487e802adc4b59a62ef53000053f586377
Diffstat (limited to 'contrib/libs/clang20-rt/lib/interception/interception_linux.cpp')
| -rw-r--r-- | contrib/libs/clang20-rt/lib/interception/interception_linux.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/contrib/libs/clang20-rt/lib/interception/interception_linux.cpp b/contrib/libs/clang20-rt/lib/interception/interception_linux.cpp new file mode 100644 index 00000000000..ef8136eb4fc --- /dev/null +++ b/contrib/libs/clang20-rt/lib/interception/interception_linux.cpp @@ -0,0 +1,83 @@ +//===-- interception_linux.cpp ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Linux-specific interception methods. +//===----------------------------------------------------------------------===// + +#include "interception.h" + +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS + +#include <dlfcn.h> // for dlsym() and dlvsym() + +namespace __interception { + +#if SANITIZER_NETBSD +static int StrCmp(const char *s1, const char *s2) { + while (true) { + if (*s1 != *s2) + return false; + if (*s1 == 0) + return true; + s1++; + s2++; + } +} +#endif + +static void *GetFuncAddr(const char *name, uptr trampoline) { +#if SANITIZER_NETBSD + // FIXME: Find a better way to handle renames + if (StrCmp(name, "sigaction")) + name = "__sigaction14"; +#endif + void *addr = dlsym(RTLD_NEXT, name); + if (!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. + addr = dlsym(RTLD_DEFAULT, name); + + // In case `name' is not loaded, dlsym ends up finding the actual wrapper. + // We don't want to intercept the wrapper and have it point to itself. + if ((uptr)addr == trampoline) + addr = nullptr; + } + return addr; +} + +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr trampoline) { + void *addr = GetFuncAddr(name, trampoline); + *ptr_to_real = (uptr)addr; + return addr && (func == trampoline); +} + +// dlvsym is a GNU extension supported by some other platforms. +#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD +static void *GetFuncAddr(const char *name, const char *ver) { + return dlvsym(RTLD_NEXT, name, ver); +} + +bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, + uptr func, uptr trampoline) { + void *addr = GetFuncAddr(name, ver); + *ptr_to_real = (uptr)addr; + return addr && (func == trampoline); +} +# endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD + +} // namespace __interception + +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || + // SANITIZER_SOLARIS |
