summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Host/XML.h3
-rw-r--r--lldb/include/lldb/Target/MemoryRegionInfo.h12
-rw-r--r--lldb/include/lldb/Target/Process.h7
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestGDBRemoteLoad.py61
-rw-r--r--lldb/source/Host/common/XML.cpp12
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp39
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp149
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h11
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp171
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h13
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp33
-rw-r--r--lldb/source/Target/Process.cpp11
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 &region) {
- 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(
- [&region](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 &region);
-
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) {
OpenPOWER on IntegriCloud