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;