Merge "Update Android.bp"
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index 132f7ef..444a7b6 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -329,6 +329,8 @@
bool valid; /* true if the image is a valid elf image */
bool load_attempted; /* true if we've already attempted to load the elf */
bool mapped; /* true if the elf image was mmap'd in */
+ void* mini_debug_info_data; /* decompressed .gnu_debugdata section */
+ size_t mini_debug_info_size;
union
{
struct
diff --git a/include/tdep-aarch64/libunwind_i.h b/include/tdep-aarch64/libunwind_i.h
index d3d69ab..9104027 100644
--- a/include/tdep-aarch64/libunwind_i.h
+++ b/include/tdep-aarch64/libunwind_i.h
@@ -302,7 +302,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h
index c140c05..8ca1516 100644
--- a/include/tdep-arm/libunwind_i.h
+++ b/include/tdep-arm/libunwind_i.h
@@ -295,7 +295,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-hppa/libunwind_i.h b/include/tdep-hppa/libunwind_i.h
index ab737a8..4bffd76 100644
--- a/include/tdep-hppa/libunwind_i.h
+++ b/include/tdep-hppa/libunwind_i.h
@@ -285,7 +285,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-ia64/libunwind_i.h b/include/tdep-ia64/libunwind_i.h
index 41056c0..4b5a43b 100644
--- a/include/tdep-ia64/libunwind_i.h
+++ b/include/tdep-ia64/libunwind_i.h
@@ -268,7 +268,7 @@
extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum,
uint8_t *nat_bitnr);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-mips/libunwind_i.h b/include/tdep-mips/libunwind_i.h
index c4059b2..fa4f39f 100644
--- a/include/tdep-mips/libunwind_i.h
+++ b/include/tdep-mips/libunwind_i.h
@@ -341,7 +341,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-ppc32/libunwind_i.h b/include/tdep-ppc32/libunwind_i.h
index c375b9b..ddf8f3a 100644
--- a/include/tdep-ppc32/libunwind_i.h
+++ b/include/tdep-ppc32/libunwind_i.h
@@ -306,7 +306,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t * uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-ppc64/libunwind_i.h b/include/tdep-ppc64/libunwind_i.h
index cbeb16a..fbb7a79 100644
--- a/include/tdep-ppc64/libunwind_i.h
+++ b/include/tdep-ppc64/libunwind_i.h
@@ -306,7 +306,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t * uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-sh/libunwind_i.h b/include/tdep-sh/libunwind_i.h
index 4a2afd7..e19e2ac 100644
--- a/include/tdep-sh/libunwind_i.h
+++ b/include/tdep-sh/libunwind_i.h
@@ -286,7 +286,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-x86/libunwind_i.h b/include/tdep-x86/libunwind_i.h
index f87bd71..96457e7 100644
--- a/include/tdep-x86/libunwind_i.h
+++ b/include/tdep-x86/libunwind_i.h
@@ -289,7 +289,7 @@
int need_unwind_info, void *arg);
extern void *tdep_uc_addr (ucontext_t *uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/include/tdep-x86_64/libunwind_i.h b/include/tdep-x86_64/libunwind_i.h
index 184989e..fd9cca4 100644
--- a/include/tdep-x86_64/libunwind_i.h
+++ b/include/tdep-x86_64/libunwind_i.h
@@ -235,7 +235,7 @@
int need_unwind_info, void *arg);
extern void *x86_64_r_uc_addr (ucontext_t *uc, int reg);
/* ANDROID support update. */
-extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff,
char **path, void *as_arg);
diff --git a/src/Los-common.c b/src/Los-common.c
index f52c1e2..f09e6f3 100644
--- a/src/Los-common.c
+++ b/src/Los-common.c
@@ -71,6 +71,9 @@
new_list->ei.u.memory.map = new_list;
/* If it was mapped before, make sure to mark it unmapped now. */
old_list->ei.mapped = false;
+ /* Clear the old mini debug info so we do not try to free it twice */
+ old_list->ei.mini_debug_info_data = NULL;
+ old_list->ei.mini_debug_info_size = 0;
/* Don't bother breaking out of the loop, the next while check
is guaranteed to fail, causing us to break out of the loop
after advancing to the next map element. */
@@ -173,7 +176,7 @@
}
PROTECTED int
-local_get_elf_image (unw_addr_space_t as, struct elf_image *ei, unw_word_t ip,
+local_get_elf_image (unw_addr_space_t as, struct elf_image **ei, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, char **path, void *as_arg)
{
struct map_info *map;
@@ -194,9 +197,9 @@
if (map && elf_map_cached_image (as, as_arg, map, ip))
{
- *ei = map->ei;
+ *ei = &map->ei;
*segbase = map->start;
- if (ei->mapped)
+ if ((*ei)->mapped)
*mapoff = map->offset;
else
/* Always use zero as the map offset for in memory maps. The
diff --git a/src/elfxx.c b/src/elfxx.c
index 7454778..efc1d51 100644
--- a/src/elfxx.c
+++ b/src/elfxx.c
@@ -479,6 +479,11 @@
do {
*dst_size *= 2;
*dst = realloc(*dst, *dst_size);
+ if (*dst == NULL) {
+ Debug (1, "LZMA decompression failed due to failed realloc.\n");
+ XzUnpacker_Free(&state);
+ return false;
+ }
src_remaining = src_size - src_offset;
dst_remaining = *dst_size - dst_offset;
int res = XzUnpacker_Code(&state,
@@ -553,14 +558,23 @@
return false;
}
-static bool
-elf_w (extract_minidebuginfo_mapped) (struct elf_image *ei, struct elf_image *mdi)
-{
+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)) {
- return elf_w (xz_decompress) (compressed, compressed_len,
- (uint8_t**)&mdi->u.mapped.image, &mdi->u.mapped.size);
+ 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;
}
@@ -584,10 +598,14 @@
// If the ELF image doesn't contain a match, look up the symbol in
// the MiniDebugInfo.
- struct elf_image mdi;
- if (ei->mapped && elf_w (extract_minidebuginfo_mapped) (ei, &mdi)) {
- mdi.valid = elf_w (valid_object_mapped) (&mdi);
+ uint8_t* mdi_data;
+ size_t mdi_size;
+ if (ei->mapped && elf_w (extract_minidebuginfo_mapped) (ei, &mdi_data, &mdi_size)) {
+ struct elf_image mdi;
mdi.mapped = true;
+ mdi.u.mapped.image = mdi_data;
+ mdi.u.mapped.size = mdi_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.
ElfW(Addr) ei_text_address, mdi_text_address;
@@ -596,7 +614,6 @@
load_offset += ei_text_address - mdi_text_address;
}
bool ret_val = elf_w (lookup_symbol) (as, ip, &mdi, load_offset, buf, buf_len, offp, &ehdr);
- free(mdi.u.mapped.image);
return ret_val;
}
return false;
@@ -606,13 +623,13 @@
unw_addr_space_t as, pid_t pid, unw_word_t ip, char* buf, size_t buf_len,
unw_word_t* offp, void* as_arg) {
unsigned long segbase, mapoff;
- struct elf_image ei;
+ struct elf_image* ei;
if (tdep_get_elf_image(as, &ei, pid, ip, &segbase, &mapoff, NULL, as_arg) < 0) {
return false;
}
- return elf_w (get_proc_name_in_image) (as, &ei, segbase, mapoff, ip, buf, buf_len, offp);
+ return elf_w (get_proc_name_in_image) (as, ei, segbase, mapoff, ip, buf, buf_len, offp);
}
HIDDEN bool elf_w (get_load_base) (struct elf_image* ei, unw_word_t mapoff, unw_word_t* load_base) {
diff --git a/src/mi/map.c b/src/mi/map.c
index b37ad14..2a297b8 100644
--- a/src/mi/map.c
+++ b/src/mi/map.c
@@ -122,6 +122,10 @@
munmap (map->ei.u.mapped.image, map->ei.u.mapped.size);
if (map->path)
free (map->path);
+ if (map->ei.mini_debug_info_data) {
+ Debug(1, "Freed cached .gnu_debugdata");
+ free (map->ei.mini_debug_info_data);
+ }
map_free_info (map);
}
}
diff --git a/src/os-common.c b/src/os-common.c
index 751c9d2..7e3d184 100644
--- a/src/os-common.c
+++ b/src/os-common.c
@@ -26,12 +26,12 @@
#include "libunwind_i.h"
#include "map_info.h"
-extern int local_get_elf_image (unw_addr_space_t as, struct elf_image *,
+extern int local_get_elf_image (unw_addr_space_t as, struct elf_image **,
unw_word_t, unsigned long *, unsigned long *,
char **, void *);
PROTECTED int
-tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, char **path,
void *as_arg)
@@ -48,9 +48,9 @@
if (!elf_map_cached_image (as, as_arg, map, ip))
return -UNW_ENOINFO;
- *ei = map->ei;
+ *ei = &map->ei;
*segbase = map->start;
- if (ei->mapped)
+ if ((*ei)->mapped)
*mapoff = map->offset;
else
/* Always use zero as the map offset for in memory maps. The
diff --git a/src/os-hpux.c b/src/os-hpux.c
index 2127c94..488641c 100644
--- a/src/os-hpux.c
+++ b/src/os-hpux.c
@@ -42,7 +42,7 @@
}
PROTECTED int
-tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
+tdep_get_elf_image (unw_addr_space_t as, struct elf_image **ei,
pid_t pid, unw_word_t ip,
unsigned long *segbase, unsigned long *mapoff, char **path)
{
@@ -119,7 +119,7 @@
finish:
if (map)
{
- *ei = map->ei;
+ *ei = &map->ei;
*segbase = map->start;
*mapoff = map->offset;
if (path != NULL)
diff --git a/src/os-linux.c b/src/os-linux.c
index f65c98a..d52fdf0 100644
--- a/src/os-linux.c
+++ b/src/os-linux.c
@@ -62,6 +62,8 @@
cur_map->ei.valid = false;
cur_map->ei.load_attempted = false;
cur_map->ei.mapped = false;
+ cur_map->ei.mini_debug_info_data = NULL;
+ cur_map->ei.mini_debug_info_size = 0;
/* Indicate mapped memory of devices is special and should not
be read or written. Use a special flag instead of zeroing the
diff --git a/src/ptrace/_UPT_find_proc_info.c b/src/ptrace/_UPT_find_proc_info.c
index acaa5f9..546f37e 100644
--- a/src/ptrace/_UPT_find_proc_info.c
+++ b/src/ptrace/_UPT_find_proc_info.c
@@ -37,7 +37,7 @@
{
/* ANDROID support update. */
unsigned long segbase, mapoff;
- struct elf_image ei;
+ struct elf_image* ei;
int ret;
char *path = NULL;
/* End of ANDROID update. */
@@ -66,7 +66,7 @@
if (tdep_get_elf_image (as, &ei, pid, ip, &segbase, &mapoff, &path, as_arg) < 0)
return -UNW_ENOINFO;
- ret = tdep_find_unwind_table (edi, &ei, as, path, segbase, mapoff, ip);
+ ret = tdep_find_unwind_table (edi, ei, as, path, segbase, mapoff, ip);
free(path);
if (ret < 0)
return ret;