Esempio n. 1
0
bool PrintCommand::Run(Debugger* debugger) {
  VIXL_ASSERT(debugger->IsDebuggerRunning());

  Token* tok = target();
  if (tok->IsIdentifier()) {
    char* identifier = IdentifierToken::Cast(tok)->value();
    if (strcmp(identifier, "regs") == 0) {
      debugger->PrintRegisters();
    } else if (strcmp(identifier, "fpregs") == 0) {
      debugger->PrintFPRegisters();
    } else if (strcmp(identifier, "sysregs") == 0) {
      debugger->PrintSystemRegisters();
    } else if (strcmp(identifier, "pc") == 0) {
      printf("pc = %16p\n", reinterpret_cast<const void*>(debugger->pc()));
    } else {
      printf(" ** Unknown identifier to print: %s **\n", identifier);
    }

    return false;
  }

  FormatToken* format_tok = format();
  VIXL_ASSERT(format_tok != NULL);
  if (format_tok->type_code() == 'i') {
    // TODO(all): Add support for instruction disassembly.
    printf(" ** unsupported format: instructions **\n");
    return false;
  }

  if (tok->IsRegister()) {
    RegisterToken* reg_tok = RegisterToken::Cast(tok);
    Register reg = reg_tok->value();
    debugger->PrintRegister(reg, reg_tok->Name(), format_tok);
    return false;
  }

  if (tok->IsFPRegister()) {
    FPRegister fpreg = FPRegisterToken::Cast(tok)->value();
    debugger->PrintFPRegister(fpreg, format_tok);
    return false;
  }

  VIXL_UNREACHABLE();
  return false;
}
Esempio n. 2
0
DebugCommand* PrintCommand::Build(std::vector<Token*> args) {
  if (args.size() < 2) {
    return new InvalidCommand(args, -1, "too few arguments");
  }

  Token* target = args[1];
  if (!target->IsRegister() &&
      !target->IsFPRegister() &&
      !target->IsIdentifier()) {
    return new InvalidCommand(args, 1, "expects reg or identifier");
  }

  FormatToken* format = NULL;
  int target_size = 0;
  if (target->IsRegister()) {
    Register reg = RegisterToken::Cast(target)->value();
    target_size = reg.SizeInBytes();
  } else if (target->IsFPRegister()) {
    FPRegister fpreg = FPRegisterToken::Cast(target)->value();
    target_size = fpreg.SizeInBytes();
  }
  // If the target is an identifier there must be no format. This is checked
  // in the switch statement below.

  switch (args.size()) {
    case 2: {
      if (target->IsRegister()) {
        switch (target_size) {
          case 4: format = new Format<uint32_t>("%08" PRIx32, 'x'); break;
          case 8: format = new Format<uint64_t>("%016" PRIx64, 'x'); break;
          default: VIXL_UNREACHABLE();
        }
      } else if (target->IsFPRegister()) {
        switch (target_size) {
          case 4: format = new Format<float>("%8g", 'f'); break;
          case 8: format = new Format<double>("%8g", 'f'); break;
          default: VIXL_UNREACHABLE();
        }
      }
      break;
    }
    case 3: {
      if (target->IsIdentifier()) {
        return new InvalidCommand(args, 2,
            "format is only allowed with registers");
      }

      Token* second = args[2];
      if (!second->IsFormat()) {
        return new InvalidCommand(args, 2, "expects format");
      }
      format = FormatToken::Cast(second);

      if (format->SizeOf() > target_size) {
        return new InvalidCommand(args, 2, "format too wide");
      }

      break;
    }
    default:
      return new InvalidCommand(args, -1, "too many arguments");
  }

  return new PrintCommand(args[0], target, format);
}