bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.empty()) { Log::ListAllLogChannels(&result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishResult); } else { for (auto &entry : args.entries()) { Log::Callbacks log_callbacks; if (Log::GetLogChannelCallbacks(ConstString(entry.ref), log_callbacks)) { log_callbacks.list_categories(&result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishResult); } else if (entry.ref == "all") { Log::ListAllLogChannels(&result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishResult); } else { LogChannelSP log_channel_sp(LogChannel::FindPlugin(entry.c_str())); if (log_channel_sp) { log_channel_sp->ListCategories(&result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else result.AppendErrorWithFormat("Invalid log channel '%s'.\n", entry.c_str()); } } } return result.Succeeded(); }
static void FixupEnvironment(Args &env) { #ifdef __ANDROID__ // If there is no PATH variable specified inside the environment then set the // path to /system/bin. It is required because the default path used by // execve() is wrong on android. static const char *path = "PATH="; for (auto &entry : env.entries()) { if (entry.ref.startswith(path)) return; } env.AppendArgument(llvm::StringRef("PATH=/system/bin")); #endif }
bool DoExecute(Args &command, CommandReturnObject &result) override { bool demangled_any = false; bool error_any = false; for (auto &entry : command.entries()) { if (entry.ref.empty()) continue; // the actual Mangled class should be strict about this, but on the // command line if you're copying mangled names out of 'nm' on Darwin, // they will come out with an extra underscore - be willing to strip // this on behalf of the user. This is the moral equivalent of the -_/-n // options to c++filt auto name = entry.ref; if (name.startswith("__Z")) name = name.drop_front(); Mangled mangled(name, true); if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) { ConstString demangled( mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus)); demangled_any = true; result.AppendMessageWithFormat("%s ---> %s\n", entry.ref.str().c_str(), demangled.GetCString()); } else { error_any = true; result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", entry.ref.str().c_str()); } } result.SetStatus( error_any ? lldb::eReturnStatusFailed : (demangled_any ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult)); return result.Succeeded(); }
bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) { ConstString target_triple; Process *process = m_exe_ctx.GetProcessPtr(); if (!process) { result.AppendError("Args found no process."); result.SetStatus(eReturnStatusFailed); return false; } const ABI *abi = process->GetABI().get(); if (!abi) { result.AppendError("The current process has no ABI."); result.SetStatus(eReturnStatusFailed); return false; } if (args.empty()) { result.AppendError("args requires at least one argument"); result.SetStatus(eReturnStatusFailed); return false; } Thread *thread = m_exe_ctx.GetThreadPtr(); if (!thread) { result.AppendError("args found no thread."); result.SetStatus(eReturnStatusFailed); return false; } lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame(); if (!thread_cur_frame) { result.AppendError("The current thread has no current frame."); result.SetStatus(eReturnStatusFailed); return false; } ModuleSP thread_module_sp( thread_cur_frame->GetFrameCodeAddress().GetModule()); if (!thread_module_sp) { result.AppendError("The PC has no associated module."); result.SetStatus(eReturnStatusFailed); return false; } TypeSystem *type_system = thread_module_sp->GetTypeSystemForLanguage(eLanguageTypeC); if (type_system == nullptr) { result.AppendError("Unable to create C type system."); result.SetStatus(eReturnStatusFailed); return false; } ValueList value_list; for (auto &arg_entry : args.entries()) { llvm::StringRef arg_type = arg_entry.ref; Value value; value.SetValueType(Value::eValueTypeScalar); CompilerType compiler_type; std::size_t int_pos = arg_type.find("int"); if (int_pos != llvm::StringRef::npos) { Encoding encoding = eEncodingSint; int width = 0; if (int_pos > 1) { result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str()); result.SetStatus(eReturnStatusFailed); return false; } if (int_pos == 1 && arg_type[0] != 'u') { result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str()); result.SetStatus(eReturnStatusFailed); return false; } if (arg_type[0] == 'u') { encoding = eEncodingUint; } llvm::StringRef width_spec = arg_type.drop_front(int_pos + 3); auto exp_result = llvm::StringSwitch<llvm::Optional<int>>(width_spec) .Case("8_t", 8) .Case("16_t", 16) .Case("32_t", 32) .Case("64_t", 64) .Default(llvm::None); if (!exp_result.hasValue()) { result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str()); result.SetStatus(eReturnStatusFailed); return false; } width = *exp_result; compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(encoding, width); if (!compiler_type.IsValid()) { result.AppendErrorWithFormat( "Couldn't get Clang type for format %s (%s integer, width %d).\n", arg_entry.c_str(), (encoding == eEncodingSint ? "signed" : "unsigned"), width); result.SetStatus(eReturnStatusFailed); return false; } } else if (arg_type == "void*") { compiler_type = type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType(); } else if (arg_type == "char*") { compiler_type = type_system->GetBasicTypeFromAST(eBasicTypeChar).GetPointerType(); } else { result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str()); result.SetStatus(eReturnStatusFailed); return false; } value.SetCompilerType(compiler_type); value_list.PushValue(value); } if (!abi->GetArgumentValues(*thread, value_list)) { result.AppendError("Couldn't get argument values"); result.SetStatus(eReturnStatusFailed); return false; } result.GetOutputStream().Printf("Arguments : \n"); for (auto entry : llvm::enumerate(args.entries())) { result.GetOutputStream().Printf("%" PRIu64 " (%s): ", (uint64_t)entry.Index, entry.Value.c_str()); value_list.GetValueAtIndex(entry.Index)->Dump(&result.GetOutputStream()); result.GetOutputStream().Printf("\n"); } return result.Succeeded(); }
bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { CommandObject::CommandMap::iterator pos; CommandObject *cmd_obj; const size_t argc = command.GetArgumentCount(); // 'help' doesn't take any arguments, other than command names. If argc is 0, // we show the user // all commands (aliases and user commands if asked for). Otherwise every // argument must be the name of a command or a sub-command. if (argc == 0) { uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin; if (m_options.m_show_aliases) cmd_types |= CommandInterpreter::eCommandTypesAliases; if (m_options.m_show_user_defined) cmd_types |= CommandInterpreter::eCommandTypesUserDef; if (m_options.m_show_hidden) cmd_types |= CommandInterpreter::eCommandTypesHidden; result.SetStatus(eReturnStatusSuccessFinishNoResult); m_interpreter.GetHelp(result, cmd_types); // General help } else { // Get command object for the first command argument. Only search built-in // command dictionary. StringList matches; auto command_name = command[0].ref; cmd_obj = m_interpreter.GetCommandObject(command_name, &matches); if (cmd_obj != nullptr) { StringList matches; bool all_okay = true; CommandObject *sub_cmd_obj = cmd_obj; // Loop down through sub_command dictionaries until we find the command // object that corresponds to the help command entered. std::string sub_command; for (auto &entry : command.entries().drop_front()) { sub_command = entry.ref; matches.Clear(); if (sub_cmd_obj->IsAlias()) sub_cmd_obj = ((CommandAlias *)sub_cmd_obj)->GetUnderlyingCommand().get(); if (!sub_cmd_obj->IsMultiwordObject()) { all_okay = false; break; } else { CommandObject *found_cmd; found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches); if (found_cmd == nullptr || matches.GetSize() > 1) { all_okay = false; break; } else sub_cmd_obj = found_cmd; } } if (!all_okay || (sub_cmd_obj == nullptr)) { std::string cmd_string; command.GetCommandString(cmd_string); if (matches.GetSize() >= 2) { StreamString s; s.Printf("ambiguous command %s", cmd_string.c_str()); size_t num_matches = matches.GetSize(); for (size_t match_idx = 0; match_idx < num_matches; match_idx++) { s.Printf("\n\t%s", matches.GetStringAtIndex(match_idx)); } s.Printf("\n"); result.AppendError(s.GetString()); result.SetStatus(eReturnStatusFailed); return false; } else if (!sub_cmd_obj) { StreamString error_msg_stream; GenerateAdditionalHelpAvenuesMessage( &error_msg_stream, cmd_string.c_str(), m_interpreter.GetCommandPrefix(), sub_command.c_str()); result.AppendError(error_msg_stream.GetString()); result.SetStatus(eReturnStatusFailed); return false; } else { GenerateAdditionalHelpAvenuesMessage( &result.GetOutputStream(), cmd_string.c_str(), m_interpreter.GetCommandPrefix(), sub_command.c_str()); result.GetOutputStream().Printf( "\nThe closest match is '%s'. Help on it follows.\n\n", sub_cmd_obj->GetCommandName().str().c_str()); } } sub_cmd_obj->GenerateHelpText(result); if (m_interpreter.AliasExists(command_name)) { StreamString sstr; m_interpreter.GetAlias(command_name)->GetAliasExpansion(sstr); result.GetOutputStream().Printf("\n'%s' is an abbreviation for %s\n", command[0].c_str(), sstr.GetData()); } } else if (matches.GetSize() > 0) { Stream &output_strm = result.GetOutputStream(); output_strm.Printf("Help requested with ambiguous command name, possible " "completions:\n"); const size_t match_count = matches.GetSize(); for (size_t i = 0; i < match_count; i++) { output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i)); } } else { // Maybe the user is asking for help about a command argument rather than // a command. const CommandArgumentType arg_type = CommandObject::LookupArgumentName(command_name); if (arg_type != eArgTypeLastArg) { Stream &output_strm = result.GetOutputStream(); CommandObject::GetArgumentHelp(output_strm, arg_type, m_interpreter); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { StreamString error_msg_stream; GenerateAdditionalHelpAvenuesMessage(&error_msg_stream, command_name, m_interpreter.GetCommandPrefix(), ""); result.AppendError(error_msg_stream.GetString()); result.SetStatus(eReturnStatusFailed); } } } return result.Succeeded(); }