Fix the caching of the compressed section.

A previous change fixed a race condtion, but caused a big memory
leak of the compressed section data. In order to fix this, move
the caching of the compressed section at the point that we cache
the elf image data itself.

Bug: 27152097
Change-Id: I934916c527225274b29638a6afef7a5fba48a5af
diff --git a/src/elfxx.c b/src/elfxx.c
index 52f122e..7fda0b7 100644
--- a/src/elfxx.c
+++ b/src/elfxx.c
@@ -557,27 +557,6 @@
   }
   return false;
 }
-
-static bool elf_w (extract_minidebuginfo_mapped) (struct elf_image *ei, uint8_t** data, size_t* size) {
-  if (ei->mini_debug_info_data != NULL) {
-    // Return cached result.
-    *data = ei->mini_debug_info_data;
-    *size = ei->mini_debug_info_size;
-    return true;
-  }
-  uint8_t *compressed = NULL;
-  size_t compressed_len;
-  if (elf_w (find_section_mapped) (ei, ".gnu_debugdata", &compressed, &compressed_len, NULL)) {
-    if (elf_w (xz_decompress) (compressed, compressed_len, data, size)) {
-      // Also cache the result for next time.
-      ei->mini_debug_info_data = *data;
-      ei->mini_debug_info_size = *size;
-      Debug (1, "Decompressed and cached .gnu_debugdata");
-      return true;
-    }
-  }
-  return false;
-}
 /* ANDROID support update. */
 
 // Find the ELF image that contains IP and return the procedure name from
@@ -598,13 +577,11 @@
 
   // If the ELF image doesn't contain a match, look up the symbol in
   // the MiniDebugInfo.
-  uint8_t* mdi_data;
-  size_t mdi_size;
-  if (ei->mapped && elf_w (extract_minidebuginfo_mapped) (ei, &mdi_data, &mdi_size)) {
+  if (ei->mapped && ei->mini_debug_info_data) {
     struct elf_image mdi;
     mdi.mapped = true;
-    mdi.u.mapped.image = mdi_data;
-    mdi.u.mapped.size = mdi_size;
+    mdi.u.mapped.image = ei->mini_debug_info_data;
+    mdi.u.mapped.size = ei->mini_debug_info_size;
     mdi.valid = elf_w (valid_object_mapped) (&mdi);
     // The ELF file might have been relocated after the debug
     // information has been compresses and embedded.
diff --git a/src/elfxx.h b/src/elfxx.h
index 7af4d28..ff73ec5 100644
--- a/src/elfxx.h
+++ b/src/elfxx.h
@@ -183,6 +183,20 @@
         map->ei.u.memory.as_arg = as_arg;
         map->ei.valid = elf_w (valid_object_memory) (&map->ei);
       }
+    } else {
+      // Try to cache the minidebuginfo data.
+      uint8_t *compressed = NULL;
+      size_t compressed_len;
+      if (elf_w (find_section_mapped) (&map->ei, ".gnu_debugdata", &compressed,
+          &compressed_len, NULL)) {
+        if (elf_w (xz_decompress) (compressed, compressed_len,
+            (uint8_t**) &map->ei.mini_debug_info_data, &map->ei.mini_debug_info_size)) {
+          Debug (1, "Decompressed and cached .gnu_debugdata");
+        } else {
+          map->ei.mini_debug_info_data = NULL;
+          map->ei.mini_debug_info_size = 0;
+        }
+      }
     }
     unw_word_t load_base;
     if (map->ei.valid && elf_w (get_load_base) (&map->ei, map->offset, &load_base)) {