summaryrefslogtreecommitdiff
path: root/source/Commands/CommandObjectTarget.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
commitf73363f1dd94996356cefbf24388f561891acf0b (patch)
treee3c31248bdb36eaec5fd833490d4278162dba2a0 /source/Commands/CommandObjectTarget.cpp
parent160ee69dd7ae18978f4068116777639ea98dc951 (diff)
Notes
Diffstat (limited to 'source/Commands/CommandObjectTarget.cpp')
-rw-r--r--source/Commands/CommandObjectTarget.cpp245
1 files changed, 115 insertions, 130 deletions
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index c83061d8de74..a9062c14b367 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -21,9 +21,9 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupArchitecture.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFile.h"
@@ -45,10 +45,12 @@
#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"
#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Timer.h"
#include "llvm/Support/FileSystem.h"
@@ -193,20 +195,13 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
@@ -256,7 +251,7 @@ protected:
FileSpec file_spec;
if (file_path)
- file_spec.SetFile(file_path, true);
+ file_spec.SetFile(file_path, true, FileSpec::Style::native);
bool must_set_platform_path = false;
@@ -272,10 +267,8 @@ protected:
if (target_sp) {
// Only get the platform after we create the target because we might
- // have
- // switched platforms depending on what the arguments were to
- // CreateTarget()
- // we can't rely on the selected platform.
+ // have switched platforms depending on what the arguments were to
+ // CreateTarget() we can't rely on the selected platform.
PlatformSP platform_sp = target_sp->GetPlatform();
@@ -366,8 +359,8 @@ protected:
&core_file));
if (process_sp) {
- // Seems weird that we Launch a core file, but that is
- // what we do!
+ // Seems weird that we Launch a core file, but that is what we
+ // do!
error = process_sp->LoadCore();
if (error.Fail()) {
@@ -616,8 +609,8 @@ protected:
target_list.DeleteTarget(target_sp);
target_sp->Destroy();
}
- // If "--clean" was specified, prune any orphaned shared modules from
- // the global shared module list
+ // If "--clean" was specified, prune any orphaned shared modules from the
+ // global shared module list
if (m_cleanup_option.GetOptionValue()) {
const bool mandatory = true;
ModuleList::RemoveOrphanSharedModules(mandatory);
@@ -752,7 +745,7 @@ public:
VariableList &variable_list) {
Target *target = static_cast<Target *>(baton);
if (target) {
- return target->GetImages().FindGlobalVariables(ConstString(name), true,
+ return target->GetImages().FindGlobalVariables(ConstString(name),
UINT32_MAX, variable_list);
}
return 0;
@@ -818,8 +811,8 @@ protected:
return false;
}
use_var_name = true;
- matches = target->GetImages().FindGlobalVariables(
- regex, true, UINT32_MAX, variable_list);
+ matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
+ variable_list);
} else {
Status error(Variable::GetValuesForVariableExpressionPath(
arg, m_exe_ctx.GetBestExecutionContextScope(),
@@ -947,8 +940,8 @@ protected:
llvm::StringRef(
".")); // Any global with at least one character
VariableList variable_list;
- sc.module_sp->FindGlobalVariables(all_globals_regex, append,
- UINT32_MAX, variable_list);
+ sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
+ variable_list);
DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
}
}
@@ -995,10 +988,9 @@ public:
new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
- // There are two required arguments that must always occur together, i.e. an
- // argument "pair". Because they
- // must always occur together, they are treated as two variants of one
- // argument rather than two independent
+ // There are two required arguments that must always occur together, i.e.
+ // an argument "pair". Because they must always occur together, they are
+ // treated as two variants of one argument rather than two independent
// arguments. Push them both into the first argument position for
// m_arguments...
@@ -1109,10 +1101,9 @@ public:
new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
- // There are two required arguments that must always occur together, i.e. an
- // argument "pair". Because they
- // must always occur together, they are treated as two variants of one
- // argument rather than two independent
+ // There are two required arguments that must always occur together, i.e.
+ // an argument "pair". Because they must always occur together, they are
+ // treated as two variants of one argument rather than two independent
// arguments. Push them both into the same argument position for
// m_arguments...
@@ -1386,7 +1377,12 @@ static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
strm.EOL();
}
ObjectFile *objfile = module->GetObjectFile();
- objfile->Dump(&strm);
+ if (objfile)
+ objfile->Dump(&strm);
+ else {
+ strm.Format("No object file for module: {0:F}\n",
+ module->GetFileSpec());
+ }
}
}
strm.IndentLess();
@@ -1632,8 +1628,8 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
strm.PutCString(":\n");
for (TypeSP type_sp : type_list.Types()) {
if (type_sp) {
- // Resolve the clang type so that any forward references
- // to types that haven't yet been parsed will get parsed.
+ // Resolve the clang type so that any forward references to types
+ // that haven't yet been parsed will get parsed.
type_sp->GetFullCompilerType();
type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
// Print all typedef chains
@@ -1683,8 +1679,8 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
TypeSP type_sp(type_list.GetTypeAtIndex(0));
if (type_sp) {
- // Resolve the clang type so that any forward references
- // to types that haven't yet been parsed will get parsed.
+ // Resolve the clang type so that any forward references to types that
+ // haven't yet been parsed will get parsed.
type_sp->GetFullCompilerType();
type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
// Print all typedef chains
@@ -1762,9 +1758,8 @@ static size_t FindModulesByName(Target *target, const char *module_name,
const size_t num_matches =
target->GetImages().FindModules(module_spec, module_list);
- // Not found in our module list for our target, check the main
- // shared module list in case it is a extra file used somewhere
- // else
+ // Not found in our module list for our target, check the main shared
+ // module list in case it is a extra file used somewhere else
if (num_matches == 0) {
module_spec.GetArchitecture() = target->GetArchitecture();
ModuleList::FindSharedModules(module_spec, module_list);
@@ -1809,21 +1804,13 @@ public:
~CommandObjectTargetModulesModuleAutoComplete() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- // Arguments are the standard module completer.
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
- GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
+ nullptr);
+ return request.GetMatches().GetSize();
}
};
@@ -1858,21 +1845,13 @@ public:
~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- // Arguments are the standard source file completer.
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
};
@@ -1982,7 +1961,7 @@ public:
switch (short_option) {
case 's':
- m_sort_order = (SortOrder)Args::StringToOptionEnum(
+ m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
option_arg, GetDefinitions()[option_idx].enum_values,
eSortOrderNone, error);
break;
@@ -2408,20 +2387,13 @@ public:
Options *GetOptions() override { return &m_option_group; }
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
protected:
@@ -2604,8 +2576,7 @@ protected:
ModuleSpec module_spec;
bool search_using_module_spec = false;
- // Allow "load" option to work without --file or --uuid
- // option.
+ // Allow "load" option to work without --file or --uuid option.
if (load) {
if (!m_file_option.GetOptionValue().OptionWasSet() &&
!m_uuid_option_group.GetOptionValue().OptionWasSet()) {
@@ -2746,11 +2717,34 @@ protected:
process->Flush();
}
if (load) {
- Status error = module->LoadInMemory(*target, set_pc);
+ ProcessSP process = target->CalculateProcess();
+ Address file_entry = objfile->GetEntryPointAddress();
+ if (!process) {
+ result.AppendError("No process");
+ return false;
+ }
+ if (set_pc && !file_entry.IsValid()) {
+ result.AppendError("No entry address in object file");
+ return false;
+ }
+ std::vector<ObjectFile::LoadableData> loadables(
+ objfile->GetLoadableData(*target));
+ if (loadables.size() == 0) {
+ result.AppendError("No loadable sections");
+ return false;
+ }
+ Status error = process->WriteObjectFile(std::move(loadables));
if (error.Fail()) {
result.AppendError(error.AsCString());
return false;
}
+ if (set_pc) {
+ ThreadList &thread_list = process->GetThreadList();
+ ThreadSP curr_thread(thread_list.GetSelectedThread());
+ RegisterContextSP reg_context(
+ curr_thread->GetRegisterContext());
+ reg_context->SetPC(file_entry.GetLoadAddress(target));
+ }
}
} else {
module->GetFileSpec().GetPath(path, sizeof(path));
@@ -2861,8 +2855,8 @@ public:
if (short_option == 'g') {
m_use_global_module_list = true;
} else if (short_option == 'a') {
- m_module_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_module_addr = OptionArgParser::ToAddress(
+ execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
} else {
unsigned long width = 0;
option_arg.getAsInteger(0, width);
@@ -2904,9 +2898,8 @@ protected:
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
const bool use_global_module_list = m_options.m_use_global_module_list;
// Define a local module list here to ensure it lives longer than any
- // "locker"
- // object which might lock its contents below (through the "module_list_ptr"
- // variable).
+ // "locker" object which might lock its contents below (through the
+ // "module_list_ptr" variable).
ModuleList module_list;
if (target == nullptr && !use_global_module_list) {
result.AppendError("invalid target, create a debug target using the "
@@ -2954,10 +2947,9 @@ protected:
size_t num_modules = 0;
// This locker will be locked on the mutex in module_list_ptr if it is
- // non-nullptr.
- // Otherwise it will lock the AllocationModuleCollectionMutex when
- // accessing
- // the global module list directly.
+ // non-nullptr. Otherwise it will lock the
+ // AllocationModuleCollectionMutex when accessing the global module list
+ // directly.
std::unique_lock<std::recursive_mutex> guard(
Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
@@ -3227,8 +3219,8 @@ public:
case 'a': {
m_str = option_arg;
m_type = eLookupTypeAddress;
- m_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
if (m_addr == LLDB_INVALID_ADDRESS)
error.SetErrorStringWithFormat("invalid address string '%s'",
option_arg.str().c_str());
@@ -3543,8 +3535,8 @@ public:
switch (short_option) {
case 'a': {
m_type = eLookupTypeAddress;
- m_addr = Args::StringToAddress(execution_context, option_arg,
- LLDB_INVALID_ADDRESS, &error);
+ m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
} break;
case 'o':
@@ -3559,7 +3551,7 @@ public:
break;
case 'f':
- m_file.SetFile(option_arg, false);
+ m_file.SetFile(option_arg, false, FileSpec::Style::native);
m_type = eLookupTypeFileLine;
break;
@@ -3805,9 +3797,9 @@ protected:
if (command.GetArgumentCount() == 0) {
ModuleSP current_module;
- // Where it is possible to look in the current symbol context
- // first, try that. If this search was successful and --all
- // was not passed, don't print anything else.
+ // Where it is possible to look in the current symbol context first,
+ // try that. If this search was successful and --all was not passed,
+ // don't print anything else.
if (LookupHere(m_interpreter, result, syntax_error)) {
result.GetOutputStream().EOL();
num_successful_lookups++;
@@ -3989,20 +3981,13 @@ public:
~CommandObjectTargetSymbolsAdd() override = default;
- int HandleArgumentCompletion(Args &input, int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point, int max_return_elements,
- bool &word_complete,
- StringList &matches) override {
- std::string completion_str(input.GetArgumentAtIndex(cursor_index));
- completion_str.erase(cursor_char_position);
-
+ int HandleArgumentCompletion(
+ CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
CommandCompletions::InvokeCommonCompletionCallbacks(
GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(), match_start_point, max_return_elements, nullptr,
- word_complete, matches);
- return matches.GetSize();
+ request, nullptr);
+ return request.GetMatches().GetSize();
}
Options *GetOptions() override { return &m_option_group; }
@@ -4019,10 +4004,9 @@ protected:
if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
}
- // We now have a module that represents a symbol file
- // that can be used for a module that might exist in the
- // current target, so we need to find that module in the
- // target
+ // We now have a module that represents a symbol file that can be used
+ // for a module that might exist in the current target, so we need to
+ // find that module in the target
ModuleList matching_module_list;
size_t num_matches = 0;
@@ -4048,8 +4032,7 @@ protected:
if (num_matches == 0) {
// No matches yet, iterate through the module specs to find a UUID
- // value that
- // we can match up to an image in our target
+ // value that we can match up to an image in our target
const size_t num_symfile_module_specs =
symfile_module_specs.GetSize();
for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
@@ -4069,8 +4052,8 @@ protected:
}
}
- // Just try to match up the file by basename if we have no matches at this
- // point
+ // Just try to match up the file by basename if we have no matches at
+ // this point
if (num_matches == 0)
num_matches =
target->GetImages().FindModules(module_spec, matching_module_list);
@@ -4082,7 +4065,8 @@ protected:
if (!filename_no_extension)
break;
- // Check if there was no extension to strip and the basename is the same
+ // Check if there was no extension to strip and the basename is the
+ // same
if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
break;
@@ -4101,9 +4085,9 @@ protected:
} else if (num_matches == 1) {
ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
- // The module has not yet created its symbol vendor, we can just
- // give the existing target module the symfile path to use for
- // when it decides to create it!
+ // The module has not yet created its symbol vendor, we can just give
+ // the existing target module the symfile path to use for when it
+ // decides to create it!
module_sp->SetSymbolFileFileSpec(symbol_fspec);
SymbolVendor *symbol_vendor =
@@ -4121,8 +4105,8 @@ protected:
"symbol file '%s' has been added to '%s'\n", symfile_path,
module_fs.GetPath().c_str());
- // Let clients know something changed in the module
- // if it is currently loaded
+ // Let clients know something changed in the module if it is
+ // currently loaded
ModuleList module_list;
module_list.Append(module_sp);
target->SymbolsDidLoad(module_list);
@@ -4298,7 +4282,8 @@ protected:
for (auto &entry : args.entries()) {
if (!entry.ref.empty()) {
- module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
+ module_spec.GetSymbolFileSpec().SetFile(entry.ref, true,
+ FileSpec::Style::native);
if (file_option_set) {
module_spec.GetFileSpec() =
m_file_option.GetOptionValue().GetCurrentValue();