diff options
-rw-r--r-- | lldb/include/lldb/Host/XML.h | 3 | ||||
-rw-r--r-- | lldb/include/lldb/Target/MemoryRegionInfo.h | 12 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Process.h | 7 | ||||
-rw-r--r-- | lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestGDBRemoteLoad.py | 61 | ||||
-rw-r--r-- | lldb/source/Host/common/XML.cpp | 12 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 39 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 149 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h | 11 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 171 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 13 | ||||
-rw-r--r-- | lldb/source/Symbol/ObjectFile.cpp | 33 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 11 |
13 files changed, 23 insertions, 505 deletions
diff --git a/lldb/include/lldb/Host/XML.h b/lldb/include/lldb/Host/XML.h index c274e83d370..96b5227305e 100644 --- a/lldb/include/lldb/Host/XML.h +++ b/lldb/include/lldb/Host/XML.h @@ -82,9 +82,6 @@ public: llvm::StringRef GetAttributeValue(const char *name, const char *fail_value = nullptr) const; - bool GetAttributeValueAsUnsigned(const char *name, uint64_t &value, - uint64_t fail_value = 0, int base = 0) const; - XMLNode FindFirstChildElementWithName(const char *name) const; XMLNode GetElementForPath(const NamePath &path); diff --git a/lldb/include/lldb/Target/MemoryRegionInfo.h b/lldb/include/lldb/Target/MemoryRegionInfo.h index 63a7b721701..0824b2442ac 100644 --- a/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -25,7 +25,7 @@ public: MemoryRegionInfo() : m_range(), m_read(eDontKnow), m_write(eDontKnow), m_execute(eDontKnow), - m_mapped(eDontKnow), m_flash(eDontKnow), m_blocksize(0) {} + m_mapped(eDontKnow) {} ~MemoryRegionInfo() {} @@ -58,14 +58,6 @@ public: void SetName(const char *name) { m_name = ConstString(name); } - OptionalBool GetFlash() const { return m_flash; } - - void SetFlash(OptionalBool val) { m_flash = val; } - - lldb::offset_t GetBlocksize() const { return m_blocksize; } - - void SetBlocksize(lldb::offset_t blocksize) { m_blocksize = blocksize; } - //---------------------------------------------------------------------- // Get permissions as a uint32_t that is a mask of one or more bits from // the lldb::Permissions @@ -106,8 +98,6 @@ protected: OptionalBool m_execute; OptionalBool m_mapped; ConstString m_name; - OptionalBool m_flash; - lldb::offset_t m_blocksize; }; } diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index e9b243c2f02..16f37f4dd5d 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -556,11 +556,6 @@ public: return GetStaticBroadcasterClass(); } - struct WriteEntry { - lldb::addr_t Dest; - llvm::ArrayRef<uint8_t> Contents; - }; - //------------------------------------------------------------------ /// A notification structure that can be used by clients to listen /// for changes in a process's lifetime. @@ -1955,8 +1950,6 @@ public: return LLDB_INVALID_ADDRESS; } - virtual Status WriteObjectFile(std::vector<WriteEntry> entries); - //------------------------------------------------------------------ /// The public interface to allocating memory in the process. /// diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestGDBRemoteLoad.py b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestGDBRemoteLoad.py deleted file mode 100644 index cce19a3bfa7..00000000000 --- a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestGDBRemoteLoad.py +++ /dev/null @@ -1,61 +0,0 @@ -import lldb -from lldbsuite.test.lldbtest import * -from lldbsuite.test.decorators import * -from gdbclientutils import * - - -class TestGDBRemoteLoad(GDBRemoteTestBase): - - def test_ram_load(self): - """Test loading an object file to a target's ram""" - target = self.createTarget("a.yaml") - process = self.connect(target) - self.dbg.HandleCommand("target modules load -l -s0") - self.assertPacketLogContains([ - "M1000,4:c3c3c3c3", - "M1004,2:3232" - ]) - - @skipIfXmlSupportMissing - def test_flash_load(self): - """Test loading an object file to a target's flash memory""" - - class Responder(MockGDBServerResponder): - def qSupported(self, client_supported): - return "PacketSize=3fff;QStartNoAckMode+;qXfer:memory-map:read+" - - def qXferRead(self, obj, annex, offset, length): - if obj == "memory-map": - return (self.MEMORY_MAP[offset:offset + length], - offset + length < len(self.MEMORY_MAP)) - return None, False - - def other(self, packet): - if packet[0:11] == "vFlashErase": - return "OK" - if packet[0:11] == "vFlashWrite": - return "OK" - if packet == "vFlashDone": - return "OK" - return "" - - MEMORY_MAP = """<?xml version="1.0"?> -<memory-map> - <memory type="ram" start="0x0" length="0x1000"/> - <memory type="flash" start="0x1000" length="0x1000"> - <property name="blocksize">0x100</property> - </memory> - <memory type="ram" start="0x2000" length="0x1D400"/> -</memory-map> -""" - - self.server.responder = Responder() - target = self.createTarget("a.yaml") - process = self.connect(target) - self.dbg.HandleCommand("target modules load -l -s0") - self.assertPacketLogContains([ - "vFlashErase:1000,100", - "vFlashWrite:1000:\xc3\xc3\xc3\xc3", - "vFlashWrite:1004:\x32\x32", - "vFlashDone" - ]) diff --git a/lldb/source/Host/common/XML.cpp b/lldb/source/Host/common/XML.cpp index 42e3d4b6e92..c3169bd6e08 100644 --- a/lldb/source/Host/common/XML.cpp +++ b/lldb/source/Host/common/XML.cpp @@ -151,18 +151,6 @@ llvm::StringRef XMLNode::GetAttributeValue(const char *name, return llvm::StringRef(); } -bool XMLNode::GetAttributeValueAsUnsigned(const char *name, uint64_t &value, - uint64_t fail_value, int base) const { -#if defined(LIBXML2_DEFINED) - llvm::StringRef str_value = GetAttributeValue(name, ""); -#else - llvm::StringRef str_value; -#endif - bool success = false; - value = StringConvert::ToUInt64(str_value.data(), fail_value, base, &success); - return success; -} - void XMLNode::ForEachChildNode(NodeCallback const &callback) const { #if defined(LIBXML2_DEFINED) if (IsValid()) diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 644fddb06a4..9d606063f93 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -827,7 +827,7 @@ bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value, // of the sections that have SHF_ALLOC in their flag bits. SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); if (section_sp && section_sp->Test(SHF_ALLOC)) { - lldb::addr_t load_addr = GetSectionPhysicalAddress(section_sp); + lldb::addr_t load_addr = section_sp->GetFileAddress(); // We don't want to update the load address of a section with type // eSectionTypeAbsoluteAddress as they already have the absolute load // address @@ -3470,40 +3470,3 @@ size_t ObjectFileELF::ReadSectionData(Section *section, section_data.SetData(buffer_sp); return buffer_sp->GetByteSize(); } - -bool ObjectFileELF::AnySegmentHasPhysicalAddress() { - size_t header_count = ParseProgramHeaders(); - for (size_t i = 1; i <= header_count; ++i) { - auto header = GetProgramHeaderByIndex(i); - if (header->p_paddr != 0) - return true; - } - return false; -} - -const elf::ELFProgramHeader * -ObjectFileELF::GetSectionSegment(SectionSP section_sp) { - auto section_size = section_sp->GetFileSize(); - if (section_size == 0) - section_size = 1; - size_t header_count = ParseProgramHeaders(); - for (size_t i = 1; i <= header_count; ++i) { - auto header = GetProgramHeaderByIndex(i); - if (section_sp->GetFileOffset() >= header->p_offset && - section_sp->GetFileOffset() + section_size <= - header->p_offset + header->p_filesz) - return header; - } - return nullptr; -} - -addr_t ObjectFileELF::GetSectionPhysicalAddress(SectionSP section_sp) { - auto segment = GetSectionSegment(section_sp); - if (segment == nullptr) - return section_sp->GetFileAddress(); - if (segment->p_type != PT_LOAD) - return LLDB_INVALID_ADDRESS; - auto base_address = - AnySegmentHasPhysicalAddress() ? segment->p_paddr : segment->p_vaddr; - return base_address + (section_sp->GetFileOffset() - segment->p_offset); -} diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 3dda496ab62..2909f4e52e4 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -383,12 +383,6 @@ private: RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid); - - bool AnySegmentHasPhysicalAddress(); - - const elf::ELFProgramHeader *GetSectionSegment(lldb::SectionSP section_sp); - - lldb::addr_t GetSectionPhysicalAddress(lldb::SectionSP section_sp); }; #endif // liblldb_ObjectFileELF_h_ 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 diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp index ce8f04a9ff1..2129a4463cd 100644 --- a/lldb/source/Symbol/ObjectFile.cpp +++ b/lldb/source/Symbol/ObjectFile.cpp @@ -659,31 +659,22 @@ Status ObjectFile::LoadInMemory(Target &target, bool set_pc) { SectionList *section_list = GetSectionList(); if (!section_list) return Status("No section in object file"); - - std::vector<Process::WriteEntry> writeEntries; - - // Create a list of write entries from loadable sections size_t section_count = section_list->GetNumSections(0); for (size_t i = 0; i < section_count; ++i) { - Process::WriteEntry entry; SectionSP section_sp = section_list->GetSectionAtIndex(i); - entry.Dest = target.GetSectionLoadList().GetSectionLoadAddress(section_sp); - if (entry.Dest == LLDB_INVALID_ADDRESS) - continue; - // We can skip sections like bss - if (section_sp->GetFileSize() == 0) - continue; - DataExtractor section_data; - section_sp->GetSectionData(section_data); - entry.Contents = llvm::ArrayRef<uint8_t>(section_data.GetDataStart(), - section_data.GetByteSize()); - writeEntries.push_back(entry); + addr_t addr = target.GetSectionLoadList().GetSectionLoadAddress(section_sp); + if (addr != LLDB_INVALID_ADDRESS) { + DataExtractor section_data; + // We can skip sections like bss + if (section_sp->GetFileSize() == 0) + continue; + section_sp->GetSectionData(section_data); + lldb::offset_t written = process->WriteMemory( + addr, section_data.GetDataStart(), section_data.GetByteSize(), error); + if (written != section_data.GetByteSize()) + return error; + } } - - error = process->WriteObjectFile(std::move(writeEntries)); - if (!error.Success()) - return error; - if (set_pc) { ThreadList &thread_list = process->GetThreadList(); ThreadSP curr_thread(thread_list.GetSelectedThread()); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index d394b13696a..d54112ab5d8 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2533,17 +2533,6 @@ size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size, return 0; } -Status Process::WriteObjectFile(std::vector<WriteEntry> entries) { - Status error; - for (const auto &Entry : entries) { - WriteMemory(Entry.Dest, Entry.Contents.data(), Entry.Contents.size(), - error); - if (!error.Success()) - break; - } - return error; -} - #define USE_ALLOCATE_MEMORY_CACHE 1 addr_t Process::AllocateMemory(size_t size, uint32_t permissions, Status &error) { |