1 //===-- sanitizer_libignore.cpp -------------------------------------------===//
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 #include "sanitizer_platform.h"
11 #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
14 #include "sanitizer_libignore.h"
15 #include "sanitizer_flags.h"
16 #include "sanitizer_posix.h"
17 #include "sanitizer_procmaps.h"
19 namespace __sanitizer
{
21 LibIgnore::LibIgnore(LinkerInitialized
) {
24 void LibIgnore::AddIgnoredLibrary(const char *name_templ
) {
26 if (count_
>= kMaxLibs
) {
27 Report("%s: too many ignored libraries (max: %zu)\n", SanitizerToolName
,
31 Lib
*lib
= &libs_
[count_
++];
32 lib
->templ
= internal_strdup(name_templ
);
34 lib
->real_name
= nullptr;
38 void LibIgnore::OnLibraryLoaded(const char *name
) {
40 // Try to match suppressions with symlink target.
41 InternalMmapVector
<char> buf(kMaxPathLength
);
42 if (name
&& internal_readlink(name
, buf
.data(), buf
.size() - 1) > 0 &&
44 for (uptr i
= 0; i
< count_
; i
++) {
46 if (!lib
->loaded
&& (!lib
->real_name
) &&
47 TemplateMatch(lib
->templ
, name
))
48 lib
->real_name
= internal_strdup(buf
.data());
52 // Scan suppressions list and find newly loaded and unloaded libraries.
53 ListOfModules modules
;
55 for (uptr i
= 0; i
< count_
; i
++) {
58 for (const auto &mod
: modules
) {
59 for (const auto &range
: mod
.ranges()) {
60 if (!range
.executable
)
62 if (!TemplateMatch(lib
->templ
, mod
.full_name()) &&
64 internal_strcmp(lib
->real_name
, mod
.full_name()) == 0))
67 Report("%s: called_from_lib suppression '%s' is matched against"
68 " 2 libraries: '%s' and '%s'\n",
69 SanitizerToolName
, lib
->templ
, lib
->name
, mod
.full_name());
76 "Matched called_from_lib suppression '%s' against library"
78 lib
->templ
, mod
.full_name());
80 lib
->name
= internal_strdup(mod
.full_name());
82 atomic_load(&ignored_ranges_count_
, memory_order_relaxed
);
83 CHECK_LT(idx
, ARRAY_SIZE(ignored_code_ranges_
));
84 ignored_code_ranges_
[idx
].begin
= range
.beg
;
85 ignored_code_ranges_
[idx
].end
= range
.end
;
86 atomic_store(&ignored_ranges_count_
, idx
+ 1, memory_order_release
);
90 if (lib
->loaded
&& !loaded
) {
91 Report("%s: library '%s' that was matched against called_from_lib"
92 " suppression '%s' is unloaded\n",
93 SanitizerToolName
, lib
->name
, lib
->templ
);
98 // Track instrumented ranges.
99 if (track_instrumented_libs_
) {
100 for (const auto &mod
: modules
) {
101 if (!mod
.instrumented())
103 for (const auto &range
: mod
.ranges()) {
104 if (!range
.executable
)
106 if (IsPcInstrumented(range
.beg
) && IsPcInstrumented(range
.end
- 1))
108 VReport(1, "Adding instrumented range 0x%zx-0x%zx from library '%s'\n",
109 range
.beg
, range
.end
, mod
.full_name());
111 atomic_load(&instrumented_ranges_count_
, memory_order_relaxed
);
112 CHECK_LT(idx
, ARRAY_SIZE(instrumented_code_ranges_
));
113 instrumented_code_ranges_
[idx
].begin
= range
.beg
;
114 instrumented_code_ranges_
[idx
].end
= range
.end
;
115 atomic_store(&instrumented_ranges_count_
, idx
+ 1,
116 memory_order_release
);
122 void LibIgnore::OnLibraryUnloaded() {
123 OnLibraryLoaded(nullptr);
126 } // namespace __sanitizer
128 #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC ||