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 || \
11 SANITIZER_NETBSD || SANITIZER_OPENBSD
13 #include "sanitizer_libignore.h"
14 #include "sanitizer_flags.h"
15 #include "sanitizer_posix.h"
16 #include "sanitizer_procmaps.h"
18 namespace __sanitizer
{
20 LibIgnore::LibIgnore(LinkerInitialized
) {
23 void LibIgnore::AddIgnoredLibrary(const char *name_templ
) {
24 BlockingMutexLock
lock(&mutex_
);
25 if (count_
>= kMaxLibs
) {
26 Report("%s: too many ignored libraries (max: %d)\n", SanitizerToolName
,
30 Lib
*lib
= &libs_
[count_
++];
31 lib
->templ
= internal_strdup(name_templ
);
33 lib
->real_name
= nullptr;
37 void LibIgnore::OnLibraryLoaded(const char *name
) {
38 BlockingMutexLock
lock(&mutex_
);
39 // Try to match suppressions with symlink target.
40 InternalScopedString
buf(kMaxPathLength
);
41 if (name
&& internal_readlink(name
, buf
.data(), buf
.size() - 1) > 0 &&
43 for (uptr i
= 0; i
< count_
; i
++) {
45 if (!lib
->loaded
&& (!lib
->real_name
) &&
46 TemplateMatch(lib
->templ
, name
))
47 lib
->real_name
= internal_strdup(buf
.data());
51 // Scan suppressions list and find newly loaded and unloaded libraries.
52 ListOfModules modules
;
54 for (uptr i
= 0; i
< count_
; i
++) {
57 for (const auto &mod
: modules
) {
58 for (const auto &range
: mod
.ranges()) {
59 if (!range
.executable
)
61 if (!TemplateMatch(lib
->templ
, mod
.full_name()) &&
63 internal_strcmp(lib
->real_name
, mod
.full_name()) == 0))
66 Report("%s: called_from_lib suppression '%s' is matched against"
67 " 2 libraries: '%s' and '%s'\n",
68 SanitizerToolName
, lib
->templ
, lib
->name
, mod
.full_name());
75 "Matched called_from_lib suppression '%s' against library"
77 lib
->templ
, mod
.full_name());
79 lib
->name
= internal_strdup(mod
.full_name());
81 atomic_load(&ignored_ranges_count_
, memory_order_relaxed
);
82 CHECK_LT(idx
, ARRAY_SIZE(ignored_code_ranges_
));
83 ignored_code_ranges_
[idx
].begin
= range
.beg
;
84 ignored_code_ranges_
[idx
].end
= range
.end
;
85 atomic_store(&ignored_ranges_count_
, idx
+ 1, memory_order_release
);
89 if (lib
->loaded
&& !loaded
) {
90 Report("%s: library '%s' that was matched against called_from_lib"
91 " suppression '%s' is unloaded\n",
92 SanitizerToolName
, lib
->name
, lib
->templ
);
97 // Track instrumented ranges.
98 if (track_instrumented_libs_
) {
99 for (const auto &mod
: modules
) {
100 if (!mod
.instrumented())
102 for (const auto &range
: mod
.ranges()) {
103 if (!range
.executable
)
105 if (IsPcInstrumented(range
.beg
) && IsPcInstrumented(range
.end
- 1))
107 VReport(1, "Adding instrumented range %p-%p from library '%s'\n",
108 range
.beg
, range
.end
, mod
.full_name());
110 atomic_load(&instrumented_ranges_count_
, memory_order_relaxed
);
111 CHECK_LT(idx
, ARRAY_SIZE(instrumented_code_ranges_
));
112 instrumented_code_ranges_
[idx
].begin
= range
.beg
;
113 instrumented_code_ranges_
[idx
].end
= range
.end
;
114 atomic_store(&instrumented_ranges_count_
, idx
+ 1,
115 memory_order_release
);
121 void LibIgnore::OnLibraryUnloaded() {
122 OnLibraryLoaded(nullptr);
125 } // namespace __sanitizer
127 #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC ||