diff options
Diffstat (limited to 'lldb/source/Plugins/Instruction/ARM')
4 files changed, 131 insertions, 128 deletions
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index c4a6cfe0ee7..702ca061da3 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -13309,25 +13309,31 @@ EmulateInstructionARM::EvaluateInstruction () } bool -EmulateInstructionARM::TestEmulation (Stream *out_stream, FILE *test_file, ArchSpec &arch) +EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) { - if (!test_file) + if (!test_data) { - out_stream->Printf ("TestEmulation: Missing test file.\n"); + out_stream->Printf ("TestEmulation: Missing test data.\n"); return false; } + + static ConstString opcode_key ("opcode"); + static ConstString before_key ("before_state"); + static ConstString after_key ("after_state"); + + OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); uint32_t test_opcode; - if (fscanf (test_file, "%x", &test_opcode) != 1) + if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) { - out_stream->Printf ("Test Emulation: Error reading opcode from test file.\n"); + out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); return false; } + test_opcode = value_sp->GetUInt64Value (); - char buffer[256]; - fgets (buffer, 255, test_file); // consume the newline after reading the opcode. - - SetAdvancePC (true); + // If the instruction emulation does not directly update the PC, advance the PC to the next instruction after + // performing the emulation. + SetAdvancePC (true); if (arch.GetTriple().getArch() == llvm::Triple::arm) { @@ -13345,60 +13351,41 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, FILE *test_file, ArchS } else { - out_stream->Printf ("Test Emulation: Invalid arch.\n"); + out_stream->Printf ("TestEmulation: Invalid arch.\n"); return false; } - EmulationStateARM before_state; EmulationStateARM after_state; - // Read Memory info & load into before_state - if (!fgets (buffer, 255, test_file)) + value_sp = test_data->GetValueForKey (before_key); + if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) { - out_stream->Printf ("Test Emulation: Error attempting to read from test file.\n"); + out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); return false; } - - if (strncmp (buffer, "Memory-Begin", 12) != 0) + + OptionValueDictionary *state_dictionary = value_sp->GetAsDictionaryValue (); + if (!before_state.LoadStateFromDictionary (state_dictionary)) { - out_stream->Printf ("Test Emulation: Cannot find Memory-Begin in test file.\n"); + out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); return false; } - bool done = false; - while (!done) + value_sp = test_data->GetValueForKey (after_key); + if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) { - if (fgets (buffer, 255, test_file)) - { - if (strncmp (buffer, "Memory-End", 10) == 0) - done = true; - else - { - uint32_t addr; - uint32_t value; - if (sscanf (buffer, "%x %x", &addr, &value) == 2) - before_state.StoreToPseudoAddress ((addr_t) addr, (uint64_t) value, 4); - else - { - out_stream->Printf ("Test Emulation: Error attempting to sscanf address/value pair.\n"); - return false; - } - } - } - else - { - out_stream->Printf ("Test Emulation: Error attemping to read test file.\n"); - return false; - } + out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); + return false; } - - if (!EmulationStateARM::LoadRegisterStatesFromTestFile (test_file, before_state, after_state)) + + state_dictionary = value_sp->GetAsDictionaryValue (); + if (!after_state.LoadStateFromDictionary (state_dictionary)) { - out_stream->Printf ("Test Emulation: Error occurred while attempting to load the register data.\n"); + out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); return false; } - + SetBaton ((void *) &before_state); SetCallbacks (&EmulationStateARM::ReadPseudoMemory, &EmulationStateARM::WritePseudoMemory, @@ -13408,11 +13395,14 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, FILE *test_file, ArchS bool success = EvaluateInstruction (); if (!success) { - out_stream->Printf ("Test Emulation: EvaluateInstruction() failed.\n"); + out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); return false; } success = before_state.CompareState (after_state); + if (!success) + out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); + return success; } diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index 49ade996186..faaae730680 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -12,6 +12,7 @@ #include "lldb/Core/EmulateInstruction.h" #include "lldb/Core/Error.h" +#include "lldb/Interpreter/NamedOptionValue.h" #include "Plugins/Process/Utility/ARMDefines.h" namespace lldb_private { @@ -150,7 +151,7 @@ public: EvaluateInstruction (); virtual bool - TestEmulation (Stream *out_stream, FILE *test_file, ArchSpec &arch); + TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data); uint32_t ArchVersion(); diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index c3f363fb9f7..7fb65a495be 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -315,82 +315,6 @@ EmulationStateARM::WritePseudoRegister (void *baton, } bool -EmulationStateARM::LoadState (FILE *test_file) -{ - if (!test_file) - return false; - - uint32_t num_regs; - uint32_t value32; - uint64_t value64; - - /* Load general register state */ - if (fscanf (test_file, "%d", &num_regs) != 1) - return false; - - - for (int i = 0; i < num_regs; ++i) - { - if (fscanf (test_file, "%x", &value32) == 1) - { - if (i < 17) // We only have 17 general registers, but if for some reason the file contains more - // we need to read them all, to get to the next set of register values. - m_gpr[i] = value32; - } - else - return false; - } - - /* Load d register state */ - if (fscanf (test_file, "%d", &num_regs) != 1) - return false; - - for (int i = 0; i < num_regs; ++i) - { - if (fscanf (test_file, "%x", &value64) == 1) - { - if (i < 32) - { - if (i < 16) - m_vfp_regs.sd_regs[i].d_reg = value64; - else - m_vfp_regs.d_regs[i - 16] = value64; - } - } - else - return false; - } - - /* Load s register state */ - if (fscanf (test_file, "%d", &num_regs) != 1) - return false; - - for (int i = 0; i < num_regs; ++i) - { - if (fscanf (test_file, "%x", &value32) == 1) - m_vfp_regs.sd_regs[i / 2].s_reg[i % 2] = value32; - else - return false; - } - - return true; -} - -bool -EmulationStateARM::LoadRegisterStatesFromTestFile (FILE *test_file, - EmulationStateARM &before_state, - EmulationStateARM &after_state) -{ - if (test_file) - { - if (before_state.LoadState (test_file)) - return after_state.LoadState (test_file); - } - - return false; -} - -bool EmulationStateARM::CompareState (EmulationStateARM &other_state) { bool match = true; @@ -426,3 +350,93 @@ EmulationStateARM::CompareState (EmulationStateARM &other_state) return match; } + +bool +EmulationStateARM::LoadStateFromDictionary (OptionValueDictionary *test_data) +{ + static ConstString memory_key ("memory"); + static ConstString registers_key ("registers"); + + if (!test_data) + return false; + + OptionValueSP value_sp = test_data->GetValueForKey (memory_key); + + // Load memory, if present. + + if (value_sp.get() != NULL) + { + static ConstString address_key ("address"); + static ConstString data_key ("data"); + uint64_t start_address = 0; + + OptionValueDictionary *mem_dict = value_sp->GetAsDictionaryValue(); + value_sp = mem_dict->GetValueForKey (address_key); + if (value_sp.get() == NULL) + return false; + else + start_address = value_sp->GetUInt64Value (); + + value_sp = mem_dict->GetValueForKey (data_key); + OptionValueArray *mem_array = value_sp->GetAsArrayValue(); + if (!mem_array) + return false; + + uint32_t num_elts = mem_array->GetSize(); + uint32_t address = (uint32_t) start_address; + + for (int i = 0; i < num_elts; ++i) + { + value_sp = mem_array->GetValueAtIndex (i); + if (value_sp.get() == NULL) + return false; + uint64_t value = value_sp->GetUInt64Value(); + StoreToPseudoAddress (address, value, 4); + address = address + 4; + } + } + + value_sp = test_data->GetValueForKey (registers_key); + if (value_sp.get() == NULL) + return false; + + + // Load General Registers + + OptionValueDictionary *reg_dict = value_sp->GetAsDictionaryValue (); + + StreamString sstr; + for (int i = 0; i < 16; ++i) + { + sstr.Clear(); + sstr.Printf ("r%d", i); + ConstString reg_name (sstr.GetData()); + value_sp = reg_dict->GetValueForKey (reg_name); + if (value_sp.get() == NULL) + return false; + uint64_t reg_value = value_sp->GetUInt64Value(); + StorePseudoRegisterValue (dwarf_r0 + i, reg_value); + } + + static ConstString cpsr_name ("cpsr"); + value_sp = reg_dict->GetValueForKey (cpsr_name); + if (value_sp.get() == NULL) + return false; + StorePseudoRegisterValue (dwarf_cpsr, value_sp->GetUInt64Value()); + + // Load s/d Registers + for (int i = 0; i < 32; ++i) + { + sstr.Clear(); + sstr.Printf ("s%d", i); + ConstString reg_name (sstr.GetData()); + value_sp = reg_dict->GetValueForKey (reg_name); + if (value_sp.get() == NULL) + return false; + uint64_t reg_value = value_sp->GetUInt64Value(); + StorePseudoRegisterValue (dwarf_s0 + i, reg_value); + } + + return true; +} + diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h index 8ddfbed4bb4..025ff9e3d94 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h @@ -14,6 +14,7 @@ #include "lldb/Core/EmulateInstruction.h" #include "lldb/Core/Opcode.h" +#include "lldb/Interpreter/NamedOptionValue.h" namespace lldb_private { @@ -47,11 +48,8 @@ public: LoadPseudoRegistersFromFrame (StackFrame &frame); bool - LoadState (FILE *test_file); - - static bool - LoadRegisterStatesFromTestFile (FILE *test_file, EmulationStateARM &before_state, EmulationStateARM &after_state); - + LoadStateFromDictionary (OptionValueDictionary *test_data); + bool CompareState (EmulationStateARM &other_state); |

