diff options
author | Pavel Labath <labath@google.com> | 2018-02-28 20:42:29 +0000 |
---|---|---|
committer | Pavel Labath <labath@google.com> | 2018-02-28 20:42:29 +0000 |
commit | ec03d7e3babb18f222d9b83a04e747f206f416a5 (patch) | |
tree | 242cc79fe6f09deb8ff99826bfb123cc331a4e65 /lldb/source/Plugins/Process/gdb-remote | |
parent | fde8b042358ac2b8ac0b7c3a590e9471d3515462 (diff) | |
download | bcm5719-llvm-ec03d7e3babb18f222d9b83a04e747f206f416a5.tar.gz bcm5719-llvm-ec03d7e3babb18f222d9b83a04e747f206f416a5.zip |
Revert "[lldb] Use vFlash commands when writing to target's flash memory regions"
This reverts commit r326261 as it introduces inconsistencies in the
handling of load addresses for ObjectFileELF -- some parts of the class
use physical addresses, and some use virtual. This has manifested itself
as us not being able to set the load address of the vdso "module" on
android.
llvm-svn: 326367
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
4 files changed, 9 insertions, 335 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 30db5583ac8..b0785a687f5 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -21,7 +21,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/XML.h" #include "lldb/Interpreter/Args.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/MemoryRegionInfo.h" @@ -82,7 +81,6 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() m_supports_qXfer_libraries_read(eLazyBoolCalculate), m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate), m_supports_qXfer_features_read(eLazyBoolCalculate), - m_supports_qXfer_memory_map_read(eLazyBoolCalculate), m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate), m_supports_jThreadExtendedInfo(eLazyBoolCalculate), m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate), @@ -105,8 +103,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() m_hostname(), m_gdb_server_name(), m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0), m_max_packet_size(0), m_qSupported_response(), m_supported_async_json_packets_is_valid(false), - m_supported_async_json_packets_sp(), m_qXfer_memory_map(), - m_qXfer_memory_map_loaded(false) {} + m_supported_async_json_packets_sp() {} //---------------------------------------------------------------------- // Destructor @@ -195,13 +192,6 @@ bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() { return m_supports_qXfer_features_read == eLazyBoolYes; } -bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() { - if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) { - GetRemoteQSupported(); - } - return m_supports_qXfer_memory_map_read == eLazyBoolYes; -} - uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() { if (m_max_packet_size == 0) { GetRemoteQSupported(); @@ -306,7 +296,6 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) { m_supports_qXfer_libraries_read = eLazyBoolCalculate; m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate; m_supports_qXfer_features_read = eLazyBoolCalculate; - m_supports_qXfer_memory_map_read = eLazyBoolCalculate; m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate; m_supports_qProcessInfoPID = true; m_supports_qfProcessInfo = true; @@ -353,7 +342,6 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_qXfer_libraries_svr4_read = eLazyBoolNo; m_supports_augmented_libraries_svr4_read = eLazyBoolNo; m_supports_qXfer_features_read = eLazyBoolNo; - m_supports_qXfer_memory_map_read = eLazyBoolNo; m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if // not, we assume no limit @@ -389,8 +377,6 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_qXfer_libraries_read = eLazyBoolYes; if (::strstr(response_cstr, "qXfer:features:read+")) m_supports_qXfer_features_read = eLazyBoolYes; - if (::strstr(response_cstr, "qXfer:memory-map:read+")) - m_supports_qXfer_memory_map_read = eLazyBoolYes; // Look for a list of compressions in the features list e.g. // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma @@ -1474,8 +1460,7 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo( UNUSED_IF_ASSERT_DISABLED(packet_len); StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(packet, response, false) == - PacketResult::Success && - response.GetResponseType() == StringExtractorGDBRemote::eResponse) { + PacketResult::Success) { llvm::StringRef name; llvm::StringRef value; addr_t addr_value = LLDB_INVALID_ADDRESS; @@ -1551,134 +1536,8 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo( if (m_supports_memory_region_info == eLazyBoolNo) { error.SetErrorString("qMemoryRegionInfo is not supported"); } - - // Try qXfer:memory-map:read to get region information not included in - // qMemoryRegionInfo - MemoryRegionInfo qXfer_region_info; - Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info); - - if (error.Fail()) { - // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, - // use the qXfer result as a fallback - if (qXfer_error.Success()) { - region_info = qXfer_region_info; - error.Clear(); - } else { - region_info.Clear(); - } - } else if (qXfer_error.Success()) { - // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if - // both regions are the same range, update the result to include the - // flash-memory information that is specific to the qXfer result. - if (region_info.GetRange() == qXfer_region_info.GetRange()) { - region_info.SetFlash(qXfer_region_info.GetFlash()); - region_info.SetBlocksize(qXfer_region_info.GetBlocksize()); - } - } - return error; -} - -Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo( - lldb::addr_t addr, MemoryRegionInfo ®ion) { - Status error = LoadQXferMemoryMap(); - if (!error.Success()) - return error; - for (const auto &map_region : m_qXfer_memory_map) { - if (map_region.GetRange().Contains(addr)) { - region = map_region; - return error; - } - } - error.SetErrorString("Region not found"); - return error; -} - -Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() { - - Status error; - - if (m_qXfer_memory_map_loaded) - // Already loaded, return success - return error; - - if (!XMLDocument::XMLEnabled()) { - error.SetErrorString("XML is not supported"); - return error; - } - - if (!GetQXferMemoryMapReadSupported()) { - error.SetErrorString("Memory map is not supported"); - return error; - } - - std::string xml; - lldb_private::Status lldberr; - if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml, - lldberr)) { - error.SetErrorString("Failed to read memory map"); - return error; - } - - XMLDocument xml_document; - - if (!xml_document.ParseMemory(xml.c_str(), xml.size())) { - error.SetErrorString("Failed to parse memory map xml"); - return error; - } - - XMLNode map_node = xml_document.GetRootElement("memory-map"); - if (!map_node) { - error.SetErrorString("Invalid root node in memory map xml"); - return error; - } - - m_qXfer_memory_map.clear(); - - map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool { - if (!memory_node.IsElement()) - return true; - if (memory_node.GetName() != "memory") - return true; - auto type = memory_node.GetAttributeValue("type", ""); - uint64_t start; - uint64_t length; - if (!memory_node.GetAttributeValueAsUnsigned("start", start)) - return true; - if (!memory_node.GetAttributeValueAsUnsigned("length", length)) - return true; - MemoryRegionInfo region; - region.GetRange().SetRangeBase(start); - region.GetRange().SetByteSize(length); - if (type == "rom") { - region.SetReadable(MemoryRegionInfo::eYes); - this->m_qXfer_memory_map.push_back(region); - } else if (type == "ram") { - region.SetReadable(MemoryRegionInfo::eYes); - region.SetWritable(MemoryRegionInfo::eYes); - this->m_qXfer_memory_map.push_back(region); - } else if (type == "flash") { - region.SetFlash(MemoryRegionInfo::eYes); - memory_node.ForEachChildElement( - [®ion](const XMLNode &prop_node) -> bool { - if (!prop_node.IsElement()) - return true; - if (prop_node.GetName() != "property") - return true; - auto propname = prop_node.GetAttributeValue("name", ""); - if (propname == "blocksize") { - uint64_t blocksize; - if (prop_node.GetElementTextAsUnsigned(blocksize)) - region.SetBlocksize(blocksize); - } - return true; - }); - this->m_qXfer_memory_map.push_back(region); - } - return true; - }); - - m_qXfer_memory_map_loaded = true; - + if (error.Fail()) + region_info.Clear(); return error; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 8898767e83c..45913157c29 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -355,8 +355,6 @@ public: bool GetQXferFeaturesReadSupported(); - bool GetQXferMemoryMapReadSupported(); - LazyBool SupportsAllocDeallocMemory() // const { // Uncomment this to have lldb pretend the debug server doesn't respond to @@ -547,7 +545,6 @@ protected: LazyBool m_supports_qXfer_libraries_read; LazyBool m_supports_qXfer_libraries_svr4_read; LazyBool m_supports_qXfer_features_read; - LazyBool m_supports_qXfer_memory_map_read; LazyBool m_supports_augmented_libraries_svr4_read; LazyBool m_supports_jThreadExtendedInfo; LazyBool m_supports_jLoadedDynamicLibrariesInfos; @@ -591,9 +588,6 @@ protected: bool m_supported_async_json_packets_is_valid; lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp; - std::vector<MemoryRegionInfo> m_qXfer_memory_map; - bool m_qXfer_memory_map_loaded; - bool GetCurrentProcessInfo(bool allow_lazy_pid = true); bool GetGDBServerVersion(); @@ -616,11 +610,6 @@ protected: llvm::MutableArrayRef<uint8_t> &buffer, size_t offset); - Status LoadQXferMemoryMap(); - - Status GetQXferMemoryMapRegionInfo(lldb::addr_t addr, - MemoryRegionInfo ®ion); - private: DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient); }; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index b97c0bd8cbc..0823add538d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -59,7 +59,6 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/TargetList.h" @@ -257,8 +256,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, m_addr_to_mmap_size(), m_thread_create_bp_sp(), m_waiting_for_attach(false), m_destroy_tried_resuming(false), m_command_sp(), m_breakpoint_pc_offset(0), - m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false), - m_erased_flash_ranges() { + m_initial_tid(LLDB_INVALID_THREAD_ID) { m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, @@ -2800,142 +2798,6 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size, return 0; } -Status ProcessGDBRemote::WriteObjectFile(std::vector<WriteEntry> entries) { - Status error; - // Sort the entries by address because some writes, like those to flash - // memory, must happen in order of increasing address. - std::stable_sort( - std::begin(entries), std::end(entries), - [](const WriteEntry a, const WriteEntry b) { return a.Dest < b.Dest; }); - m_allow_flash_writes = true; - error = Process::WriteObjectFile(entries); - if (error.Success()) - error = FlashDone(); - else - // Even though some of the writing failed, try to send a flash done if - // some of the writing succeeded so the flash state is reset to normal, - // but don't stomp on the error status that was set in the write failure - // since that's the one we want to report back. - FlashDone(); - m_allow_flash_writes = false; - return error; -} - -bool ProcessGDBRemote::HasErased(FlashRange range) { - auto size = m_erased_flash_ranges.GetSize(); - for (size_t i = 0; i < size; ++i) - if (m_erased_flash_ranges.GetEntryAtIndex(i)->Contains(range)) - return true; - return false; -} - -Status ProcessGDBRemote::FlashErase(lldb::addr_t addr, size_t size) { - Status status; - - MemoryRegionInfo region; - status = GetMemoryRegionInfo(addr, region); - if (!status.Success()) - return status; - - // The gdb spec doesn't say if erasures are allowed across multiple regions, - // but we'll disallow it to be safe and to keep the logic simple by worring - // about only one region's block size. DoMemoryWrite is this function's - // primary user, and it can easily keep writes within a single memory region - if (addr + size > region.GetRange().GetRangeEnd()) { - status.SetErrorString("Unable to erase flash in multiple regions"); - return status; - } - - uint64_t blocksize = region.GetBlocksize(); - if (blocksize == 0) { - status.SetErrorString("Unable to erase flash because blocksize is 0"); - return status; - } - - // Erasures can only be done on block boundary adresses, so round down addr - // and round up size - lldb::addr_t block_start_addr = addr - (addr % blocksize); - size += (addr - block_start_addr); - if ((size % blocksize) != 0) - size += (blocksize - size % blocksize); - - FlashRange range(block_start_addr, size); - - if (HasErased(range)) - return status; - - // We haven't erased the entire range, but we may have erased part of it. - // (e.g., block A is already erased and range starts in A and ends in B). - // So, adjust range if necessary to exclude already erased blocks. - if (!m_erased_flash_ranges.IsEmpty()) { - // Assuming that writes and erasures are done in increasing addr order, - // because that is a requirement of the vFlashWrite command. Therefore, - // we only need to look at the last range in the list for overlap. - const auto &last_range = *m_erased_flash_ranges.Back(); - if (range.GetRangeBase() < last_range.GetRangeEnd()) { - auto overlap = last_range.GetRangeEnd() - range.GetRangeBase(); - // overlap will be less than range.GetByteSize() or else HasErased() would - // have been true - range.SetByteSize(range.GetByteSize() - overlap); - range.SetRangeBase(range.GetRangeBase() + overlap); - } - } - - StreamString packet; - packet.Printf("vFlashErase:%" PRIx64 ",%" PRIx64, range.GetRangeBase(), - (uint64_t)range.GetByteSize()); - - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, - true) == - GDBRemoteCommunication::PacketResult::Success) { - if (response.IsOKResponse()) { - m_erased_flash_ranges.Insert(range, true); - } else { - if (response.IsErrorResponse()) - status.SetErrorStringWithFormat("flash erase failed for 0x%" PRIx64, - addr); - else if (response.IsUnsupportedResponse()) - status.SetErrorStringWithFormat("GDB server does not support flashing"); - else - status.SetErrorStringWithFormat( - "unexpected response to GDB server flash erase packet '%s': '%s'", - packet.GetData(), response.GetStringRef().c_str()); - } - } else { - status.SetErrorStringWithFormat("failed to send packet: '%s'", - packet.GetData()); - } - return status; -} - -Status ProcessGDBRemote::FlashDone() { - Status status; - // If we haven't erased any blocks, then we must not have written anything - // either, so there is no need to actually send a vFlashDone command - if (m_erased_flash_ranges.IsEmpty()) - return status; - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response, true) == - GDBRemoteCommunication::PacketResult::Success) { - if (response.IsOKResponse()) { - m_erased_flash_ranges.Clear(); - } else { - if (response.IsErrorResponse()) - status.SetErrorStringWithFormat("flash done failed"); - else if (response.IsUnsupportedResponse()) - status.SetErrorStringWithFormat("GDB server does not support flashing"); - else - status.SetErrorStringWithFormat( - "unexpected response to GDB server flash done packet: '%s'", - response.GetStringRef().c_str()); - } - } else { - status.SetErrorStringWithFormat("failed to send flash done packet"); - } - return status; -} - size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf, size_t size, Status &error) { GetMaxMemorySize(); @@ -2948,33 +2810,10 @@ size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf, size = max_memory_size; } - StreamGDBRemote packet; - - MemoryRegionInfo region; - Status region_status = GetMemoryRegionInfo(addr, region); - - bool is_flash = - region_status.Success() && region.GetFlash() == MemoryRegionInfo::eYes; - - if (is_flash) { - if (!m_allow_flash_writes) { - error.SetErrorString("Writing to flash memory is not allowed"); - return 0; - } - // Keep the write within a flash memory region - if (addr + size > region.GetRange().GetRangeEnd()) - size = region.GetRange().GetRangeEnd() - addr; - // Flash memory must be erased before it can be written - error = FlashErase(addr, size); - if (!error.Success()) - return 0; - packet.Printf("vFlashWrite:%" PRIx64 ":", addr); - packet.PutEscapedBytes(buf, size); - } else { - packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size); - packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(), - endian::InlHostByteOrder()); - } + StreamString packet; + packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size); + packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(), + endian::InlHostByteOrder()); StringExtractorGDBRemote response; if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, true) == diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 10679e0b68d..42d1c4ecd66 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -144,8 +144,6 @@ public: size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) override; - Status WriteObjectFile(std::vector<WriteEntry> entries) override; - size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, Status &error) override; @@ -304,11 +302,6 @@ protected: int64_t m_breakpoint_pc_offset; lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach - bool m_allow_flash_writes; - using FlashRangeVector = lldb_private::RangeVector<lldb::addr_t, size_t>; - using FlashRange = FlashRangeVector::Entry; - FlashRangeVector m_erased_flash_ranges; - //---------------------------------------------------------------------- // Accessors //---------------------------------------------------------------------- @@ -415,12 +408,6 @@ protected: Status UpdateAutomaticSignalFiltering() override; - Status FlashErase(lldb::addr_t addr, size_t size); - - Status FlashDone(); - - bool HasErased(FlashRange range); - private: //------------------------------------------------------------------ // For ProcessGDBRemote only |