AddressSanitizer: add support for malloc_usable_size() function

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@148287 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_allocator.cc b/lib/asan/asan_allocator.cc
index e2057dc..b5de1f8 100644
--- a/lib/asan/asan_allocator.cc
+++ b/lib/asan/asan_allocator.cc
@@ -811,19 +811,46 @@
   return 0;
 }
 
-size_t __asan_mz_size(const void *ptr) {
-  return malloc_info.AllocationSize((uintptr_t)ptr);
+static void GetAllocationSizeAndOwnership(const void *ptr, size_t *size,
+                                          bool *owned) {
+  size_t allocation_size = malloc_info.AllocationSize((uintptr_t)ptr);
+  if (size != NULL) {
+    *size = allocation_size;
+  }
+  if (owned != NULL) {
+    *owned = (ptr == NULL) || (allocation_size > 0);
+  }
+}
+
+size_t asan_malloc_usable_size(void *ptr, AsanStackTrace *stack) {
+  size_t usable_size;
+  bool owned;
+  GetAllocationSizeAndOwnership(ptr, &usable_size, &owned);
+  if (!owned) {
+    Report("ERROR: AddressSanitizer attempting to call malloc_usable_size() "
+           "for pointer which is not owned: %p\n", ptr);
+    stack->PrintStack();
+    Describe((uintptr_t)ptr, 1);
+    ShowStatsAndAbort();
+  }
+  return usable_size;
+}
+
+size_t asan_mz_size(const void *ptr) {
+  size_t mz_size;
+  GetAllocationSizeAndOwnership(ptr, &mz_size, NULL);
+  return mz_size;
 }
 
 void DescribeHeapAddress(uintptr_t addr, uintptr_t access_size) {
   Describe(addr, access_size);
 }
 
-void __asan_mz_force_lock() {
+void asan_mz_force_lock() {
   malloc_info.ForceLock();
 }
 
-void __asan_mz_force_unlock() {
+void asan_mz_force_unlock() {
   malloc_info.ForceUnlock();
 }
 
@@ -999,17 +1026,22 @@
 }
 
 bool __asan_get_ownership(const void *p) {
-  return (p == NULL) ||
-      (malloc_info.AllocationSize((uintptr_t)p) > 0);
+  bool owned;
+  GetAllocationSizeAndOwnership(p, NULL, &owned);
+  return owned;
 }
 
 size_t __asan_get_allocated_size(const void *p) {
-  if (p == NULL) return 0;
-  size_t allocated_size = malloc_info.AllocationSize((uintptr_t)p);
+  size_t allocated_size;
+  bool owned;
+  GetAllocationSizeAndOwnership(p, &allocated_size, &owned);
   // Die if p is not malloced or if it is already freed.
-  if (allocated_size == 0) {
-    Printf("__asan_get_allocated_size failed, ptr=%p is not owned\n", p);
+  if (!owned) {
+    Report("ERROR: AddressSanitizer attempting to call "
+           "__asan_get_allocated_size() for pointer which is "
+           "not owned: %p\n", p);
     PRINT_CURRENT_STACK();
+    Describe((uintptr_t)p, 1);
     ShowStatsAndAbort();
   }
   return allocated_size;