Merge tag android-5.1.0_r1 into AOSP_5.1_MERGE
Change-Id: I2dd6a87b4a5ea59e4f04b4bd2c094500bdeae0d8
diff --git a/src/Los-common.c b/src/Los-common.c
index cad43d0..d8f57e3 100644
--- a/src/Los-common.c
+++ b/src/Los-common.c
@@ -30,10 +30,18 @@
extern struct map_info *local_map_list;
extern lock_rdwr_var (local_rdwr_lock);
+static pthread_once_t local_rdwr_lock_init = PTHREAD_ONCE_INIT;
+
+static void
+map_local_init_once (void)
+{
+ lock_rdwr_init (&local_rdwr_lock);
+}
+
HIDDEN void
map_local_init (void)
{
- lock_rdwr_init (&local_rdwr_lock);
+ pthread_once (&local_rdwr_lock_init, map_local_init_once);
}
static void
diff --git a/src/aarch64/Gis_signal_frame.c b/src/aarch64/Gis_signal_frame.c
index 53e32de..d1ba021 100644
--- a/src/aarch64/Gis_signal_frame.c
+++ b/src/aarch64/Gis_signal_frame.c
@@ -47,10 +47,16 @@
arg = c->dwarf.as_arg;
ip = c->dwarf.ip;
+ /* ANDROID support update. */
+ /* Undo the attempt to correct the PC or we'll be pointing to the nop instead of the mov. */
+ ip += 4;
+ /* ANDROID support update. */
ret = (*a->access_mem) (as, ip, &w0, 0, arg);
if (ret < 0)
- return ret;
+ /* ANDROID support update. */
+ return 0;
+ /* End ANDROID update. */
/* FIXME: distinguish 32bit insn vs 64bit registers. */
if (w0 != 0xd4000001d2801168)
diff --git a/src/aarch64/Gstep.c b/src/aarch64/Gstep.c
index 8a517fd..fd1159d 100644
--- a/src/aarch64/Gstep.c
+++ b/src/aarch64/Gstep.c
@@ -107,17 +107,41 @@
unw_step (unw_cursor_t *cursor)
{
struct cursor *c = (struct cursor *) cursor;
- int ret;
+ int ret = -UNW_ENOINFO;
Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx))\n",
c, c->dwarf.ip, c->dwarf.cfa);
/* Check if this is a signal frame. */
if (unw_is_signal_frame (cursor))
- return unw_handle_signal_frame (cursor);
+ /* ANDROID support update. */
+ ret = unw_handle_signal_frame (cursor);
+ /* End ANDROID update. */
- ret = dwarf_step (&c->dwarf);
- Debug(1, "dwarf_step()=%d\n", ret);
+ /* ANDROID support update. */
+ if (ret < 0)
+ {
+ ret = dwarf_step (&c->dwarf);
+ Debug(1, "dwarf_step()=%d\n", ret);
+ }
+
+ if (ret < 0 && c->dwarf.frame == 0)
+ {
+ /* If this is the first frame, the code may be executing garbage
+ * in the middle of nowhere. In this case, try using the lr as
+ * the pc.
+ */
+ unw_word_t lr;
+ if (dwarf_get(&c->dwarf, c->dwarf.loc[UNW_AARCH64_X30], &lr) >= 0)
+ {
+ if (lr != c->dwarf.ip)
+ {
+ ret = 1;
+ c->dwarf.ip = lr;
+ }
+ }
+ }
+ /* End ANDROID update. */
if (ret >= 0)
{
diff --git a/src/arm/Gis_signal_frame.c b/src/arm/Gis_signal_frame.c
index e8efe7f..4126de9 100644
--- a/src/arm/Gis_signal_frame.c
+++ b/src/arm/Gis_signal_frame.c
@@ -66,7 +66,9 @@
ip = c->dwarf.ip;
if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0)
- return ret;
+ /* ANDROID support update. */
+ return 0;
+ /* End ANDROID update. */
/* Return 1 if the IP points to a non-RT sigreturn sequence. */
if (w0 == MOV_R7_SIGRETURN || w0 == ARM_SIGRETURN || w0 == THUMB_SIGRETURN)
diff --git a/src/mi/Lmap.c b/src/mi/Lmap.c
index e07a50a..ba93ab9 100644
--- a/src/mi/Lmap.c
+++ b/src/mi/Lmap.c
@@ -36,6 +36,10 @@
{
intrmask_t saved_mask;
+ /* This function can be called before any other unwind code, so make sure
+ the lock has been initialized. */
+ map_local_init ();
+
lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);
map_cursor->map_list = local_map_list;
map_cursor->cur_map = local_map_list;
@@ -56,6 +60,10 @@
intrmask_t saved_mask;
int ret_value = 0;
+ /* This function can be called before any other unwind code, so make sure
+ the lock has been initialized. */
+ map_local_init ();
+
lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);
if (local_map_list_refs == 0)
{
@@ -76,6 +84,10 @@
{
intrmask_t saved_mask;
+ /* This function can be called before any other unwind code, so make sure
+ the lock has been initialized. */
+ map_local_init ();
+
lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);
if (local_map_list != NULL && --local_map_list_refs == 0)
{
@@ -95,6 +107,10 @@
if (map_info == NULL)
return 0;
+ /* This function can be called before any other unwind code, so make sure
+ the lock has been initialized. */
+ map_local_init ();
+
lock_rdwr_rd_acquire (&local_rdwr_lock, saved_mask);
if (map_cursor->map_list != local_map_list)
{