Allow to re-use the same crash_detail.

This is for advanced use-cases that have high performance demands and
know they will repeatedly re-use the crash_detail.

Bug: 155462331
Change-Id: Ib15dac70d1d598f78b74b539aeadf88b0ca32bc7
diff --git a/libc/bionic/android_set_abort_message.cpp b/libc/bionic/android_set_abort_message.cpp
index 53d7576..21e4a44 100644
--- a/libc/bionic/android_set_abort_message.cpp
+++ b/libc/bionic/android_set_abort_message.cpp
@@ -165,3 +165,17 @@
     } while (!atomic_compare_exchange_strong(&free_head, &prev, crash_detail));
   }
 }
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+void android_replace_crash_detail_data(crash_detail_t* crash_detail, const void* data,
+                                       size_t data_size) {
+  crash_detail->data = reinterpret_cast<const char*>(data);
+  crash_detail->data_size = data_size;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+void android_replace_crash_detail_name(crash_detail_t* crash_detail, const void* name,
+                                       size_t name_size) {
+  crash_detail->name = reinterpret_cast<const char*>(name);
+  crash_detail->name_size = name_size;
+}
diff --git a/libc/include/android/set_abort_message.h b/libc/include/android/set_abort_message.h
index e92c6ec..44307f3 100644
--- a/libc/include/android/set_abort_message.h
+++ b/libc/include/android/set_abort_message.h
@@ -78,13 +78,15 @@
  *             this should generally be a human-readable debug string, but we are treating
  *             it as arbitrary bytes because it could be corrupted by the crash.
  * \param name_size number of bytes of the buffer pointed to by name
- * \param data a buffer containing the extra detail bytes
+ * \param data a buffer containing the extra detail bytes, if null the crash detail
+ *             is disabled until android_replace_crash_detail_data replaces it with
+ *             a non-null pointer.
  * \param data_size number of bytes of the buffer pointed to by data
  *
- * \return a handle to the extra crash detail for use with android_unregister_crash_detail.
+ * \return a handle to the extra crash detail.
  */
 crash_detail_t* _Nullable android_register_crash_detail(
-    const void* _Nonnull name, size_t name_size, const void* _Nonnull data, size_t data_size) __INTRODUCED_IN(35);
+    const void* _Nonnull name, size_t name_size, const void* _Nullable data, size_t data_size) __INTRODUCED_IN(35);
 
 /**
  * Unregister crash detail from being logged into tombstones.
@@ -98,4 +100,33 @@
  */
 void android_unregister_crash_detail(crash_detail_t* _Nonnull crash_detail) __INTRODUCED_IN(35);
 
+/**
+ * Replace data of crash detail.
+ *
+ * This is more efficient than using android_unregister_crash_detail followed by
+ * android_register_crash_detail. If you very frequently need to swap out the data,
+ * you can hold onto the crash_detail.
+ *
+ * Introduced in API 35.
+ *
+ * \param data the new buffer containing the extra detail bytes, or null to disable until
+ *             android_replace_crash_detail_data is called again with non-null data.
+ * \param data_size the number of bytes of the buffer pointed to by data.
+ */
+void android_replace_crash_detail_data(crash_detail_t* _Nonnull crash_detail, const void* _Nullable data, size_t data_size) __INTRODUCED_IN(35);
+
+/**
+ * Replace name of crash detail.
+ *
+ * This is more efficient than using android_unregister_crash_detail followed by
+ * android_register_crash_detail. If you very frequently need to swap out the name,
+ * you can hold onto the crash_detail.
+ *
+ * Introduced in API 35.
+ *
+ * \param name identifying name for this extra data.
+ * \param name_size number of bytes of the buffer pointed to by name
+ */
+void android_replace_crash_detail_name(crash_detail_t* _Nonnull crash_detail, const void* _Nonnull name, size_t name_size) __INTRODUCED_IN(35);
+
 __END_DECLS
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index ecdb25c..bf1d0c1 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1588,6 +1588,8 @@
   global:
     android_register_crash_detail;
     android_unregister_crash_detail;
+    android_replace_crash_detail_data;
+    android_replace_crash_detail_name;
     epoll_pwait2;
     epoll_pwait2_64;
     localtime_rz;