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"
9 #if SANITIZER_FREEBSD || SANITIZER_LINUX
11 #include "sanitizer_libignore.h"
12 #include "sanitizer_flags.h"
13 #include "sanitizer_procmaps.h"
15 namespace __sanitizer
{
17 LibIgnore::LibIgnore(LinkerInitialized
) {
20 void LibIgnore::Init(const SuppressionContext
&supp
) {
21 BlockingMutexLock
lock(&mutex_
);
23 const uptr n
= supp
.SuppressionCount();
24 for (uptr i
= 0; i
< n
; i
++) {
25 const Suppression
*s
= supp
.SuppressionAt(i
);
26 if (s
->type
!= SuppressionLib
)
28 if (count_
>= kMaxLibs
) {
29 Report("%s: too many called_from_lib suppressions (max: %d)\n",
30 SanitizerToolName
, kMaxLibs
);
33 Lib
*lib
= &libs_
[count_
++];
34 lib
->templ
= internal_strdup(s
->templ
);
40 void LibIgnore::OnLibraryLoaded(const char *name
) {
41 BlockingMutexLock
lock(&mutex_
);
42 // Try to match suppressions with symlink target.
43 InternalScopedBuffer
<char> buf(4096);
44 if (name
!= 0 && internal_readlink(name
, buf
.data(), buf
.size() - 1) > 0 &&
46 for (uptr i
= 0; i
< count_
; i
++) {
48 if (!lib
->loaded
&& lib
->real_name
== 0 &&
49 TemplateMatch(lib
->templ
, name
))
50 lib
->real_name
= internal_strdup(buf
.data());
54 // Scan suppressions list and find newly loaded and unloaded libraries.
55 MemoryMappingLayout
proc_maps(/*cache_enabled*/false);
56 InternalScopedBuffer
<char> module(4096);
57 for (uptr i
= 0; i
< count_
; i
++) {
62 while (proc_maps
.Next(&b
, &e
, &off
, module
.data(), module
.size(), &prot
)) {
63 if ((prot
& MemoryMappingLayout::kProtectionExecute
) == 0)
65 if (TemplateMatch(lib
->templ
, module
.data()) ||
66 (lib
->real_name
!= 0 &&
67 internal_strcmp(lib
->real_name
, module
.data()) == 0)) {
69 Report("%s: called_from_lib suppression '%s' is matched against"
70 " 2 libraries: '%s' and '%s'\n",
71 SanitizerToolName
, lib
->templ
, lib
->name
, module
.data());
78 "Matched called_from_lib suppression '%s' against library"
80 lib
->templ
, module
.data());
82 lib
->name
= internal_strdup(module
.data());
83 const uptr idx
= atomic_load(&loaded_count_
, memory_order_relaxed
);
84 code_ranges_
[idx
].begin
= b
;
85 code_ranges_
[idx
].end
= e
;
86 atomic_store(&loaded_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
);
98 void LibIgnore::OnLibraryUnloaded() {
102 } // namespace __sanitizer
104 #endif // #if SANITIZER_FREEBSD || SANITIZER_LINUX