1 //===-- interception_linux.cpp ----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file is a part of AddressSanitizer, an address sanity checker.
11 // Linux-specific interception methods.
12 //===----------------------------------------------------------------------===//
14 #include "interception.h"
16 #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
19 #include <dlfcn.h> // for dlsym() and dlvsym()
21 namespace __interception
{
24 static int StrCmp(const char *s1
, const char *s2
) {
36 static void *GetFuncAddr(const char *name
, uptr wrapper_addr
) {
38 // FIXME: Find a better way to handle renames
39 if (StrCmp(name
, "sigaction"))
40 name
= "__sigaction14";
42 void *addr
= dlsym(RTLD_NEXT
, name
);
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
49 addr
= dlsym(RTLD_DEFAULT
, name
);
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
== wrapper_addr
)
59 bool InterceptFunction(const char *name
, uptr
*ptr_to_real
, uptr func
,
61 void *addr
= GetFuncAddr(name
, wrapper
);
62 *ptr_to_real
= (uptr
)addr
;
63 return addr
&& (func
== wrapper
);
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
);
72 bool InterceptFunction(const char *name
, const char *ver
, uptr
*ptr_to_real
,
73 uptr func
, uptr wrapper
) {
74 void *addr
= GetFuncAddr(name
, ver
);
75 *ptr_to_real
= (uptr
)addr
;
76 return addr
&& (func
== wrapper
);
78 #endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
80 } // namespace __interception
82 #endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||