[compiler-rt] 2b026fe - [NFC][asan] Handle non-intersecting case early

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 29 10:57:58 PST 2022


Author: Vitaly Buka
Date: 2022-11-29T10:56:17-08:00
New Revision: 2b026fedcaabba317fbea02a6d58573de9d8c58b

URL: https://github.com/llvm/llvm-project/commit/2b026fedcaabba317fbea02a6d58573de9d8c58b
DIFF: https://github.com/llvm/llvm-project/commit/2b026fedcaabba317fbea02a6d58573de9d8c58b.diff

LOG: [NFC][asan] Handle non-intersecting case early

Differential Revision: https://reviews.llvm.org/D138772

Added: 
    

Modified: 
    compiler-rt/lib/asan/asan_poisoning.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/asan/asan_poisoning.cpp b/compiler-rt/lib/asan/asan_poisoning.cpp
index 1b5701c22148..195b556bca42 100644
--- a/compiler-rt/lib/asan/asan_poisoning.cpp
+++ b/compiler-rt/lib/asan/asan_poisoning.cpp
@@ -512,97 +512,94 @@ void __sanitizer_annotate_double_ended_contiguous_container(
   FixUnalignedStorage(storage_beg, storage_end, old_beg, old_end, new_beg,
                       new_end);
 
-  if (old_beg == old_end) {
-    old_beg = old_end = new_beg;
-  } else if (new_end <= old_beg || old_end <= new_beg || new_beg == new_end) {
-    // Poisoining whole memory.
-    uptr a = RoundDownTo(old_beg, granularity);
-    uptr b = RoundUpTo(old_end, granularity);
-    PoisonShadow(a, b - a, kAsanContiguousContainerOOBMagic);
-
-    old_beg = old_end = new_beg;
-  }
-
-  if (old_beg != new_beg) {
-    // There are two situations: we are poisoning or unpoisoning.
-    // WARNING: at the moment we do not poison prefixes of blocks described by
-    // one byte in shadow memory, so we have to unpoison prefixes of blocks with
-    // content. Up to (granularity - 1) bytes not-in-use may not be poisoned.
+  // Handle non-intersecting new/old containers separately have simpler
+  // intersecting case.
+  if (old_beg == old_end || new_beg == new_end || new_end <= old_beg ||
+      old_end <= new_beg) {
+    if (old_beg != old_end) {
+      // Poisoning the old container.
+      uptr a = RoundDownTo(old_beg, granularity);
+      uptr b = RoundUpTo(old_end, granularity);
+      PoisonShadow(a, b - a, kAsanContiguousContainerOOBMagic);
+    }
 
-    if (new_beg < old_beg) {  // We are unpoisoning
+    if (new_beg != new_end) {
+      // Unpoisoning the new container.
       uptr a = RoundDownTo(new_beg, granularity);
-      uptr c = RoundDownTo(old_beg, granularity);
-      // State at the moment is:
-      // [storage_beg, a] is poisoned and should remain like that.
-      // [a, c] is poisoned as well (interval may be empty if new_beg
-      // and old_beg are in the same block). If the container is not
-      // empty, first element starts somewhere in [c, c+granularity]. Because we
-      // do not poison prefixes, memory [c, container_end] is not poisoned and
-      // we won't change it. If container is empty, we have to unpoison memory
-      // for elements after c, so [c, container_end]
-      PoisonShadow(a, c - a, 0);
-      if (old_beg == old_end &&
-          !AddrIsAlignedByGranularity(old_beg)) {  // was empty && ends in the
-                                                   // middle of a block
-        *(u8 *)MemToShadow(c) = static_cast<u8>(old_end - c);
-      }
-      // else: we cannot poison prefix of a block with elements or there is
-      // nothing to poison.
-    } else {  // we are poisoning as beginning moved further in memory
-      uptr a = RoundDownTo(old_beg, granularity);
-      uptr c = RoundDownTo(new_beg, granularity);
-      // State at the moment is:
-      // [storage_beg, a] is poisoned and should remain like that.
-      // [a, c] is not poisoned (interval may be empty if new_beg and
-      // old_beg are in the same block) [c, container_end] is not
-      // poisoned. If there are remaining elements in the container:
-      //   We have to poison [a, c], but because we do not poison prefixes, we
-      //   cannot poison memory after c (even that there are not elements of the
-      //   container). Up to granularity-1 unused bytes will not be poisoned.
-      // Otherwise:
-      //   We have to poison the last byte as well.
-      PoisonShadow(a, c - a, kAsanContiguousContainerOOBMagic);
-      if (new_beg == old_end &&
-          !AddrIsAlignedByGranularity(new_beg)) {  // is empty && ends in the
-                                                   // middle of a block
-        *(u8 *)MemToShadow(c) =
-            static_cast<u8>(kAsanContiguousContainerOOBMagic);
-      }
+      uptr b = RoundDownTo(new_end, granularity);
+      PoisonShadow(a, b - a, 0);
+      if (!AddrIsAlignedByGranularity(new_end))
+        *(u8 *)MemToShadow(b) = static_cast<u8>(new_end - b);
     }
 
-    old_beg = new_beg;
+    return;
   }
 
-  if (old_end != new_end) {
-    if (old_end < new_end) {  // We are unpoisoning memory
-      uptr a = RoundDownTo(old_end, granularity);
-      uptr c = RoundDownTo(new_end, granularity);
-      // State at the moment is:
-      // if container_beg < a : [container_beg, a] is correct and we will not be
-      // changing it. else [a, container_beg] cannot be poisoned, so we do not
-      // have to think about it. we have to makr as unpoisoned [a, c]. [c, end]
-      // is correctly poisoned.
-      PoisonShadow(a, c - a, 0);
-      if (!AddrIsAlignedByGranularity(
-              new_end))  // ends in the middle of a block
-        *(u8 *)MemToShadow(c) = static_cast<u8>(new_end - c);
-    } else {  // We are poisoning memory
+  // Intersection of old and new containers is not empty.
+  CHECK_LT(new_beg, old_end);
+  CHECK_GT(new_end, old_beg);
+
+  // There are two situations: we are poisoning or unpoisoning.
+  // WARNING: at the moment we do not poison prefixes of blocks described by
+  // one byte in shadow memory, so we have to unpoison prefixes of blocks with
+  // content. Up to (granularity - 1) bytes not-in-use may not be poisoned.
+
+  if (new_beg < old_beg) {
+    // We are unpoisoning.
+    uptr a = RoundDownTo(new_beg, granularity);
+    uptr c = RoundDownTo(old_beg, granularity);
+    // State at the moment is:
+    // [storage_beg, a] is poisoned and should remain like that.
+    // [a, c] is poisoned as well (interval may be empty if new_beg
+    // and old_beg are in the same block). If the container is not
+    // empty, first element starts somewhere in [c, c+granularity]. Because we
+    // do not poison prefixes, memory [c, container_end] is not poisoned and
+    // we won't change it. If container is empty, we have to unpoison memory
+    // for elements after c, so [c, container_end]
+    PoisonShadow(a, c - a, 0);
+  } else if (new_beg > old_beg) {
+    // We are poisoning as beginning moved further in memory.
+    uptr a = RoundDownTo(old_beg, granularity);
+    uptr c = RoundDownTo(new_beg, granularity);
+    // State at the moment is:
+    // [storage_beg, a] is poisoned and should remain like that.
+    // [a, c] is not poisoned (interval may be empty if new_beg and
+    // old_beg are in the same block) [c, container_end] is not
+    // poisoned. If there are remaining elements in the container:
+    //   We have to poison [a, c], but because we do not poison prefixes, we
+    //   cannot poison memory after c (even that there are not elements of the
+    //   container). Up to granularity-1 unused bytes will not be poisoned.
+    // Otherwise:
+    //   We have to poison the last byte as well.
+    PoisonShadow(a, c - a, kAsanContiguousContainerOOBMagic);
+  }
+
+  if (new_end > old_end) {
+    // We are unpoisoning memory.
+    uptr a = RoundDownTo(old_end, granularity);
+    uptr c = RoundDownTo(new_end, granularity);
+    // State at the moment is:
+    // if container_beg < a : [container_beg, a] is correct and we will not be
+    // changing it. else [a, container_beg] cannot be poisoned, so we do not
+    // have to think about it. we have to makr as unpoisoned [a, c]. [c, end]
+    // is correctly poisoned.
+    PoisonShadow(a, c - a, 0);
+    if (!AddrIsAlignedByGranularity(new_end))  // ends in the middle of a block
+      *(u8 *)MemToShadow(c) = static_cast<u8>(new_end - c);
+  } else if (new_end < old_end) {
+    // We are poisoning memory.
+    // State at the moment is:
+    // [storage_beg, a] is correctly annotated
+    // if container is empty after the removal, then a < container_beg and we
+    // will have to poison memory which is adressable only because we are not
+    // poisoning prefixes.
+    uptr a2 = RoundUpTo(new_end, granularity);
+    uptr c2 = RoundUpTo(old_end, granularity);
+    PoisonShadow(a2, c2 - a2, kAsanContiguousContainerOOBMagic);
+    if (!AddrIsAlignedByGranularity(new_end)) {
+      // Starts in the middle of the block
       uptr a = RoundDownTo(new_end, granularity);
-      // State at the moment is:
-      // [storage_beg, a] is correctly annotated
-      // if container is empty after the removal, then a < container_beg and we
-      // will have to poison memory which is adressable only because we are not
-      // poisoning prefixes.
-      uptr a2 = RoundUpTo(new_end, granularity);
-      uptr c2 = RoundUpTo(old_end, granularity);
-      PoisonShadow(a2, c2 - a2, kAsanContiguousContainerOOBMagic);
-      if (!AddrIsAlignedByGranularity(
-              new_end)) {        // Starts in the middle of the block
-        if (new_end == old_beg)  // empty
-          *(u8 *)MemToShadow(a) = kAsanContiguousContainerOOBMagic;
-        else  // not empty
-          *(u8 *)MemToShadow(a) = static_cast<u8>(new_end - a);
-      }
+      *(u8 *)MemToShadow(a) = static_cast<u8>(new_end - a);
     }
   }
 }


        


More information about the llvm-commits mailing list