abidh updated this revision to Diff 84979.
abidh added a comment.

Changed the name of the option. Added LoadInMemory function to Module and 
ObjectFile class and moved the functionality of writing to memory there. 
Removed part which set the pc.


https://reviews.llvm.org/D28804

Files:
  include/lldb/Core/Module.h
  include/lldb/Symbol/ObjectFile.h
  source/Commands/CommandObjectTarget.cpp
  source/Core/Module.cpp
  source/Symbol/ObjectFile.cpp

Index: source/Symbol/ObjectFile.cpp
===================================================================
--- source/Symbol/ObjectFile.cpp
+++ source/Symbol/ObjectFile.cpp
@@ -20,6 +20,9 @@
 #include "lldb/Core/Timer.h"
 #include "lldb/Symbol/ObjectContainer.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Process.h"
 #include "lldb/lldb-private.h"
 
@@ -648,3 +651,31 @@
             file_name.GetCString());
   return ConstString(ss.GetString());
 }
+
+Error ObjectFile::LoadInMemory(Target &target) {
+  Error error;
+  ProcessSP process = target.CalculateProcess();
+  if (!process)
+    return Error("No Process");
+
+  SectionList *section_list = GetSectionList();
+  if (!section_list)
+      return Error("No section in object file");
+  size_t section_count = section_list->GetNumSections(0);
+  for (size_t i = 0; i < section_count; ++i) {
+    SectionSP section_sp = section_list->GetSectionAtIndex(i);
+    addr_t addr = target.GetSectionLoadList().GetSectionLoadAddress(section_sp);
+    if (addr != LLDB_INVALID_ADDRESS) {
+      DataExtractor section_data;
+      // We can skip sections like bss
+      if (section_sp->GetFileSize() == 0)
+        continue;
+      section_sp->GetSectionData(section_data);
+      lldb::offset_t written = process->WriteMemory(
+          addr, section_data.GetDataStart(), section_data.GetByteSize(), error);
+      if (written != section_data.GetByteSize())
+        return error;
+    }
+  }
+  return error;
+}
Index: source/Core/Module.cpp
===================================================================
--- source/Core/Module.cpp
+++ source/Core/Module.cpp
@@ -1664,3 +1664,7 @@
 
   return false;
 }
+
+Error Module::LoadInMemory(Target &target) {
+  return m_objfile_sp->LoadInMemory(target);
+}
Index: source/Commands/CommandObjectTarget.cpp
===================================================================
--- source/Commands/CommandObjectTarget.cpp
+++ source/Commands/CommandObjectTarget.cpp
@@ -2567,13 +2567,18 @@
         m_option_group(),
         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
                       "Fullpath or basename for module to load.", ""),
+        m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
+                      "Write file contents to the memory and set PC to its"
+                      "entry address.",
+                      false, true),
         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
                        "Set the load address for all sections to be the "
                        "virtual address in the file plus the offset.",
                        0) {
     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
                           LLDB_OPT_SET_1);
     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+    m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
     m_option_group.Finalize();
   }
@@ -2585,6 +2590,7 @@
 protected:
   bool DoExecute(Args &args, CommandReturnObject &result) override {
     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+    const bool load = m_load_option.GetOptionValue().GetCurrentValue();
     if (target == nullptr) {
       result.AppendError("invalid target, create a debug target using the "
                          "'target create' command");
@@ -2594,6 +2600,21 @@
       const size_t argc = args.GetArgumentCount();
       ModuleSpec module_spec;
       bool search_using_module_spec = false;
+
+      // Allow "load" option to work without --file or --uuid
+      // option.
+      if (load) {
+        if (!m_file_option.GetOptionValue().OptionWasSet() &&
+            !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
+          ModuleList &module_list = target->GetImages();
+          if (module_list.GetSize() == 1) {
+            search_using_module_spec = true;
+            module_spec.GetFileSpec() =
+                module_list.GetModuleAtIndex(0)->GetFileSpec();
+          }
+        }
+      }
+
       if (m_file_option.GetOptionValue().OptionWasSet()) {
         search_using_module_spec = true;
         const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
@@ -2721,6 +2742,13 @@
                   if (process)
                     process->Flush();
                 }
+                if (load) {
+                  Error error = module->LoadInMemory(*target);
+                  if (error.Fail()) {
+                    result.AppendError(error.AsCString());
+                    return false;
+                  }
+                }
               } else {
                 module->GetFileSpec().GetPath(path, sizeof(path));
                 result.AppendErrorWithFormat(
@@ -2783,6 +2811,7 @@
   OptionGroupOptions m_option_group;
   OptionGroupUUID m_uuid_option_group;
   OptionGroupString m_file_option;
+  OptionGroupBoolean m_load_option;
   OptionGroupUInt64 m_slide_option;
 };
 
Index: include/lldb/Symbol/ObjectFile.h
===================================================================
--- include/lldb/Symbol/ObjectFile.h
+++ include/lldb/Symbol/ObjectFile.h
@@ -774,6 +774,20 @@
       llvm::StringRef name,
       lldb::SymbolType symbol_type_hint = lldb::eSymbolTypeUndefined);
 
+  //------------------------------------------------------------------
+  /// Loads this objfile to memory.
+  ///
+  /// Loads the bits needed to create an executable image to the memory.
+  /// It is useful with bare-metal targets where target does not have the
+  /// ability to start a process itself.
+  ///
+  /// @param[in] target
+  ///     Target where to load.
+  ///
+  /// @return
+  //------------------------------------------------------------------
+  virtual Error LoadInMemory(Target &target);
+
 protected:
   //------------------------------------------------------------------
   // Member variables.
Index: include/lldb/Core/Module.h
===================================================================
--- include/lldb/Core/Module.h
+++ include/lldb/Core/Module.h
@@ -962,6 +962,20 @@
   bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const;
   bool RemapSourceFile(const char *, std::string &) const = delete;
 
+  //------------------------------------------------------------------
+  /// Loads this module to memory.
+  ///
+  /// Loads the bits needed to create an executable image to the memory.
+  /// It is useful with bare-metal targets where target does not have the
+  /// ability to start a process itself.
+  ///
+  /// @param[in] target
+  ///     Target where to load the module.
+  ///
+  /// @return
+  //------------------------------------------------------------------
+  Error LoadInMemory(Target &target);
+
   //----------------------------------------------------------------------
   /// @class LookupInfo Module.h "lldb/Core/Module.h"
   /// @brief A class that encapsulates name lookup information.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to