Mangle the pointers stored in PointerData.

The libmemunreachable library looks through memory to determine
if pointers are leaked. Unfortunately, the malloc debug code
stores the original pointer in data structures, so it looks like
pointers are still in use. The fix is to mangle the pointers
stored in memory so that it doesn't trick the library into thinking
they are live.

Test: All unit/system tests pass.
Test: Ran libmemunreachable and verified leaks show up.
Change-Id: Ic40a0a5ae73857cde936fd76895d88829686a643
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index b982c0a..eaa0eb7 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -35,6 +35,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <functional>
 #include <mutex>
 #include <string>
 #include <unordered_map>
@@ -195,40 +196,41 @@
 }
 
 void PointerData::Add(const void* ptr, size_t pointer_size) {
-  uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
   size_t hash_index = 0;
   if (backtrace_enabled_) {
     hash_index = AddBacktrace(g_debug->config().backtrace_frames());
   }
 
   std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
-  pointers_[pointer] = PointerInfoType{PointerInfoType::GetEncodedSize(pointer_size), hash_index};
+  uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+  pointers_[mangled_ptr] =
+      PointerInfoType{PointerInfoType::GetEncodedSize(pointer_size), hash_index};
 }
 
 void PointerData::Remove(const void* ptr) {
-  uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
   size_t hash_index;
   {
     std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
-    auto entry = pointers_.find(pointer);
+    uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+    auto entry = pointers_.find(mangled_ptr);
     if (entry == pointers_.end()) {
       // Attempt to remove unknown pointer.
-      error_log("No tracked pointer found for 0x%" PRIxPTR, pointer);
+      error_log("No tracked pointer found for 0x%" PRIxPTR, DemanglePointer(mangled_ptr));
       return;
     }
     hash_index = entry->second.hash_index;
-    pointers_.erase(pointer);
+    pointers_.erase(mangled_ptr);
   }
 
   RemoveBacktrace(hash_index);
 }
 
 size_t PointerData::GetFrames(const void* ptr, uintptr_t* frames, size_t max_frames) {
-  uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
   size_t hash_index;
   {
     std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
-    auto entry = pointers_.find(pointer);
+    uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+    auto entry = pointers_.find(mangled_ptr);
     if (entry == pointers_.end()) {
       return 0;
     }
@@ -274,7 +276,8 @@
 
 void PointerData::LogFreeError(const FreePointerInfoType& info, size_t max_cmp_bytes) {
   error_log(LOG_DIVIDER);
-  uint8_t* memory = reinterpret_cast<uint8_t*>(info.pointer);
+  uintptr_t pointer = DemanglePointer(info.mangled_ptr);
+  uint8_t* memory = reinterpret_cast<uint8_t*>(pointer);
   error_log("+++ ALLOCATION %p USED AFTER FREE", memory);
   uint8_t fill_free_value = g_debug->config().fill_free_value();
   for (size_t i = 0; i < max_cmp_bytes; i++) {
@@ -296,13 +299,14 @@
 
 void PointerData::VerifyFreedPointer(const FreePointerInfoType& info) {
   size_t usable_size;
+  uintptr_t pointer = DemanglePointer(info.mangled_ptr);
   if (g_debug->HeaderEnabled()) {
     // Check to see if the tag data has been damaged.
-    Header* header = g_debug->GetHeader(reinterpret_cast<const void*>(info.pointer));
+    Header* header = g_debug->GetHeader(reinterpret_cast<const void*>(pointer));
     if (header->tag != DEBUG_FREE_TAG) {
       error_log(LOG_DIVIDER);
-      error_log("+++ ALLOCATION 0x%" PRIxPTR " HAS CORRUPTED HEADER TAG 0x%x AFTER FREE",
-                info.pointer, header->tag);
+      error_log("+++ ALLOCATION 0x%" PRIxPTR " HAS CORRUPTED HEADER TAG 0x%x AFTER FREE", pointer,
+                header->tag);
       error_log(LOG_DIVIDER);
       if (g_debug->config().options() & ABORT_ON_ERROR) {
         abort();
@@ -314,14 +318,14 @@
     }
     usable_size = header->usable_size;
   } else {
-    usable_size = g_dispatch->malloc_usable_size(reinterpret_cast<const void*>(info.pointer));
+    usable_size = g_dispatch->malloc_usable_size(reinterpret_cast<const void*>(pointer));
   }
 
   size_t bytes = (usable_size < g_debug->config().fill_on_free_bytes())
                      ? usable_size
                      : g_debug->config().fill_on_free_bytes();
   size_t max_cmp_bytes = bytes;
-  const uint8_t* memory = reinterpret_cast<const uint8_t*>(info.pointer);
+  const uint8_t* memory = reinterpret_cast<const uint8_t*>(pointer);
   while (bytes > 0) {
     size_t bytes_to_cmp = (bytes < g_cmp_mem.size()) ? bytes : g_cmp_mem.size();
     if (memcmp(memory, g_cmp_mem.data(), bytes_to_cmp) != 0) {
@@ -333,8 +337,6 @@
 }
 
 void* PointerData::AddFreed(const void* ptr) {
-  uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
-
   size_t hash_index = 0;
   size_t num_frames = g_debug->config().free_track_backtrace_num_frames();
   if (num_frames) {
@@ -348,10 +350,11 @@
     free_pointers_.pop_front();
     VerifyFreedPointer(info);
     RemoveBacktrace(info.hash_index);
-    last = reinterpret_cast<void*>(info.pointer);
+    last = reinterpret_cast<void*>(DemanglePointer(info.mangled_ptr));
   }
 
-  free_pointers_.emplace_back(FreePointerInfoType{pointer, hash_index});
+  uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+  free_pointers_.emplace_back(FreePointerInfoType{mangled_ptr, hash_index});
   return last;
 }
 
@@ -361,7 +364,7 @@
     uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
     std::lock_guard<std::mutex> freed_guard(free_pointer_mutex_);
     for (const auto& info : free_pointers_) {
-      if (info.pointer == pointer) {
+      if (DemanglePointer(info.mangled_ptr) == pointer) {
         hash_index = info.hash_index;
         break;
       }
@@ -388,6 +391,7 @@
   for (const auto& entry : pointers_) {
     FrameInfoType* frame_info = nullptr;
     std::vector<unwindstack::FrameData>* backtrace_info = nullptr;
+    uintptr_t pointer = DemanglePointer(entry.first);
     size_t hash_index = entry.second.hash_index;
     if (hash_index > kBacktraceEmptyIndex) {
       auto frame_entry = frames_.find(hash_index);
@@ -397,7 +401,7 @@
         // occurs after the hash_index and frame data have been added.
         // When removing a pointer, the pointer is deleted before the frame
         // data.
-        error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", entry.first, hash_index);
+        error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", pointer, hash_index);
       } else {
         frame_info = &frame_entry->second;
       }
@@ -405,7 +409,7 @@
       if (g_debug->config().options() & BACKTRACE_FULL) {
         auto backtrace_entry = backtraces_info_.find(hash_index);
         if (backtrace_entry == backtraces_info_.end()) {
-          error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", entry.first, hash_index);
+          error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", pointer, hash_index);
         } else {
           backtrace_info = &backtrace_entry->second;
         }
@@ -415,7 +419,7 @@
       continue;
     }
 
-    list->emplace_back(ListInfoType{entry.first, 1, entry.second.RealSize(),
+    list->emplace_back(ListInfoType{pointer, 1, entry.second.RealSize(),
                                     entry.second.ZygoteChildAlloc(), frame_info, backtrace_info});
   }
 
@@ -550,9 +554,9 @@
 }
 
 bool PointerData::Exists(const void* ptr) {
-  uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
   std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
-  return pointers_.count(pointer) != 0;
+  uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+  return pointers_.count(mangled_ptr) != 0;
 }
 
 void PointerData::DumpLiveToFile(int fd) {
@@ -637,3 +641,10 @@
   free_pointer_mutex_.try_lock();
   free_pointer_mutex_.unlock();
 }
+
+void PointerData::IteratePointers(std::function<void(uintptr_t pointer)> fn) {
+  std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
+  for (const auto entry : pointers_) {
+    fn(DemanglePointer(entry.first));
+  }
+}