Move all leak info functions to android_mallopt.

Bug: 130028357

Test: malloc_hooks unit tests.
Test: Enable backtrace for mediaserver, run dumpsys media.player -m
Test: Enable backtrace for calendar, run am dumpheap -n <PID> <FILE>
Change-Id: I6774e28ccd9b3f2310127a5b39ccd15fe696a787
Merged-In: I6774e28ccd9b3f2310127a5b39ccd15fe696a787
(cherry picked from commit 3aadc5e80a5e2cf6b6760ed90d528709223bb449)
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 3f1bcc3..60ee138 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -32,14 +32,7 @@
 // calls and add special debugging code to attempt to catch allocation
 // errors. All of the debugging code is implemented in a separate shared
 // library that is only loaded when the property "libc.debug.malloc.options"
-// is set to a non-zero value. There are two functions exported to
-// allow ddms, or other external users to get information from the debug
-// allocation.
-//   get_malloc_leak_info: Returns information about all of the known native
-//                         allocations that are currently in use.
-//   free_malloc_leak_info: Frees the data allocated by the call to
-//                          get_malloc_leak_info.
-//   write_malloc_leak_info: Writes the leak info data to a file.
+// is set to a non-zero value.
 
 #include <errno.h>
 #include <stdint.h>
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 64f9f6f..599ac6a 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -409,39 +409,29 @@
 // =============================================================================
 // Functions to support dumping of native heap allocations using malloc debug.
 // =============================================================================
-
-// Retrieve native heap information.
-//
-// "*info" is set to a buffer we allocate
-// "*overall_size" is set to the size of the "info" buffer
-// "*info_size" is set to the size of a single entry
-// "*total_memory" is set to the sum of all allocations we're tracking; does
-//   not include heap overhead
-// "*backtrace_size" is set to the maximum number of entries in the back trace
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overall_size,
-    size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
+bool GetMallocLeakInfo(android_mallopt_leak_info_t* leak_info) {
   void* func = gFunctions[FUNC_GET_MALLOC_LEAK_INFO];
   if (func == nullptr) {
-    return;
+    errno = ENOTSUP;
+    return false;
   }
-  reinterpret_cast<get_malloc_leak_info_func_t>(func)(info, overall_size, info_size, total_memory,
-                                                      backtrace_size);
+  reinterpret_cast<get_malloc_leak_info_func_t>(func)(
+      &leak_info->buffer, &leak_info->overall_size, &leak_info->info_size,
+      &leak_info->total_memory, &leak_info->backtrace_size);
+  return true;
 }
 
-extern "C" void free_malloc_leak_info(uint8_t* info) {
+bool FreeMallocLeakInfo(android_mallopt_leak_info_t* leak_info) {
   void* func = gFunctions[FUNC_FREE_MALLOC_LEAK_INFO];
   if (func == nullptr) {
-    return;
+    errno = ENOTSUP;
+    return false;
   }
-  reinterpret_cast<free_malloc_leak_info_func_t>(func)(info);
+  reinterpret_cast<free_malloc_leak_info_func_t>(func)(leak_info->buffer);
+  return true;
 }
 
-extern "C" void write_malloc_leak_info(FILE* fp) {
-  if (fp == nullptr) {
-    error_log("write_malloc_leak_info called with a nullptr");
-    return;
-  }
-
+bool WriteMallocLeakInfo(FILE* fp) {
   void* func = gFunctions[FUNC_WRITE_LEAK_INFO];
   bool written = false;
   if (func != nullptr) {
@@ -453,7 +443,9 @@
     fprintf(fp, "# adb shell stop\n");
     fprintf(fp, "# adb shell setprop libc.debug.malloc.options backtrace\n");
     fprintf(fp, "# adb shell start\n");
+    errno = ENOTSUP;
   }
+  return written;
 }
 // =============================================================================
 
@@ -484,6 +476,27 @@
   if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) {
     return LimitEnable(arg, arg_size);
   }
+  if (opcode == M_WRITE_MALLOC_LEAK_INFO_TO_FILE) {
+    if (arg == nullptr || arg_size != sizeof(FILE*)) {
+      errno = EINVAL;
+      return false;
+    }
+    return WriteMallocLeakInfo(reinterpret_cast<FILE*>(arg));
+  }
+  if (opcode == M_GET_MALLOC_LEAK_INFO) {
+    if (arg == nullptr || arg_size != sizeof(android_mallopt_leak_info_t)) {
+      errno = EINVAL;
+      return false;
+    }
+    return GetMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg));
+  }
+  if (opcode == M_FREE_MALLOC_LEAK_INFO) {
+    if (arg == nullptr || arg_size != sizeof(android_mallopt_leak_info_t)) {
+      errno = EINVAL;
+      return false;
+    }
+    return FreeMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg));
+  }
   return HeapprofdMallopt(opcode, arg, arg_size);
 }
 // =============================================================================