1 //===-- sanitizer_libignore.cc --------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "sanitizer_platform.h"
13 #include "sanitizer_libignore.h"
14 #include "sanitizer_procmaps.h"
16 namespace __sanitizer
{
18 LibIgnore::LibIgnore(LinkerInitialized
) {
21 void LibIgnore::Init(const SuppressionContext
&supp
) {
22 BlockingMutexLock
lock(&mutex_
);
24 const uptr n
= supp
.SuppressionCount();
25 for (uptr i
= 0; i
< n
; i
++) {
26 const Suppression
*s
= supp
.SuppressionAt(i
);
27 if (s
->type
!= SuppressionLib
)
29 if (count_
>= kMaxLibs
) {
30 Report("%s: too many called_from_lib suppressions (max: %d)\n",
31 SanitizerToolName
, kMaxLibs
);
34 Lib
*lib
= &libs_
[count_
++];
35 lib
->templ
= internal_strdup(s
->templ
);
41 void LibIgnore::OnLibraryLoaded(const char *name
) {
42 const char *real_name
= 0;
43 InternalScopedBuffer
<char> buf(4096);
44 if (name
!= 0 && internal_readlink(name
, buf
.data(), buf
.size() - 1) > 0)
45 real_name
= buf
.data();
47 BlockingMutexLock
lock(&mutex_
);
48 MemoryMappingLayout
proc_maps(/*cache_enabled*/false);
49 InternalScopedBuffer
<char> module(4096);
50 for (uptr i
= 0; i
< count_
; i
++) {
55 while (proc_maps
.Next(&b
, &e
, &off
, module
.data(), module
.size(), &prot
)) {
56 if ((prot
& MemoryMappingLayout::kProtectionExecute
) == 0)
60 if (TemplateMatch(lib
->templ
, module
.data()))
63 if (real_name
!= 0 && real_name
[0] != 0 &&
64 TemplateMatch(lib
->templ
, name
) &&
65 internal_strcmp(real_name
, module
.data()) == 0) {
72 Report("%s: called_from_lib suppression '%s' is matched against"
73 " 2 libraries: '%s' and '%s'\n",
74 SanitizerToolName
, lib
->templ
, lib
->name
, module
.data());
81 lib
->name
= internal_strdup(module
.data());
83 lib
->real_name
= internal_strdup(real_name
);
84 const uptr idx
= atomic_load(&loaded_count_
, memory_order_relaxed
);
85 code_ranges_
[idx
].begin
= b
;
86 code_ranges_
[idx
].end
= e
;
87 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_LINUX