DavidSpickett created this revision.
Herald added a subscriber: kristof.beyls.
Herald added a project: All.
DavidSpickett requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Since some s and d registers overlap we will error if we find both.
This prevents you overwriting one with the other in a test case.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130462

Files:
  lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
  lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h


Index: lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
===================================================================
--- lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -61,6 +61,10 @@
                       const lldb_private::RegisterValue &reg_value);
 
 private:
+  bool LoadRegistersStateFromDictionary(
+      lldb_private::OptionValueDictionary *reg_dict, char kind, int first_reg,
+      int num);
+
   uint32_t m_gpr[17] = {0};
   struct _sd_regs {
     uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
Index: lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
===================================================================
--- lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -272,6 +272,23 @@
   return match;
 }
 
+bool EmulationStateARM::LoadRegistersStateFromDictionary(
+    OptionValueDictionary *reg_dict, char kind, int first_reg, int num) {
+  StreamString sstr;
+  for (int i = 0; i < num; ++i) {
+    sstr.Clear();
+    sstr.Printf("%c%d", kind, i);
+    OptionValueSP value_sp =
+        reg_dict->GetValueForKey(ConstString(sstr.GetString()));
+    if (value_sp.get() == nullptr)
+      return false;
+    uint64_t reg_value = value_sp->GetUInt64Value();
+    StorePseudoRegisterValue(first_reg + i, reg_value);
+  }
+
+  return true;
+}
+
 bool EmulationStateARM::LoadStateFromDictionary(
     OptionValueDictionary *test_data) {
   static ConstString memory_key("memory");
@@ -321,18 +338,8 @@
   // Load General Registers
 
   OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
-
-  StreamString sstr;
-  for (int i = 0; i < 16; ++i) {
-    sstr.Clear();
-    sstr.Printf("r%d", i);
-    ConstString reg_name(sstr.GetString());
-    value_sp = reg_dict->GetValueForKey(reg_name);
-    if (value_sp.get() == nullptr)
-      return false;
-    uint64_t reg_value = value_sp->GetUInt64Value();
-    StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
-  }
+  if (!LoadRegistersStateFromDictionary(reg_dict, 'r', dwarf_r0, 16))
+    return false;
 
   static ConstString cpsr_name("cpsr");
   value_sp = reg_dict->GetValueForKey(cpsr_name);
@@ -341,16 +348,13 @@
   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.GetString());
-    value_sp = reg_dict->GetValueForKey(reg_name);
-    if (value_sp.get() == nullptr)
-      return false;
-    uint64_t reg_value = value_sp->GetUInt64Value();
-    StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
-  }
-
-  return true;
+  // To prevent you giving both types in a state and overwriting
+  // one or the other, we'll expect to get either all S registers,
+  // or all D registers. Not a mix of the two.
+  bool found_s_registers =
+      LoadRegistersStateFromDictionary(reg_dict, 's', dwarf_s0, 32);
+  bool found_d_registers =
+      LoadRegistersStateFromDictionary(reg_dict, 'd', dwarf_d0, 32);
+
+  return found_s_registers != found_d_registers;
 }


Index: lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
===================================================================
--- lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -61,6 +61,10 @@
                       const lldb_private::RegisterValue &reg_value);
 
 private:
+  bool LoadRegistersStateFromDictionary(
+      lldb_private::OptionValueDictionary *reg_dict, char kind, int first_reg,
+      int num);
+
   uint32_t m_gpr[17] = {0};
   struct _sd_regs {
     uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
Index: lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
===================================================================
--- lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -272,6 +272,23 @@
   return match;
 }
 
+bool EmulationStateARM::LoadRegistersStateFromDictionary(
+    OptionValueDictionary *reg_dict, char kind, int first_reg, int num) {
+  StreamString sstr;
+  for (int i = 0; i < num; ++i) {
+    sstr.Clear();
+    sstr.Printf("%c%d", kind, i);
+    OptionValueSP value_sp =
+        reg_dict->GetValueForKey(ConstString(sstr.GetString()));
+    if (value_sp.get() == nullptr)
+      return false;
+    uint64_t reg_value = value_sp->GetUInt64Value();
+    StorePseudoRegisterValue(first_reg + i, reg_value);
+  }
+
+  return true;
+}
+
 bool EmulationStateARM::LoadStateFromDictionary(
     OptionValueDictionary *test_data) {
   static ConstString memory_key("memory");
@@ -321,18 +338,8 @@
   // Load General Registers
 
   OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
-
-  StreamString sstr;
-  for (int i = 0; i < 16; ++i) {
-    sstr.Clear();
-    sstr.Printf("r%d", i);
-    ConstString reg_name(sstr.GetString());
-    value_sp = reg_dict->GetValueForKey(reg_name);
-    if (value_sp.get() == nullptr)
-      return false;
-    uint64_t reg_value = value_sp->GetUInt64Value();
-    StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
-  }
+  if (!LoadRegistersStateFromDictionary(reg_dict, 'r', dwarf_r0, 16))
+    return false;
 
   static ConstString cpsr_name("cpsr");
   value_sp = reg_dict->GetValueForKey(cpsr_name);
@@ -341,16 +348,13 @@
   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.GetString());
-    value_sp = reg_dict->GetValueForKey(reg_name);
-    if (value_sp.get() == nullptr)
-      return false;
-    uint64_t reg_value = value_sp->GetUInt64Value();
-    StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
-  }
-
-  return true;
+  // To prevent you giving both types in a state and overwriting
+  // one or the other, we'll expect to get either all S registers,
+  // or all D registers. Not a mix of the two.
+  bool found_s_registers =
+      LoadRegistersStateFromDictionary(reg_dict, 's', dwarf_s0, 32);
+  bool found_d_registers =
+      LoadRegistersStateFromDictionary(reg_dict, 'd', dwarf_d0, 32);
+
+  return found_s_registers != found_d_registers;
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to