am a82985b6: am 7cd45071: Merge "Include page protections in the debuggerd map output."

* commit 'a82985b6686f8b47119193fee2f804376a90125b':
  Include page protections in the debuggerd map output.
diff --git a/debuggerd/tombstone.c b/debuggerd/tombstone.c
index 98016c3..e8b3e24 100644
--- a/debuggerd/tombstone.c
+++ b/debuggerd/tombstone.c
@@ -350,6 +350,18 @@
     }
 }
 
+static void dump_map(log_t* log, map_info_t* m, const char* what) {
+    if (m != NULL) {
+        _LOG(log, false, "    %08x-%08x %c%c%c %s\n", m->start, m->end,
+             m->is_readable ? 'r' : '-',
+             m->is_writable ? 'w' : '-',
+             m->is_executable ? 'x' : '-',
+             m->name);
+    } else {
+        _LOG(log, false, "    (no %s)\n", what);
+    }
+}
+
 static void dump_nearby_maps(const ptrace_context_t* context, log_t* log, pid_t tid) {
     siginfo_t si;
     memset(&si, 0, sizeof(si));
@@ -396,21 +408,9 @@
      * Show "next" then "match" then "prev" so that the addresses appear in
      * ascending order (like /proc/pid/maps).
      */
-    if (next != NULL) {
-        _LOG(log, false, "    %08x-%08x %s\n", next->start, next->end, next->name);
-    } else {
-        _LOG(log, false, "    (no map below)\n");
-    }
-    if (map != NULL) {
-        _LOG(log, false, "    %08x-%08x %s\n", map->start, map->end, map->name);
-    } else {
-        _LOG(log, false, "    (no map for address)\n");
-    }
-    if (prev != NULL) {
-        _LOG(log, false, "    %08x-%08x %s\n", prev->start, prev->end, prev->name);
-    } else {
-        _LOG(log, false, "    (no map above)\n");
-    }
+    dump_map(log, next, "map below");
+    dump_map(log, map, "map for address");
+    dump_map(log, prev, "map above");
 }
 
 static void dump_thread(const ptrace_context_t* context, log_t* log, pid_t tid, bool at_fault,
diff --git a/include/corkscrew/map_info.h b/include/corkscrew/map_info.h
index ea1d35f..c9b241d 100644
--- a/include/corkscrew/map_info.h
+++ b/include/corkscrew/map_info.h
@@ -32,6 +32,7 @@
     uintptr_t start;
     uintptr_t end;
     bool is_readable;
+    bool is_writable;
     bool is_executable;
     void* data; // arbitrary data associated with the map by the user, initially NULL
     char name[];
@@ -46,9 +47,10 @@
 /* Finds the memory map that contains the specified address. */
 const map_info_t* find_map_info(const map_info_t* milist, uintptr_t addr);
 
-/* Returns true if the addr is in an readable map. */
+/* Returns true if the addr is in a readable map. */
 bool is_readable_map(const map_info_t* milist, uintptr_t addr);
-
+/* Returns true if the addr is in a writable map. */
+bool is_writable_map(const map_info_t* milist, uintptr_t addr);
 /* Returns true if the addr is in an executable map. */
 bool is_executable_map(const map_info_t* milist, uintptr_t addr);
 
diff --git a/libcorkscrew/map_info.c b/libcorkscrew/map_info.c
index 3c52854..6a27664 100644
--- a/libcorkscrew/map_info.c
+++ b/libcorkscrew/map_info.c
@@ -57,13 +57,15 @@
         mi->start = start;
         mi->end = end;
         mi->is_readable = strlen(permissions) == 4 && permissions[0] == 'r';
+        mi->is_writable = strlen(permissions) == 4 && permissions[1] == 'w';
         mi->is_executable = strlen(permissions) == 4 && permissions[2] == 'x';
         mi->data = NULL;
         memcpy(mi->name, name, name_len);
         mi->name[name_len] = '\0';
         ALOGV("Parsed map: start=0x%08x, end=0x%08x, "
-                "is_readable=%d, is_executable=%d, name=%s",
-                mi->start, mi->end, mi->is_readable, mi->is_executable, mi->name);
+                "is_readable=%d, is_writable=%d, is_executable=%d, name=%s",
+                mi->start, mi->end,
+                mi->is_readable, mi->is_writable, mi->is_executable, mi->name);
     }
     return mi;
 }
@@ -110,6 +112,11 @@
     return mi && mi->is_readable;
 }
 
+bool is_writable_map(const map_info_t* milist, uintptr_t addr) {
+    const map_info_t* mi = find_map_info(milist, addr);
+    return mi && mi->is_writable;
+}
+
 bool is_executable_map(const map_info_t* milist, uintptr_t addr) {
     const map_info_t* mi = find_map_info(milist, addr);
     return mi && mi->is_executable;