Index: source/Commands/CommandObjectTarget.cpp =================================================================== --- source/Commands/CommandObjectTarget.cpp +++ source/Commands/CommandObjectTarget.cpp @@ -45,6 +45,7 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ABI.h" #include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" @@ -2567,6 +2568,10 @@ m_option_group(), m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""), + m_write_option(LLDB_OPT_SET_1, false, "write-to-mem", 'w', + "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.", @@ -2574,6 +2579,7 @@ 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_write_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(); } @@ -2583,8 +2589,50 @@ Options *GetOptions() override { return &m_option_group; } protected: + bool WriteToMemory(CommandReturnObject &result, Module *module) { + ObjectFile *objfile = module->GetObjectFile(); + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + Process *process = m_exe_ctx.GetProcessPtr(); + if (objfile && target && process) { + SectionList *section_list = module->GetSectionList(); + 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; + Error error; + section_sp->GetSectionData(section_data); + lldb::offset_t written = + process->WriteMemory(addr, section_data.GetDataStart(), + section_data.GetByteSize(), error); + if (written != section_data.GetByteSize()) { + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + result.AppendMessageWithFormat( + "Loading section %s Size 0x%" PRIx64 "Addr 0x%" PRIx64 "\n", + section_sp->GetName().AsCString(), section_data.GetByteSize(), + addr); + } + } + ThreadList &thread_list = process->GetThreadList(); + ThreadSP curr_thread(thread_list.GetSelectedThread()); + RegisterContextSP reg_context(curr_thread->GetRegisterContext()); + reg_context->SetPC(objfile->GetEntryPointAddress()); + return result.Succeeded(); + } + return false; + } + bool DoExecute(Args &args, CommandReturnObject &result) override { Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + const bool write = m_write_option.GetOptionValue().GetCurrentValue(); if (target == nullptr) { result.AppendError("invalid target, create a debug target using the " "'target create' command"); @@ -2594,6 +2642,21 @@ const size_t argc = args.GetArgumentCount(); ModuleSpec module_spec; bool search_using_module_spec = false; + + // Allow "--write-to-mem" option to work without --file or --uuid + // option. + if (write) { + 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 +2784,8 @@ if (process) process->Flush(); } + if (write) + return WriteToMemory(result, module); } else { module->GetFileSpec().GetPath(path, sizeof(path)); result.AppendErrorWithFormat( @@ -2783,6 +2848,7 @@ OptionGroupOptions m_option_group; OptionGroupUUID m_uuid_option_group; OptionGroupString m_file_option; + OptionGroupBoolean m_write_option; OptionGroupUInt64 m_slide_option; };