1 //===-- sanitizer_libignore.cc --------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 #include "sanitizer_platform.h"
10 #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_NETBSD
12 #include "sanitizer_libignore.h"
13 #include "sanitizer_flags.h"
14 #include "sanitizer_posix.h"
15 #include "sanitizer_procmaps.h"
17 namespace __sanitizer
{
19 LibIgnore::LibIgnore(LinkerInitialized
) {
22 void LibIgnore::AddIgnoredLibrary(const char *name_templ
) {
23 BlockingMutexLock
lock(&mutex_
);
24 if (count_
>= kMaxLibs
) {
25 Report("%s: too many ignored libraries (max: %d)\n", SanitizerToolName
,
29 Lib
*lib
= &libs_
[count_
++];
30 lib
->templ
= internal_strdup(name_templ
);
32 lib
->real_name
= nullptr;
36 void LibIgnore::OnLibraryLoaded(const char *name
) {
37 BlockingMutexLock
lock(&mutex_
);
38 // Try to match suppressions with symlink target.
39 InternalScopedString
buf(kMaxPathLength
);
40 if (name
&& internal_readlink(name
, buf
.data(), buf
.size() - 1) > 0 &&
42 for (uptr i
= 0; i
< count_
; i
++) {
44 if (!lib
->loaded
&& (!lib
->real_name
) &&
45 TemplateMatch(lib
->templ
, name
))
46 lib
->real_name
= internal_strdup(buf
.data());
50 // Scan suppressions list and find newly loaded and unloaded libraries.
51 ListOfModules modules
;
53 for (uptr i
= 0; i
< count_
; i
++) {
56 for (const auto &mod
: modules
) {
57 for (const auto &range
: mod
.ranges()) {
58 if (!range
.executable
)
60 if (!TemplateMatch(lib
->templ
, mod
.full_name()) &&
62 internal_strcmp(lib
->real_name
, mod
.full_name()) == 0))
65 Report("%s: called_from_lib suppression '%s' is matched against"
66 " 2 libraries: '%s' and '%s'\n",
67 SanitizerToolName
, lib
->templ
, lib
->name
, mod
.full_name());
74 "Matched called_from_lib suppression '%s' against library"
76 lib
->templ
, mod
.full_name());
78 lib
->name
= internal_strdup(mod
.full_name());
80 atomic_load(&ignored_ranges_count_
, memory_order_relaxed
);
81 CHECK_LT(idx
, kMaxLibs
);
82 ignored_code_ranges_
[idx
].begin
= range
.beg
;
83 ignored_code_ranges_
[idx
].end
= range
.end
;
84 atomic_store(&ignored_ranges_count_
, idx
+ 1, memory_order_release
);
88 if (lib
->loaded
&& !loaded
) {
89 Report("%s: library '%s' that was matched against called_from_lib"
90 " suppression '%s' is unloaded\n",
91 SanitizerToolName
, lib
->name
, lib
->templ
);
96 // Track instrumented ranges.
97 if (track_instrumented_libs_
) {
98 for (const auto &mod
: modules
) {
99 if (!mod
.instrumented())
101 for (const auto &range
: mod
.ranges()) {
102 if (!range
.executable
)
104 if (IsPcInstrumented(range
.beg
) && IsPcInstrumented(range
.end
- 1))
106 VReport(1, "Adding instrumented range %p-%p from library '%s'\n",
107 range
.beg
, range
.end
, mod
.full_name());
109 atomic_load(&instrumented_ranges_count_
, memory_order_relaxed
);
110 CHECK_LT(idx
, kMaxLibs
);
111 instrumented_code_ranges_
[idx
].begin
= range
.beg
;
112 instrumented_code_ranges_
[idx
].end
= range
.end
;
113 atomic_store(&instrumented_ranges_count_
, idx
+ 1,
114 memory_order_release
);
120 void LibIgnore::OnLibraryUnloaded() {
121 OnLibraryLoaded(nullptr);
124 } // namespace __sanitizer
126 #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC ||