diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index 12950102edd5..f60c26fab6d6 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -1139,7 +1139,7 @@ DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) // //---------------------------------------------------------------------- int -DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) +DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) { MachProcessSP procSP; if (GetProcessSP (pid, procSP)) diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h index 2e791f41e218..1f612a6605bb 100644 --- a/lldb/tools/debugserver/source/DNB.h +++ b/lldb/tools/debugserver/source/DNB.h @@ -64,9 +64,9 @@ nub_bool_t DNBProcessSignal (nub_process_t pid, int signal) DNB_EXPO nub_bool_t DNBProcessKill (nub_process_t pid) DNB_EXPORT; nub_size_t DNBProcessMemoryRead (nub_process_t pid, nub_addr_t addr, nub_size_t size, void *buf) DNB_EXPORT; nub_size_t DNBProcessMemoryWrite (nub_process_t pid, nub_addr_t addr, nub_size_t size, const void *buf) DNB_EXPORT; -nub_addr_t DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions) DNB_EXPORT; -nub_bool_t DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) DNB_EXPORT; -int DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT; +nub_addr_t DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions) DNB_EXPORT; +nub_bool_t DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) DNB_EXPORT; +int DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT; //---------------------------------------------------------------------- // Process status diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp index 5a9276dd28a3..c3c66f84b2e7 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp @@ -52,7 +52,7 @@ MachVMMemory::MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count) return count; } -int +nub_bool_t MachVMMemory::GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info) { MachVMRegion vmRegion(task); @@ -62,12 +62,30 @@ MachVMMemory::GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo region_info->addr = vmRegion.StartAddress(); region_info->size = vmRegion.GetByteSize(); region_info->permissions = vmRegion.GetDNBPermissions(); - return 1; } - region_info->addr = 0; - region_info->size = 0; - region_info->permissions = 0; - return 0; + else + { + region_info->addr = address; + region_info->size = 0; + if (vmRegion.GetError().Success()) + { + // vmRegion.GetRegionForAddress() return false, indicating that "address" + // wasn't in a valid region, but the "vmRegion" info was successfully + // read from the task which means the info describes the next valid + // region from which we can infer the size of this invalid region + mach_vm_address_t start_addr = vmRegion.StartAddress(); + if (address < start_addr) + region_info->size = start_addr - address; + } + // If we can't get any infor about the size from the next region, just fill + // 1 in as the byte size + if (region_info->size == 0) + region_info->size = 1; + + // Not readable, writeable or executable + region_info->permissions = 0; + } + return true; } nub_size_t diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h index e32fa4f4c447..d7162d0d79f2 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h +++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h @@ -27,7 +27,7 @@ public: nub_size_t Read(task_t task, nub_addr_t address, void *data, nub_size_t data_count); nub_size_t Write(task_t task, nub_addr_t address, const void *data, nub_size_t data_count); nub_size_t PageSize(); - int GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info); + nub_bool_t GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info); protected: nub_size_t MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count); diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp index e1667f0c196d..38757595cfed 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp @@ -128,66 +128,59 @@ MachVMRegion::GetRegionForAddress(nub_addr_t addr) { // Restore any original protections and clear our vars Clear(); + m_err.Clear(); m_addr = addr; m_start = addr; m_depth = 1024; mach_msg_type_number_t info_size = kRegionInfoSize; assert(sizeof(info_size) == 4); m_err = ::mach_vm_region_recurse (m_task, &m_start, &m_size, &m_depth, (vm_region_recurse_info_t)&m_data, &info_size); - const bool log_protections = DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS); - if (m_err.Success()) - { - if ((addr < m_start) || (addr >= (m_start + m_size))) - { - m_err.SetErrorString("no region for address"); - m_err.SetError(-1, DNBError::Generic); - if (log_protections) - m_err.LogThreaded("::mach_vm_region_recurse ( task = 0x%4.4x, address => 0x%8.8llx, size => %llu, nesting_depth => %d, info => %p, infoCnt => %d) addr = 0x%8.8llx not in range [0x%8.8llx - 0x%8.8llx)", - m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth, &m_data, info_size, (uint64_t)addr, (uint64_t)m_start, (uint64_t)m_start + m_size); - return false; - } - } - if (log_protections || m_err.Fail()) - m_err.LogThreaded("::mach_vm_region_recurse ( task = 0x%4.4x, address => 0x%8.8llx, size => %llu, nesting_depth => %d, info => %p, infoCnt => %d) addr = 0x%8.8llx ", m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth, &m_data, info_size, (uint64_t)addr); - if (m_err.Fail()) - { - return false; - } - else - { - if (log_protections) - { - DNBLogThreaded("info = { prot = %u, " - "max_prot = %u, " - "inheritance = 0x%8.8x, " - "offset = 0x%8.8llx, " - "user_tag = 0x%8.8x, " - "ref_count = %u, " - "shadow_depth = %u, " - "ext_pager = %u, " - "share_mode = %u, " - "is_submap = %d, " - "behavior = %d, " - "object_id = 0x%8.8x, " - "user_wired_count = 0x%4.4x }", - m_data.protection, - m_data.max_protection, - m_data.inheritance, - (uint64_t)m_data.offset, - m_data.user_tag, - m_data.ref_count, - m_data.shadow_depth, - m_data.external_pager, - m_data.share_mode, - m_data.is_submap, - m_data.behavior, - m_data.object_id, - m_data.user_wired_count); - } - } + const bool failed = m_err.Fail(); + const bool log_protections = DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS); + if (log_protections || failed) + m_err.LogThreaded("::mach_vm_region_recurse ( task = 0x%4.4x, address => 0x%8.8llx, size => %llu, nesting_depth => %d, info => %p, infoCnt => %d) addr = 0x%8.8llx ", m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth, &m_data, info_size, (uint64_t)addr); + + if (failed) + return false; + if (log_protections) + { + DNBLogThreaded("info = { prot = %u, " + "max_prot = %u, " + "inheritance = 0x%8.8x, " + "offset = 0x%8.8llx, " + "user_tag = 0x%8.8x, " + "ref_count = %u, " + "shadow_depth = %u, " + "ext_pager = %u, " + "share_mode = %u, " + "is_submap = %d, " + "behavior = %d, " + "object_id = 0x%8.8x, " + "user_wired_count = 0x%4.4x }", + m_data.protection, + m_data.max_protection, + m_data.inheritance, + (uint64_t)m_data.offset, + m_data.user_tag, + m_data.ref_count, + m_data.shadow_depth, + m_data.external_pager, + m_data.share_mode, + m_data.is_submap, + m_data.behavior, + m_data.object_id, + m_data.user_wired_count); + } m_curr_protection = m_data.protection; + + // We make a request for an address and got no error back, but this + // doesn't mean that "addr" is in the range. The data in this object will + // be valid though, so you could see where the next region begins. So we + // return false, yet leave "m_err" with a successfull return code. + if ((addr < m_start) || (addr >= (m_start + m_size))) + return false; return true; } diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h index e856f0b24140..bcac60b83182 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h +++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h @@ -47,6 +47,11 @@ public: uint32_t GetDNBPermissions () const; + const DNBError & + GetError () + { + return m_err; + } protected: #if defined (VM_REGION_SUBMAP_SHORT_INFO_COUNT_64) typedef vm_region_submap_short_info_data_64_t RegionInfo; diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index c640023b21ee..deb9db6ad57f 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -3283,52 +3283,28 @@ RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) } DNBRegionInfo region_info = { 0, 0, 0 }; - int ret = DNBMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); + DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); std::ostringstream ostrm; - if (ret == 1 && region_info.size > 0) - { // start:3a50000,size:100000,permissions:rwx - ostrm << "start:" << std::hex << region_info.addr << ';' - << "size:" << std::hex << region_info.size << ';'; - - if (region_info.permissions) - { - ostrm << "permissions:"; - - if (region_info.permissions & eMemoryPermissionsReadable) - ostrm << 'r'; - if (region_info.permissions & eMemoryPermissionsWritable) - ostrm << 'w'; - if (region_info.permissions & eMemoryPermissionsExecutable) - ostrm << 'x'; - ostrm << ';'; - } - return SendPacket (ostrm.str()); - } - else - { - ostrm << std::hex << "error:"; - const char *error_message = NULL; - if (ret == -1) - { - error_message = "region lookup cannot be performed"; - } - else - { - error_message = "address in unmapped region"; - } - // hex encode the error message so we can send any characters we want in - // the future since this is text - const int error_message_len = strlen (error_message); - const uint8_t *u_error_message = (const uint8_t *)error_message; - for (int i = 0; i < error_message_len; i++) - ostrm << RAWHEX8(u_error_message[i]); - ostrm << ';'; - return SendPacket (ostrm.str()); - } + ostrm << "start:" << std::hex << region_info.addr << ';'; - return SendPacket ("E68"); + if (region_info.size > 0) + ostrm << "size:" << std::hex << region_info.size << ';'; + + if (region_info.permissions) + { + ostrm << "permissions:"; + + if (region_info.permissions & eMemoryPermissionsReadable) + ostrm << 'r'; + if (region_info.permissions & eMemoryPermissionsWritable) + ostrm << 'w'; + if (region_info.permissions & eMemoryPermissionsExecutable) + ostrm << 'x'; + ostrm << ';'; + } + return SendPacket (ostrm.str()); }