[compiler-rt] [tsan] Allow unloading of ignored libraries (PR #105660)

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 15 23:15:27 PDT 2024


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/105660

>From 8291ea25814a6e42987f7510c083acdf5a507e0f Mon Sep 17 00:00:00 2001
From: Pierre Gousseau <pierre.gousseau at sony.com>
Date: Wed, 21 Aug 2024 15:52:52 +0000
Subject: [PATCH 1/7] [tsan] Allow unloading of ignored libraries

Allows unloading and reloading of ignored libraries.
We don't attempt to reuse or free memory of unloaded library.
So TSan will assert if an ignored library is reloaded 128 times.
---
 .../sanitizer_common/sanitizer_libignore.cpp  | 14 ++++++--
 .../sanitizer_common/sanitizer_libignore.h    | 32 +++++++++++++++++--
 compiler-rt/test/tsan/ignore_lib3.cpp         | 29 ++++++++++++-----
 3 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
index f0e1e3d69def53..85b97ac0e78a93 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
@@ -33,6 +33,7 @@ void LibIgnore::AddIgnoredLibrary(const char *name_templ) {
   lib->name = nullptr;
   lib->real_name = nullptr;
   lib->loaded = false;
+  lib->ignored_code_range_id = kInvalidCodeRangeId;
 }
 
 void LibIgnore::OnLibraryLoaded(const char *name) {
@@ -81,17 +82,24 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
         const uptr idx =
             atomic_load(&ignored_ranges_count_, memory_order_relaxed);
         CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));
-        ignored_code_ranges_[idx].begin = range.beg;
+        ignored_code_ranges_[idx].begin(range.beg);
         ignored_code_ranges_[idx].end = range.end;
+        ignored_code_ranges_[idx].loaded = 1;
+        // Record the index of the ignored range.
+        lib->ignored_code_range_id = idx;
         atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
         break;
       }
     }
     if (lib->loaded && !loaded) {
-      Report("%s: library '%s' that was matched against called_from_lib"
+      VReport(1, "%s: library '%s' that was matched against called_from_lib"
              " suppression '%s' is unloaded\n",
              SanitizerToolName, lib->name, lib->templ);
-      Die();
+      // The library is unloaded so mark the ignored code range as unloaded.
+      CHECK_NE(lib->ignored_code_range_id, kInvalidCodeRangeId);
+      ignored_code_ranges_[lib->ignored_code_range_id].loaded = 0;
+      lib->ignored_code_range_id = kInvalidCodeRangeId;
+      lib->loaded = false;
     }
   }
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
index 18e4d83ed77fb8..228d15b3733cc7 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
@@ -54,6 +54,7 @@ class LibIgnore {
     char *name;
     char *real_name;  // target of symlink
     bool loaded;
+    uptr ignored_code_range_id;
   };
 
   struct LibCodeRange {
@@ -61,6 +62,31 @@ class LibIgnore {
     uptr end;
   };
 
+  // Marks a range as loaded by utilizing the least significant bit of the code
+  // range. Assumes the start of the code range is 2-byte aligned.
+  struct LibLoadedCodeRange {
+    uptr begin() const { return begin_ << 1; }
+    void begin(uptr begin) {
+      CHECK_EQ(begin & 0x1, 0);
+      begin_ = begin >> 1;
+    }
+
+  private:
+    uptr begin_ : 63;
+
+  public:
+    uptr loaded : 1;
+    uptr end;
+  };
+
+  static_assert(sizeof(LibLoadedCodeRange) == 16,
+                "LibLoadedCodeRange size expected to be 16-bytes for "
+                "performance reasons.");
+
+  inline bool IsInRange(uptr pc, const LibLoadedCodeRange &range) const {
+    return (pc >= range.begin() && pc < range.end);
+  }
+
   inline bool IsInRange(uptr pc, const LibCodeRange &range) const {
     return (pc >= range.begin && pc < range.end);
   }
@@ -68,10 +94,11 @@ class LibIgnore {
   static const uptr kMaxIgnoredRanges = 128;
   static const uptr kMaxInstrumentedRanges = 1024;
   static const uptr kMaxLibs = 1024;
+  static const uptr kInvalidCodeRangeId = ~0x0ULL;
 
   // Hot part:
   atomic_uintptr_t ignored_ranges_count_;
-  LibCodeRange ignored_code_ranges_[kMaxIgnoredRanges];
+  LibLoadedCodeRange ignored_code_ranges_[kMaxIgnoredRanges];
 
   atomic_uintptr_t instrumented_ranges_count_;
   LibCodeRange instrumented_code_ranges_[kMaxInstrumentedRanges];
@@ -90,7 +117,8 @@ class LibIgnore {
 inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const {
   const uptr n = atomic_load(&ignored_ranges_count_, memory_order_acquire);
   for (uptr i = 0; i < n; i++) {
-    if (IsInRange(pc, ignored_code_ranges_[i])) {
+    if (ignored_code_ranges_[i].loaded &&
+        IsInRange(pc, ignored_code_ranges_[i])) {
       *pc_in_ignored_lib = true;
       return true;
     }
diff --git a/compiler-rt/test/tsan/ignore_lib3.cpp b/compiler-rt/test/tsan/ignore_lib3.cpp
index b1a3940d03b615..c1fac0138f68ef 100644
--- a/compiler-rt/test/tsan/ignore_lib3.cpp
+++ b/compiler-rt/test/tsan/ignore_lib3.cpp
@@ -3,10 +3,10 @@
 
 // RUN: %clangxx_tsan -O1 %s -DLIB -fPIC -fno-sanitize=thread -shared -o %t-dir/libignore_lib3.so
 // RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t-dir/executable
-// RUN: %env_tsan_opts=suppressions='%s.supp' %deflake %run %t-dir/executable | FileCheck %s
+// RUN: %env_tsan_opts=suppressions='%s.supp':verbosity=1 %run %t-dir/executable 2>&1 | FileCheck %s
 
 // Tests that unloading of a library matched against called_from_lib suppression
-// causes program crash (this is not supported).
+// is supported.
 
 // Some aarch64 kernels do not support non executable write pages
 // REQUIRES: stable-runtime
@@ -22,18 +22,31 @@
 
 int main(int argc, char **argv) {
   std::string lib = std::string(dirname(argv[0])) + "/libignore_lib3.so";
-  void *h = dlopen(lib.c_str(), RTLD_GLOBAL | RTLD_NOW);
-  dlclose(h);
+  void *h;
+  void (*f)();
+  // Try opening, closing and reopening the ignored lib.
+  for (unsigned int k = 0; k < 2; k++) {
+    h = dlopen(lib.c_str(), RTLD_GLOBAL | RTLD_NOW);
+    if (h == 0)
+      exit(printf("failed to load the library (%d)\n", errno));
+    f = (void (*)())dlsym(h, "libfunc");
+    if (f == 0)
+      exit(printf("failed to find the func (%d)\n", errno));
+    f();
+    dlclose(h);
+  }
   fprintf(stderr, "OK\n");
 }
 
 #else  // #ifdef LIB
 
-extern "C" void libfunc() {
-}
+#include "ignore_lib_lib.h"
 
 #endif  // #ifdef LIB
 
-// CHECK: ThreadSanitizer: library {{.*}} that was matched against called_from_lib suppression 'ignore_lib3.so' is unloaded
-// CHECK-NOT: OK
+// CHECK: Matched called_from_lib suppression 'ignore_lib3.so'
+// CHECK: library '{{.*}}ignore_lib3.so' that was matched against called_from_lib suppression 'ignore_lib3.so' is unloaded
+// CHECK: Matched called_from_lib suppression 'ignore_lib3.so'
+// CHECK: library '{{.*}}ignore_lib3.so' that was matched against called_from_lib suppression 'ignore_lib3.so' is unloaded
+// CHECK: OK
 

>From 6fdb73e38ca963bb0ad43a3d9a014263989ddc14 Mon Sep 17 00:00:00 2001
From: Pierre Gousseau <pierre.gousseau at sony.com>
Date: Fri, 23 Aug 2024 10:18:58 +0000
Subject: [PATCH 2/7] apply clang-format

---
 compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp | 7 ++++---
 compiler-rt/lib/sanitizer_common/sanitizer_libignore.h   | 4 ++--
 compiler-rt/test/tsan/ignore_lib3.cpp                    | 3 +--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
index 85b97ac0e78a93..1df97181a713be 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
@@ -92,9 +92,10 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
       }
     }
     if (lib->loaded && !loaded) {
-      VReport(1, "%s: library '%s' that was matched against called_from_lib"
-             " suppression '%s' is unloaded\n",
-             SanitizerToolName, lib->name, lib->templ);
+      VReport(1,
+              "%s: library '%s' that was matched against called_from_lib"
+              " suppression '%s' is unloaded\n",
+              SanitizerToolName, lib->name, lib->templ);
       // The library is unloaded so mark the ignored code range as unloaded.
       CHECK_NE(lib->ignored_code_range_id, kInvalidCodeRangeId);
       ignored_code_ranges_[lib->ignored_code_range_id].loaded = 0;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
index 228d15b3733cc7..b4f891ca1d35bc 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
@@ -71,10 +71,10 @@ class LibIgnore {
       begin_ = begin >> 1;
     }
 
-  private:
+   private:
     uptr begin_ : 63;
 
-  public:
+   public:
     uptr loaded : 1;
     uptr end;
   };
diff --git a/compiler-rt/test/tsan/ignore_lib3.cpp b/compiler-rt/test/tsan/ignore_lib3.cpp
index c1fac0138f68ef..a919a3ee4e7a4e 100644
--- a/compiler-rt/test/tsan/ignore_lib3.cpp
+++ b/compiler-rt/test/tsan/ignore_lib3.cpp
@@ -40,7 +40,7 @@ int main(int argc, char **argv) {
 
 #else  // #ifdef LIB
 
-#include "ignore_lib_lib.h"
+#  include "ignore_lib_lib.h"
 
 #endif  // #ifdef LIB
 
@@ -49,4 +49,3 @@ int main(int argc, char **argv) {
 // CHECK: Matched called_from_lib suppression 'ignore_lib3.so'
 // CHECK: library '{{.*}}ignore_lib3.so' that was matched against called_from_lib suppression 'ignore_lib3.so' is unloaded
 // CHECK: OK
-

>From f0651b5be8c284953e0f0f47d254298dc8986f21 Mon Sep 17 00:00:00 2001
From: Pierre Gousseau <pierre.gousseau at sony.com>
Date: Tue, 27 Aug 2024 17:04:00 +0000
Subject: [PATCH 3/7] Changes following review comments. Set end value to 0 to
 mark an ignored range's module as unloaded.

---
 .../sanitizer_common/sanitizer_libignore.cpp  | 12 +++---
 .../sanitizer_common/sanitizer_libignore.h    | 40 +++++--------------
 2 files changed, 16 insertions(+), 36 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
index 1df97181a713be..d8aa24bc54c879 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
@@ -82,9 +82,9 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
         const uptr idx =
             atomic_load(&ignored_ranges_count_, memory_order_relaxed);
         CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));
-        ignored_code_ranges_[idx].begin(range.beg);
-        ignored_code_ranges_[idx].end = range.end;
-        ignored_code_ranges_[idx].loaded = 1;
+        ignored_code_ranges_[idx].begin = range.beg;
+        atomic_store(&ignored_code_ranges_[idx].end, range.end,
+                     memory_order_release);
         // Record the index of the ignored range.
         lib->ignored_code_range_id = idx;
         atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
@@ -98,7 +98,8 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
               SanitizerToolName, lib->name, lib->templ);
       // The library is unloaded so mark the ignored code range as unloaded.
       CHECK_NE(lib->ignored_code_range_id, kInvalidCodeRangeId);
-      ignored_code_ranges_[lib->ignored_code_range_id].loaded = 0;
+      atomic_store(&ignored_code_ranges_[lib->ignored_code_range_id].end, 0,
+                   memory_order_release);
       lib->ignored_code_range_id = kInvalidCodeRangeId;
       lib->loaded = false;
     }
@@ -120,7 +121,8 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
             atomic_load(&instrumented_ranges_count_, memory_order_relaxed);
         CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_));
         instrumented_code_ranges_[idx].begin = range.beg;
-        instrumented_code_ranges_[idx].end = range.end;
+        atomic_store(&instrumented_code_ranges_[idx].end, range.end,
+                     memory_order_release);
         atomic_store(&instrumented_ranges_count_, idx + 1,
                      memory_order_release);
       }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
index b4f891ca1d35bc..18785b36efa006 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
@@ -59,38 +59,17 @@ class LibIgnore {
 
   struct LibCodeRange {
     uptr begin;
-    uptr end;
-  };
-
-  // Marks a range as loaded by utilizing the least significant bit of the code
-  // range. Assumes the start of the code range is 2-byte aligned.
-  struct LibLoadedCodeRange {
-    uptr begin() const { return begin_ << 1; }
-    void begin(uptr begin) {
-      CHECK_EQ(begin & 0x1, 0);
-      begin_ = begin >> 1;
+    // A value of 0 means the associated module was unloaded.
+    atomic_uintptr_t end;
+    bool IsInRange(uptr pc) const {
+      return (pc >= begin && pc < atomic_load(&end, memory_order_relaxed));
     }
-
-   private:
-    uptr begin_ : 63;
-
-   public:
-    uptr loaded : 1;
-    uptr end;
   };
 
-  static_assert(sizeof(LibLoadedCodeRange) == 16,
-                "LibLoadedCodeRange size expected to be 16-bytes for "
+  static_assert(sizeof(LibCodeRange) == 16,
+                "LibCodeRange size expected to be 16-bytes for "
                 "performance reasons.");
 
-  inline bool IsInRange(uptr pc, const LibLoadedCodeRange &range) const {
-    return (pc >= range.begin() && pc < range.end);
-  }
-
-  inline bool IsInRange(uptr pc, const LibCodeRange &range) const {
-    return (pc >= range.begin && pc < range.end);
-  }
-
   static const uptr kMaxIgnoredRanges = 128;
   static const uptr kMaxInstrumentedRanges = 1024;
   static const uptr kMaxLibs = 1024;
@@ -98,7 +77,7 @@ class LibIgnore {
 
   // Hot part:
   atomic_uintptr_t ignored_ranges_count_;
-  LibLoadedCodeRange ignored_code_ranges_[kMaxIgnoredRanges];
+  LibCodeRange ignored_code_ranges_[kMaxIgnoredRanges];
 
   atomic_uintptr_t instrumented_ranges_count_;
   LibCodeRange instrumented_code_ranges_[kMaxInstrumentedRanges];
@@ -117,8 +96,7 @@ class LibIgnore {
 inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const {
   const uptr n = atomic_load(&ignored_ranges_count_, memory_order_acquire);
   for (uptr i = 0; i < n; i++) {
-    if (ignored_code_ranges_[i].loaded &&
-        IsInRange(pc, ignored_code_ranges_[i])) {
+    if (ignored_code_ranges_[i].IsInRange(pc)) {
       *pc_in_ignored_lib = true;
       return true;
     }
@@ -132,7 +110,7 @@ inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const {
 inline bool LibIgnore::IsPcInstrumented(uptr pc) const {
   const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire);
   for (uptr i = 0; i < n; i++) {
-    if (IsInRange(pc, instrumented_code_ranges_[i]))
+    if (instrumented_code_ranges_[i].IsInRange(pc))
       return true;
   }
   return false;

>From 387afa501fe49118f9775194b4cbdf7d53db5550 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sun, 15 Sep 2024 22:54:21 -0700
Subject: [PATCH 4/7] Move constants before types and -1 to avoid truncation
 warning

---
 .../lib/sanitizer_common/sanitizer_libignore.h     | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
index 18785b36efa006..bc1e13f908fcb6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
@@ -49,6 +49,11 @@ class LibIgnore {
   bool IsPcInstrumented(uptr pc) const;
 
  private:
+  static const uptr kMaxIgnoredRanges = 128;
+  static const uptr kMaxInstrumentedRanges = 1024;
+  static const uptr kMaxLibs = 1024;
+  static const uptr kInvalidCodeRangeId = -1;
+
   struct Lib {
     char *templ;
     char *name;
@@ -66,15 +71,6 @@ class LibIgnore {
     }
   };
 
-  static_assert(sizeof(LibCodeRange) == 16,
-                "LibCodeRange size expected to be 16-bytes for "
-                "performance reasons.");
-
-  static const uptr kMaxIgnoredRanges = 128;
-  static const uptr kMaxInstrumentedRanges = 1024;
-  static const uptr kMaxLibs = 1024;
-  static const uptr kInvalidCodeRangeId = ~0x0ULL;
-
   // Hot part:
   atomic_uintptr_t ignored_ranges_count_;
   LibCodeRange ignored_code_ranges_[kMaxIgnoredRanges];

>From 3f7266e4c27ad1c0d7f415cacdac331e1ecec508 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sun, 15 Sep 2024 23:02:25 -0700
Subject: [PATCH 5/7] remove redundant field

---
 .../sanitizer_common/sanitizer_libignore.cpp   | 18 +++++++-----------
 .../lib/sanitizer_common/sanitizer_libignore.h |  4 ++--
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
index d8aa24bc54c879..7fae6404c82ee5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
@@ -32,8 +32,7 @@ void LibIgnore::AddIgnoredLibrary(const char *name_templ) {
   lib->templ = internal_strdup(name_templ);
   lib->name = nullptr;
   lib->real_name = nullptr;
-  lib->loaded = false;
-  lib->ignored_code_range_id = kInvalidCodeRangeId;
+  lib->range_id = kInvalidCodeRangeId;
 }
 
 void LibIgnore::OnLibraryLoaded(const char *name) {
@@ -44,7 +43,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
       buf[0]) {
     for (uptr i = 0; i < count_; i++) {
       Lib *lib = &libs_[i];
-      if (!lib->loaded && (!lib->real_name) &&
+      if (!lib->loaded() && (!lib->real_name) &&
           TemplateMatch(lib->templ, name))
         lib->real_name = internal_strdup(buf.data());
     }
@@ -71,13 +70,12 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
           Die();
         }
         loaded = true;
-        if (lib->loaded)
+        if (lib->loaded())
           continue;
         VReport(1,
                 "Matched called_from_lib suppression '%s' against library"
                 " '%s'\n",
                 lib->templ, mod.full_name());
-        lib->loaded = true;
         lib->name = internal_strdup(mod.full_name());
         const uptr idx =
             atomic_load(&ignored_ranges_count_, memory_order_relaxed);
@@ -86,22 +84,20 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
         atomic_store(&ignored_code_ranges_[idx].end, range.end,
                      memory_order_release);
         // Record the index of the ignored range.
-        lib->ignored_code_range_id = idx;
+        lib->range_id = idx;
         atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
         break;
       }
     }
-    if (lib->loaded && !loaded) {
+    if (lib->loaded() && !loaded) {
       VReport(1,
               "%s: library '%s' that was matched against called_from_lib"
               " suppression '%s' is unloaded\n",
               SanitizerToolName, lib->name, lib->templ);
       // The library is unloaded so mark the ignored code range as unloaded.
-      CHECK_NE(lib->ignored_code_range_id, kInvalidCodeRangeId);
-      atomic_store(&ignored_code_ranges_[lib->ignored_code_range_id].end, 0,
+      atomic_store(&ignored_code_ranges_[lib->range_id].end, 0,
                    memory_order_release);
-      lib->ignored_code_range_id = kInvalidCodeRangeId;
-      lib->loaded = false;
+      lib->range_id = kInvalidCodeRangeId;
     }
   }
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
index bc1e13f908fcb6..796989ad63d8f2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
@@ -58,8 +58,8 @@ class LibIgnore {
     char *templ;
     char *name;
     char *real_name;  // target of symlink
-    bool loaded;
-    uptr ignored_code_range_id;
+    uptr range_id;
+    bool loaded() const { return range_id != kInvalidCodeRangeId; };
   };
 
   struct LibCodeRange {

>From 86a687c01e67298f45f06e1b4683fd16e5d843a8 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sun, 15 Sep 2024 23:04:13 -0700
Subject: [PATCH 6/7] Hide atomic ops in methods of LibCodeRange

---
 .../sanitizer_common/sanitizer_libignore.cpp    | 11 +++--------
 .../lib/sanitizer_common/sanitizer_libignore.h  | 17 ++++++++++++++---
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
index 7fae6404c82ee5..16c39dcf07cb99 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
@@ -80,9 +80,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
         const uptr idx =
             atomic_load(&ignored_ranges_count_, memory_order_relaxed);
         CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));
-        ignored_code_ranges_[idx].begin = range.beg;
-        atomic_store(&ignored_code_ranges_[idx].end, range.end,
-                     memory_order_release);
+        ignored_code_ranges_[idx].OnLoad(range.beg ,range.end);
         // Record the index of the ignored range.
         lib->range_id = idx;
         atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
@@ -95,8 +93,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
               " suppression '%s' is unloaded\n",
               SanitizerToolName, lib->name, lib->templ);
       // The library is unloaded so mark the ignored code range as unloaded.
-      atomic_store(&ignored_code_ranges_[lib->range_id].end, 0,
-                   memory_order_release);
+      ignored_code_ranges_[lib->range_id].OnUnload();
       lib->range_id = kInvalidCodeRangeId;
     }
   }
@@ -116,9 +113,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
         const uptr idx =
             atomic_load(&instrumented_ranges_count_, memory_order_relaxed);
         CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_));
-        instrumented_code_ranges_[idx].begin = range.beg;
-        atomic_store(&instrumented_code_ranges_[idx].end, range.end,
-                     memory_order_release);
+        instrumented_code_ranges_[idx].OnLoad(range.beg, range.end);
         atomic_store(&instrumented_ranges_count_, idx + 1,
                      memory_order_release);
       }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
index 796989ad63d8f2..f78fa38fb02dd9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
@@ -63,12 +63,23 @@ class LibIgnore {
   };
 
   struct LibCodeRange {
+    bool IsInRange(uptr pc) const {
+      return (pc >= begin && pc < atomic_load(&end, memory_order_acquire));
+    }
+
+    void OnLoad(uptr b, uptr e) {
+      begin = b;
+      atomic_store(&end, e, memory_order_release);
+    }
+
+    void OnUnload() {
+      atomic_store(&end, 0, memory_order_release);
+    }
+
+  private:
     uptr begin;
     // A value of 0 means the associated module was unloaded.
     atomic_uintptr_t end;
-    bool IsInRange(uptr pc) const {
-      return (pc >= begin && pc < atomic_load(&end, memory_order_relaxed));
-    }
   };
 
   // Hot part:

>From ec93a2c5f87ab9f27e923c900490d25b97a4e5be Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sun, 15 Sep 2024 23:15:08 -0700
Subject: [PATCH 7/7] format

---
 compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp | 2 +-
 compiler-rt/lib/sanitizer_common/sanitizer_libignore.h   | 6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
index 16c39dcf07cb99..271c92e330b66d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp
@@ -80,7 +80,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
         const uptr idx =
             atomic_load(&ignored_ranges_count_, memory_order_relaxed);
         CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));
-        ignored_code_ranges_[idx].OnLoad(range.beg ,range.end);
+        ignored_code_ranges_[idx].OnLoad(range.beg, range.end);
         // Record the index of the ignored range.
         lib->range_id = idx;
         atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
index f78fa38fb02dd9..0e26ff44c81cf4 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.h
@@ -72,11 +72,9 @@ class LibIgnore {
       atomic_store(&end, e, memory_order_release);
     }
 
-    void OnUnload() {
-      atomic_store(&end, 0, memory_order_release);
-    }
+    void OnUnload() { atomic_store(&end, 0, memory_order_release); }
 
-  private:
+   private:
     uptr begin;
     // A value of 0 means the associated module was unloaded.
     atomic_uintptr_t end;



More information about the llvm-commits mailing list