diff options
Diffstat (limited to 'lldb/source')
29 files changed, 2026 insertions, 1725 deletions
diff --git a/lldb/source/Commands/CommandObjectRegister.cpp b/lldb/source/Commands/CommandObjectRegister.cpp index 45444065ac6..e1377bbe55e 100644 --- a/lldb/source/Commands/CommandObjectRegister.cpp +++ b/lldb/source/Commands/CommandObjectRegister.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/Debugger.h" #include "lldb/Interpreter/Args.h" @@ -77,26 +78,24 @@ public: { if (reg_info) { - uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + RegisterValue reg_value; - DataExtractor reg_data; - - if (reg_ctx->ReadRegisterBytes(reg, reg_data)) + if (reg_ctx->ReadRegister (reg_info, reg_value)) { strm.Indent (); - strm.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>"); Format format; if (m_options.format == eFormatDefault) format = reg_info->format; else format = m_options.format; - reg_data.Dump(&strm, 0, format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); + bool prefix_with_name = true; + reg_value.Dump(&strm, reg_info, prefix_with_name, m_options.format); if (((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) && (reg_info->byte_size == reg_ctx->GetThread().GetProcess().GetAddressByteSize())) { - addr_t reg_addr = reg_ctx->ReadRegisterAsUnsigned (reg, 0); - if (reg_addr) + addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); + if (reg_addr != LLDB_INVALID_ADDRESS) { Address so_reg_addr; if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) @@ -393,11 +392,12 @@ public: if (reg_info) { - Scalar scalar; - Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); + RegisterValue reg_value; + + Error error (reg_value.SetValueFromCString (reg_info, value_str)); if (error.Success()) { - if (reg_ctx->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar)) + if (reg_ctx->WriteRegister (reg_info, reg_value)) { result.SetStatus (eReturnStatusSuccessFinishNoResult); return true; diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp index 10a2029527d..9c07dc9c9fc 100644 --- a/lldb/source/Core/DataExtractor.cpp +++ b/lldb/source/Core/DataExtractor.cpp @@ -1035,6 +1035,116 @@ DataExtractor::GetData (uint32_t *offset_ptr, uint32_t length) const return bytes; } +// Extract data and swap if needed when doing the copy +uint32_t +DataExtractor::CopyByteOrderedData (uint32_t src_offset, + uint32_t src_len, + void *dst_void_ptr, + uint32_t dst_len, + ByteOrder dst_byte_order) const +{ + // Validate the source info + assert (ValidOffsetForDataOfSize(src_offset, src_len)); + assert (src_len > 0); + assert (m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle); + + // Validate the destination info + assert (dst_void_ptr != NULL); + assert (dst_len > 0); + assert (dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle); + + // Must have valid byte orders set in this object and for destination + if (!(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle) || + !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle)) + return 0; + + uint32_t i; + uint8_t* dst = (uint8_t*)dst_void_ptr; + const uint8_t* src = (const uint8_t *)PeekData (src_offset, src_len); + if (src) + { + if (src_len >= dst_len) + { + // We are copying the entire value from src into dst. + // Calculate how many, if any, zeroes we need for the most + // significant bytes if "dst_len" is greater than "src_len"... + const uint32_t num_zeroes = dst_len - src_len; + if (dst_byte_order == eByteOrderBig) + { + // Big endian, so we lead with zeroes... + if (num_zeroes > 0) + ::memset (dst, 0, num_zeroes); + // Then either copy or swap the rest + if (m_byte_order == eByteOrderBig) + { + ::memcpy (dst + num_zeroes, src, src_len); + } + else + { + for (i=0; i<src_len; ++i) + dst[i+num_zeroes] = src[src_len - 1 - i]; + } + } + else + { + // Little endian destination, so we lead the value bytes + if (m_byte_order == eByteOrderBig) + { + for (i=0; i<src_len; ++i) + dst[i] = src[src_len - 1 - i]; + } + else + { + ::memcpy (dst, src, src_len); + } + // And zero the rest... + if (num_zeroes > 0) + ::memset (dst + src_len, 0, num_zeroes); + } + return src_len; + } + else + { + // We are only copying some of the value from src into dst.. + + if (dst_byte_order == eByteOrderBig) + { + // Big endian dst + if (m_byte_order == eByteOrderBig) + { + // Big endian dst, with big endian src + ::memcpy (dst, src + (src_len - dst_len), dst_len); + } + else + { + // Big endian dst, with little endian src + for (i=0; i<dst_len; ++i) + dst[i] = src[dst_len - 1 - i]; + } + } + else + { + // Little endian dst + if (m_byte_order == eByteOrderBig) + { + // Little endian dst, with big endian src + for (i=0; i<dst_len; ++i) + dst[i] = src[src_len - 1 - i]; + } + else + { + // Little endian dst, with big endian src + ::memcpy (dst, src, dst_len); + } + } + return dst_len; + } + + } + return 0; +} + + //---------------------------------------------------------------------- // Extracts a AsCString (fixed length, or variable length) from // the data at the offset pointed to by "offset_ptr". If diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index f328c626fd1..7ae54bd38bd 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -11,6 +11,7 @@ #include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/InputReader.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" @@ -1088,10 +1089,11 @@ Debugger::FormatPrompt if (reg_info != NULL) { - DataExtractor reg_data; - var_success = reg_ctx->ReadRegisterBytes (reg_info->kinds[eRegisterKindLLDB], reg_data); + RegisterValue reg_value; + var_success = reg_ctx->ReadRegister (reg_info, reg_value); + if (var_success) { - reg_data.Dump(&s, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); + reg_value.Dump(&s, reg_info, false); } } diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index 7c28a5be6a3..995a82c30d4 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -782,10 +782,10 @@ bool Instruction::Emulate (const ArchSpec &arch, uint32_t evaluate_options, void *baton, - EmulateInstruction::ReadMemory read_mem_callback, - EmulateInstruction::WriteMemory write_mem_callback, - EmulateInstruction::ReadRegister read_reg_callback, - EmulateInstruction::WriteRegister write_reg_callback) + EmulateInstruction::ReadMemoryCallback read_mem_callback, + EmulateInstruction::WriteMemoryCallback write_mem_callback, + EmulateInstruction::ReadRegisterCallback read_reg_callback, + EmulateInstruction::WriteRegisterCallback write_reg_callback) { std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); if (insn_emulator_ap.get()) diff --git a/lldb/source/Core/EmulateInstruction.cpp b/lldb/source/Core/EmulateInstruction.cpp index 9ae9a1c1617..ac149e020ec 100644 --- a/lldb/source/Core/EmulateInstruction.cpp +++ b/lldb/source/Core/EmulateInstruction.cpp @@ -14,6 +14,8 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Error.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/UnwindPlan.h" @@ -64,42 +66,114 @@ EmulateInstruction::EmulateInstruction (const ArchSpec &arch) : } -uint64_t -EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr) +bool +EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value) +{ + if (m_read_reg_callback) + return m_read_reg_callback (this, m_baton, reg_info, reg_value); + return false; +} + +bool +EmulateInstruction::ReadRegister (uint32_t reg_kind, uint32_t reg_num, RegisterValue& reg_value) { RegisterInfo reg_info; if (GetRegisterInfo(reg_kind, reg_num, reg_info)) - return ReadRegisterUnsigned (reg_info, fail_value, success_ptr); + return ReadRegister (®_info, reg_value); + return false; +} + +uint64_t +EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, + uint32_t reg_num, + uint64_t fail_value, + bool *success_ptr) +{ + RegisterValue reg_value; + if (ReadRegister (reg_kind, reg_num, reg_value)) + return reg_value.GetAsUInt64(fail_value, success_ptr); if (success_ptr) *success_ptr = false; return fail_value; } uint64_t -EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo ®_info, uint64_t fail_value, bool *success_ptr) +EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info, + uint64_t fail_value, + bool *success_ptr) { - uint64_t uval64 = 0; - bool success = m_read_reg_callback (this, m_baton, reg_info, uval64); + RegisterValue reg_value; + if (ReadRegister (reg_info, reg_value)) + return reg_value.GetAsUInt64(fail_value, success_ptr); if (success_ptr) - *success_ptr = success; - if (!success) - uval64 = fail_value; - return uval64; + *success_ptr = false; + return fail_value; +} + +bool +EmulateInstruction::WriteRegister (const Context &context, + const RegisterInfo *reg_info, + const RegisterValue& reg_value) +{ + if (m_write_reg_callback) + return m_write_reg_callback (this, m_baton, context, reg_info, reg_value); + return false; +} + +bool +EmulateInstruction::WriteRegister (const Context &context, + uint32_t reg_kind, + uint32_t reg_num, + const RegisterValue& reg_value) +{ + RegisterInfo reg_info; + if (GetRegisterInfo(reg_kind, reg_num, reg_info)) + return WriteRegister (context, ®_info, reg_value); + return false; } + bool -EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value) +EmulateInstruction::WriteRegisterUnsigned (const Context &context, + uint32_t reg_kind, + uint32_t reg_num, + uint64_t uint_value) { + RegisterInfo reg_info; if (GetRegisterInfo(reg_kind, reg_num, reg_info)) - return WriteRegisterUnsigned (context, reg_info, reg_value); + { + RegisterValue reg_value; + if (reg_value.SetUInt(uint_value, reg_info.byte_size)) + return WriteRegister (context, ®_info, reg_value); + } return false; } bool -EmulateInstruction::WriteRegisterUnsigned (const Context &context, const RegisterInfo ®_info, uint64_t reg_value) +EmulateInstruction::WriteRegisterUnsigned (const Context &context, + const RegisterInfo *reg_info, + uint64_t uint_value) +{ + + if (reg_info) + { + RegisterValue reg_value; + if (reg_value.SetUInt(uint_value, reg_info->byte_size)) + return WriteRegister (context, reg_info, reg_value); + } + return false; +} + +size_t +EmulateInstruction::ReadMemory (const Context &context, + lldb::addr_t addr, + void *dst, + size_t dst_len) { - return m_write_reg_callback (this, m_baton, context, reg_info, reg_value); + if (m_read_mem_callback) + return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len; + return false; } uint64_t @@ -144,6 +218,17 @@ EmulateInstruction::WriteMemoryUnsigned (const Context &context, return false; } +bool +EmulateInstruction::WriteMemory (const Context &context, + lldb::addr_t addr, + const void *src, + size_t src_len) +{ + if (m_write_mem_callback) + return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len; + return false; +} + void EmulateInstruction::SetBaton (void *baton) @@ -152,10 +237,10 @@ EmulateInstruction::SetBaton (void *baton) } void -EmulateInstruction::SetCallbacks (ReadMemory read_mem_callback, - WriteMemory write_mem_callback, - ReadRegister read_reg_callback, - WriteRegister write_reg_callback) +EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback, + WriteMemoryCallback write_mem_callback, + ReadRegisterCallback read_reg_callback, + WriteRegisterCallback write_reg_callback) { m_read_mem_callback = read_mem_callback; m_write_mem_callback = write_mem_callback; @@ -164,28 +249,28 @@ EmulateInstruction::SetCallbacks (ReadMemory read_mem_callback, } void -EmulateInstruction::SetReadMemCallback (ReadMemory read_mem_callback) +EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback) { m_read_mem_callback = read_mem_callback; } void -EmulateInstruction::SetWriteMemCallback (WriteMemory write_mem_callback) +EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback) { m_write_mem_callback = write_mem_callback; } void -EmulateInstruction::SetReadRegCallback (ReadRegister read_reg_callback) +EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback) { m_read_reg_callback = read_reg_callback; } void -EmulateInstruction::SetWriteRegCallback (WriteRegister write_reg_callback) +EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback) { m_write_reg_callback = write_reg_callback; } @@ -255,46 +340,28 @@ EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction, bool EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction, void *baton, - const RegisterInfo ®_info, - uint64_t ®_value) + const RegisterInfo *reg_info, + RegisterValue ®_value) { if (!baton) return false; StackFrame *frame = (StackFrame *) baton; - RegisterContext *reg_ctx = frame->GetRegisterContext().get(); - Scalar value; - - const uint32_t internal_reg_num = GetInternalRegisterNumber (reg_ctx, reg_info); - - if (internal_reg_num != LLDB_INVALID_REGNUM) - { - if (reg_ctx->ReadRegisterValue (internal_reg_num, value)) - { - reg_value = value.GetRawBits64 (0); - return true; - } - } - return false; + return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value); } bool EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction, void *baton, const Context &context, - const RegisterInfo ®_info, - uint64_t reg_value) + const RegisterInfo *reg_info, + const RegisterValue ®_value) { if (!baton) return false; StackFrame *frame = (StackFrame *) baton; - RegisterContext *reg_ctx = frame->GetRegisterContext().get(); - Scalar value (reg_value); - const uint32_t internal_reg_num = GetInternalRegisterNumber (reg_ctx, reg_info); - if (internal_reg_num != LLDB_INVALID_REGNUM) - return reg_ctx->WriteRegisterValue (internal_reg_num, value); - return false; + return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value); } size_t @@ -327,15 +394,15 @@ EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction, bool EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction, void *baton, - const RegisterInfo ®_info, - uint64_t ®_value) + const RegisterInfo *reg_info, + RegisterValue ®_value) { - fprintf (stdout, " Read Register (%s)\n", reg_info.name); + fprintf (stdout, " Read Register (%s)\n", reg_info->name); uint32_t reg_kind, reg_num; if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num)) - reg_value = (uint64_t)reg_kind << 24 | reg_num; + reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num); else - reg_value = 0; + reg_value.SetUInt64(0); return true; } @@ -344,10 +411,13 @@ bool EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction, void *baton, const Context &context, - const RegisterInfo ®_info, - uint64_t reg_value) + const RegisterInfo *reg_info, + const RegisterValue ®_value) { - fprintf (stdout, " Write to Register (name = %s, value = 0x%llx, context = ", reg_info.name, reg_value); + StreamFile strm (stdout, false); + strm.Printf (" Write to Register (name = %s, value = " , reg_info->name); + reg_value.Dump(&strm, reg_info, false); + strm.PutCString (", context = "); context.Dump (stdout, instruction); return true; } @@ -548,41 +618,41 @@ EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_ad } bool -EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo ®_info, +EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, uint32_t ®_kind, uint32_t ®_num) { // Generic and DWARF should be the two most popular register kinds when // emulating instructions since they are the most platform agnostic... - reg_num = reg_info.kinds[eRegisterKindGeneric]; + reg_num = reg_info->kinds[eRegisterKindGeneric]; if (reg_num != LLDB_INVALID_REGNUM) { reg_kind = eRegisterKindGeneric; return true; } - reg_num = reg_info.kinds[eRegisterKindDWARF]; + reg_num = reg_info->kinds[eRegisterKindDWARF]; if (reg_num != LLDB_INVALID_REGNUM) { reg_kind = eRegisterKindDWARF; return true; } - reg_num = reg_info.kinds[eRegisterKindLLDB]; + reg_num = reg_info->kinds[eRegisterKindLLDB]; if (reg_num != LLDB_INVALID_REGNUM) { reg_kind = eRegisterKindLLDB; return true; } - reg_num = reg_info.kinds[eRegisterKindGCC]; + reg_num = reg_info->kinds[eRegisterKindGCC]; if (reg_num != LLDB_INVALID_REGNUM) { reg_kind = eRegisterKindGCC; return true; } - reg_num = reg_info.kinds[eRegisterKindGDB]; + reg_num = reg_info->kinds[eRegisterKindGDB]; if (reg_num != LLDB_INVALID_REGNUM) { reg_kind = eRegisterKindGDB; @@ -595,7 +665,7 @@ uint32_t EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo ®_info) { uint32_t reg_kind, reg_num; - if (reg_ctx && GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num)) + if (reg_ctx && GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num)) return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num); return LLDB_INVALID_REGNUM; } diff --git a/lldb/source/Core/RegisterValue.cpp b/lldb/source/Core/RegisterValue.cpp new file mode 100644 index 00000000000..bc66a8c2185 --- /dev/null +++ b/lldb/source/Core/RegisterValue.cpp @@ -0,0 +1,896 @@ +//===-- RegisterValue.cpp ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/RegisterValue.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Core/Stream.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + + +bool +RegisterValue::Dump (Stream *s, const RegisterInfo *reg_info, bool prefix_with_name, Format format) const +{ + DataExtractor data; + if (GetData (data)) + { + if (prefix_with_name && reg_info->name != NULL) + s->Printf ("%s = ", reg_info->name); + if (format == eFormatDefault) + format = reg_info->format; + + data.Dump (s, + 0, // Offset in "data" + format, // Format to use when dumping + reg_info->byte_size, // item_byte_size + 1, // item_count + UINT32_MAX, // num_per_line + LLDB_INVALID_ADDRESS, // base_addr + 0, // item_bit_size + 0); // item_bit_offset + return true; + } + return false; +} + + +bool +RegisterValue::GetData (DataExtractor &data) const +{ + return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0; +} + + +uint32_t +RegisterValue::GetAsMemoryData (const RegisterInfo *reg_info, + void *dst, + uint32_t dst_len, + lldb::ByteOrder dst_byte_order, + Error &error) const +{ + if (reg_info == NULL) + { + error.SetErrorString ("invalid register info argument."); + return 0; + } + + // ReadRegister should have already been called on tgus object prior to + // calling this. + if (GetType() == eTypeInvalid) + { + // No value has been read into this object... + error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name); + return 0; + } + + if (dst_len > kMaxRegisterByteSize) + { + error.SetErrorString ("destination is too big"); + return 0; + } + + const uint32_t src_len = reg_info->byte_size; + + // Extract the register data into a data extractor + DataExtractor reg_data; + if (!GetData(reg_data)) + { + error.SetErrorString ("invalid register value to copy into"); + return 0; + } + + // Prepare a memory buffer that contains some or all of the register value + const uint32_t bytes_copied = reg_data.CopyByteOrderedData (0, // src offset + src_len, // src length + dst, // dst buffer + dst_len, // dst length + dst_byte_order); // dst byte order + if (bytes_copied == 0) + error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name); + + return bytes_copied; +} + +uint32_t +RegisterValue::SetFromMemoryData (const RegisterInfo *reg_info, + const void *src, + uint32_t src_len, + lldb::ByteOrder src_byte_order, + Error &error) +{ + if (reg_info == NULL) + { + error.SetErrorString ("invalid register info argument."); + return 0; + } + + // Moving from addr into a register + // + // Case 1: src_len == dst_len + // + // |AABBCCDD| Address contents + // |AABBCCDD| Register contents + // + // Case 2: src_len > dst_len + // + // Error! (The register should always be big enough to hold the data) + // + // Case 3: src_len < dst_len + // + // |AABB| Address contents + // |AABB0000| Register contents [on little-endian hardware] + // |0000AABB| Register contents [on big-endian hardware] + if (src_len > kMaxRegisterByteSize) + { + error.SetErrorStringWithFormat ("register buffer is too small to receive %u bytes of data.", src_len); + return 0; + } + + const uint32_t dst_len = reg_info->byte_size; + + if (src_len > dst_len) + { + error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len); + return 0; + } + + // Use a data extractor to correctly copy and pad the bytes read into the + // register value + DataExtractor src_data (src, src_len, src_byte_order, 4); + + // Given the register info, set the value type of this RegisterValue object + SetType (reg_info); + // And make sure we were able to figure out what that register value was + RegisterValue::Type value_type = GetType(); + if (value_type == eTypeInvalid) + { + // No value has been read into this object... + error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name); + return 0; + } + else if (value_type == eTypeBytes) + { + m_data.buffer.byte_order = src_byte_order; + } + + const uint32_t bytes_copied = src_data.CopyByteOrderedData (0, // src offset + src_len, // src length + GetBytes(), // dst buffer + GetByteSize(), // dst length + GetByteOrder()); // dst byte order + if (bytes_copied == 0) + error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name); + + return bytes_copied; +} + +bool +RegisterValue::GetScalarValue (Scalar &scalar) const +{ + switch (m_type) + { + case eTypeInvalid: break; + case eTypeBytes: break; + case eTypeUInt8: scalar = m_data.uint8; return true; + case eTypeUInt16: scalar = m_data.uint16; return true; + case eTypeUInt32: scalar = m_data.uint32; return true; + case eTypeUInt64: scalar = m_data.uint64; return true; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: break; +#endif + case eTypeFloat: scalar = m_data.ieee_float; return true; + case eTypeDouble: scalar = m_data.ieee_double; return true; + case eTypeLongDouble: scalar = m_data.ieee_long_double; return true; + } + return false; +} + +void +RegisterValue::Clear() +{ + m_type = eTypeInvalid; +} + +RegisterValue::Type +RegisterValue::SetType (const RegisterInfo *reg_info) +{ + m_type = eTypeInvalid; + const uint32_t byte_size = reg_info->byte_size; + switch (reg_info->encoding) + { + case eEncodingInvalid: + break; + + case eEncodingUint: + case eEncodingSint: + if (byte_size == 1) + m_type = eTypeUInt8; + else if (byte_size <= 2) + m_type = eTypeUInt16; + else if (byte_size <= 4) + m_type = eTypeUInt32; + else if (byte_size <= 8) + m_type = eTypeUInt64; +#if defined (ENABLE_128_BIT_SUPPORT) + else if (byte_size <= 16) + m_type = eTypeUInt128; +#endif + break; + + case eEncodingIEEE754: + if (byte_size == sizeof(float)) + m_type = eTypeFloat; + if (byte_size == sizeof(double)) + m_type = eTypeDouble; + if (byte_size == sizeof(long double)) + m_type = eTypeLongDouble; + break; + + case eEncodingVector: + m_type = eTypeBytes; + break; + } + return m_type; +} + +Error +RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, uint32_t src_offset, bool partial_data_ok) +{ + Error error; + + if (src.GetByteSize() == 0) + { + error.SetErrorString ("empty data."); + return error; + } + + if (reg_info->byte_size == 0) + { + error.SetErrorString ("invalid register info."); + return error; + } + + uint32_t src_len = src.GetByteSize() - src_offset; + + if (!partial_data_ok && (src_len < reg_info->byte_size)) + { + error.SetErrorString ("not enough data."); + return error; + } + + // Cap the data length if there is more than enough bytes for this register + // value + if (src_len > reg_info->byte_size) + src_len = reg_info->byte_size; + + // Zero out the value in case we get partial data... + memset (m_data.buffer.bytes, 0, sizeof (m_data.buffer.bytes)); + + switch (SetType (reg_info)) + { + case eTypeInvalid: + error.SetErrorString(""); + break; + case eTypeUInt8: SetUInt8 (src.GetMaxU32 (&src_offset, src_len)); break; + case eTypeUInt16: SetUInt16 (src.GetMaxU32 (&src_offset, src_len)); break; + case eTypeUInt32: SetUInt32 (src.GetMaxU32 (&src_offset, src_len)); break; + case eTypeUInt64: SetUInt64 (src.GetMaxU64 (&src_offset, src_len)); break; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: + { + __uint128_t data1 = src.GetU64 (&src_offset); + __uint128_t data2 = src.GetU64 (&src_offset); + if (src.GetByteSize() == eByteOrderBig) + SetUInt128 (data1 << 64 + data2); + else + SetUInt128 (data2 << 64 + data1); + } + break; +#endif + case eTypeFloat: SetFloat (src.GetFloat (&src_offset)); break; + case eTypeDouble: SetDouble(src.GetDouble (&src_offset)); break; + case eTypeLongDouble: SetFloat (src.GetLongDouble (&src_offset)); break; + case eTypeBytes: + { + m_data.buffer.length = reg_info->byte_size; + m_data.buffer.byte_order = src.GetByteOrder(); + assert (m_data.buffer.length <= kMaxRegisterByteSize); + if (m_data.buffer.length > kMaxRegisterByteSize) + m_data.buffer.length = kMaxRegisterByteSize; + if (src.CopyByteOrderedData (src_offset, // offset within "src" to start extracting data + src_len, // src length + m_data.buffer.bytes, // dst buffer + m_data.buffer.length, // dst length + m_data.buffer.byte_order) == 0)// dst byte order + { + error.SetErrorString ("data copy failed data."); + return error; + } + } + } + + return error; +} + +Error +RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *value_str) +{ + Error error; + if (reg_info == NULL) + { + error.SetErrorString ("Invalid register info argument."); + return error; + } + + if (value_str == NULL && value_str[0] == '\0') + { + error.SetErrorString ("Invalid c-string value string."); + return error; + } + bool success = false; + const uint32_t byte_size = reg_info->byte_size; + switch (reg_info->encoding) + { + default: + case eEncodingInvalid: + error.SetErrorString ("Invalid encoding."); + break; + + case eEncodingUint: + if (byte_size <= sizeof (uint64_t)) + { + uint64_t uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success); + if (!success) + error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value.\n", value_str); + else if (!Args::UInt64ValueIsValidForByteSize (uval64, byte_size)) + error.SetErrorStringWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, byte_size); + else + { + if (!SetUInt (uval64, reg_info->byte_size)) + error.SetErrorStringWithFormat ("Unsupported unsigned integer byte size: %u.\n", byte_size); + } + } + else + { + error.SetErrorStringWithFormat ("Unsupported unsigned integer byte size: %u.\n", byte_size); + return error; + } + break; + + case eEncodingSint: + if (byte_size <= sizeof (long long)) + { + uint64_t sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success); + if (!success) + error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value.\n", value_str); + else if (!Args::SInt64ValueIsValidForByteSize (sval64, byte_size)) + error.SetErrorStringWithFormat ("Value 0x%llx is too large to fit in a %u byte signed integer value.\n", sval64, byte_size); + else + { + if (!SetUInt (sval64, reg_info->byte_size)) + error.SetErrorStringWithFormat ("Unsupported signed integer byte size: %u.\n", byte_size); + } + } + else + { + error.SetErrorStringWithFormat ("Unsupported signed integer byte size: %u.\n", byte_size); + return error; + } + break; + + case eEncodingIEEE754: + if (byte_size == sizeof (float)) + { + if (::sscanf (value_str, "%f", &m_data.ieee_float) == 1) + m_type = eTypeFloat; + else + error.SetErrorStringWithFormat ("'%s' is not a valid float string value.\n", value_str); + } + else if (byte_size == sizeof (double)) + { + if (::sscanf (value_str, "%lf", &m_data.ieee_double) == 1) + m_type = eTypeDouble; + else + error.SetErrorStringWithFormat ("'%s' is not a valid float string value.\n", value_str); + } + else if (byte_size == sizeof (long double)) + { + if (::sscanf (value_str, "%Lf", &m_data.ieee_long_double) == 1) + m_type = eTypeLongDouble; + else + error.SetErrorStringWithFormat ("'%s' is not a valid float string value.\n", value_str); + } + else + { + error.SetErrorStringWithFormat ("Unsupported float byte size: %u.\n", byte_size); + return error; + } + break; + + case eEncodingVector: + error.SetErrorString ("Vector encoding unsupported."); + break; + } + if (error.Fail()) + m_type = eTypeInvalid; + + return error; +} + + +bool +RegisterValue::SignExtend (uint32_t sign_bitpos) +{ + switch (m_type) + { + case eTypeInvalid: + break; + + case eTypeUInt8: + if (sign_bitpos == (8-1)) + return true; + else if (sign_bitpos < (8-1)) + { + uint8_t sign_bit = 1u << sign_bitpos; + if (m_data.uint8 & sign_bit) + { + const uint8_t mask = ~(sign_bit) + 1u; + m_data.uint8 |= mask; + } + return true; + } + break; + + case eTypeUInt16: + if (sign_bitpos == (16-1)) + return true; + else if (sign_bitpos < (16-1)) + { + uint16_t sign_bit = 1u << sign_bitpos; + if (m_data.uint16 & sign_bit) + { + const uint16_t mask = ~(sign_bit) + 1u; + m_data.uint16 |= mask; + } + return true; + } + break; + + case eTypeUInt32: + if (sign_bitpos == (32-1)) + return true; + else if (sign_bitpos < (32-1)) + { + uint32_t sign_bit = 1u << sign_bitpos; + if (m_data.uint32 & sign_bit) + { + const uint32_t mask = ~(sign_bit) + 1u; + m_data.uint32 |= mask; + } + return true; + } + break; + + case eTypeUInt64: + if (sign_bitpos == (64-1)) + return true; + else if (sign_bitpos < (64-1)) + { + uint64_t sign_bit = 1ull << sign_bitpos; + if (m_data.uint64 & sign_bit) + { + const uint64_t mask = ~(sign_bit) + 1ull; + m_data.uint64 |= mask; + } + return true; + } + break; + +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: + if (sign_bitpos == (128-1)) + return true; + else if (sign_bitpos < (128-1)) + { + __uint128_t sign_bit = (__uint128_t)1u << sign_bitpos; + if (m_data.uint128 & sign_bit) + { + const uint128_t mask = ~(sign_bit) + 1u; + m_data.uint128 |= mask; + } + return true; + } + break; +#endif + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: + case eTypeBytes: + break; + } + return false; +} + +bool +RegisterValue::CopyValue (const RegisterValue &rhs) +{ + m_type = rhs.m_type; + switch (m_type) + { + default: + case eTypeInvalid: + return false; + case eTypeUInt8: m_data.uint8 = rhs.m_data.uint8; break; + case eTypeUInt16: m_data.uint16 = rhs.m_data.uint16; break; + case eTypeUInt32: m_data.uint32 = rhs.m_data.uint32; break; + case eTypeUInt64: m_data.uint64 = rhs.m_data.uint64; break; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: m_data.uint128 = rhs.m_data.uint128; break; +#endif + case eTypeFloat: m_data.ieee_float = rhs.m_data.ieee_float; break; + case eTypeDouble: m_data.ieee_double = rhs.m_data.ieee_double; break; + case eTypeLongDouble: m_data.ieee_long_double = rhs.m_data.ieee_long_double; break; + case eTypeBytes: + assert (rhs.m_data.buffer.length <= kMaxRegisterByteSize); + ::memcpy (m_data.buffer.bytes, rhs.m_data.buffer.bytes, kMaxRegisterByteSize); + m_data.buffer.length = rhs.m_data.buffer.length; + m_data.buffer.byte_order = rhs.m_data.buffer.byte_order; + break; + } + return true; +} + +uint16_t +RegisterValue::GetAsUInt16 (uint16_t fail_value, bool *success_ptr) const +{ + if (success_ptr) + *success_ptr = true; + + switch (m_type) + { + default: break; + case eTypeUInt8: return m_data.uint8; + case eTypeUInt16: return m_data.uint16; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +uint32_t +RegisterValue::GetAsUInt32 (uint32_t fail_value, bool *success_ptr) const +{ + if (success_ptr) + *success_ptr = true; + switch (m_type) + { + default: break; + case eTypeUInt8: return m_data.uint8; + case eTypeUInt16: return m_data.uint16; + case eTypeUInt32: return m_data.uint32; + case eTypeFloat: + if (sizeof(float) == sizeof(uint32_t)) + return m_data.uint32; + break; + case eTypeDouble: + if (sizeof(double) == sizeof(uint32_t)) + return m_data.uint32; + break; + case eTypeLongDouble: + if (sizeof(long double) == sizeof(uint32_t)) + return m_data.uint32; + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +uint64_t +RegisterValue::GetAsUInt64 (uint64_t fail_value, bool *success_ptr) const +{ + if (success_ptr) + *success_ptr = true; + switch (m_type) + { + default: break; + case eTypeUInt8: return m_data.uint8; + case eTypeUInt16: return m_data.uint16; + case eTypeUInt32: return m_data.uint32; + case eTypeUInt64: return m_data.uint64; + case eTypeFloat: + if (sizeof(float) == sizeof(uint64_t)) + return m_data.uint64; + break; + case eTypeDouble: + if (sizeof(double) == sizeof(uint64_t)) + return m_data.uint64; + break; + case eTypeLongDouble: + if (sizeof(long double) == sizeof(uint64_t)) + return m_data.uint64; + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +#if defined (ENABLE_128_BIT_SUPPORT) +__uint128_t +RegisterValue::GetAsUInt128 (__uint128_t fail_value, bool *success_ptr) const +{ + if (success_ptr) + *success_ptr = true; + switch (m_type) + { + default: break; + case eTypeUInt8: return m_data.uint8; + case eTypeUInt16: return m_data.uint16; + case eTypeUInt32: return m_data.uint32; + case eTypeUInt64: return m_data.uint64; + case eTypeUInt128: return m_data.uint128; + case eTypeFloat: + if (sizeof(float) == sizeof(__uint128_t)) + return m_data.uint128; + break; + case eTypeDouble: + if (sizeof(double) == sizeof(__uint128_t)) + return m_data.uint128; + break; + case eTypeLongDouble: + if (sizeof(long double) == sizeof(__uint128_t)) + return m_data.uint128; + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} +#endif +float +RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const +{ + if (success_ptr) + *success_ptr = true; + switch (m_type) + { + default: break; + case eTypeUInt32: + if (sizeof(float) == sizeof(m_data.uint32)) + return m_data.ieee_float; + break; + case eTypeUInt64: + if (sizeof(float) == sizeof(m_data.uint64)) + return m_data.ieee_float; + break; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: + if (sizeof(float) == sizeof(m_data.uint128)) + return m_data.ieee_float; + break; +#endif + case eTypeFloat: return m_data.ieee_float; + case eTypeDouble: + if (sizeof(float) == sizeof(double)) + return m_data.ieee_float; + break; + case eTypeLongDouble: + if (sizeof(float) == sizeof(long double)) + return m_data.ieee_float; + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +double +RegisterValue::GetAsDouble (double fail_value, bool *success_ptr) const +{ + if (success_ptr) + *success_ptr = true; + switch (m_type) + { + default: + break; + + case eTypeUInt32: + if (sizeof(double) == sizeof(m_data.uint32)) + return m_data.ieee_double; + break; + + case eTypeUInt64: + if (sizeof(double) == sizeof(m_data.uint64)) + return m_data.ieee_double; + break; + +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: + if (sizeof(double) == sizeof(m_data.uint128)) + return m_data.ieee_double; +#endif + case eTypeFloat: return m_data.ieee_float; + case eTypeDouble: return m_data.ieee_double; + + case eTypeLongDouble: + if (sizeof(double) == sizeof(long double)) + return m_data.ieee_double; + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +long double +RegisterValue::GetAsLongDouble (long double fail_value, bool *success_ptr) const +{ + if (success_ptr) + *success_ptr = true; + switch (m_type) + { + default: + break; + + case eTypeUInt32: + if (sizeof(long double) == sizeof(m_data.uint32)) + return m_data.ieee_long_double; + break; + + case eTypeUInt64: + if (sizeof(long double) == sizeof(m_data.uint64)) + return m_data.ieee_long_double; + break; + +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: + if (sizeof(long double) == sizeof(m_data.uint128)) + return m_data.ieee_long_double; +#endif + case eTypeFloat: return m_data.ieee_float; + case eTypeDouble: return m_data.ieee_double; + case eTypeLongDouble: return m_data.ieee_long_double; + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + +const void * +RegisterValue::GetBytes () const +{ + switch (m_type) + { + case eTypeInvalid: break; + case eTypeUInt8: return &m_data.uint8; + case eTypeUInt16: return &m_data.uint16; + case eTypeUInt32: return &m_data.uint32; + case eTypeUInt64: return &m_data.uint64; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: return &m_data.uint128; +#endif + case eTypeFloat: return &m_data.ieee_float; + case eTypeDouble: return &m_data.ieee_double; + case eTypeLongDouble: return &m_data.ieee_long_double; + case eTypeBytes: return m_data.buffer.bytes; + } + return NULL; +} + +void * +RegisterValue::GetBytes () +{ + switch (m_type) + { + case eTypeInvalid: break; + case eTypeUInt8: return &m_data.uint8; + case eTypeUInt16: return &m_data.uint16; + case eTypeUInt32: return &m_data.uint32; + case eTypeUInt64: return &m_data.uint64; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: return &m_data.uint128; +#endif + case eTypeFloat: return &m_data.ieee_float; + case eTypeDouble: return &m_data.ieee_double; + case eTypeLongDouble: return &m_data.ieee_long_double; + case eTypeBytes: return m_data.buffer.bytes; + } + return NULL; +} + +uint32_t +RegisterValue::GetByteSize () const +{ + switch (m_type) + { + case eTypeInvalid: break; + case eTypeUInt8: return sizeof(m_data.uint8); + case eTypeUInt16: return sizeof(m_data.uint16); + case eTypeUInt32: return sizeof(m_data.uint32); + case eTypeUInt64: return sizeof(m_data.uint64); +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: return sizeof(m_data.uint128); +#endif + case eTypeFloat: return sizeof(m_data.ieee_float); + case eTypeDouble: return sizeof(m_data.ieee_double); + case eTypeLongDouble: return sizeof(m_data.ieee_long_double); + case eTypeBytes: return m_data.buffer.length; + } + return 0; +} + + +bool +RegisterValue::SetUInt (uint64_t uint, uint32_t byte_size) +{ + if (byte_size == 0) + { + SetUInt64 (uint); + } + else if (byte_size == 1) + { + SetUInt8 (uint); + } + else if (byte_size <= 2) + { + SetUInt16 (uint); + } + else if (byte_size <= 4) + { + SetUInt32 (uint); + } + else if (byte_size <= 8) + { + SetUInt64 (uint); + } +#if defined (ENABLE_128_BIT_SUPPORT) + else if (byte_size <= 16) + { + SetUInt128 (uint); + } +#endif + else + return false; + return true; +} + +void +RegisterValue::SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order) +{ + // If this assertion fires off we need to increase the size of + // m_data.buffer.bytes, or make it something that is allocated on + // the heap. Since the data buffer is in a union, we can't make it + // a collection class like SmallVector... + assert (length <= sizeof (m_data.buffer.bytes)); + if (bytes && length > 0) + { + m_type = eTypeBytes; + m_data.buffer.length = length; + assert (length < sizeof (m_data.buffer.bytes)); + memcpy (m_data.buffer.bytes, bytes, length); + m_data.buffer.byte_order = byte_order; + } + else + { + m_type = eTypeInvalid; + m_data.buffer.length = 0; + } +} + diff --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp index df80ce3ff29..bcefc3064d7 100644 --- a/lldb/source/Core/ValueObjectRegister.cpp +++ b/lldb/source/Core/ValueObjectRegister.cpp @@ -252,28 +252,29 @@ ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name) #pragma mark ValueObjectRegister void -ValueObjectRegister::ConstructObject () +ValueObjectRegister::ConstructObject (uint32_t reg_num) { - m_reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_num); - if (m_reg_info) + const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num); + if (reg_info) { - if (m_reg_info->name) - m_name.SetCString(m_reg_info->name); - else if (m_reg_info->alt_name) - m_name.SetCString(m_reg_info->alt_name); + m_reg_info = *reg_info; + if (reg_info->name) + m_name.SetCString(reg_info->name); + else if (reg_info->alt_name) + m_name.SetCString(reg_info->alt_name); } } -ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP ®_ctx, uint32_t reg_num) : +ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num) : ValueObject (parent), - m_reg_ctx_sp (reg_ctx), - m_reg_info (NULL), - m_reg_num (reg_num), + m_reg_ctx_sp (reg_ctx_sp), + m_reg_info (), + m_reg_value (), m_type_name (), m_clang_type (NULL) { - assert (reg_ctx); - ConstructObject(); + assert (reg_ctx_sp.get()); + ConstructObject(reg_num); } ValueObjectSP @@ -285,13 +286,13 @@ ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterCon ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx, uint32_t reg_num) : ValueObject (exe_scope), m_reg_ctx_sp (reg_ctx), - m_reg_info (NULL), - m_reg_num (reg_num), + m_reg_info (), + m_reg_value (), m_type_name (), m_clang_type (NULL) { assert (reg_ctx); - ConstructObject(); + ConstructObject(reg_num); } ValueObjectRegister::~ValueObjectRegister() @@ -301,7 +302,7 @@ ValueObjectRegister::~ValueObjectRegister() lldb::clang_type_t ValueObjectRegister::GetClangType () { - if (m_clang_type == NULL && m_reg_info) + if (m_clang_type == NULL) { Process *process = m_reg_ctx_sp->CalculateProcess (); if (process) @@ -309,7 +310,8 @@ ValueObjectRegister::GetClangType () Module *exe_module = process->GetTarget().GetExecutableModule ().get(); if (exe_module) { - m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info->encoding, m_reg_info->byte_size * 8); + m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding, + m_reg_info.byte_size * 8); } } } @@ -346,7 +348,7 @@ ValueObjectRegister::GetClangAST () size_t ValueObjectRegister::GetByteSize() { - return m_reg_info->byte_size; + return m_reg_info.byte_size; } bool @@ -355,41 +357,26 @@ ValueObjectRegister::UpdateValue () m_error.Clear(); ExecutionContextScope *exe_scope = GetExecutionContextScope(); StackFrame *frame = exe_scope->CalculateStackFrame(); - if (frame) - { - m_reg_ctx_sp = frame->GetRegisterContext(); - if (m_reg_ctx_sp) - { - const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_num); - if (m_reg_info != reg_info) - { - m_reg_info = reg_info; - if (m_reg_info) - { - if (m_reg_info->name) - m_name.SetCString(m_reg_info->name); - else if (m_reg_info->alt_name) - m_name.SetCString(m_reg_info->alt_name); - } - } - } - } - else + if (frame == NULL) { m_reg_ctx_sp.reset(); - m_reg_info = NULL; + m_reg_value.Clear(); } - if (m_reg_ctx_sp && m_reg_info) + if (m_reg_ctx_sp) { - if (m_reg_ctx_sp->ReadRegisterBytes (m_reg_num, m_data)) + if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value)) { - m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)m_reg_info); - m_value.SetValueType(Value::eValueTypeHostAddress); - m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); - SetValueIsValid (true); - return true; + if (m_reg_value.GetData (m_data)) + { + m_data.SetAddressByteSize(m_reg_ctx_sp->GetThread().GetProcess().GetAddressByteSize()); + m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info); + m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); + SetValueIsValid (true); + return true; + } } } diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index fa69e49e44d..3540a4d0783 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -20,6 +20,7 @@ #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Expression/ASTDumper.h" #include "lldb/Expression/ClangASTSource.h" @@ -686,25 +687,25 @@ ClangExpressionDeclMap::GetObjectPointer return false; } - RegisterInfo *register_info = location_value->GetRegisterInfo(); + RegisterInfo *reg_info = location_value->GetRegisterInfo(); - if (!register_info) + if (!reg_info) { err.SetErrorStringWithFormat("Couldn't get the register information for %s", object_name.GetCString()); return false; } - RegisterContext *register_context = exe_ctx.GetRegisterContext(); + RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); - if (!register_context) + if (!reg_ctx) { - err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", object_name.GetCString(), register_info->name); + err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", object_name.GetCString(), reg_info->name); return false; } - uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB]; + uint32_t register_number = reg_info->kinds[lldb::eRegisterKindLLDB]; - object_ptr = register_context->ReadRegisterAsUnsigned(register_number, 0x0); + object_ptr = reg_ctx->ReadRegisterAsUnsigned(register_number, 0x0); return true; } @@ -1328,26 +1329,27 @@ ClangExpressionDeclMap::DoMaterializeOneVariable return false; } - lldb::addr_t mem; // The address of a spare memory area aused to hold the variable. + lldb::addr_t reg_addr = LLDB_INVALID_ADDRESS; // The address of a spare memory area aused to hold the variable. - RegisterInfo *register_info = location_value->GetRegisterInfo(); + RegisterInfo *reg_info = location_value->GetRegisterInfo(); - if (!register_info) + if (!reg_info) { err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString()); return false; } - - RegisterContext *register_context = exe_ctx.GetRegisterContext(); - if (!register_context) + RegisterValue reg_value; + + RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); + + if (!reg_ctx) { - err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name); + err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), reg_info->name); return false; } - uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB]; - uint32_t register_byte_size = register_info->byte_size; + uint32_t register_byte_size = reg_info->byte_size; if (dematerialize) { @@ -1365,66 +1367,21 @@ ClangExpressionDeclMap::DoMaterializeOneVariable return false; } - mem = expr_var->m_live_sp->GetValue().GetScalar().ULongLong(); - - // Moving from addr into a register - // - // Case 1: addr_byte_size and register_byte_size are the same - // - // |AABBCCDD| Address contents - // |AABBCCDD| Register contents - // - // Case 2: addr_byte_size is bigger than register_byte_size - // - // Error! (The register should always be big enough to hold the data) - // - // Case 3: register_byte_size is bigger than addr_byte_size - // - // |AABB| Address contents - // |AABB0000| Register contents [on little-endian hardware] - // |0000AABB| Register contents [on big-endian hardware] - - if (value_byte_size > register_byte_size) - { - err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name); - return false; - } - - uint32_t register_offset; + reg_addr = expr_var->m_live_sp->GetValue().GetScalar().ULongLong(); - switch (exe_ctx.process->GetByteOrder()) - { - default: - err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString()); + err = reg_ctx->ReadRegisterValueFromMemory (reg_info, reg_addr, value_byte_size, reg_value); + if (err.Fail()) return false; - case lldb::eByteOrderLittle: - register_offset = 0; - break; - case lldb::eByteOrderBig: - register_offset = register_byte_size - value_byte_size; - break; - } - - DataBufferHeap register_data (register_byte_size, 0); - - Error error; - if (exe_ctx.process->ReadMemory (mem, register_data.GetBytes() + register_offset, value_byte_size, error) != value_byte_size) - { - err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString()); - return false; - } - - DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize()); - - if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0)) + + if (!reg_ctx->WriteRegister (reg_info, reg_value)) { - err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name); + err.SetErrorStringWithFormat("Couldn't write %s to register %s", name.GetCString(), reg_info->name); return false; } // Deallocate the spare area and clear the variable's live data. - Error deallocate_error = exe_ctx.process->DeallocateMemory(mem); + Error deallocate_error = exe_ctx.process->DeallocateMemory(reg_addr); if (!deallocate_error.Success()) { @@ -1441,11 +1398,11 @@ ClangExpressionDeclMap::DoMaterializeOneVariable Error allocate_error; - mem = exe_ctx.process->AllocateMemory(value_byte_size, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - allocate_error); + reg_addr = exe_ctx.process->AllocateMemory (value_byte_size, + lldb::ePermissionsReadable | lldb::ePermissionsWritable, + allocate_error); - if (mem == LLDB_INVALID_ADDRESS) + if (reg_addr == LLDB_INVALID_ADDRESS) { err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", name.GetCString(), allocate_error.AsCString()); return false; @@ -1457,14 +1414,14 @@ ClangExpressionDeclMap::DoMaterializeOneVariable type.GetASTContext(), type.GetOpaqueQualType(), name, - mem, + reg_addr, eAddressTypeLoad, value_byte_size); // Now write the location of the area into the struct. Error write_error; - if (!WriteAddressInto(exe_ctx, addr, mem, write_error)) + if (!WriteAddressInto(exe_ctx, addr, reg_addr, write_error)) { err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), write_error.AsCString()); return false; @@ -1489,7 +1446,7 @@ ClangExpressionDeclMap::DoMaterializeOneVariable if (value_byte_size > register_byte_size) { - err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name); + err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), reg_info->name); return false; } @@ -1507,28 +1464,18 @@ ClangExpressionDeclMap::DoMaterializeOneVariable register_offset = register_byte_size - value_byte_size; break; } - - DataExtractor register_extractor; - - if (!register_context->ReadRegisterBytes(register_number, register_extractor)) - { - err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name); - return false; - } - - const void *register_data = register_extractor.GetData(®ister_offset, value_byte_size); - - if (!register_data) + + RegisterValue reg_value; + + if (!reg_ctx->ReadRegister (reg_info, reg_value)) { - err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name); + err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), reg_info->name); return false; } - if (exe_ctx.process->WriteMemory (mem, register_data, value_byte_size, write_error) != value_byte_size) - { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", write_error.AsCString()); + err = reg_ctx->WriteRegisterValueToMemory(reg_info, reg_addr, value_byte_size, reg_value); + if (err.Fail()) return false; - } } } } @@ -1547,52 +1494,36 @@ ClangExpressionDeclMap::DoMaterializeOneRegister Error &err ) { - uint32_t register_number = reg_info.kinds[lldb::eRegisterKindLLDB]; uint32_t register_byte_size = reg_info.byte_size; - + RegisterValue reg_value; if (dematerialize) { - DataBufferHeap register_data (register_byte_size, 0); - - Error read_error; - if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes(), register_byte_size, read_error) != register_byte_size) + Error read_error (reg_ctx.ReadRegisterValueFromMemory(®_info, addr, register_byte_size, reg_value)); + if (read_error.Fail()) { err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, read_error.AsCString()); return false; } - DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize()); - - if (!reg_ctx.WriteRegisterBytes(register_number, register_extractor, 0)) + if (!reg_ctx.WriteRegister (®_info, reg_value)) { - err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name); + err.SetErrorStringWithFormat("Couldn't write register %s (dematerialize)", reg_info.name); return false; } } else { - DataExtractor register_extractor; - - if (!reg_ctx.ReadRegisterBytes(register_number, register_extractor)) - { - err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name); - return false; - } - - uint32_t register_offset = 0; - - const void *register_data = register_extractor.GetData(®ister_offset, register_byte_size); - if (!register_data) + if (!reg_ctx.ReadRegister(®_info, reg_value)) { - err.SetErrorStringWithFormat("Read but couldn't extract data for %s", reg_info.name); + err.SetErrorStringWithFormat("Couldn't read %s (materialize)", reg_info.name); return false; } - Error error; - if (exe_ctx.process->WriteMemory (addr, register_data, register_byte_size, error) != register_byte_size) + Error write_error (reg_ctx.WriteRegisterValueToMemory(®_info, addr, register_byte_size, reg_value)); + if (write_error.Fail()) { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString()); + err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", write_error.AsCString()); return false; } } diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 5d88bd78779..161fd957d5c 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/dwarf.h" #include "lldb/Core/Log.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" @@ -612,21 +613,21 @@ DWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level, addr_t static bool ReadRegisterValueAsScalar ( - RegisterContext *reg_context, + RegisterContext *reg_ctx, uint32_t reg_kind, uint32_t reg_num, Error *error_ptr, Value &value ) { - if (reg_context == NULL) + if (reg_ctx == NULL) { if (error_ptr) error_ptr->SetErrorStringWithFormat("No register context in frame.\n"); } else { - uint32_t native_reg = reg_context->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); + uint32_t native_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num); if (native_reg == LLDB_INVALID_REGNUM) { if (error_ptr) @@ -634,14 +635,29 @@ ReadRegisterValueAsScalar } else { - value.SetValueType (Value::eValueTypeScalar); - value.SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_context->GetRegisterInfoAtIndex(native_reg))); - - if (reg_context->ReadRegisterValue (native_reg, value.GetScalar())) - return true; - - if (error_ptr) - error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg); + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(native_reg); + RegisterValue reg_value; + if (reg_ctx->ReadRegister (reg_info, reg_value)) + { + if (reg_value.GetScalarValue(value.GetScalar())) + { + value.SetValueType (Value::eValueTypeScalar); + value.SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_info)); + if (error_ptr) + error_ptr->Clear(); + return true; + } + else + { + if (error_ptr) + error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg); + } + } + else + { + if (error_ptr) + error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg); + } } } return false; diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index fb331f2e02e..91f1f1c0438 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -501,9 +501,7 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco data = MemARead(context, addr, 4, 0, &success); if (!success) return false; - RegisterInfo reg_info; - GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); - if (!WriteRegisterUnsigned(context, reg_info, data)) + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) return false; addr += addr_byte_size; } @@ -802,12 +800,12 @@ EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding break; case eEncodingA1: - // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); + // d = UInt(Rd); setflags = (S == Ô1Õ); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); Rd = Bits32 (opcode, 15, 12); setflags = BitIsSet (opcode, 20); imm32 = ARMExpandImm_C (opcode, APSR_C, carry); - // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; + // if Rd == Ô1111Õ && S == Ô1Õ then SEE SUBS PC, LR and related instructions; if ((Rd == 15) && setflags) return EmulateSUBSPcLrEtc (opcode, encoding); @@ -1981,7 +1979,7 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); // uint64_t to accommodate 64-bit registers. - uint64_t reg_value = ReadRegisterUnsigned(dwarf_reg, 0, &success); + uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); if (!success) return false; if (!MemAWrite (context, addr, reg_value, reg_byte_size)) @@ -2077,7 +2075,7 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc data = MemARead(context, addr, reg_byte_size, 0, &success); if (!success) return false; - if (!WriteRegisterUnsigned(context, dwarf_reg, data)) + if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) return false; addr += reg_byte_size; } @@ -4232,7 +4230,7 @@ EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding en break; case eEncodingA1: - // if W == '1' && Rn == '1101’ && BitCount(register_list) >= 2 then SEE PUSH; + // if W == '1' && Rn == '1101Õ && BitCount(register_list) >= 2 then SEE PUSH; if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) { // See Push @@ -9275,7 +9273,7 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding if ConditionPassed() then EncodingSpecificOperations(); shifted = Shift(R[m], shift_t, shift_n, APSR.C); - (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’); + (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), Ô1Õ); if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); // setflags is always FALSE here else @@ -9300,7 +9298,7 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding switch (encoding) { case eEncodingT1: - // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’); + // d = UInt(Rd); m = UInt(Rm); setflags = (S == Ô1Õ); d = Bits32 (opcode, 11, 8); m = Bits32 (opcode, 3, 0); setflags = BitIsSet (opcode, 20); @@ -9318,12 +9316,12 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding break; case eEncodingA1: - // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’); + // d = UInt(Rd); m = UInt(Rm); setflags = (S == Ô1Õ); d = Bits32 (opcode, 15, 12); m = Bits32 (opcode, 3, 0); setflags = BitIsSet (opcode, 20); - // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; + // if Rd == Ô1111Õ && S == Ô1Õ then SEE SUBS PC, LR and related instructions; if (d == 15 && setflags) EmulateSUBSPcLrEtc (opcode, encoding); @@ -9342,7 +9340,7 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); - // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’); + // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), Ô1Õ); uint32_t sp_val = ReadCoreReg (SP_REG, &success); if (!success) return false; @@ -9373,7 +9371,7 @@ EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncod EncodingSpecificOperations(); shift_n = UInt(R[s]<7:0>); shifted = Shift(R[m], shift_t, shift_n, APSR.C); - (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’); + (result, carry, overflow) = AddWithCarry(R[n], shifted, Ô0Õ); R[d] = result; if setflags then APSR.N = result<31>; @@ -9402,7 +9400,7 @@ EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncod m = Bits32 (opcode, 3, 0); s = Bits32 (opcode, 11, 8); - // setflags = (S == ‘1’); shift_t = DecodeRegShift(type); + // setflags = (S == Ô1Õ); shift_t = DecodeRegShift(type); setflags = BitIsSet (opcode, 20); shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); @@ -9429,7 +9427,7 @@ EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncod uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); - // (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’); + // (result, carry, overflow) = AddWithCarry(R[n], shifted, Ô0Õ); uint32_t Rn = ReadCoreReg (n, &success); if (!success) return false; @@ -9468,7 +9466,7 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e if ConditionPassed() then EncodingSpecificOperations(); shifted = Shift(R[m], shift_t, shift_n, APSR.C); - (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’); + (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), Ô1Õ); if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); // setflags is always FALSE here else @@ -9507,9 +9505,9 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e break; case eEncodingT2: - // if Rd == ‘1111’ && S == ‘1’ then SEE CMP (register); - // if Rn == ‘1101’ then SEE SUB (SP minus register); - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’); + // if Rd == Ô1111Õ && S == Ô1Õ then SEE CMP (register); + // if Rn == Ô1101Õ then SEE SUB (SP minus register); + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == Ô1Õ); d = Bits32 (opcode, 11, 8); n = Bits32 (opcode, 19, 16); m = Bits32 (opcode, 3, 0); @@ -9525,14 +9523,14 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e break; case eEncodingA1: - // if Rn == ‘1101’ then SEE SUB (SP minus register); - // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’); + // if Rn == Ô1101Õ then SEE SUB (SP minus register); + // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == Ô1Õ); d = Bits32 (opcode, 15, 12); n = Bits32 (opcode, 19, 16); m = Bits32 (opcode, 3, 0); setflags = BitIsSet (opcode, 20); - // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions; + // if Rd == Ô1111Õ && S == Ô1Õ then SEE SUBS PC, LR and related instructions; if ((d == 15) && setflags) EmulateSUBSPcLrEtc (opcode, encoding); @@ -9552,7 +9550,7 @@ EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding e uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C); - // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’); + // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), Ô1Õ); uint32_t Rn = ReadCoreReg (n, &success); if (!success) return false; @@ -9613,7 +9611,7 @@ EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding en switch (encoding) { case eEncodingT1: - // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32); + // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:Õ00Õ, 32); d = Bits32 (opcode, 11, 8); t = Bits32 (opcode, 15, 12); n = Bits32 (opcode, 19, 16); @@ -9719,13 +9717,13 @@ EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncodi switch (encoding) { case eEncodingA1: - // if P == ‘0’ && W == ‘1’ then SEE STRBT; + // if P == Ô0Õ && W == Ô1Õ then SEE STRBT; // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); t = Bits32 (opcode, 15, 12); n = Bits32 (opcode, 19, 16); imm32 = Bits32 (opcode, 11, 0); - // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); + // index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (P == Ô0Õ) || (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); @@ -9817,14 +9815,14 @@ EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncodin switch (encoding) { case eEncodingA1: - // if P == ‘0’ && W == ‘1’ then SEE STRT; - // if Rn == ‘1101’ && P == ‘1’ && U == ‘0’ && W == ‘1’ && imm12 == ‘000000000100’ then SEE PUSH; + // if P == Ô0Õ && W == Ô1Õ then SEE STRT; + // if Rn == Ô1101Õ && P == Ô1Õ && U == Ô0Õ && W == Ô1Õ && imm12 == Ô000000000100Õ then SEE PUSH; // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); t = Bits32 (opcode, 15, 12); n = Bits32 (opcode, 19, 16); imm32 = Bits32 (opcode, 11, 0); - // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); + // index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (P == Ô0Õ) || (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); @@ -9929,15 +9927,15 @@ EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEnc switch (encoding) { case eEncodingT1: - //if P == ‘0’ && W == ‘0’ then SEE “Related encodingsâ€; - //if Rn == ‘1111’ then SEE LDRD (literal); - //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32); + //if P == Ô0Õ && W == Ô0Õ then SEE ÒRelated encodingsÓ; + //if Rn == Ô1111Õ then SEE LDRD (literal); + //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:Õ00Õ, 32); t = Bits32 (opcode, 15, 12); t2 = Bits32 (opcode, 11, 8); n = Bits32 (opcode, 19, 16); imm32 = Bits32 (opcode, 7, 0) << 2; - //index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’); + //index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsSet (opcode, 21); @@ -9953,8 +9951,8 @@ EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEnc break; case eEncodingA1: - //if Rn == ‘1111’ then SEE LDRD (literal); - //if Rt<0> == ‘1’ then UNPREDICTABLE; + //if Rn == Ô1111Õ then SEE LDRD (literal); + //if Rt<0> == Ô1Õ then UNPREDICTABLE; //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); t = Bits32 (opcode, 15, 12); if (BitIsSet (t, 0)) @@ -9963,12 +9961,12 @@ EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEnc n = Bits32 (opcode, 19, 16); imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); - //index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); + //index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (P == Ô0Õ) || (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - //if P == ‘0’ && W == ‘1’ then UNPREDICTABLE; + //if P == Ô0Õ && W == Ô1Õ then UNPREDICTABLE; if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) return false; @@ -10074,7 +10072,7 @@ EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEnco switch (encoding) { case eEncodingA1: - // if Rt<0> == ‘1’ then UNPREDICTABLE; + // if Rt<0> == Ô1Õ then UNPREDICTABLE; // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); t = Bits32 (opcode, 15, 12); if (BitIsSet (t, 0)) @@ -10083,12 +10081,12 @@ EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEnco n = Bits32 (opcode, 19, 16); m = Bits32 (opcode, 3, 0); - // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); + // index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (P == Ô0Õ) || (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE; + // if P == Ô0Õ && W == Ô1Õ then UNPREDICTABLE; if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) return false; @@ -10201,14 +10199,14 @@ EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding switch (encoding) { case eEncodingT1: - // if P == ‘0’ && W == ‘0’ then SEE “Related encodingsâ€; - // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32); + // if P == Ô0Õ && W == Ô0Õ then SEE ÒRelated encodingsÓ; + // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:Õ00Õ, 32); t = Bits32 (opcode, 15, 12); t2 = Bits32 (opcode, 11, 8); n = Bits32 (opcode, 19, 16); imm32 = Bits32 (opcode, 7, 0) << 2; - // index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’); + // index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsSet (opcode, 21); @@ -10224,7 +10222,7 @@ EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding break; case eEncodingA1: - // if Rt<0> == ‘1’ then UNPREDICTABLE; + // if Rt<0> == Ô1Õ then UNPREDICTABLE; // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); t = Bits32 (opcode, 15, 12); if (BitIsSet (t, 0)) @@ -10234,12 +10232,12 @@ EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding n = Bits32 (opcode, 19, 16); imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); - // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); + // index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (P == Ô0Õ) || (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE; + // if P == Ô0Õ && W == Ô1Õ then UNPREDICTABLE; if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) return false; @@ -10349,7 +10347,7 @@ EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding switch (encoding) { case eEncodingA1: - // if Rt<0> == ‘1’ then UNPREDICTABLE; + // if Rt<0> == Ô1Õ then UNPREDICTABLE; // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); t = Bits32 (opcode, 15, 12); if (BitIsSet (t, 0)) @@ -10359,12 +10357,12 @@ EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding n = Bits32 (opcode, 19, 16); m = Bits32 (opcode, 3, 0); - // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’); + // index = (P == Ô1Õ); add = (U == Ô1Õ); wback = (P == Ô0Õ) || (W == Ô1Õ); index = BitIsSet (opcode, 24); add = BitIsSet (opcode, 23); wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); - // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE; + // if P == Ô0Õ && W == Ô1Õ then UNPREDICTABLE; if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) return false; @@ -10490,25 +10488,25 @@ EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding enc { case eEncodingT1: case eEncodingA1: - // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodingsâ€; - // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP; - // if P == ‘1’ && W == ‘0’ then SEE VLDR; - // if P == U && W == ‘1’ then UNDEFINED; + // if P == Ô0Õ && U == Ô0Õ && W == Ô0Õ then SEE ÒRelated encodingsÓ; + // if P == Ô0Õ && U == Ô1Õ && W == Ô1Õ && Rn == Ô1101Õ then SEE VPOP; + // if P == Ô1Õ && W == Ô0Õ then SEE VLDR; + // if P == U && W == Ô1Õ then UNDEFINED; if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) return false; // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’); + // single_regs = FALSE; add = (U == Ô1Õ); wback = (W == Ô1Õ); single_regs = false; add = BitIsSet (opcode, 23); wback = BitIsSet (opcode, 21); - // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32); + // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:Õ00Õ, 32); d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); n = Bits32 (opcode, 19, 16); imm32 = Bits32 (opcode, 7, 0) << 2; - // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FLDMXâ€. + // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see ÒFLDMXÓ. regs = Bits32 (opcode, 7, 0) / 2; // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; @@ -10523,22 +10521,22 @@ EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding enc case eEncodingT2: case eEncodingA2: - // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodingsâ€; - // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP; - // if P == ‘1’ && W == ‘0’ then SEE VLDR; - // if P == U && W == ‘1’ then UNDEFINED; + // if P == Ô0Õ && U == Ô0Õ && W == Ô0Õ then SEE ÒRelated encodingsÓ; + // if P == Ô0Õ && U == Ô1Õ && W == Ô1Õ && Rn == Ô1101Õ then SEE VPOP; + // if P == Ô1Õ && W == Ô0Õ then SEE VLDR; + // if P == U && W == Ô1Õ then UNDEFINED; if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) return false; // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn); + // single_regs = TRUE; add = (U == Ô1Õ); wback = (W == Ô1Õ); d = UInt(Vd:D); n = UInt(Rn); single_regs = true; add = BitIsSet (opcode, 23); wback = BitIsSet (opcode, 21); d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); n = Bits32 (opcode, 19, 16); - // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8); + // imm32 = ZeroExtend(imm8:Õ00Õ, 32); regs = UInt(imm8); imm32 = Bits32 (opcode, 7, 0) << 2; regs = Bits32 (opcode, 7, 0); @@ -10682,25 +10680,25 @@ EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding enc { case eEncodingT1: case eEncodingA1: - // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodingsâ€; - // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH; - // if P == ‘1’ && W == ‘0’ then SEE VSTR; - // if P == U && W == ‘1’ then UNDEFINED; + // if P == Ô0Õ && U == Ô0Õ && W == Ô0Õ then SEE ÒRelated encodingsÓ; + // if P == Ô1Õ && U == Ô0Õ && W == Ô1Õ && Rn == Ô1101Õ then SEE VPUSH; + // if P == Ô1Õ && W == Ô0Õ then SEE VSTR; + // if P == U && W == Ô1Õ then UNDEFINED; if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) return false; // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’); + // single_regs = FALSE; add = (U == Ô1Õ); wback = (W == Ô1Õ); single_regs = false; add = BitIsSet (opcode, 23); wback = BitIsSet (opcode, 21); - // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32); + // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:Õ00Õ, 32); d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); n = Bits32 (opcode, 19, 16); imm32 = Bits32 (opcode, 7, 0) << 2; - // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FSTMXâ€. + // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see ÒFSTMXÓ. regs = Bits32 (opcode, 7, 0) / 2; // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; @@ -10715,22 +10713,22 @@ EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding enc case eEncodingT2: case eEncodingA2: - // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodingsâ€; - // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH; - // if P == ‘1’ && W == ‘0’ then SEE VSTR; - // if P == U && W == ‘1’ then UNDEFINED; + // if P == Ô0Õ && U == Ô0Õ && W == Ô0Õ then SEE ÒRelated encodingsÓ; + // if P == Ô1Õ && U == Ô0Õ && W == Ô1Õ && Rn == Ô1101Õ then SEE VPUSH; + // if P == Ô1Õ && W == Ô0Õ then SEE VSTR; + // if P == U && W == Ô1Õ then UNDEFINED; if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) return false; // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) - // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn); + // single_regs = TRUE; add = (U == Ô1Õ); wback = (W == Ô1Õ); d = UInt(Vd:D); n = UInt(Rn); single_regs = true; add = BitIsSet (opcode, 23); wback = BitIsSet (opcode, 21); d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); n = Bits32 (opcode, 19, 16); - // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8); + // imm32 = ZeroExtend(imm8:Õ00Õ, 32); regs = UInt(imm8); imm32 = Bits32 (opcode, 7, 0) << 2; regs = Bits32 (opcode, 7, 0); @@ -10875,7 +10873,7 @@ EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) { case eEncodingT1: case eEncodingA1: - // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32); + // single_reg = FALSE; add = (U == Ô1Õ); imm32 = ZeroExtend(imm8:Õ00Õ, 32); single_reg = false; add = BitIsSet (opcode, 23); imm32 = Bits32 (opcode, 7, 0) << 2; @@ -10888,7 +10886,7 @@ EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) case eEncodingT2: case eEncodingA2: - // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32); + // single_reg = TRUE; add = (U == Ô1Õ); imm32 = ZeroExtend(imm8:Õ00Õ, 32); single_reg = true; add = BitIsSet (opcode, 23); imm32 = Bits32 (opcode, 7, 0) << 2; @@ -11004,7 +11002,7 @@ EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) { case eEncodingT1: case eEncodingA1: - // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32); + // single_reg = FALSE; add = (U == Ô1Õ); imm32 = ZeroExtend(imm8:Õ00Õ, 32); single_reg = false; add = BitIsSet (opcode, 23); imm32 = Bits32 (opcode, 7, 0) << 2; @@ -11021,7 +11019,7 @@ EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) case eEncodingT2: case eEncodingA2: - // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32); + // single_reg = TRUE; add = (U == Ô1Õ); imm32 = ZeroExtend(imm8:Õ00Õ, 32); single_reg = true; add = BitIsSet (opcode, 23); imm32 = Bits32 (opcode, 7, 0) << 2; @@ -11143,16 +11141,16 @@ EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding e case eEncodingA1: { // case type of - // when ‘0111’ - // regs = 1; if align<1> == ‘1’ then UNDEFINED; - // when ‘1010’ - // regs = 2; if align == ‘11’ then UNDEFINED; - // when ‘0110’ - // regs = 3; if align<1> == ‘1’ then UNDEFINED; - // when ‘0010’ + // when Ô0111Õ + // regs = 1; if align<1> == Ô1Õ then UNDEFINED; + // when Ô1010Õ + // regs = 2; if align == Ô11Õ then UNDEFINED; + // when Ô0110Õ + // regs = 3; if align<1> == Ô1Õ then UNDEFINED; + // when Ô0010Õ // regs = 4; // otherwise - // SEE “Related encodingsâ€; + // SEE ÒRelated encodingsÓ; uint32_t type = Bits32 (opcode, 11, 8); uint32_t align = Bits32 (opcode, 5, 4); if (type == 7) // '0111' @@ -11181,7 +11179,7 @@ EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding e else return false; - // alignment = if align == ‘00’ then 1 else 4 << UInt(align); + // alignment = if align == Ô00Õ then 1 else 4 << UInt(align); if (align == 0) alignment = 1; else @@ -11306,13 +11304,13 @@ EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncodi { uint32_t size = Bits32 (opcode, 11, 10); uint32_t index_align = Bits32 (opcode, 7, 4); - // if size == ‘11’ then SEE VLD1 (single element to all lanes); + // if size == Ô11Õ then SEE VLD1 (single element to all lanes); if (size == 3) return EmulateVLD1SingleAll (opcode, encoding); // case size of if (size == 0) // when '00' { - // if index_align<0> != ‘0’ then UNDEFINED; + // if index_align<0> != Ô0Õ then UNDEFINED; if (BitIsClear (index_align, 0)) return false; @@ -11322,9 +11320,9 @@ EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncodi index = Bits32 (index_align, 3, 1); alignment = 1; } - else if (size == 1) // when ‘01’ + else if (size == 1) // when Ô01Õ { - // if index_align<1> != ‘0’ then UNDEFINED; + // if index_align<1> != Ô0Õ then UNDEFINED; if (BitIsClear (index_align, 1)) return false; @@ -11333,19 +11331,19 @@ EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncodi esize = 16; index = Bits32 (index_align, 3, 2); - // alignment = if index_align<0> == ‘0’ then 1 else 2; + // alignment = if index_align<0> == Ô0Õ then 1 else 2; if (BitIsClear (index_align, 0)) alignment = 1; else alignment = 2; } - else if (size == 2) // when ‘10’ + else if (size == 2) // when Ô10Õ { - // if index_align<2> != ‘0’ then UNDEFINED; + // if index_align<2> != Ô0Õ then UNDEFINED; if (BitIsClear (index_align, 2)) return false; - // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED; + // if index_align<1:0> != Ô00Õ && index_align<1:0> != Ô11Õ then UNDEFINED; if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) return false; @@ -11354,7 +11352,7 @@ EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncodi esize = 32; index = Bit32 (index_align, 3); - // alignment = if index_align<1:0> == ‘00’ then 1 else 4; + // alignment = if index_align<1:0> == Ô00Õ then 1 else 4; if (Bits32 (index_align, 1, 0) == 0) alignment = 1; else @@ -11484,35 +11482,35 @@ EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding e uint32_t align = Bits32 (opcode, 5, 4); // case type of - if (type == 7) // when ‘0111’ + if (type == 7) // when Ô0111Õ { - // regs = 1; if align<1> == ‘1’ then UNDEFINED; + // regs = 1; if align<1> == Ô1Õ then UNDEFINED; regs = 1; if (BitIsSet (align, 1)) return false; } - else if (type == 10) // when ‘1010’ + else if (type == 10) // when Ô1010Õ { - // regs = 2; if align == ‘11’ then UNDEFINED; + // regs = 2; if align == Ô11Õ then UNDEFINED; regs = 2; if (align == 3) return false; } - else if (type == 6) // when ‘0110’ + else if (type == 6) // when Ô0110Õ { - // regs = 3; if align<1> == ‘1’ then UNDEFINED; + // regs = 3; if align<1> == Ô1Õ then UNDEFINED; regs = 3; if (BitIsSet (align, 1)) return false; } - else if (type == 2) // when ‘0010’ + else if (type == 2) // when Ô0010Õ // regs = 4; regs = 4; else // otherwise - // SEE “Related encodingsâ€; + // SEE ÒRelated encodingsÓ; return false; - // alignment = if align == ‘00’ then 1 else 4 << UInt(align); + // alignment = if align == Ô00Õ then 1 else 4 << UInt(align); if (align == 0) alignment = 0; else @@ -11642,14 +11640,14 @@ EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding enc uint32_t size = Bits32 (opcode, 11, 10); uint32_t index_align = Bits32 (opcode, 7, 4); - // if size == ‘11’ then UNDEFINED; + // if size == Ô11Õ then UNDEFINED; if (size == 3) return false; // case size of - if (size == 0) // when ‘00’ + if (size == 0) // when Ô00Õ { - // if index_align<0> != ‘0’ then UNDEFINED; + // if index_align<0> != Ô0Õ then UNDEFINED; if (BitIsClear (index_align, 0)) return false; // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; @@ -11658,9 +11656,9 @@ EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding enc index = Bits32 (index_align, 3, 1); alignment = 1; } - else if (size == 1) // when ‘01’ + else if (size == 1) // when Ô01Õ { - // if index_align<1> != ‘0’ then UNDEFINED; + // if index_align<1> != Ô0Õ then UNDEFINED; if (BitIsClear (index_align, 1)) return false; @@ -11669,19 +11667,19 @@ EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding enc esize = 16; index = Bits32 (index_align, 3, 2); - // alignment = if index_align<0> == ‘0’ then 1 else 2; + // alignment = if index_align<0> == Ô0Õ then 1 else 2; if (BitIsClear (index_align, 0)) alignment = 1; else alignment = 2; } - else if (size == 2) // when ‘10’ + else if (size == 2) // when Ô10Õ { - // if index_align<2> != ‘0’ then UNDEFINED; + // if index_align<2> != Ô0Õ then UNDEFINED; if (BitIsClear (index_align, 2)) return false; - // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED; + // if index_align<1:0> != Ô00Õ && index_align<1:0> != Ô11Õ then UNDEFINED; if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) return false; @@ -11690,7 +11688,7 @@ EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding enc esize = 32; index = Bit32 (index_align, 3); - // alignment = if index_align<1:0> == ‘00’ then 1 else 4; + // alignment = if index_align<1:0> == Ô00Õ then 1 else 4; if (Bits32 (index_align, 1, 0) == 0) alignment = 1; else @@ -11799,12 +11797,12 @@ EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEnc case eEncodingT1: case eEncodingA1: { - //if size == ‘11’ || (size == ‘00’ && a == ‘1’) then UNDEFINED; + //if size == Ô11Õ || (size == Ô00Õ && a == Ô1Õ) then UNDEFINED; uint32_t size = Bits32 (opcode, 7, 6); if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) return false; - //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == ‘0’ then 1 else 2; + //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == Ô0Õ then 1 else 2; ebytes = 1 << size; elements = 8 / ebytes; if (BitIsClear (opcode, 5)) @@ -11812,7 +11810,7 @@ EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEnc else regs = 2; - //alignment = if a == ‘0’ then 1 else ebytes; + //alignment = if a == Ô0Õ then 1 else ebytes; if (BitIsClear (opcode, 4)) alignment = 1; else @@ -11909,19 +11907,19 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod UNPREDICTABLE; operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; case opcode of - when ‘0000’ result = R[n] AND operand2; // AND - when ‘0001’ result = R[n] EOR operand2; // EOR - when ‘0010’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB - when ‘0011’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB - when ‘0100’ (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD - when ‘0101’ (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC - when ‘0110’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC - when ‘0111’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC - when ‘1100’ result = R[n] OR operand2; // ORR - when ‘1101’ result = operand2; // MOV - when ‘1110’ result = R[n] AND NOT(operand2); // BIC - when ‘1111’ result = NOT(operand2); // MVN - CPSRWriteByInstr(SPSR[], ‘1111’, TRUE); + when Ô0000Õ result = R[n] AND operand2; // AND + when Ô0001Õ result = R[n] EOR operand2; // EOR + when Ô0010Õ (result, -, -) = AddWithCarry(R[n], NOT(operand2), Ô1Õ); // SUB + when Ô0011Õ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, Ô1Õ); // RSB + when Ô0100Õ (result, -, -) = AddWithCarry(R[n], operand2, Ô0Õ); // ADD + when Ô0101Õ (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC + when Ô0110Õ (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC + when Ô0111Õ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC + when Ô1100Õ result = R[n] OR operand2; // ORR + when Ô1101Õ result = operand2; // MOV + when Ô1110Õ result = R[n] AND NOT(operand2); // BIC + when Ô1111Õ result = NOT(operand2); // MVN + CPSRWriteByInstr(SPSR[], Ô1111Õ, TRUE); BranchWritePC(result); #endif @@ -11941,7 +11939,7 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod { case eEncodingT1: // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE - // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = ‘0010’; // = SUB + // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = Ô0010Õ; // = SUB n = 14; imm32 = Bits32 (opcode, 7, 0); register_form = false; @@ -12002,62 +12000,62 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod // case opcode of switch (code) { - case 0: // when ‘0000’ + case 0: // when Ô0000Õ // result = R[n] AND operand2; // AND result.result = Rn & operand2; break; - case 1: // when ‘0001’ + case 1: // when Ô0001Õ // result = R[n] EOR operand2; // EOR result.result = Rn ^ operand2; break; - case 2: // when ‘0010’ - // (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB + case 2: // when Ô0010Õ + // (result, -, -) = AddWithCarry(R[n], NOT(operand2), Ô1Õ); // SUB result = AddWithCarry (Rn, ~(operand2), 1); break; - case 3: // when ‘0011’ - // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB + case 3: // when Ô0011Õ + // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, Ô1Õ); // RSB result = AddWithCarry (~(Rn), operand2, 1); break; - case 4: // when ‘0100’ - // (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD + case 4: // when Ô0100Õ + // (result, -, -) = AddWithCarry(R[n], operand2, Ô0Õ); // ADD result = AddWithCarry (Rn, operand2, 0); break; - case 5: // when ‘0101’ + case 5: // when Ô0101Õ // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC result = AddWithCarry (Rn, operand2, APSR_C); break; - case 6: // when ‘0110’ + case 6: // when Ô0110Õ // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC result = AddWithCarry (Rn, ~(operand2), APSR_C); break; - case 7: // when ‘0111’ + case 7: // when Ô0111Õ // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC result = AddWithCarry (~(Rn), operand2, APSR_C); break; - case 10: // when ‘1100’ + case 10: // when Ô1100Õ // result = R[n] OR operand2; // ORR result.result = Rn | operand2; break; - case 11: // when ‘1101’ + case 11: // when Ô1101Õ // result = operand2; // MOV result.result = operand2; break; - case 12: // when ‘1110’ + case 12: // when Ô1110Õ // result = R[n] AND NOT(operand2); // BIC result.result = Rn & ~(operand2); break; - case 15: // when ‘1111’ + case 15: // when Ô1111Õ // result = NOT(operand2); // MVN result.result = ~(operand2); break; @@ -12065,7 +12063,7 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod default: return false; } - // CPSRWriteByInstr(SPSR[], ‘1111’, TRUE); + // CPSRWriteByInstr(SPSR[], Ô1111Õ, TRUE); // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for // the best. @@ -13249,9 +13247,9 @@ EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, - dwarf_cpsr, - 0, - &success); + dwarf_cpsr, + 0, + &success); } // Only return false if we are unable to read the CPSR if we care about conditions diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index 1db2f451a1c..1d042f9aeb1 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -9,6 +9,7 @@ #include "EmulationStateARM.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/RegisterContext.h" @@ -33,33 +34,18 @@ EmulationStateARM::~EmulationStateARM () bool EmulationStateARM::LoadPseudoRegistersFromFrame (StackFrame &frame) { - RegisterContext *reg_context = frame.GetRegisterContext().get(); - Scalar value; - uint64_t reg_value64; - uint32_t reg_value32; - + RegisterContext *reg_ctx = frame.GetRegisterContext().get(); bool success = true; + uint32_t reg_num; for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) { - uint32_t internal_reg_num = reg_context->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i); - if (reg_context->ReadRegisterValue (internal_reg_num, value)) + reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i); + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); + RegisterValue reg_value; + if (reg_ctx->ReadRegister (reg_info, reg_value)) { - reg_value32 = (uint32_t) value.GetRawBits64 (0); - m_gpr[i - dwarf_r0] = reg_value32; - } - else - success = false; - } - - for (int i = dwarf_s0; i < dwarf_s0 + 32; ++i) - { - uint32_t internal_reg_num = reg_context->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i); - if (reg_context->ReadRegisterValue (internal_reg_num, value)) - { - uint32_t idx = i - dwarf_s0; - reg_value32 = (uint32_t) value.GetRawBits64 (0); - m_vfp_regs.sd_regs[idx / 2].s_reg[idx % 2] = reg_value32; + m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32(); } else success = false; @@ -67,15 +53,17 @@ EmulationStateARM::LoadPseudoRegistersFromFrame (StackFrame &frame) for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) { - uint32_t internal_reg_num = reg_context->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i); - if (reg_context->ReadRegisterValue (internal_reg_num, value)) + reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindDWARF, i); + RegisterValue reg_value; + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num); + + if (reg_ctx->ReadRegister (reg_info, reg_value)) { uint32_t idx = i - dwarf_d0; - reg_value64 = value.GetRawBits64 (0); if (i < 16) - m_vfp_regs.sd_regs[idx].d_reg = reg_value64; + m_vfp_regs.sd_regs[idx].d_reg = reg_value.GetAsUInt64(); else - m_vfp_regs.d_regs[idx - 16] = reg_value64; + m_vfp_regs.d_regs[idx - 16] = reg_value.GetAsUInt64(); } else success = false; @@ -254,18 +242,20 @@ EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction, bool EmulationStateARM::ReadPseudoRegister (EmulateInstruction *instruction, void *baton, - const RegisterInfo ®_info, - uint64_t ®_value) + const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue ®_value) { - if (!baton) + if (!baton || !reg_info) return false; bool success = true; EmulationStateARM *pseudo_state = (EmulationStateARM *) baton; + const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF]; + assert (dwarf_reg_num != LLDB_INVALID_REGNUM); + uint64_t reg_uval = pseudo_state->ReadPseudoRegisterValue (dwarf_reg_num, success); - assert (reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM); - reg_value = pseudo_state->ReadPseudoRegisterValue (reg_info.kinds[eRegisterKindDWARF], success); - + if (success) + success = reg_value.SetUInt(reg_uval, reg_info->byte_size); return success; } @@ -274,15 +264,16 @@ bool EmulationStateARM::WritePseudoRegister (EmulateInstruction *instruction, void *baton, const EmulateInstruction::Context &context, - const RegisterInfo ®_info, - uint64_t reg_value) + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_value) { - if (!baton) + if (!baton || !reg_info) return false; - assert (reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM); EmulationStateARM *pseudo_state = (EmulationStateARM *) baton; - return pseudo_state->StorePseudoRegisterValue (reg_info.kinds[eRegisterKindDWARF], reg_value); + const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF]; + assert (dwarf_reg_num != LLDB_INVALID_REGNUM); + return pseudo_state->StorePseudoRegisterValue (dwarf_reg_num, reg_value.GetAsUInt64()); } bool diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h index b4cc28b4423..472c5d64098 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h @@ -70,15 +70,15 @@ public: static bool ReadPseudoRegister (lldb_private::EmulateInstruction *instruction, void *baton, - const lldb_private::RegisterInfo ®_info, - uint64_t ®_value); + const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue ®_value); static bool WritePseudoRegister (lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, - const lldb_private::RegisterInfo ®_info, - uint64_t reg_value); + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_value); private: uint32_t m_gpr[17]; struct sd_regs diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp index 35805b52d7e..4f3fe1a53b2 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp @@ -17,6 +17,7 @@ // Other libraries and framework includes #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Host/Endian.h" @@ -627,8 +628,9 @@ RegisterContextMach_arm::LogDBGRegisters (Log *log, const DBG& dbg) bool -RegisterContextMach_arm::ReadRegisterValue (uint32_t reg, Scalar &value) +RegisterContextMach_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = RegisterContextMach_arm::GetSetForNativeRegNum (reg); if (set == -1) @@ -656,7 +658,7 @@ RegisterContextMach_arm::ReadRegisterValue (uint32_t reg, Scalar &value) case gpr_lr: case gpr_pc: case gpr_cpsr: - value = gpr.r[reg - gpr_r0]; + value.SetUInt32 (gpr.r[reg - gpr_r0]); break; case fpu_s0: @@ -691,24 +693,25 @@ RegisterContextMach_arm::ReadRegisterValue (uint32_t reg, Scalar &value) case fpu_s29: case fpu_s30: case fpu_s31: - value = fpu.floats.s[reg]; + value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat); break; case fpu_fpscr: - value = fpu.fpscr; + value.SetUInt32 (fpu.fpscr); break; case exc_exception: - value = exc.exception; + value.SetUInt32 (exc.exception); break; case exc_fsr: - value = exc.fsr; + value.SetUInt32 (exc.fsr); break; case exc_far: - value = exc.far; + value.SetUInt32 (exc.far); break; default: + value.SetValueToInvalid(); return false; } @@ -717,8 +720,10 @@ RegisterContextMach_arm::ReadRegisterValue (uint32_t reg, Scalar &value) bool -RegisterContextMach_arm::WriteRegisterValue (uint32_t reg, const Scalar &value) +RegisterContextMach_arm::WriteRegister (const RegisterInfo *reg_info, + const RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = GetSetForNativeRegNum (reg); if (set == -1) @@ -746,7 +751,7 @@ RegisterContextMach_arm::WriteRegisterValue (uint32_t reg, const Scalar &value) case gpr_lr: case gpr_pc: case gpr_cpsr: - gpr.r[reg - gpr_r0] = value.UInt(0); + gpr.r[reg - gpr_r0] = value.GetAsUInt32(); break; case fpu_s0: @@ -781,21 +786,21 @@ RegisterContextMach_arm::WriteRegisterValue (uint32_t reg, const Scalar &value) case fpu_s29: case fpu_s30: case fpu_s31: - fpu.floats.s[reg] = value.UInt(0); + fpu.floats.s[reg] = value.GetAsUInt32(); break; case fpu_fpscr: - fpu.fpscr = value.UInt(0); + fpu.fpscr = value.GetAsUInt32(); break; case exc_exception: - exc.exception = value.UInt(0); + exc.exception = value.GetAsUInt32(); break; case exc_fsr: - exc.fsr = value.UInt(0); + exc.fsr = value.GetAsUInt32(); break; case exc_far: - exc.far = value.UInt(0); + exc.far = value.GetAsUInt32(); break; default: @@ -806,195 +811,6 @@ RegisterContextMach_arm::WriteRegisterValue (uint32_t reg, const Scalar &value) } bool -RegisterContextMach_arm::ReadRegisterBytes (uint32_t reg, DataExtractor &data) -{ - int set = RegisterContextMach_arm::GetSetForNativeRegNum (reg); - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL) - return false; - - switch (reg) - { - case gpr_r0: - case gpr_r1: - case gpr_r2: - case gpr_r3: - case gpr_r4: - case gpr_r5: - case gpr_r6: - case gpr_r7: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_sp: - case gpr_lr: - case gpr_pc: - case gpr_cpsr: - data.SetData(&gpr.r[reg - gpr_r0], reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_s0: - case fpu_s1: - case fpu_s2: - case fpu_s3: - case fpu_s4: - case fpu_s5: - case fpu_s6: - case fpu_s7: - case fpu_s8: - case fpu_s9: - case fpu_s10: - case fpu_s11: - case fpu_s12: - case fpu_s13: - case fpu_s14: - case fpu_s15: - case fpu_s16: - case fpu_s17: - case fpu_s18: - case fpu_s19: - case fpu_s20: - case fpu_s21: - case fpu_s22: - case fpu_s23: - case fpu_s24: - case fpu_s25: - case fpu_s26: - case fpu_s27: - case fpu_s28: - case fpu_s29: - case fpu_s30: - case fpu_s31: - data.SetData(&fpu.floats.s[reg - fpu_s0], reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_fpscr: - data.SetData(&fpu.fpscr, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_exception: - data.SetData(&exc.exception, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_fsr: - data.SetData(&exc.fsr, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_far: - data.SetData(&exc.far, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - default: - return false; - } - return true; -} - -bool -RegisterContextMach_arm::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset) -{ - int set = GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - - const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL && data.ValidOffsetForDataOfSize(data_offset, reg_info->byte_size)) - return false; - - uint32_t offset = data_offset; - switch (reg) - { - case gpr_r0: - case gpr_r1: - case gpr_r2: - case gpr_r3: - case gpr_r4: - case gpr_r5: - case gpr_r6: - case gpr_r7: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_sp: - case gpr_lr: - case gpr_pc: - case gpr_cpsr: - gpr.r[reg - gpr_r0] = data.GetU32 (&offset); - break; - - case fpu_s0: - case fpu_s1: - case fpu_s2: - case fpu_s3: - case fpu_s4: - case fpu_s5: - case fpu_s6: - case fpu_s7: - case fpu_s8: - case fpu_s9: - case fpu_s10: - case fpu_s11: - case fpu_s12: - case fpu_s13: - case fpu_s14: - case fpu_s15: - case fpu_s16: - case fpu_s17: - case fpu_s18: - case fpu_s19: - case fpu_s20: - case fpu_s21: - case fpu_s22: - case fpu_s23: - case fpu_s24: - case fpu_s25: - case fpu_s26: - case fpu_s27: - case fpu_s28: - case fpu_s29: - case fpu_s30: - case fpu_s31: - fpu.floats.s[reg - fpu_s0] = data.GetU32 (&offset); - break; - - case fpu_fpscr: - fpu.fpscr = data.GetU32 (&offset); - break; - - case exc_exception: - fpu.fpscr = data.GetU32 (&offset); - break; - - case exc_fsr: - exc.fsr = data.GetU32 (&offset); - break; - - case exc_far: - exc.far = data.GetU32 (&offset); - break; - - default: - return false; - } - return WriteRegisterSet(set) == KERN_SUCCESS; -} - -bool RegisterContextMach_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) { data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h index ef4b7af4e82..23fd08e656c 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h @@ -75,21 +75,17 @@ public: GetRegisterSet (uint32_t set); virtual bool - ReadRegisterValue (uint32_t reg, lldb_private::Scalar &value); - + ReadRegister (const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue ®_value); + virtual bool - ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data); - + WriteRegister (const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_value); + virtual bool ReadAllRegisterValues (lldb::DataBufferSP &data_sp); virtual bool - WriteRegisterValue (uint32_t reg, const lldb_private::Scalar &value); - - virtual bool - WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset = 0); - - virtual bool WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); virtual uint32_t diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp index 6bf4dec3691..be1a10f5df2 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp @@ -15,6 +15,7 @@ // Other libraries and framework includes #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Host/Endian.h" @@ -553,8 +554,10 @@ RegisterContextMach_i386::WriteRegisterSet (uint32_t set) } bool -RegisterContextMach_i386::ReadRegisterValue (uint32_t reg, Scalar &value) +RegisterContextMach_i386::ReadRegister (const RegisterInfo *reg_info, + RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = RegisterContextMach_i386::GetSetForNativeRegNum (reg); if (set == -1) @@ -671,8 +674,10 @@ RegisterContextMach_i386::ReadRegisterValue (uint32_t reg, Scalar &value) bool -RegisterContextMach_i386::WriteRegisterValue (uint32_t reg, const Scalar &value) +RegisterContextMach_i386::WriteRegister (const RegisterInfo *reg_info, + const RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = GetSetForNativeRegNum (reg); if (set == -1) @@ -699,47 +704,47 @@ RegisterContextMach_i386::WriteRegisterValue (uint32_t reg, const Scalar &value) case gpr_es: case gpr_fs: case gpr_gs: - (&gpr.eax)[reg - gpr_eax] = value.UInt(0); + (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32(); break; case fpu_fcw: - fpu.fcw = value.UInt(0); + fpu.fcw = value.GetAsUInt16(); break; case fpu_fsw: - fpu.fsw = value.UInt(0); + fpu.fsw = value.GetAsUInt16(); break; case fpu_ftw: - fpu.ftw = value.UInt(0); + fpu.ftw = value.GetAsUInt8(); break; case fpu_fop: - fpu.fop = value.UInt(0); + fpu.fop = value.GetAsUInt16(); break; case fpu_ip: - fpu.ip = value.UInt(0); + fpu.ip = value.GetAsUInt32(); break; case fpu_cs: - fpu.cs = value.UInt(0); + fpu.cs = value.GetAsUInt16(); break; case fpu_dp: - fpu.dp = value.UInt(0); + fpu.dp = value.GetAsUInt32(); break; case fpu_ds: - fpu.ds = value.UInt(0); + fpu.ds = value.GetAsUInt16(); break; case fpu_mxcsr: - fpu.mxcsr = value.UInt(0); + fpu.mxcsr = value.GetAsUInt32(); break; case fpu_mxcsrmask: - fpu.mxcsrmask = value.UInt(0); + fpu.mxcsrmask = value.GetAsUInt32(); break; case fpu_stmm0: @@ -752,7 +757,7 @@ RegisterContextMach_i386::WriteRegisterValue (uint32_t reg, const Scalar &value) case fpu_stmm7: // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() // must be used for these registers - //::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, reg_value.value.vector.uint8, 10); + ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); return false; case fpu_xmm0: @@ -765,254 +770,19 @@ RegisterContextMach_i386::WriteRegisterValue (uint32_t reg, const Scalar &value) case fpu_xmm7: // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() // must be used for these registers - //::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, reg_value.value.vector.uint8, 16); + ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); return false; case exc_trapno: - exc.trapno = value.UInt(0); + exc.trapno = value.GetAsUInt32(); break; case exc_err: - exc.err = value.UInt(0); + exc.err = value.GetAsUInt32(); break; case exc_faultvaddr: - exc.faultvaddr = value.UInt(0); - break; - - default: - return false; - } - return WriteRegisterSet(set) == KERN_SUCCESS; -} - -bool -RegisterContextMach_i386::ReadRegisterBytes (uint32_t reg, DataExtractor &data) -{ - int set = RegisterContextMach_i386::GetSetForNativeRegNum (reg); - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL) - return false; - - switch (reg) - { - case gpr_eax: - case gpr_ebx: - case gpr_ecx: - case gpr_edx: - case gpr_edi: - case gpr_esi: - case gpr_ebp: - case gpr_esp: - case gpr_ss: - case gpr_eflags: - case gpr_eip: - case gpr_cs: - case gpr_ds: - case gpr_es: - case gpr_fs: - case gpr_gs: - data.SetData(&gpr.eax + reg - gpr_eax, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_fcw: - data.SetData(&fpu.fcw, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_fsw: - data.SetData(&fpu.fsw, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_ftw: - data.SetData(&fpu.ftw, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_fop: - data.SetData(&fpu.fop, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_ip: - data.SetData(&fpu.ip, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_cs: - data.SetData(&fpu.cs, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_dp: - data.SetData(&fpu.dp, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_ds: - data.SetData(&fpu.ds, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_mxcsr: - data.SetData(&fpu.mxcsr, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_mxcsrmask: - data.SetData(&fpu.mxcsrmask, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - data.SetData(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - data.SetData(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_trapno: - data.SetData(&exc.trapno, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_err: - data.SetData(&exc.err, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_faultvaddr: - data.SetData(&exc.faultvaddr, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - default: - return false; - } - return true; -} - -bool -RegisterContextMach_i386::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset) -{ - int set = GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - - const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL && data.ValidOffsetForDataOfSize(data_offset, reg_info->byte_size)) - return false; - - uint32_t offset = data_offset; - switch (reg) - { - case gpr_eax: - case gpr_ebx: - case gpr_ecx: - case gpr_edx: - case gpr_edi: - case gpr_esi: - case gpr_ebp: - case gpr_esp: - case gpr_ss: - case gpr_eflags: - case gpr_eip: - case gpr_cs: - case gpr_ds: - case gpr_es: - case gpr_fs: - case gpr_gs: - (&gpr.eax)[reg - gpr_eax] = data.GetU32 (&offset); - break; - - case fpu_fcw: - fpu.fcw = data.GetU16(&offset); - break; - - case fpu_fsw: - fpu.fsw = data.GetU16(&offset); - break; - - case fpu_ftw: - fpu.ftw = data.GetU8(&offset); - break; - - case fpu_fop: - fpu.fop = data.GetU16(&offset); - break; - - case fpu_ip: - fpu.ip = data.GetU32(&offset); - break; - - case fpu_cs: - fpu.cs = data.GetU16(&offset); - break; - - case fpu_dp: - fpu.dp = data.GetU32(&offset); - break; - - case fpu_ds: - fpu.ds = data.GetU16(&offset); - break; - - case fpu_mxcsr: - fpu.mxcsr = data.GetU32(&offset); - break; - - case fpu_mxcsrmask: - fpu.mxcsrmask = data.GetU32(&offset); - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, data.PeekData(offset, reg_info->byte_size), reg_info->byte_size); - return false; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, data.PeekData(offset, reg_info->byte_size), reg_info->byte_size); - return false; - - case exc_trapno: - exc.trapno = data.GetU32 (&offset); - break; - - case exc_err: - exc.err = data.GetU32 (&offset); - break; - - case exc_faultvaddr: - exc.faultvaddr = data.GetU32 (&offset); + exc.faultvaddr = value.GetAsUInt32(); break; default: diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h index 969fa9a1417..c066107d78c 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h @@ -43,21 +43,15 @@ public: GetRegisterSet (uint32_t set); virtual bool - ReadRegisterValue (uint32_t reg, lldb_private::Scalar &value); + ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); virtual bool - ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data); - + WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); + virtual bool ReadAllRegisterValues (lldb::DataBufferSP &data_sp); virtual bool - WriteRegisterValue (uint32_t reg, const lldb_private::Scalar &value); - - virtual bool - WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset = 0); - - virtual bool WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); virtual uint32_t diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp index 098a168ed38..7cdcbbb3975 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp @@ -15,6 +15,7 @@ // Other libraries and framework includes #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Host/Endian.h" @@ -600,10 +601,11 @@ RegisterContextMach_x86_64::WriteRegisterSet(uint32_t set) bool -RegisterContextMach_x86_64::ReadRegisterValue (uint32_t reg, Scalar &value) +RegisterContextMach_x86_64::ReadRegister (const RegisterInfo *reg_info, + RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = RegisterContextMach_x86_64::GetSetForNativeRegNum (reg); - if (set == -1) return false; @@ -684,11 +686,8 @@ RegisterContextMach_x86_64::ReadRegisterValue (uint32_t reg, Scalar &value) case fpu_stmm5: case fpu_stmm6: case fpu_stmm7: - // These values don't fit into scalar types, - // RegisterContext::ReadRegisterBytes() must be used for these - // registers - //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes, 10); - return false; + value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); + break; case fpu_xmm0: case fpu_xmm1: @@ -706,10 +705,8 @@ RegisterContextMach_x86_64::ReadRegisterValue (uint32_t reg, Scalar &value) case fpu_xmm13: case fpu_xmm14: case fpu_xmm15: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes, 16); - return false; + value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); + break; case exc_trapno: value = exc.trapno; @@ -731,8 +728,10 @@ RegisterContextMach_x86_64::ReadRegisterValue (uint32_t reg, Scalar &value) bool -RegisterContextMach_x86_64::WriteRegisterValue (uint32_t reg, const Scalar &value) +RegisterContextMach_x86_64::WriteRegister (const RegisterInfo *reg_info, + const RegisterValue &value) { + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = RegisterContextMach_x86_64::GetSetForNativeRegNum (reg); if (set == -1) @@ -764,47 +763,47 @@ RegisterContextMach_x86_64::WriteRegisterValue (uint32_t reg, const Scalar &valu case gpr_cs: case gpr_fs: case gpr_gs: - (&gpr.rax)[reg - gpr_rax] = value.ULongLong(0); + (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64(); break; case fpu_fcw: - fpu.fcw = value.UInt(0); + fpu.fcw = value.GetAsUInt16(); break; case fpu_fsw: - fpu.fsw = value.UInt(0); + fpu.fsw = value.GetAsUInt16(); break; case fpu_ftw: - fpu.ftw = value.UInt(0); + fpu.ftw = value.GetAsUInt8(); break; case fpu_fop: - fpu.fop = value.UInt(0); + fpu.fop = value.GetAsUInt16(); break; case fpu_ip: - fpu.ip = value.UInt(0); + fpu.ip = value.GetAsUInt32(); break; case fpu_cs: - fpu.cs = value.UInt(0); + fpu.cs = value.GetAsUInt16(); break; case fpu_dp: - fpu.dp = value.UInt(0); + fpu.dp = value.GetAsUInt32(); break; case fpu_ds: - fpu.ds = value.UInt(0); + fpu.ds = value.GetAsUInt16(); break; case fpu_mxcsr: - fpu.mxcsr = value.UInt(0); + fpu.mxcsr = value.GetAsUInt32(); break; case fpu_mxcsrmask: - fpu.mxcsrmask = value.UInt(0); + fpu.mxcsrmask = value.GetAsUInt32(); break; case fpu_stmm0: @@ -815,272 +814,9 @@ RegisterContextMach_x86_64::WriteRegisterValue (uint32_t reg, const Scalar &valu case fpu_stmm5: case fpu_stmm6: case fpu_stmm7: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - //::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, reg_value.value.vector.uint8, 10); - return false; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - case fpu_xmm8: - case fpu_xmm9: - case fpu_xmm10: - case fpu_xmm11: - case fpu_xmm12: - case fpu_xmm13: - case fpu_xmm14: - case fpu_xmm15: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - //::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, reg_value.value.vector.uint8, 16); - return false; - - case exc_trapno: - exc.trapno = value.UInt(0); - break; - - case exc_err: - exc.err = value.UInt(0); + ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); break; - case exc_faultvaddr: - exc.faultvaddr = value.UInt(0); - break; - - default: - return false; - } - return WriteRegisterSet(set) == KERN_SUCCESS; -} - -bool -RegisterContextMach_x86_64::ReadRegisterBytes (uint32_t reg, DataExtractor &data) -{ - int set = RegisterContextMach_x86_64::GetSetForNativeRegNum (reg); - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL) - return false; - - switch (reg) - { - case gpr_rax: - case gpr_rbx: - case gpr_rcx: - case gpr_rdx: - case gpr_rdi: - case gpr_rsi: - case gpr_rbp: - case gpr_rsp: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_r13: - case gpr_r14: - case gpr_r15: - case gpr_rip: - case gpr_rflags: - case gpr_cs: - case gpr_fs: - case gpr_gs: - data.SetData(&gpr.rax + reg - gpr_rax, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_fcw: - data.SetData(&fpu.fcw, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_fsw: - data.SetData(&fpu.fsw, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_ftw: - data.SetData(&fpu.ftw, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_fop: - data.SetData(&fpu.fop, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_ip: - data.SetData(&fpu.ip, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_cs: - data.SetData(&fpu.cs, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_dp: - data.SetData(&fpu.dp, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_ds: - data.SetData(&fpu.ds, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_mxcsr: - data.SetData(&fpu.mxcsr, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_mxcsrmask: - data.SetData(&fpu.mxcsrmask, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - data.SetData(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - case fpu_xmm8: - case fpu_xmm9: - case fpu_xmm10: - case fpu_xmm11: - case fpu_xmm12: - case fpu_xmm13: - case fpu_xmm14: - case fpu_xmm15: - data.SetData(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_trapno: - data.SetData(&exc.trapno, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_err: - data.SetData(&exc.err, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_faultvaddr: - data.SetData(&exc.faultvaddr, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - default: - return false; - } - return true; -} - -bool -RegisterContextMach_x86_64::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset) -{ - int set = RegisterContextMach_x86_64::GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - - const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL && data.ValidOffsetForDataOfSize(data_offset, reg_info->byte_size)) - return false; - - uint32_t offset = data_offset; - switch (reg) - { - case gpr_rax: - case gpr_rbx: - case gpr_rcx: - case gpr_rdx: - case gpr_rdi: - case gpr_rsi: - case gpr_rbp: - case gpr_rsp: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_r13: - case gpr_r14: - case gpr_r15: - case gpr_rip: - case gpr_rflags: - case gpr_cs: - case gpr_fs: - case gpr_gs: - (&gpr.rax)[reg - gpr_rax] = data.GetU32 (&offset); - break; - - case fpu_fcw: - fpu.fcw = data.GetU16(&offset); - break; - - case fpu_fsw: - fpu.fsw = data.GetU16(&offset); - break; - - case fpu_ftw: - fpu.ftw = data.GetU8(&offset); - break; - - case fpu_fop: - fpu.fop = data.GetU16(&offset); - break; - - case fpu_ip: - fpu.ip = data.GetU32(&offset); - break; - - case fpu_cs: - fpu.cs = data.GetU16(&offset); - break; - - case fpu_dp: - fpu.dp = data.GetU32(&offset); - break; - - case fpu_ds: - fpu.ds = data.GetU16(&offset); - break; - - case fpu_mxcsr: - fpu.mxcsr = data.GetU32(&offset); - break; - - case fpu_mxcsrmask: - fpu.mxcsrmask = data.GetU32(&offset); - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, data.PeekData(offset, reg_info->byte_size), reg_info->byte_size); - return false; - case fpu_xmm0: case fpu_xmm1: case fpu_xmm2: @@ -1097,21 +833,19 @@ RegisterContextMach_x86_64::WriteRegisterBytes (uint32_t reg, DataExtractor &dat case fpu_xmm13: case fpu_xmm14: case fpu_xmm15: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, data.PeekData(offset, reg_info->byte_size), reg_info->byte_size); + ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); return false; case exc_trapno: - exc.trapno = data.GetU32 (&offset); + exc.trapno = value.GetAsUInt32(); break; case exc_err: - exc.err = data.GetU32 (&offset); + exc.err = value.GetAsUInt32(); break; case exc_faultvaddr: - exc.faultvaddr = data.GetU32 (&offset); + exc.faultvaddr = value.GetAsUInt64(); break; default: diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h index 5b0bdc7ed31..e8217222da1 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h @@ -42,21 +42,15 @@ public: GetRegisterSet (uint32_t set); virtual bool - ReadRegisterValue (uint32_t reg, lldb_private::Scalar &value); + ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); virtual bool - ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data); - + WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); + virtual bool ReadAllRegisterValues (lldb::DataBufferSP &data_sp); virtual bool - WriteRegisterValue (uint32_t reg, const lldb_private::Scalar &value); - - virtual bool - WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset = 0); - - virtual bool WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); virtual uint32_t diff --git a/lldb/source/Plugins/Process/Utility/ARMUtils.h b/lldb/source/Plugins/Process/Utility/ARMUtils.h index 71ee03afe99..e950f2b55df 100644 --- a/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ b/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -1,4 +1,4 @@ -//===-- lldb_ARMUtils.h -----------------------------------------*- C++ -*-===// +//===-- ARMUtils.h ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/lldb/source/Plugins/Process/Utility/InstructionUtils.h index c03b63e7644..4bb644e6efe 100644 --- a/lldb/source/Plugins/Process/Utility/InstructionUtils.h +++ b/lldb/source/Plugins/Process/Utility/InstructionUtils.h @@ -1,4 +1,4 @@ -//===-- lldb_InstructionUtils.h ---------------------------------*- C++ -*-===// +//===-- InstructionUtils.h --------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -36,7 +36,13 @@ Bits32 (const uint32_t bits, const uint32_t msbit, const uint32_t lsbit) static inline uint32_t Bit32 (const uint32_t bits, const uint32_t bit) { - return Bits32(bits, bit, bit); + return (bits >> bit) & 1u; +} + +static inline uint64_t +Bit64 (const uint64_t bits, const uint32_t bit) +{ + return (bits >> bit) & 1ull; } // Set the bit field(s) from the most significant bit (msbit) to the diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 1b63ad795b7..ef882fa540d 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -14,6 +14,7 @@ #include "lldb/Core/AddressRange.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Log.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/Function.h" @@ -658,132 +659,99 @@ RegisterContextLLDB::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_ } bool -RegisterContextLLDB::ReadRegisterBytesFromRegisterLocation (uint32_t regnum, RegisterLocation regloc, DataExtractor &data) +RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (RegisterLocation regloc, + const RegisterInfo *reg_info, + RegisterValue &value) { if (!IsValid()) return false; + bool success = false; - if (regloc.type == eRegisterInRegister) + switch (regloc.type) { - data.SetAddressByteSize (m_thread.GetProcess().GetAddressByteSize()); - data.SetByteOrder (m_thread.GetProcess().GetByteOrder()); - if (IsFrameZero ()) - { - return m_thread.GetRegisterContext()->ReadRegisterBytes (regloc.location.register_number, data); - } - else - { - return m_next_frame->ReadRegisterBytes (regloc.location.register_number, data); - } - } - if (regloc.type == eRegisterNotSaved) - { - return false; - } - if (regloc.type == eRegisterSavedAtHostMemoryLocation) - { - assert ("FIXME debugger inferior function call unwind"); - } - if (regloc.type != eRegisterSavedAtMemoryLocation) - { - assert ("Unknown RegisterLocation type."); - } - - const RegisterInfo *reg_info = m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (regnum); - DataBufferSP data_sp (new DataBufferHeap (reg_info->byte_size, 0)); - data.SetData (data_sp, 0, reg_info->byte_size); - data.SetAddressByteSize (m_thread.GetProcess().GetAddressByteSize()); - - if (regloc.type == eRegisterValueInferred) - { - data.SetByteOrder (lldb::endian::InlHostByteOrder()); - switch (reg_info->byte_size) + case eRegisterInRegister: { - case 1: - { - uint8_t val = regloc.location.register_value; - memcpy (data_sp->GetBytes(), &val, sizeof (val)); - data.SetByteOrder (lldb::endian::InlHostByteOrder()); - return true; - } - case 2: - { - uint16_t val = regloc.location.register_value; - memcpy (data_sp->GetBytes(), &val, sizeof (val)); - data.SetByteOrder (lldb::endian::InlHostByteOrder()); - return true; - } - case 4: + const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); + if (IsFrameZero ()) { - uint32_t val = regloc.location.register_value; - memcpy (data_sp->GetBytes(), &val, sizeof (val)); - data.SetByteOrder (lldb::endian::InlHostByteOrder()); - return true; + success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value); } - case 8: + else { - uint64_t val = regloc.location.register_value; - memcpy (data_sp->GetBytes(), &val, sizeof (val)); - data.SetByteOrder (lldb::endian::InlHostByteOrder()); - return true; + success = m_next_frame->ReadRegister (other_reg_info, value); } } - return false; + break; + case eRegisterValueInferred: + success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size); + break; + + case eRegisterNotSaved: + break; + case eRegisterSavedAtHostMemoryLocation: + assert ("FIXME debugger inferior function call unwind"); + break; + case eRegisterSavedAtMemoryLocation: + { + Error error (ReadRegisterValueFromMemory(reg_info, + regloc.location.target_memory_location, + reg_info->byte_size, + value)); + success = error.Success(); + } + break; + default: + assert ("Unknown RegisterLocation type."); + break; } - - assert (regloc.type == eRegisterSavedAtMemoryLocation); - Error error; - data.SetByteOrder (m_thread.GetProcess().GetByteOrder()); - if (!m_thread.GetProcess().ReadMemory (regloc.location.target_memory_location, data_sp->GetBytes(), reg_info->byte_size, error)) - return false; - return true; + return success; } bool -RegisterContextLLDB::WriteRegisterBytesToRegisterLocation (uint32_t regnum, RegisterLocation regloc, DataExtractor &data, uint32_t data_offset) +RegisterContextLLDB::WriteRegisterValueToRegisterLocation (RegisterLocation regloc, + const RegisterInfo *reg_info, + const RegisterValue &value) { if (!IsValid()) return false; - if (regloc.type == eRegisterInRegister) - { - if (IsFrameZero ()) - { - return m_thread.GetRegisterContext()->WriteRegisterBytes (regloc.location.register_number, data, data_offset); - } - else - { - return m_next_frame->WriteRegisterBytes (regloc.location.register_number, data, data_offset); - } - } - if (regloc.type == eRegisterNotSaved) - { - return false; - } - if (regloc.type == eRegisterValueInferred) - { - return false; - } - if (regloc.type == eRegisterSavedAtHostMemoryLocation) - { - assert ("FIXME debugger inferior function call unwind"); - } - if (regloc.type != eRegisterSavedAtMemoryLocation) + bool success = false; + + switch (regloc.type) { - assert ("Unknown RegisterLocation type."); + case eRegisterInRegister: + { + const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); + if (IsFrameZero ()) + { + success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value); + } + else + { + success = m_next_frame->WriteRegister (other_reg_info, value); + } + } + break; + case eRegisterValueInferred: + case eRegisterNotSaved: + break; + case eRegisterSavedAtHostMemoryLocation: + assert ("FIXME debugger inferior function call unwind"); + break; + case eRegisterSavedAtMemoryLocation: + { + Error error (WriteRegisterValueToMemory (reg_info, + regloc.location.target_memory_location, + reg_info->byte_size, + value)); + success = error.Success(); + } + break; + default: + assert ("Unknown RegisterLocation type."); + break; } - - Error error; - const RegisterInfo *reg_info = m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (regnum); - if (reg_info->byte_size == 0) - return false; - uint8_t *buf = (uint8_t*) alloca (reg_info->byte_size); - if (data.ExtractBytes (data_offset, reg_info->byte_size, m_thread.GetProcess().GetByteOrder(), buf) != reg_info->byte_size) - return false; - if (m_thread.GetProcess().WriteMemory (regloc.location.target_memory_location, buf, reg_info->byte_size, error) != reg_info->byte_size) - return false; - - return true; + return success; } @@ -818,10 +786,10 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, eRegisterKindLLDB, sp_regnum) && sp_regnum == lldb_regnum) { - // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.register_value) + // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value) assert (sizeof (addr_t) <= sizeof (uint64_t)); regloc.type = eRegisterValueInferred; - regloc.location.register_value = m_cfa; + regloc.location.inferred_value = m_cfa; m_registers[lldb_regnum] = regloc; return true; } @@ -976,7 +944,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc { int offset = unwindplan_regloc.GetOffset(); regloc.type = eRegisterValueInferred; - regloc.location.register_value = m_cfa + offset; + regloc.location.inferred_value = m_cfa + offset; m_registers[lldb_regnum] = regloc; return true; } @@ -1027,7 +995,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc if (unwindplan_regloc.IsDWARFExpression()) { regloc.type = eRegisterValueInferred; - regloc.location.register_value = val; + regloc.location.inferred_value = val; m_registers[lldb_regnum] = regloc; return true; } @@ -1090,18 +1058,14 @@ RegisterContextLLDB::ReadGPRValue (int register_kind, uint32_t regnum, addr_t &v return false; } - uint32_t offset = 0; - DataExtractor data; - data.SetAddressByteSize (m_thread.GetProcess().GetAddressByteSize()); - data.SetByteOrder (m_thread.GetProcess().GetByteOrder()); - + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); + RegisterValue reg_value; // if this is frame 0 (currently executing frame), get the requested reg contents from the actual thread registers if (IsFrameZero ()) { - if (m_thread.GetRegisterContext()->ReadRegisterBytes (lldb_regnum, data)) + if (m_thread.GetRegisterContext()->ReadRegister (reg_info, reg_value)) { - data.SetAddressByteSize (m_thread.GetProcess().GetAddressByteSize()); - value = data.GetAddress (&offset); + value = reg_value.GetAsUInt64(); return true; } return false; @@ -1112,29 +1076,29 @@ RegisterContextLLDB::ReadGPRValue (int register_kind, uint32_t regnum, addr_t &v { return false; } - if (!ReadRegisterBytesFromRegisterLocation (lldb_regnum, regloc, data)) + if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value)) { - return false; + value = reg_value.GetAsUInt64(); + return true; } - data.SetAddressByteSize (m_thread.GetProcess().GetAddressByteSize()); - value = data.GetAddress (&offset); - return true; + return false; } // Find the value of a register in THIS frame bool -RegisterContextLLDB::ReadRegisterBytes (uint32_t lldb_reg, DataExtractor& data) +RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); if (!IsValid()) return false; + const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; if (log && IsLogVerbose ()) { log->Printf("%*sFrame %u looking for register saved location for reg %d", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_reg); + lldb_regnum); } // If this is the 0th frame, hand this over to the live register context @@ -1144,31 +1108,32 @@ RegisterContextLLDB::ReadRegisterBytes (uint32_t lldb_reg, DataExtractor& data) { log->Printf("%*sFrame %u passing along to the live register context for reg %d", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_reg); + lldb_regnum); } - return m_thread.GetRegisterContext()->ReadRegisterBytes (lldb_reg, data); + return m_thread.GetRegisterContext()->ReadRegister (reg_info, value); } RegisterLocation regloc; // Find out where the NEXT frame saved THIS frame's register contents - if (!m_next_frame->SavedLocationForRegister (lldb_reg, regloc)) + if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc)) return false; - return ReadRegisterBytesFromRegisterLocation (lldb_reg, regloc, data); + return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value); } bool -RegisterContextLLDB::WriteRegisterBytes (uint32_t lldb_reg, DataExtractor &data, uint32_t data_offset) +RegisterContextLLDB::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); if (!IsValid()) return false; + const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; if (log && IsLogVerbose ()) { log->Printf("%*sFrame %u looking for register saved location for reg %d", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_reg); + lldb_regnum); } // If this is the 0th frame, hand this over to the live register context @@ -1178,17 +1143,17 @@ RegisterContextLLDB::WriteRegisterBytes (uint32_t lldb_reg, DataExtractor &data, { log->Printf("%*sFrame %u passing along to the live register context for reg %d", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_reg); + lldb_regnum); } - return m_thread.GetRegisterContext()->WriteRegisterBytes (lldb_reg, data, data_offset); + return m_thread.GetRegisterContext()->WriteRegister (reg_info, value); } RegisterLocation regloc; // Find out where the NEXT frame saved THIS frame's register contents - if (!m_next_frame->SavedLocationForRegister (lldb_reg, regloc)) + if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc)) return false; - return WriteRegisterBytesToRegisterLocation (lldb_reg, regloc, data, data_offset); + return WriteRegisterValueToRegisterLocation (regloc, reg_info, value); } // Don't need to implement this one diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h index ac2c5609cdc..b255636291a 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -50,13 +50,13 @@ public: GetRegisterSet (uint32_t reg_set); virtual bool - ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data); + ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - + WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); + virtual bool - WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset = 0); + ReadAllRegisterValues (lldb::DataBufferSP &data_sp); virtual bool WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); @@ -92,7 +92,7 @@ private: eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location) eRegisterInRegister, // register is available in a (possible other) register (register_number) eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space - eRegisterValueInferred // register val was computed (and is in register_value) + eRegisterValueInferred // register val was computed (and is in inferred_value) }; struct RegisterLocation @@ -103,7 +103,7 @@ private: lldb::addr_t target_memory_location; uint32_t register_number; // in eRegisterKindLLDB register numbering system void* host_memory_location; - uint64_t register_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset + uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset } location; }; @@ -138,10 +138,14 @@ private: SavedLocationForRegister (uint32_t lldb_regnum, RegisterLocation ®loc); bool - ReadRegisterBytesFromRegisterLocation (uint32_t regnum, RegisterLocation regloc, lldb_private::DataExtractor &data); + ReadRegisterValueFromRegisterLocation (RegisterLocation regloc, + const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value); bool - WriteRegisterBytesToRegisterLocation (uint32_t regnum, RegisterLocation regloc, lldb_private::DataExtractor &data, uint32_t data_offset); + WriteRegisterValueToRegisterLocation (RegisterLocation regloc, + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value); // Get the contents of a general purpose (address-size) register for this frame // (usually retrieved from the m_next_frame) diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index 0263d77bae5..e00913ea1cf 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/StreamString.h" #include "lldb/Target/Thread.h" @@ -80,17 +81,14 @@ RegisterContextMacOSXFrameBackchain::GetRegisterSet (uint32_t reg_set) bool -RegisterContextMacOSXFrameBackchain::ReadRegisterValue (uint32_t reg, Scalar &value) +RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info, + RegisterValue &value) { if (!m_cursor_is_valid) return false; uint64_t reg_value = LLDB_INVALID_ADDRESS; - const RegisterInfo *reg_info = m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg); - if (reg_info == NULL) - return false; - switch (reg_info->kinds[eRegisterKindGeneric]) { case LLDB_REGNUM_GENERIC_PC: @@ -116,34 +114,9 @@ RegisterContextMacOSXFrameBackchain::ReadRegisterValue (uint32_t reg, Scalar &va break; case eEncodingUint: - switch (reg_info->byte_size) - { - case 1: - case 2: - case 4: - value = (uint32_t)reg_value; - return true; - - case 8: - value = (uint64_t)reg_value; - return true; - } - break; - case eEncodingSint: - switch (reg_info->byte_size) - { - case 1: - case 2: - case 4: - value = (int32_t)reg_value; - return true; - - case 8: - value = (int64_t)reg_value; - return true; - } - break; + value.SetUInt(reg_value, reg_info->byte_size); + return true; case eEncodingIEEE754: switch (reg_info->byte_size) @@ -151,12 +124,12 @@ RegisterContextMacOSXFrameBackchain::ReadRegisterValue (uint32_t reg, Scalar &va case sizeof (float): if (sizeof (float) == sizeof(uint32_t)) { - value = (uint32_t)reg_value; + value.SetUInt32(reg_value, RegisterValue::eTypeFloat); return true; } else if (sizeof (float) == sizeof(uint64_t)) { - value = (uint64_t)reg_value; + value.SetUInt64(reg_value, RegisterValue::eTypeFloat); return true; } break; @@ -164,12 +137,12 @@ RegisterContextMacOSXFrameBackchain::ReadRegisterValue (uint32_t reg, Scalar &va case sizeof (double): if (sizeof (double) == sizeof(uint32_t)) { - value = (uint32_t)reg_value; + value.SetUInt32(reg_value, RegisterValue::eTypeDouble); return true; } else if (sizeof (double) == sizeof(uint64_t)) { - value = (uint64_t)reg_value; + value.SetUInt64(reg_value, RegisterValue::eTypeDouble); return true; } break; @@ -177,12 +150,12 @@ RegisterContextMacOSXFrameBackchain::ReadRegisterValue (uint32_t reg, Scalar &va case sizeof (long double): if (sizeof (long double) == sizeof(uint32_t)) { - value = (uint32_t)reg_value; + value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble); return true; } else if (sizeof (long double) == sizeof(uint64_t)) { - value = (uint64_t)reg_value; + value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble); return true; } break; @@ -192,45 +165,15 @@ RegisterContextMacOSXFrameBackchain::ReadRegisterValue (uint32_t reg, Scalar &va return false; } - -bool -RegisterContextMacOSXFrameBackchain::ReadRegisterBytes (uint32_t reg, DataExtractor &data) -{ - Scalar reg_value; - - if (ReadRegisterValue (reg, reg_value)) - { - if (reg_value.GetData(data)) - { - // "reg_value" is local and now "data" points to the data within - // "reg_value", so we must make a copy that will live within "data" - DataBufferSP data_sp (new DataBufferHeap (data.GetDataStart(), data.GetByteSize())); - data.SetData (data_sp, 0, data.GetByteSize()); - return true; - } - } - return false; -} - - bool -RegisterContextMacOSXFrameBackchain::WriteRegisterValue (uint32_t reg, const Scalar &value) +RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info, + const RegisterValue &value) { // Not supported yet. We could easily add support for this by remembering // the address of each entry (it would need to be part of the cursor) return false; } - -bool -RegisterContextMacOSXFrameBackchain::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset) -{ - // Not supported yet. We could easily add support for this by remembering - // the address of each entry (it would need to be part of the cursor) - return false; -} - - bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) { diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h index bc7c2a0e90a..cc6cb5d5d8c 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h @@ -51,21 +51,15 @@ public: GetRegisterSet (uint32_t reg_set); virtual bool - ReadRegisterValue (uint32_t reg, lldb_private::Scalar &value); + ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); virtual bool - ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data); - + WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); + virtual bool ReadAllRegisterValues (lldb::DataBufferSP &data_sp); virtual bool - WriteRegisterValue (uint32_t reg, const lldb_private::Scalar &value); - - virtual bool - WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset); - - virtual bool WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); virtual uint32_t diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 841efa207db..bf1a00c8fdb 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/StreamString.h" // Project includes @@ -115,65 +116,14 @@ GDBRemoteRegisterContext::GetRegisterSet (uint32_t reg_set) bool -GDBRemoteRegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) +GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) { // Read the register - if (ReadRegisterBytes (reg, m_reg_data)) + if (ReadRegisterBytes (reg_info, value, m_reg_data)) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - uint32_t offset = reg_info->byte_offset; - switch (reg_info->encoding) - { - case eEncodingUint: - switch (reg_info->byte_size) - { - case 1: - case 2: - case 4: - value = m_reg_data.GetMaxU32 (&offset, reg_info->byte_size); - return true; - - case 8: - value = m_reg_data.GetMaxU64 (&offset, reg_info->byte_size); - return true; - } - break; - - case eEncodingSint: - switch (reg_info->byte_size) - { - case 1: - case 2: - case 4: - value = (int32_t)m_reg_data.GetMaxU32 (&offset, reg_info->byte_size); - return true; - - case 8: - value = m_reg_data.GetMaxS64 (&offset, reg_info->byte_size); - return true; - } - break; - - case eEncodingIEEE754: - switch (reg_info->byte_size) - { - case sizeof (float): - value = m_reg_data.GetFloat (&offset); - return true; - - case sizeof (double): - value = m_reg_data.GetDouble (&offset); - return true; - - case sizeof (long double): - value = m_reg_data.GetLongDouble (&offset); - return true; - } - break; - - default: - break; - } + const bool partial_data_ok = false; + Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); + return error.Success(); } return false; } @@ -206,14 +156,14 @@ GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor bool -GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) +GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, RegisterValue &value, DataExtractor &data) { GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote()); InvalidateIfNeeded(false); - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - assert (reg_info); + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + if (!m_reg_valid[reg]) { Mutex::Locker locker; @@ -243,6 +193,7 @@ GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) else { // Get each register individually + if (thread_suffix_supported) packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4x;", reg, m_thread.GetID()); else @@ -274,21 +225,18 @@ GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) bool -GDBRemoteRegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value) +GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info, + const RegisterValue &value) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info) - { - DataExtractor data; - if (value.GetData (data, reg_info->byte_size)) - return WriteRegisterBytes (reg, data, 0); - } + DataExtractor data; + if (value.GetData (data)) + return WriteRegisterBytes (reg_info, value, data, 0); return false; } bool -GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset) +GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, const RegisterValue &value, DataExtractor &data, uint32_t data_offset) { GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote()); // FIXME: This check isn't right because IsRunning checks the Public state, but this @@ -297,34 +245,21 @@ GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, // if (gdb_comm.IsRunning()) // return false; - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - - if (reg_info) - { - // Grab a pointer to where we are going to put this register - uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); - - if (dst == NULL) - return false; - - // Grab a pointer to where we are going to grab the new value from - const uint8_t *src = data.PeekData(0, reg_info->byte_size); + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - if (src == NULL) - return false; - - if (data.GetByteOrder() == m_reg_data.GetByteOrder()) - { - // No swapping, just copy the bytes - ::memcpy (dst, src, reg_info->byte_size); - } - else - { - // Swap the bytes - for (uint32_t i=0; i<reg_info->byte_size; ++i) - dst[i] = src[reg_info->byte_size - 1 - i]; - } + // Grab a pointer to where we are going to put this register + uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); + if (dst == NULL) + return false; + + + if (data.CopyByteOrderedData (data_offset, // src offset + reg_info->byte_size, // src length + dst, // dst + reg_info->byte_size, // dst length + m_reg_data.GetByteOrder())) // dst byte order + { Mutex::Locker locker; if (gdb_comm.GetSequenceMutex (locker)) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 3848ffcd50d..315284780a4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -208,21 +208,15 @@ public: GetRegisterSet (uint32_t reg_set); virtual bool - ReadRegisterValue (uint32_t reg, lldb_private::Scalar &value); + ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); virtual bool - ReadRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data); - + WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); + virtual bool ReadAllRegisterValues (lldb::DataBufferSP &data_sp); virtual bool - WriteRegisterValue (uint32_t reg, const lldb_private::Scalar &value); - - virtual bool - WriteRegisterBytes (uint32_t reg, lldb_private::DataExtractor &data, uint32_t data_offset); - - virtual bool WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); virtual uint32_t @@ -232,6 +226,17 @@ protected: friend class ThreadGDBRemote; bool + ReadRegisterBytes (const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value, + lldb_private::DataExtractor &data); + + bool + WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value, + lldb_private::DataExtractor &data, + uint32_t data_offset); + + bool PrivateSetRegisterValue (uint32_t reg, StringExtractor &response); void diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 787778a64c6..0ce503cf7ea 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -103,7 +103,8 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& // We use the address byte size to be safe for any future addresss sizes RegisterInfo sp_reg_info; m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp_reg_info); - SetRegisterValue(sp_reg_info, (1ull << ((addr_byte_size * 8) - 1))); + m_initial_sp = (1ull << ((addr_byte_size * 8) - 1)); + SetRegisterValue(sp_reg_info, m_initial_sp); const InstructionList &inst_list = disasm_sp->GetInstructionList (); const size_t num_instructions = inst_list.GetSize(); @@ -155,7 +156,7 @@ UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, UnwindAssembly * UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch) { - std::auto_ptr<lldb_private::EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL)); + std::auto_ptr<EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL)); // Make sure that all prologue instructions are handled if (inst_emulator_ap.get()) return new UnwindAssemblyInstEmulation (arch, inst_emulator_ap.release()); @@ -215,28 +216,34 @@ UnwindAssemblyInstEmulation::GetPluginDescriptionStatic() uint64_t -UnwindAssemblyInstEmulation::MakeRegisterKindValuePair (const lldb_private::RegisterInfo ®_info) +UnwindAssemblyInstEmulation::MakeRegisterKindValuePair (const RegisterInfo ®_info) { uint32_t reg_kind, reg_num; - if (EmulateInstruction::GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num)) + if (EmulateInstruction::GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num)) return (uint64_t)reg_kind << 24 | reg_num; return 0ull; } void -UnwindAssemblyInstEmulation::SetRegisterValue (const lldb_private::RegisterInfo ®_info, uint64_t reg_value) +UnwindAssemblyInstEmulation::SetRegisterValue (const RegisterInfo ®_info, const RegisterValue ®_value) { m_register_values[MakeRegisterKindValuePair (reg_info)] = reg_value; } -uint64_t -UnwindAssemblyInstEmulation::GetRegisterValue (const lldb_private::RegisterInfo ®_info) +bool +UnwindAssemblyInstEmulation::GetRegisterValue (const RegisterInfo ®_info, RegisterValue ®_value) { const uint64_t reg_id = MakeRegisterKindValuePair (reg_info); RegisterValueMap::const_iterator pos = m_register_values.find(reg_id); if (pos != m_register_values.end()) - return pos->second; - return MakeRegisterKindValuePair (reg_info); + { + reg_value = pos->second; + return true; // We had a real value that comes from an opcode that wrote + // to it... + } + // We are making up a value that is recognizable... + reg_value.SetUInt(reg_id, reg_info.byte_size); + return false; } @@ -280,6 +287,7 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction, switch (context.type) { + default: case EmulateInstruction::eContextInvalid: case EmulateInstruction::eContextReadOpcode: case EmulateInstruction::eContextImmediate: @@ -299,6 +307,7 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction, case EmulateInstruction::eContextReturnFromException: case EmulateInstruction::eContextPopRegisterOffStack: case EmulateInstruction::eContextAdjustStackPointer: + assert (!"unhandled case, add code to handle this!"); break; case EmulateInstruction::eContextPushRegisterOnStack: @@ -308,8 +317,8 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction, { UnwindPlan::Row::RegisterLocation regloc; const uint32_t dwarf_reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindDWARF]; - const addr_t reg_cfa_offset = inst_emulator->m_curr_row.GetCFAOffset() + context.info.RegisterToRegisterPlusOffset.offset; - regloc.SetIsCFAPlusOffset (reg_cfa_offset); + //const addr_t reg_cfa_offset = inst_emulator->m_curr_row.GetCFAOffset() + context.info.RegisterToRegisterPlusOffset.offset; + regloc.SetAtCFAPlusOffset (addr - inst_emulator->m_initial_sp); inst_emulator->m_curr_row.SetRegisterInfo (dwarf_reg_num, regloc); } break; @@ -320,8 +329,6 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction, } break; - break; - } return dst_len; @@ -330,14 +337,19 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction, bool UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction, void *baton, - const RegisterInfo ®_info, - uint64_t ®_value) + const RegisterInfo *reg_info, + RegisterValue ®_value) { - UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton; - reg_value = inst_emulator->GetRegisterValue (reg_info); - - printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => value = 0x%16.16llx\n", reg_info.name, reg_value); + if (baton && reg_info) + { + UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton; + bool synthetic = inst_emulator->GetRegisterValue (*reg_info, reg_value); + StreamFile strm (stdout, false); + strm.Printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => synthetic_value = %i, value = ", reg_info->name, synthetic); + reg_value.Dump(&strm, reg_info, false, eFormatDefault); + strm.EOL(); + } return true; } @@ -345,20 +357,24 @@ bool UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction, void *baton, const EmulateInstruction::Context &context, - const RegisterInfo ®_info, - uint64_t reg_value) + const RegisterInfo *reg_info, + const RegisterValue ®_value) { + if (!baton || !reg_info) + return false; + UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton; - - printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = 0x%16.16llx, context =", - reg_info.name, - reg_value); + StreamFile strm (stdout, false); + strm.Printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name); + reg_value.Dump(&strm, reg_info, false, eFormatDefault); + strm.PutCString (", context = "); context.Dump(stdout, instruction); - inst_emulator->SetRegisterValue (reg_info, reg_value); + inst_emulator->SetRegisterValue (*reg_info, reg_value); switch (context.type) { + default: case EmulateInstruction::eContextInvalid: case EmulateInstruction::eContextReadOpcode: case EmulateInstruction::eContextImmediate: @@ -377,6 +393,7 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction, case EmulateInstruction::eContextAdvancePC: case EmulateInstruction::eContextReturnFromException: case EmulateInstruction::eContextPushRegisterOnStack: + assert (!"unhandled case, add code to handle this!"); break; case EmulateInstruction::eContextPopRegisterOffStack: @@ -385,7 +402,7 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction, { case EmulateInstruction::eInfoTypeRegisterPlusOffset: { - const uint32_t dwarf_reg_num = reg_info.kinds[eRegisterKindDWARF]; + const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF]; UnwindPlan::Row::RegisterLocation regloc; regloc.SetSame(); inst_emulator->m_curr_row.SetRegisterInfo (dwarf_reg_num, regloc); @@ -400,16 +417,7 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction, break; case EmulateInstruction::eContextAdjustStackPointer: - switch (context.info_type) - { - case EmulateInstruction::eInfoTypeImmediateSigned: - inst_emulator->m_curr_row.SetCFAOffset (inst_emulator->m_curr_row.GetCFAOffset() + context.info.signed_immediate); - break; - - default: - assert (!"unhandled case, add code to handle this!"); - break; - } + inst_emulator->m_curr_row.SetCFAOffset (reg_value.GetAsUInt64() - inst_emulator->m_initial_sp); break; } return true; diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h index 220864dff72..96c13813e48 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -12,6 +12,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/EmulateInstruction.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/UnwindAssembly.h" @@ -89,15 +90,15 @@ private: static bool ReadRegister (lldb_private::EmulateInstruction *instruction, void *baton, - const lldb_private::RegisterInfo ®_info, - uint64_t ®_value); + const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue ®_value); static bool WriteRegister (lldb_private::EmulateInstruction *instruction, void *baton, const lldb_private::EmulateInstruction::Context &context, - const lldb_private::RegisterInfo ®_info, - uint64_t reg_value); + const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue ®_value); // Call CreateInstance to get an instance of this class @@ -120,17 +121,20 @@ private: MakeRegisterKindValuePair (const lldb_private::RegisterInfo ®_info); void - SetRegisterValue (const lldb_private::RegisterInfo ®_info, uint64_t reg_value); + SetRegisterValue (const lldb_private::RegisterInfo ®_info, + const lldb_private::RegisterValue ®_value); - uint64_t - GetRegisterValue (const lldb_private::RegisterInfo ®_info); + bool + GetRegisterValue (const lldb_private::RegisterInfo ®_info, + lldb_private::RegisterValue ®_value); std::auto_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap; lldb_private::AddressRange* m_range_ptr; lldb_private::Thread* m_thread_ptr; lldb_private::UnwindPlan* m_unwind_plan_ptr; lldb_private::UnwindPlan::Row m_curr_row; - typedef std::map<uint64_t, uint64_t> RegisterValueMap; + uint64_t m_initial_sp; + typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap; RegisterValueMap m_register_values; }; diff --git a/lldb/source/Target/RegisterContext.cpp b/lldb/source/Target/RegisterContext.cpp index f884ec0ad6e..169ab743f58 100644 --- a/lldb/source/Target/RegisterContext.cpp +++ b/lldb/source/Target/RegisterContext.cpp @@ -13,6 +13,7 @@ // Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Host/Endian.h" #include "lldb/Target/ExecutionContext.h" @@ -150,9 +151,13 @@ RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value) { if (reg != LLDB_INVALID_REGNUM) { - Scalar value; - if (ReadRegisterValue (reg, value)) - return value.GetRawBits64(fail_value); + const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); + if (reg_info) + { + RegisterValue value; + if (ReadRegister (reg_info, value)) + return value.GetAsUInt64(); + } } return fail_value; } @@ -162,8 +167,14 @@ RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval) { if (reg == LLDB_INVALID_REGNUM) return false; - Scalar value(uval); - return WriteRegisterValue (reg, value); + const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); + if (reg_info) + { + RegisterValue value; + if (value.SetUInt(uval, reg_info->byte_size)) + return WriteRegister (reg_info, value); + } + return false; } lldb::tid_t @@ -215,6 +226,127 @@ RegisterContext::HardwareSingleStep (bool enable) return false; } +Error +RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info, + lldb::addr_t src_addr, + uint32_t src_len, + RegisterValue ®_value) +{ + Error error; + if (reg_info == NULL) + { + error.SetErrorString ("invalid register info argument."); + return error; + } + + + // Moving from addr into a register + // + // Case 1: src_len == dst_len + // + // |AABBCCDD| Address contents + // |AABBCCDD| Register contents + // + // Case 2: src_len > dst_len + // + // Error! (The register should always be big enough to hold the data) + // + // Case 3: src_len < dst_len + // + // |AABB| Address contents + // |AABB0000| Register contents [on little-endian hardware] + // |0000AABB| Register contents [on big-endian hardware] + if (src_len > RegisterValue::kMaxRegisterByteSize) + { + error.SetErrorString ("register too small to receive memory data"); + return error; + } + + const uint32_t dst_len = reg_info->byte_size; + + if (src_len > dst_len) + { + error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len); + return error; + } + + Process &process = m_thread.GetProcess(); + uint8_t src[RegisterValue::kMaxRegisterByteSize]; + + // Read the memory + const uint32_t bytes_read = process.ReadMemory (src_addr, src, src_len, error); + + // Make sure the memory read succeeded... + if (bytes_read != src_len) + { + if (error.Success()) + { + // This might happen if we read _some_ bytes but not all + error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, src_len); + } + return error; + } + + // We now have a memory buffer that contains the part or all of the register + // value. Set the register value using this memory data. + // TODO: we might need to add a parameter to this function in case the byte + // order of the memory data doesn't match the process. For now we are assuming + // they are the same. + reg_value.SetFromMemoryData (reg_info, + src, + src_len, + process.GetByteOrder(), + error); + return error; +} + +Error +RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info, + lldb::addr_t dst_addr, + uint32_t dst_len, + const RegisterValue ®_value) +{ + + uint8_t dst[RegisterValue::kMaxRegisterByteSize]; + + Error error; + + Process &process = m_thread.GetProcess(); + + // TODO: we might need to add a parameter to this function in case the byte + // order of the memory data doesn't match the process. For now we are assuming + // they are the same. + + const uint32_t bytes_copied = reg_value.GetAsMemoryData (reg_info, + dst, + dst_len, + process.GetByteOrder(), + error); + + if (error.Success()) + { + if (bytes_copied == 0) + { + error.SetErrorString("byte copy failed."); + } + else + { + const uint32_t bytes_written = process.WriteMemory (dst_addr, dst, bytes_copied, error); + if (bytes_written != bytes_copied) + { + if (error.Success()) + { + // This might happen if we read _some_ bytes but not all + error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied); + } + } + } + } + + return error; + +} + Target * RegisterContext::CalculateTarget () { @@ -274,124 +406,124 @@ RegisterContext::ConvertBetweenRegisterKinds (int source_rk, uint32_t source_reg return false; } -bool -RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) -{ - DataExtractor data; - if (!ReadRegisterBytes (reg, data)) - return false; - - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - uint32_t offset = 0; - switch (reg_info->encoding) - { - case eEncodingInvalid: - case eEncodingVector: - break; - - case eEncodingUint: - switch (reg_info->byte_size) - { - case 1: - { - value = data.GetU8 (&offset); - return true; - } - case 2: - { - value = data.GetU16 (&offset); - return true; - } - case 4: - { - value = data.GetU32 (&offset); - return true; - } - case 8: - { - value = data.GetU64 (&offset); - return true; - } - } - break; - case eEncodingSint: - switch (reg_info->byte_size) - { - case 1: - { - int8_t v; - if (data.ExtractBytes (0, sizeof (int8_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int8_t)) - return false; - value = v; - return true; - } - case 2: - { - int16_t v; - if (data.ExtractBytes (0, sizeof (int16_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int16_t)) - return false; - value = v; - return true; - } - case 4: - { - int32_t v; - if (data.ExtractBytes (0, sizeof (int32_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int32_t)) - return false; - value = v; - return true; - } - case 8: - { - int64_t v; - if (data.ExtractBytes (0, sizeof (int64_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int64_t)) - return false; - value = v; - return true; - } - } - break; - case eEncodingIEEE754: - switch (reg_info->byte_size) - { - case sizeof (float): - { - float v; - if (data.ExtractBytes (0, sizeof (float), lldb::endian::InlHostByteOrder(), &v) != sizeof (float)) - return false; - value = v; - return true; - } - case sizeof (double): - { - double v; - if (data.ExtractBytes (0, sizeof (double), lldb::endian::InlHostByteOrder(), &v) != sizeof (double)) - return false; - value = v; - return true; - } - case sizeof (long double): - { - double v; - if (data.ExtractBytes (0, sizeof (long double), lldb::endian::InlHostByteOrder(), &v) != sizeof (long double)) - return false; - value = v; - return true; - } - } - break; - } - return false; -} - -bool -RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value) -{ - DataExtractor data; - if (!value.IsValid()) - return false; - if (!value.GetData (data)) - return false; - - return WriteRegisterBytes (reg, data); -} +//bool +//RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) +//{ +// DataExtractor data; +// if (!ReadRegisterBytes (reg, data)) +// return false; +// +// const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); +// uint32_t offset = 0; +// switch (reg_info->encoding) +// { +// case eEncodingInvalid: +// case eEncodingVector: +// break; +// +// case eEncodingUint: +// switch (reg_info->byte_size) +// { +// case 1: +// { +// value = data.GetU8 (&offset); +// return true; +// } +// case 2: +// { +// value = data.GetU16 (&offset); +// return true; +// } +// case 4: +// { +// value = data.GetU32 (&offset); +// return true; +// } +// case 8: +// { +// value = data.GetU64 (&offset); +// return true; +// } +// } +// break; +// case eEncodingSint: +// switch (reg_info->byte_size) +// { +// case 1: +// { +// int8_t v; +// if (data.ExtractBytes (0, sizeof (int8_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int8_t)) +// return false; +// value = v; +// return true; +// } +// case 2: +// { +// int16_t v; +// if (data.ExtractBytes (0, sizeof (int16_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int16_t)) +// return false; +// value = v; +// return true; +// } +// case 4: +// { +// int32_t v; +// if (data.ExtractBytes (0, sizeof (int32_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int32_t)) +// return false; +// value = v; +// return true; +// } +// case 8: +// { +// int64_t v; +// if (data.ExtractBytes (0, sizeof (int64_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int64_t)) +// return false; +// value = v; +// return true; +// } +// } +// break; +// case eEncodingIEEE754: +// switch (reg_info->byte_size) +// { +// case sizeof (float): +// { +// float v; +// if (data.ExtractBytes (0, sizeof (float), lldb::endian::InlHostByteOrder(), &v) != sizeof (float)) +// return false; +// value = v; +// return true; +// } +// case sizeof (double): +// { +// double v; +// if (data.ExtractBytes (0, sizeof (double), lldb::endian::InlHostByteOrder(), &v) != sizeof (double)) +// return false; +// value = v; +// return true; +// } +// case sizeof (long double): +// { +// double v; +// if (data.ExtractBytes (0, sizeof (long double), lldb::endian::InlHostByteOrder(), &v) != sizeof (long double)) +// return false; +// value = v; +// return true; +// } +// } +// break; +// } +// return false; +//} +// +//bool +//RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value) +//{ +// DataExtractor data; +// if (!value.IsValid()) +// return false; +// if (!value.GetData (data)) +// return false; +// +// return WriteRegisterBytes (reg, data); +//} |