[Lldb-commits] [lldb] r129981 - in /lldb/trunk: include/lldb/Core/Disassembler.h include/lldb/Core/EmulateInstruction.h include/lldb/Interpreter/NamedOptionValue.h source/Core/Disassembler.cpp source/Interpreter/NamedOptionValue.cpp source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp source/Plugins/Instruction/ARM/EmulateInstructionARM.h source/Plugins/Instruction/ARM/EmulationStateARM.cpp source/Plugins/Instruction/ARM/EmulationStateARM.h

Caroline Tice ctice at apple.com
Thu Apr 21 22:08:45 PDT 2011


Author: ctice
Date: Fri Apr 22 00:08:45 2011
New Revision: 129981

URL: http://llvm.org/viewvc/llvm-project?rev=129981&view=rev
Log:

Change code for reading emulation data files to read the new file
format.  (The newly formatted files will go in as a separate commit in a
few minutes).


Modified:
    lldb/trunk/include/lldb/Core/Disassembler.h
    lldb/trunk/include/lldb/Core/EmulateInstruction.h
    lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Interpreter/NamedOptionValue.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
    lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.h

Modified: lldb/trunk/include/lldb/Core/Disassembler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Disassembler.h?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Disassembler.h (original)
+++ lldb/trunk/include/lldb/Core/Disassembler.h Fri Apr 22 00:08:45 2011
@@ -22,6 +22,7 @@
 #include "lldb/Core/EmulateInstruction.h"
 #include "lldb/Core/Opcode.h"
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Interpreter/NamedOptionValue.h"
 
 namespace lldb_private {
 
@@ -71,6 +72,12 @@
     virtual void
     SetDescription (const char *) {};  // May be overridden in sub-classes that have descriptions.
     
+    lldb::OptionValueSP
+    ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type);
+
+    lldb::OptionValueSP
+    ReadDictionary (FILE *in_file, Stream *out_stream);
+
     bool
     DumpEmulation (const ArchSpec &arch);
     

Modified: lldb/trunk/include/lldb/Core/EmulateInstruction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/EmulateInstruction.h?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/EmulateInstruction.h (original)
+++ lldb/trunk/include/lldb/Core/EmulateInstruction.h Fri Apr 22 00:08:45 2011
@@ -16,6 +16,7 @@
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Core/Opcode.h"
+#include "lldb/Interpreter/NamedOptionValue.h"
 
 //----------------------------------------------------------------------
 /// @class EmulateInstruction EmulateInstruction.h "lldb/Core/EmulateInstruction.h"
@@ -418,7 +419,7 @@
     EvaluateInstruction () = 0;
     
     virtual bool
-    TestEmulation (Stream *out_stream, FILE *test_file, ArchSpec &arch) = 0;
+    TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0;
     
     bool
     GetAdvancePC () { return m_advance_pc; }

Modified: lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h (original)
+++ lldb/trunk/include/lldb/Interpreter/NamedOptionValue.h Fri Apr 22 00:08:45 2011
@@ -109,6 +109,12 @@
         OptionValueDictionary *
         GetAsDictionaryValue();
 
+        const char *
+        GetStringValue ();
+
+        uint64_t
+        GetUInt64Value ();
+                
     protected:
         bool m_value_was_set; // This can be used to see if a value has been set
                               // by a call to SetValueFromCString(). It is often
@@ -116,6 +122,7 @@
                               // the command line or as a setting, versus if we
                               // just have the default value that was already
                               // populated in the option value.
+        
     };
     
     

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Fri Apr 22 00:08:45 2011
@@ -21,7 +21,9 @@
 #include "lldb/Core/EmulateInstruction.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/Timer.h"
+#include "lldb/Interpreter/NamedOptionValue.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
@@ -502,6 +504,187 @@
     return false;
 }
 
+OptionValueSP
+Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
+{
+    bool done = false;
+    char buffer[1024];
+    
+    OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
+    
+    int idx = 0;
+    while (!done)
+    {
+        if (!fgets (buffer, 1023, in_file))
+        {
+            out_stream->Printf ("Instruction::ReadArray:  Erroe reading file (fgets).\n");
+            option_value_sp.reset ();
+            return option_value_sp;
+        }
+
+        std::string line (buffer);
+        
+        int len = line.size();
+        if (line[len-1] == '\n')
+        {
+            line[len-1] = '\0';
+            line.resize (len-1);
+        }
+
+        if ((line.size() == 1) && line[0] == ']')
+        {
+            done = true;
+            line.clear();
+        }
+
+        if (line.size() > 0)
+        {
+            std::string value;
+            RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
+            bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
+            if (reg_exp_success)
+                reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
+            else
+                value = line;
+                
+            OptionValueSP data_value_sp;
+            switch (data_type)
+            {
+            case OptionValue::eTypeUInt64:
+                data_value_sp.reset (new OptionValueUInt64 (0, 0));
+                data_value_sp->SetValueFromCString (value.c_str());
+                break;
+            // Other types can be added later as needed.
+            default:
+                data_value_sp.reset (new OptionValueString (value.c_str(), ""));
+                break;
+            }
+
+            option_value_sp->GetAsArrayValue()->InsertValue (idx, data_value_sp);
+            ++idx;
+        }
+    }
+    
+    return option_value_sp;
+}
+
+OptionValueSP 
+Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
+{
+    bool done = false;
+    char buffer[1024];
+    
+    OptionValueSP option_value_sp (new OptionValueDictionary());
+    static ConstString encoding_key ("data_encoding");
+    OptionValue::Type data_type = OptionValue::eTypeInvalid;
+
+    
+    while (!done)
+    {
+        // Read the next line in the file
+        if (!fgets (buffer, 1023, in_file))
+        {
+            out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
+            option_value_sp.reset ();
+            return option_value_sp;
+        }
+        
+        // Check to see if the line contains the end-of-dictionary marker ("}")
+        std::string line (buffer);
+
+        int len = line.size();
+        if (line[len-1] == '\n')
+        {
+            line[len-1] = '\0';
+            line.resize (len-1);
+        }
+        
+        if ((line.size() == 1) && (line[0] == '}'))
+        {
+            done = true;
+            line.clear();
+        }
+        
+        // Try to find a key-value pair in the current line and add it to the dictionary.
+        if (line.size() > 0)
+        {
+            RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
+            bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
+            std::string key;
+            std::string value;
+            if (reg_exp_success)
+            {
+                reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
+                reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
+            }
+            else 
+            {
+                out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
+                option_value_sp.reset();
+                return option_value_sp;
+            }
+            
+            ConstString const_key (key.c_str());
+            // Check value to see if it's the start of an array or dictionary.
+            
+            lldb::OptionValueSP value_sp;
+            assert (value.empty() == false);
+            assert (key.empty() == false);            
+
+            if (value[0] == '{')
+            {
+                assert (value.size() == 1);
+                // value is a dictionary
+                value_sp = ReadDictionary (in_file, out_stream);
+                if (value_sp.get() == NULL)
+                {
+                    option_value_sp.reset ();
+                    return option_value_sp;
+                }
+            }
+            else if (value[0] == '[')
+            {
+                assert (value.size() == 1);
+                // value is an array
+                value_sp = ReadArray (in_file, out_stream, data_type);
+                if (value_sp.get() == NULL)
+                {
+                    option_value_sp.reset ();
+                    return option_value_sp;
+                }
+                // We've used the data_type to read an array; re-set the type to Invalid
+                data_type = OptionValue::eTypeInvalid;
+            }
+            else if ((value[0] == '0') && (value[1] == 'x'))
+            {
+                value_sp.reset (new OptionValueUInt64 (0, 0));
+                value_sp->SetValueFromCString (value.c_str());
+            }
+            else
+            {
+                int len = value.size();
+                if ((value[0] == '"') && (value[len-1] == '"'))
+                    value = value.substr (1, len-2);
+                value_sp.reset (new OptionValueString (value.c_str(), ""));
+            }
+
+         
+
+            if (const_key == encoding_key)
+            {
+                // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
+                // data type of an upcoming array (usually the next bit of data to be read in).
+                if (strcmp (value.c_str(), "uint32_t") == 0)
+                    data_type = OptionValue::eTypeUInt64;
+            }
+            else
+                option_value_sp->GetAsDictionaryValue()->SetValueForKey (const_key, value_sp, false);
+        }
+    }
+    
+    return option_value_sp;
+}
+
 bool
 Instruction::TestEmulation (Stream *out_stream, const char *file_name)
 {
@@ -521,33 +704,63 @@
         return false;
     }
 
-    ArchSpec arch;
     char buffer[256];
-    if (!fgets (buffer,255, test_file)) // Read/skip first line of file, which should be a comment line (description).
+    if (!fgets (buffer, 255, test_file))
     {
-        out_stream->Printf ("Instruction::TestEmulation: Read comment line failed.");
+        out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
         fclose (test_file);
         return false;
     }
-    SetDescription (buffer);
-            
-    if (fscanf (test_file, "%s", buffer) != 1) // Read the arch or arch-triple from the file
+    
+    if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
+    {
+        out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
+        fclose (test_file);
+        return false;
+    }
+
+    // Read all the test information from the test file into an OptionValueDictionary.
+
+    OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
+    if (data_dictionary_sp.get() == NULL)
     {
-        out_stream->Printf ("Instruction::TestEmulation: Read arch failed.");
+        out_stream->Printf ("Instruction::TestEmulation:  Error reading Dictionary Object.\n");
         fclose (test_file);
         return false;
     }
+
+    fclose (test_file);
+
+    OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionaryValue();
+    static ConstString description_key ("assembly_string");
+    static ConstString triple_key ("triple");
+
+    OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
+    
+    if (value_sp.get() == NULL)
+    {
+        out_stream->Printf ("Instruction::TestEmulation:  Test file does not contain description string.\n");
+        return false;
+    }
+
+    SetDescription (value_sp->GetStringValue());
+            
+            
+    value_sp = data_dictionary->GetValueForKey (triple_key);
+    if (value_sp.get() == NULL)
+    {
+        out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
+        return false;
+    }
     
-    const char *cptr = buffer;
-    arch.SetTriple (llvm::Triple (cptr));
+    ArchSpec arch;
+    arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
 
     bool success = false;
     std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
     if (insn_emulator_ap.get())
-        success = insn_emulator_ap->TestEmulation (out_stream, test_file, arch);
+        success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
 
-    fclose (test_file);
-    
     if (success)
         out_stream->Printf ("Emulation test succeeded.");
     else

Modified: lldb/trunk/source/Interpreter/NamedOptionValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/NamedOptionValue.cpp?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/NamedOptionValue.cpp (original)
+++ lldb/trunk/source/Interpreter/NamedOptionValue.cpp Fri Apr 22 00:08:45 2011
@@ -102,6 +102,21 @@
     return NULL;
 }
 
+const char *
+OptionValue::GetStringValue ()
+{
+    if (GetType () == OptionValue::eTypeString)
+        return static_cast<OptionValueString *>(this)->GetCurrentValue();
+    return NULL;
+}
+
+uint64_t
+OptionValue::GetUInt64Value ()
+{
+    if (GetType () == OptionValue::eTypeUInt64)
+        return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
+    return 0;
+}
 
 //-------------------------------------------------------------------------
 // OptionValueCollection

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Fri Apr 22 00:08:45 2011
@@ -13309,25 +13309,31 @@
 }
 
 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 @@
     }
     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 @@
     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;
 }
 

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.h Fri Apr 22 00:08:45 2011
@@ -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 @@
     EvaluateInstruction ();
     
     virtual bool
-    TestEmulation (Stream *out_stream, FILE *test_file, ArchSpec &arch);
+    TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data);
 
     uint32_t
     ArchVersion();

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.cpp?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.cpp Fri Apr 22 00:08:45 2011
@@ -315,82 +315,6 @@
 }
                          
 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 @@
     
     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;
+}
+

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.h?rev=129981&r1=129980&r2=129981&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.h (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulationStateARM.h Fri Apr 22 00:08:45 2011
@@ -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 @@
     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);
 





More information about the lldb-commits mailing list