When unwinding from the first frame, try to ask the remote debugserver
if this is a mapped/executable region of memory.  If it isn't, we've jumped
through a bad pointer and we know how to unwind the stack correctly based
on the ABI.  

Previously I had 0x0 special cased but if you jumped to 0x2 on x86_64 one
frame would be skipped because the unwinder would try using the x86_64 
ArchDefaultUnwindPlan which relied on the rbp.

Fixes <rdar://problem/10508291>



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@146477 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 60234ac..eaa0398 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1108,6 +1108,7 @@
             std::string value;
             addr_t addr_value;
             bool success = true;
+            bool saw_permissions = false;
             while (success && response.GetNameColonValue(name, value))
             {
                 if (name.compare ("start") == 0)
@@ -1122,14 +1123,33 @@
                     if (success)
                         region_info.GetRange().SetByteSize (addr_value);
                 }
-                else if (name.compare ("permissions") == 0)
+                else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
                 {
-                    if (value.find('r') != std::string::npos)
-                        region_info.AddPermissions (ePermissionsReadable);
-                    if (value.find('w') != std::string::npos)
-                        region_info.AddPermissions (ePermissionsWritable);
-                    if (value.find('x') != std::string::npos)
-                        region_info.AddPermissions (ePermissionsExecutable);
+                    saw_permissions = true;
+                    if (region_info.GetRange().Contains (addr))
+                    {
+                        if (value.find('r') != std::string::npos)
+                            region_info.SetReadable (MemoryRegionInfo::eYes);
+                        else
+                            region_info.SetReadable (MemoryRegionInfo::eNo);
+
+                        if (value.find('w') != std::string::npos)
+                            region_info.SetWritable (MemoryRegionInfo::eYes);
+                        else
+                            region_info.SetWritable (MemoryRegionInfo::eNo);
+
+                        if (value.find('x') != std::string::npos)
+                            region_info.SetExecutable (MemoryRegionInfo::eYes);
+                        else
+                            region_info.SetExecutable (MemoryRegionInfo::eNo);
+                    }
+                    else
+                    {
+                        // The reported region does not contain this address -- we're looking at an unmapped page
+                        region_info.SetReadable (MemoryRegionInfo::eNo);
+                        region_info.SetWritable (MemoryRegionInfo::eNo);
+                        region_info.SetExecutable (MemoryRegionInfo::eNo);
+                    }
                 }
                 else if (name.compare ("error") == 0)
                 {
@@ -1141,6 +1161,14 @@
                     error.SetErrorString(value.c_str());
                 }
             }
+
+            // We got a valid address range back but no permissions -- which means this is an unmapped page
+            if (region_info.GetRange().IsValid() && saw_permissions == false)
+            {
+                region_info.SetReadable (MemoryRegionInfo::eNo);
+                region_info.SetWritable (MemoryRegionInfo::eNo);
+                region_info.SetExecutable (MemoryRegionInfo::eNo);
+            }
         }
         else
         {