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();
  }
Exemple #2
0
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();
  }
Exemple #4
0
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();
}