summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp28
-rw-r--r--lldb/source/Core/Module.cpp4
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp31
3 files changed, 63 insertions, 0 deletions
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index d2e53aa4a14..61e9e9bcd94 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -2567,6 +2567,9 @@ public:
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.",
+ 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.",
@@ -2574,6 +2577,7 @@ public:
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 +2589,7 @@ public:
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 +2599,21 @@ protected:
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 +2741,13 @@ protected:
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 +2810,7 @@ protected:
OptionGroupOptions m_option_group;
OptionGroupUUID m_uuid_option_group;
OptionGroupString m_file_option;
+ OptionGroupBoolean m_load_option;
OptionGroupUInt64 m_slide_option;
};
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 28f140b41e1..8cd06f11507 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1664,3 +1664,7 @@ bool Module::GetIsDynamicLinkEditor() {
return false;
}
+
+Error Module::LoadInMemory(Target &target) {
+ return m_objfile_sp->LoadInMemory(target);
+}
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index 0b1d6b29983..ecae78e3954 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/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 @@ ConstString ObjectFile::GetNextSyntheticSymbolName() {
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;
+}
OpenPOWER on IntegriCloud