diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -335,6 +335,8 @@ lldb::Encoding GetEncoding(uint64_t &count) const; + lldb::ByteOrder GetByteOrder() const; + lldb::Format GetFormat() const; std::optional GetTypeBitAlign(ExecutionContextScope *exe_scope) const; diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -297,6 +297,8 @@ virtual lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) = 0; + virtual lldb::ByteOrder GetByteOrder(lldb::opaque_compiler_type_t type) = 0; + virtual lldb::Format GetFormat(lldb::opaque_compiler_type_t type) = 0; virtual uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1612,10 +1612,13 @@ /// \param[out] error /// An error value in case the memory write fails. /// + /// \param[in] byte_order + /// The byte order of destination type. /// \return /// The number of bytes that were actually written. virtual size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, - size_t size, Status &error) { + size_t size, Status &error, + lldb::ByteOrder byte_order = endian::InlHostByteOrder()) { error.SetErrorStringWithFormatv( "error: {0} does not support writing to processes", GetPluginName()); return 0; @@ -1651,7 +1654,8 @@ /// \return /// The number of bytes that were actually written. size_t WriteScalarToMemory(lldb::addr_t vm_addr, const Scalar &scalar, - size_t size, Status &error); + size_t size, Status &error, + lldb::ByteOrder byte_order = endian::InlHostByteOrder()); size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, @@ -1678,11 +1682,15 @@ /// \param[in] size /// The number of bytes to write. /// + /// \param[in] byte_order + /// The byte order of destination type. + /// /// \return /// The number of bytes that were actually written. // TODO: change this to take an ArrayRef size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - Status &error); + Status &error, + lldb::ByteOrder byte_order = endian::InlHostByteOrder()); /// Actually allocate memory in the process. /// @@ -3115,7 +3123,8 @@ const Timeout &timeout); size_t WriteMemoryPrivate(lldb::addr_t addr, const void *buf, size_t size, - Status &error); + Status &error, + lldb::ByteOrder byte_order = endian::InlHostByteOrder()); void AppendSTDOUT(const char *s, size_t len); diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -780,6 +780,8 @@ uint64_t count = 0; const Encoding encoding = GetCompilerType().GetEncoding(count); + const ByteOrder byte_order = GetCompilerType().GetByteOrder(); + const size_t byte_size = GetByteSize().value_or(0); @@ -807,7 +809,7 @@ if (process) { addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); size_t bytes_written = process->WriteMemory( - target_addr, data.GetDataStart(), byte_size, error); + target_addr, data.GetDataStart(), byte_size, error, byte_order); if (!error.Success()) return false; if (bytes_written != byte_size) { @@ -1473,6 +1475,7 @@ uint64_t count = 0; const Encoding encoding = GetCompilerType().GetEncoding(count); + const ByteOrder byte_order = GetCompilerType().GetByteOrder(); const size_t byte_size = GetByteSize().value_or(0); @@ -1499,7 +1502,7 @@ addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); size_t bytes_written = process->WriteScalarToMemory( - target_addr, new_scalar, byte_size, error); + target_addr, new_scalar, byte_size, error, byte_order); if (!error.Success()) return false; if (bytes_written != byte_size) { diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -142,7 +142,8 @@ WriteObjectFile(std::vector entries) override; size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, - Status &error) override; + Status &error, + lldb::ByteOrder byte_order = endian::InlHostByteOrder()) override; lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -2762,7 +2762,8 @@ } size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf, - size_t size, Status &error) { + size_t size, Status &error, + ByteOrder byte_order) { GetMaxMemorySize(); // M and m packets take 2 bytes for 1 byte of memory size_t max_memory_size = m_max_memory_size / 2; @@ -2798,7 +2799,7 @@ } else { packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size); packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(), - endian::InlHostByteOrder()); + byte_order); } StringExtractorGDBRemote response; if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response, diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -72,8 +72,9 @@ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) override; - size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - Status &error) override; + size_t DoWriteMemory( + lldb::addr_t vm_addr, const void *buf, size_t size, Status &error, + lldb::ByteOrder byte_order = endian::InlHostByteOrder()) override; Status EnableBreakpointSite(BreakpointSite *bp_site) override; diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -228,7 +228,8 @@ } size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, - size_t size, Status &error) { + size_t size, Status &error, + ByteOrder byte_order) { lldb::DataExtractorSP data_extractor_sp = std::make_shared( buf, size, GetByteOrder(), GetAddressByteSize()); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -817,6 +817,8 @@ lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override; + lldb::ByteOrder GetByteOrder(lldb::opaque_compiler_type_t type) override; + lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; std::optional diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -5122,6 +5122,10 @@ return lldb::eEncodingInvalid; } +lldb::ByteOrder TypeSystemClang::GetByteOrder(lldb::opaque_compiler_type_t type) { + return endian::InlHostByteOrder(); +} + lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) { if (!type) return lldb::eFormatDefault; diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -584,6 +584,13 @@ return lldb::eEncodingInvalid; } +lldb::ByteOrder CompilerType::GetByteOrder() const { + if (IsValid()) + if (auto type_system_sp = GetTypeSystem()) + return type_system_sp->GetByteOrder(m_type); + return endian::InlHostByteOrder(); +} + lldb::Format CompilerType::GetFormat() const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2111,14 +2111,14 @@ } size_t Process::WriteMemoryPrivate(addr_t addr, const void *buf, size_t size, - Status &error) { + Status &error, ByteOrder byte_order) { size_t bytes_written = 0; const uint8_t *bytes = (const uint8_t *)buf; while (bytes_written < size) { const size_t curr_size = size - bytes_written; const size_t curr_bytes_written = DoWriteMemory( - addr + bytes_written, bytes + bytes_written, curr_size, error); + addr + bytes_written, bytes + bytes_written, curr_size, error, byte_order); bytes_written += curr_bytes_written; if (curr_bytes_written == curr_size || curr_bytes_written == 0) break; @@ -2127,7 +2127,7 @@ } size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size, - Status &error) { + Status &error, ByteOrder byte_order) { if (ABISP abi_sp = GetABI()) addr = abi_sp->FixAnyAddress(addr); @@ -2146,17 +2146,17 @@ BreakpointSiteList bp_sites_in_range; if (!m_breakpoint_site_list.FindInRange(addr, addr + size, bp_sites_in_range)) - return WriteMemoryPrivate(addr, buf, size, error); + return WriteMemoryPrivate(addr, buf, size, error, byte_order); // No breakpoint sites overlap if (bp_sites_in_range.IsEmpty()) - return WriteMemoryPrivate(addr, buf, size, error); + return WriteMemoryPrivate(addr, buf, size, error, byte_order); const uint8_t *ubuf = (const uint8_t *)buf; uint64_t bytes_written = 0; bp_sites_in_range.ForEach([this, addr, size, &bytes_written, &ubuf, - &error](BreakpointSite *bp) -> void { + &error, byte_order](BreakpointSite *bp) -> void { if (error.Fail()) return; @@ -2182,7 +2182,7 @@ // write to memory size_t curr_size = intersect_addr - curr_addr; size_t curr_bytes_written = - WriteMemoryPrivate(curr_addr, ubuf + bytes_written, curr_size, error); + WriteMemoryPrivate(curr_addr, ubuf + bytes_written, curr_size, error, byte_order); bytes_written += curr_bytes_written; if (curr_bytes_written != curr_size) { // We weren't able to write all of the requested bytes, we are @@ -2203,13 +2203,14 @@ if (bytes_written < size) bytes_written += WriteMemoryPrivate(addr + bytes_written, ubuf + bytes_written, - size - bytes_written, error); + size - bytes_written, error, byte_order); return bytes_written; } size_t Process::WriteScalarToMemory(addr_t addr, const Scalar &scalar, - size_t byte_size, Status &error) { + size_t byte_size, Status &error, + ByteOrder byte_order) { if (byte_size == UINT32_MAX) byte_size = scalar.GetByteSize(); if (byte_size > 0) { @@ -2217,7 +2218,7 @@ const size_t mem_size = scalar.GetAsMemoryData(buf, byte_size, GetByteOrder(), error); if (mem_size > 0) - return WriteMemory(addr, buf, mem_size, error); + return WriteMemory(addr, buf, mem_size, error, byte_order); else error.SetErrorString("failed to get scalar as memory data"); } else {