mib updated this revision to Diff 502319.
mib added a comment.

Rebase


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144237/new/

https://reviews.llvm.org/D144237

Files:
  lldb/bindings/python/python-swigsafecast.swig
  lldb/examples/python/scripted_process/scripted_process.py
  lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
  lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
  lldb/source/Plugins/Process/scripted/ScriptedProcess.h
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
  lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
  lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===================================================================
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -286,3 +286,8 @@
 lldb_private::python::ToSWIGWrapper(lldb::ProcessLaunchInfoSP) {
   return python::PythonObject();
 }
+
+python::PythonObject
+lldb_private::python::ToSWIGWrapper(lldb::DataExtractorSP) {
+  return python::PythonObject();
+}
Index: lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
===================================================================
--- lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
+++ lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
@@ -7,20 +7,29 @@
 from lldb.plugins.scripted_process import ScriptedThread
 
 class DummyScriptedProcess(ScriptedProcess):
+    memory = None
+
     def __init__(self, exe_ctx: lldb.SBExecutionContext, args : lldb.SBStructuredData):
         super().__init__(exe_ctx, args)
         self.threads[0] = DummyScriptedThread(self, None)
-
-    def read_memory_at_address(self, addr: int, size: int, error: lldb.SBError) -> lldb.SBData:
+        self.memory = {}
+        addr = 0x500000000
         debugger = self.target.GetDebugger()
         index = debugger.GetIndexOfTarget(self.target)
+        self.memory[addr] = "Hello, target " + str(index)
+
+    def read_memory_at_address(self, addr: int, size: int, error: lldb.SBError) -> lldb.SBData:
         data = lldb.SBData().CreateDataFromCString(
                                     self.target.GetByteOrder(),
                                     self.target.GetCodeByteSize(),
-                                    "Hello, target " + str(index))
+                                    self.memory[addr])
 
         return data
 
+    def write_memory_at_address(self, addr, data, error):
+        self.memory[addr] = data.GetString(error, 0)
+        return len(self.memory[addr])
+
     def get_loaded_images(self):
         return self.loaded_images
 
Index: lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
===================================================================
--- lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
+++ lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
@@ -150,7 +150,6 @@
         self.assertEqual(process_1.GetNumThreads(), 1)
 
         # ... then try reading from target #1 process ...
-        addr = 0x500000000
         message = "Hello, target 1"
         buff = process_1.ReadCStringFromMemory(addr, len(message) + 1, error)
         self.assertSuccess(error)
@@ -158,12 +157,22 @@
 
         # ... now, reading again from target #0 process to make sure the call
         # gets dispatched to the right target.
-        addr = 0x500000000
         message = "Hello, target 0"
         buff = process_0.ReadCStringFromMemory(addr, len(message) + 1, error)
         self.assertSuccess(error)
         self.assertEqual(buff, message)
 
+        # Let's write some memory.
+        message = "Hello, world!"
+        bytes_written = process_0.WriteCStringToMemory(addr, message, error)
+        self.assertSuccess(error)
+        self.assertEqual(bytes_written, len(message) + 1)
+
+        # ... and check if that memory was saved properly.
+        buff = process_0.ReadCStringFromMemory(addr, len(message) + 1, error)
+        self.assertSuccess(error)
+        self.assertEqual(buff, message)
+
         thread = process_0.GetSelectedThread()
         self.assertTrue(thread, "Invalid thread.")
         self.assertEqual(thread.GetThreadID(), 0x19)
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
@@ -125,6 +125,10 @@
     return python::ToSWIGWrapper(arg);
   }
 
+  python::PythonObject Transform(lldb::DataExtractorSP arg) {
+    return python::ToSWIGWrapper(arg);
+  }
+
   template <typename T, typename U>
   void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
     // If U is not a PythonObject, don't touch it!
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -49,7 +49,9 @@
 
   lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size,
                                             Status &error) override;
-                                         
+
+  size_t WriteMemoryAtAddress(lldb::addr_t addr, lldb::DataExtractorSP data_sp,
+                              Status &error) override;
 
   StructuredData::ArraySP GetLoadedImages() override;
 
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -135,6 +135,22 @@
   return data_sp;
 }
 
+size_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
+    lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) {
+  Status py_error;
+  StructuredData::ObjectSP obj =
+      Dispatch("write_memory_at_address", py_error, addr, data_sp, error);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+    return LLDB_INVALID_OFFSET;
+
+  // If there was an error on the python call, surface it to the user.
+  if (py_error.Fail())
+    error = py_error;
+
+  return obj->GetIntegerValue(LLDB_INVALID_OFFSET);
+}
+
 StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
   Status error;
   StructuredData::ArraySP array =
Index: lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -79,6 +79,7 @@
 
 PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
 PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
+PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
 
 PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
 PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb);
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.h
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -69,6 +69,9 @@
   size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
                       Status &error) override;
 
+  size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+                       Status &error) override;
+
   ArchSpec GetArchitecture();
 
   Status
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -255,7 +255,31 @@
     return ScriptedInterface::ErrorWithMessage<size_t>(
         LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error);
 
-  return size;
+  // FIXME: We should use the diagnostic system to report a warning if the
+  // `bytes_copied` is different from `size`.
+
+  return bytes_copied;
+}
+
+size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
+                                      size_t size, Status &error) {
+  lldb::DataExtractorSP data_extractor_sp = std::make_shared<DataExtractor>(
+      buf, size, GetByteOrder(), GetAddressByteSize());
+
+  if (!data_extractor_sp || !data_extractor_sp->GetByteSize())
+    return 0;
+
+  size_t bytes_written =
+      GetInterface().WriteMemoryAtAddress(vm_addr, data_extractor_sp, error);
+
+  if (!bytes_written || bytes_written == LLDB_INVALID_OFFSET)
+    return ScriptedInterface::ErrorWithMessage<size_t>(
+        LLVM_PRETTY_FUNCTION, "Failed to copy write buffer to memory.", error);
+
+  // FIXME: We should use the diagnostic system to report a warning if the
+  // `bytes_written` is different from `size`.
+
+  return bytes_written;
 }
 
 ArchSpec ScriptedProcess::GetArchitecture() {
Index: lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
+++ lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
@@ -55,6 +55,12 @@
     return {};
   }
 
+  virtual size_t WriteMemoryAtAddress(lldb::addr_t addr,
+                                      lldb::DataExtractorSP data_sp,
+                                      Status &error) {
+    return LLDB_INVALID_OFFSET;
+  };
+
   virtual StructuredData::ArraySP GetLoadedImages() { return {}; }
 
   virtual lldb::pid_t GetProcessID() { return LLDB_INVALID_PROCESS_ID; }
Index: lldb/examples/python/scripted_process/scripted_process.py
===================================================================
--- lldb/examples/python/scripted_process/scripted_process.py
+++ lldb/examples/python/scripted_process/scripted_process.py
@@ -98,6 +98,21 @@
         """
         pass
 
+    def write_memory_at_address(self, addr, data, error):
+        """ Write a buffer to the scripted process memory.
+
+        Args:
+            addr (int): Address from which we should start reading.
+            data (lldb.SBData): An `lldb.SBData` buffer to write to the
+                process memory.
+            error (lldb.SBError): Error object.
+
+        Returns:
+            size (int): Size of the memory to read.
+        """
+        error.SetErrorString("%s doesn't support memory writes." % self.__class__.__name__)
+        return 0
+
     def get_loaded_images(self):
         """ Get the list of loaded images for the scripted process.
 
Index: lldb/bindings/python/python-swigsafecast.swig
===================================================================
--- lldb/bindings/python/python-swigsafecast.swig
+++ lldb/bindings/python/python-swigsafecast.swig
@@ -103,6 +103,11 @@
                        SWIGTYPE_p_lldb__SBAttachInfo);
  }
 
+PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_sp) {
+  return ToSWIGHelper(new lldb::DataExtractorSP(std::move(data_sp)),
+                      SWIGTYPE_p_lldb__SBData);
+}
+
 ScopedPythonObject<lldb::SBCommandReturnObject>
 ToSWIGWrapper(CommandReturnObject &cmd_retobj) {
   return ScopedPythonObject<lldb::SBCommandReturnObject>(
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to