Add a size when checking local reads/writes. am: 18cf8168ef
am: ac3f8501e9

* commit 'ac3f8501e951c721f62e1e98bd7793fab01aecd9':
  Add a size when checking local reads/writes.
diff --git a/include/map_info.h b/include/map_info.h
index 9c50236..a76ca15 100644
--- a/include/map_info.h
+++ b/include/map_info.h
@@ -54,9 +54,9 @@
 
 void map_local_init (void);
 
-int map_local_is_readable (unw_word_t);
+int map_local_is_readable (unw_word_t, size_t);
 
-int map_local_is_writable (unw_word_t);
+int map_local_is_writable (unw_word_t, size_t);
 
 char *map_local_get_image_name (unw_word_t);
 
diff --git a/include/tdep-aarch64/libunwind_i.h b/include/tdep-aarch64/libunwind_i.h
index 0690b1b..d3d69ab 100644
--- a/include/tdep-aarch64/libunwind_i.h
+++ b/include/tdep-aarch64/libunwind_i.h
@@ -111,7 +111,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *val = *addr;
@@ -124,7 +124,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *addr = val;
diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h
index d782cc4..c140c05 100644
--- a/include/tdep-arm/libunwind_i.h
+++ b/include/tdep-arm/libunwind_i.h
@@ -99,7 +99,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *val = *addr;
@@ -112,7 +112,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *addr = val;
diff --git a/include/tdep-hppa/libunwind_i.h b/include/tdep-hppa/libunwind_i.h
index a5cbe1b..ab737a8 100644
--- a/include/tdep-hppa/libunwind_i.h
+++ b/include/tdep-hppa/libunwind_i.h
@@ -96,7 +96,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *val = *addr;
@@ -109,7 +109,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *addr = val;
diff --git a/include/tdep-mips/libunwind_i.h b/include/tdep-mips/libunwind_i.h
index 41cc83f..c4059b2 100644
--- a/include/tdep-mips/libunwind_i.h
+++ b/include/tdep-mips/libunwind_i.h
@@ -106,7 +106,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *val = *addr;
@@ -119,7 +119,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *addr = val;
@@ -132,7 +132,7 @@
 {
 /* ANDROID support update. */
   mips_reg_t *addr = (mips_reg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_readable ((unw_word_t) (uintptr_t) addr, sizeof(mips_reg_t)))
     return -1;
 
   *val = *addr;
@@ -145,7 +145,7 @@
 {
 /* ANDROID support update. */
   mips_reg_t *addr = (mips_reg_t *) (uintptr_t) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr))
+  if (!addr || !map_local_is_writable ((unw_word_t) (uintptr_t) addr, sizeof(mips_reg_t)))
     return -1;
 
   *addr = val;
diff --git a/include/tdep-sh/libunwind_i.h b/include/tdep-sh/libunwind_i.h
index 6752f5f..4a2afd7 100644
--- a/include/tdep-sh/libunwind_i.h
+++ b/include/tdep-sh/libunwind_i.h
@@ -97,7 +97,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_readable ((unw_word_t) addr))
+  if (!addr || !map_local_is_readable ((unw_word_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *val = *addr;
@@ -110,7 +110,7 @@
 {
 /* ANDROID support update. */
   unw_fpreg_t *addr = (unw_fpreg_t *) DWARF_GET_LOC (loc);
-  if (!addr || !map_local_is_writable ((unw_word_t) addr))
+  if (!addr || !map_local_is_writable ((unw_word_t) addr, sizeof(unw_fpreg_t)))
     return -1;
 
   *addr = val;
diff --git a/src/Los-common.c b/src/Los-common.c
index fd6ae3f..f52c1e2 100644
--- a/src/Los-common.c
+++ b/src/Los-common.c
@@ -88,7 +88,7 @@
    While regenerating the list, grab a write lock to avoid any readers using
    the list while it's being modified. */
 static int
-rebuild_if_necessary (unw_word_t addr, int expected_flags)
+rebuild_if_necessary (unw_word_t addr, int expected_flags, size_t bytes)
 {
   struct map_info *map;
   struct map_info *new_list;
@@ -97,7 +97,7 @@
 
   new_list = map_create_list (UNW_MAP_CREATE_LOCAL, getpid());
   map = map_find_from_addr (new_list, addr);
-  if (map && (expected_flags == 0 || (map->flags & expected_flags)))
+  if (map && (map->end - addr >= bytes) && (expected_flags == 0 || (map->flags & expected_flags)))
     {
       /* Get a write lock on local_map_list since it's going to be modified. */
       lock_rdwr_wr_acquire (&local_rdwr_lock, saved_mask);
@@ -109,7 +109,7 @@
          would be necessary to regenerate the list one more time. */
       ret_value = 0;
       map = map_find_from_addr (local_map_list, addr);
-      if (!map || (expected_flags != 0 && !(map->flags & expected_flags)))
+      if (!map || (map->end - addr < bytes) || (expected_flags != 0 && !(map->flags & expected_flags)))
         {
           /* Move any cached items to the new list. */
           move_cached_elf_data (local_map_list, new_list);
@@ -127,7 +127,7 @@
 }
 
 static int
-is_flag_set (unw_word_t addr, int flag)
+is_flag_set (unw_word_t addr, int flag, size_t bytes)
 {
   struct map_info *map;
   int ret = 0;
@@ -142,11 +142,18 @@
           lock_rdwr_release (&local_rdwr_lock, saved_mask);
           return 0;
         }
-      ret = map->flags & flag;
+      /* Do not bother checking if the next map is readable and right at
+       * the end of this map. All of the reads/writes are of small values
+       * that should never span a map.
+       */
+      if (map->end - addr < bytes)
+        ret = 0;
+      else
+        ret = map->flags & flag;
     }
   lock_rdwr_release (&local_rdwr_lock, saved_mask);
 
-  if (!ret && rebuild_if_necessary (addr, flag) == 0)
+  if (!ret && rebuild_if_necessary (addr, flag, bytes) == 0)
     {
       return 1;
     }
@@ -154,15 +161,15 @@
 }
 
 PROTECTED int
-map_local_is_readable (unw_word_t addr)
+map_local_is_readable (unw_word_t addr, size_t read_bytes)
 {
-  return is_flag_set (addr, PROT_READ);
+  return is_flag_set (addr, PROT_READ, read_bytes);
 }
 
 PROTECTED int
-map_local_is_writable (unw_word_t addr)
+map_local_is_writable (unw_word_t addr, size_t write_bytes)
 {
-  return is_flag_set (addr, PROT_WRITE);
+  return is_flag_set (addr, PROT_WRITE, write_bytes);
 }
 
 PROTECTED int
@@ -178,7 +185,7 @@
   if (!map)
     {
       lock_rdwr_release (&local_rdwr_lock, saved_mask);
-      if (rebuild_if_necessary (ip, 0) < 0)
+      if (rebuild_if_necessary (ip, 0, sizeof(unw_word_t)) < 0)
         return -UNW_ENOINFO;
 
       lock_rdwr_rd_acquire (&local_rdwr_lock, saved_mask);
@@ -225,7 +232,7 @@
   if (!map)
     {
       lock_rdwr_release (&local_rdwr_lock, saved_mask);
-      if (rebuild_if_necessary (ip, 0) < 0)
+      if (rebuild_if_necessary (ip, 0, sizeof(unw_word_t)) < 0)
         return NULL;
 
       lock_rdwr_rd_acquire (&local_rdwr_lock, saved_mask);
diff --git a/src/aarch64/Ginit.c b/src/aarch64/Ginit.c
index bbf28e8..0bb57ea 100644
--- a/src/aarch64/Ginit.c
+++ b/src/aarch64/Ginit.c
@@ -88,7 +88,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (16, "mem[%lx] <- %lx\n", addr, *val);
@@ -107,7 +107,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/arm/Ginit.c b/src/arm/Ginit.c
index a382ac7..64c5360 100644
--- a/src/arm/Ginit.c
+++ b/src/arm/Ginit.c
@@ -80,7 +80,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (16, "mem[%x] <- %x\n", addr, *val);
@@ -99,7 +99,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/hppa/Ginit.c b/src/hppa/Ginit.c
index ac0a618..ea11490 100644
--- a/src/hppa/Ginit.c
+++ b/src/hppa/Ginit.c
@@ -93,7 +93,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (12, "mem[%x] <- %x\n", addr, *val);
@@ -112,7 +112,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/ia64/Ginit.c b/src/ia64/Ginit.c
index 874157b..1c31d45 100644
--- a/src/ia64/Ginit.c
+++ b/src/ia64/Ginit.c
@@ -80,7 +80,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (12, "mem[%lx] <- %lx\n", addr, *val);
@@ -99,7 +99,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/mips/Ginit.c b/src/mips/Ginit.c
index bd50aab..b61f47c 100644
--- a/src/mips/Ginit.c
+++ b/src/mips/Ginit.c
@@ -98,7 +98,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (16, "mem[%llx] <- %llx\n", (long long) addr, (long long) *val);
@@ -118,7 +118,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) (uintptr_t) addr;
diff --git a/src/ppc32/Ginit.c b/src/ppc32/Ginit.c
index 9b9127a..864e6d5 100644
--- a/src/ppc32/Ginit.c
+++ b/src/ppc32/Ginit.c
@@ -116,7 +116,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (12, "mem[%lx] <- %lx\n", addr, *val);
@@ -135,7 +135,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/ppc64/Ginit.c b/src/ppc64/Ginit.c
index db9bf8c..ffd64bd 100644
--- a/src/ppc64/Ginit.c
+++ b/src/ppc64/Ginit.c
@@ -120,7 +120,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (12, "mem[%lx] <- %lx\n", addr, *val);
@@ -139,7 +139,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/sh/Ginit.c b/src/sh/Ginit.c
index 72dea84..1a4ebb2 100644
--- a/src/sh/Ginit.c
+++ b/src/sh/Ginit.c
@@ -87,7 +87,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (16, "mem[%x] <- %x\n", addr, *val);
@@ -106,7 +106,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/x86/Ginit.c b/src/x86/Ginit.c
index 0ecb6be..4863c15 100644
--- a/src/x86/Ginit.c
+++ b/src/x86/Ginit.c
@@ -145,7 +145,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (16, "mem[%x] <- %x\n", addr, *val);
@@ -168,7 +168,7 @@
         return -1;
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;
diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c
index 468ca99..672b667 100644
--- a/src/x86_64/Ginit.c
+++ b/src/x86_64/Ginit.c
@@ -162,7 +162,7 @@
     {
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_writable (addr))
+      if (map_local_is_writable (addr, sizeof(unw_word_t)))
         {
 #endif
           Debug (16, "mem[%016lx] <- %lx\n", addr, *val);
@@ -187,7 +187,7 @@
 
       /* ANDROID support update. */
 #ifdef UNW_LOCAL_ONLY
-      if (map_local_is_readable (addr))
+      if (map_local_is_readable (addr, sizeof(unw_word_t)))
         {
 #endif
           *val = *(unw_word_t *) addr;