Ejemplo n.º 1
0
// Read a command. A command will be at most kMaxDebugShellLine char long and
// ends with '\n\0'.
// TODO: Should this be a utility function?
char* Debugger::ReadCommandLine(const char* prompt, char* buffer, int length) {
  int fgets_calls = 0;
  char* end = NULL;

  printf("%s", prompt);
  fflush(stdout);

  do {
    if (fgets(buffer, length, stdin) == NULL) {
      printf(" ** Error while reading command. **\n");
      return NULL;
    }

    fgets_calls++;
    end = strchr(buffer, '\n');
  } while (end == NULL);

  if (fgets_calls != 1) {
    printf(" ** Command too long. **\n");
    return NULL;
  }

  // Remove the newline from the end of the command.
  VIXL_ASSERT(end[1] == '\0');
  VIXL_ASSERT((end - buffer) < (length - 1));
  end[0] = '\0';

  return buffer;
}
Ejemplo n.º 2
0
BufferOffset Assembler::DataProcShiftedRegister(const Register& rd, const Register& rn,
                                                const Operand& operand, FlagsUpdate S, Instr op)
{
  VIXL_ASSERT(operand.IsShiftedRegister());
  VIXL_ASSERT(rn.Is64Bits() || (rn.Is32Bits() && is_uint5(operand.shift_amount())));
  return Emit(SF(rd) | op | Flags(S) |
              ShiftDP(operand.shift()) | ImmDPShift(operand.shift_amount()) |
              Rm(operand.reg()) | Rn(rn) | Rd(rd));
}
Ejemplo n.º 3
0
void MozBaseAssembler::WritePoolHeader(uint8_t* start, js::jit::Pool* p, bool isNatural) {
  JS_STATIC_ASSERT(sizeof(PoolHeader) == 4);

  // Get the total size of the pool.
  const uintptr_t totalPoolSize = sizeof(PoolHeader) + p->getPoolSize();
  const uintptr_t totalPoolInstructions = totalPoolSize / sizeof(Instruction);

  VIXL_ASSERT((totalPoolSize & 0x3) == 0);
  VIXL_ASSERT(totalPoolInstructions < (1 << 15));

  PoolHeader header(totalPoolInstructions, isNatural);
  *(PoolHeader*)start = header;
}
Ejemplo n.º 4
0
uint8_t* RegisterToken::ToAddress(Debugger* debugger) const {
  VIXL_ASSERT(CanAddressMemory());
  uint64_t reg_value = debugger->xreg(value().code(), Reg31IsStackPointer);
  uint8_t* address = NULL;
  memcpy(&address, &reg_value, sizeof(address));
  return address;
}
Ejemplo n.º 5
0
void DebugCommand::PrintHelp(const char** aliases,
                             const char* args,
                             const char* help) {
  VIXL_ASSERT(aliases[0] != NULL);
  VIXL_ASSERT(help != NULL);

  printf("\n----\n\n");
  for (const char** current = aliases; *current != NULL; current++) {
    if (args != NULL) {
      printf("%s %s\n", *current, args);
    } else {
      printf("%s\n", *current);
    }
  }
  printf("\n%s\n", help);
}
Ejemplo n.º 6
0
ptrdiff_t Assembler::LinkAndGetOffsetTo(BufferOffset branch, Label* label) {
  if (armbuffer_.oom())
    return js::jit::LabelBase::INVALID_OFFSET;

  if (label->bound()) {
    // The label is bound: all uses are already linked.
    ptrdiff_t branch_offset = ptrdiff_t(branch.getOffset() / element_size);
    ptrdiff_t label_offset = ptrdiff_t(label->offset() / element_size);
    return label_offset - branch_offset;
  }

  if (!label->used()) {
    // The label is unbound and unused: store the offset in the label itself
    // for patching by bind().
    label->use(branch.getOffset());
    return js::jit::LabelBase::INVALID_OFFSET;
  }

  // The label is unbound but used. Create an implicit linked list between
  // the branches, and update the linked list head in the label struct.
  ptrdiff_t prevHeadOffset = static_cast<ptrdiff_t>(label->offset());
  label->use(branch.getOffset());
  VIXL_ASSERT(prevHeadOffset - branch.getOffset() != js::jit::LabelBase::INVALID_OFFSET);
  return prevHeadOffset - branch.getOffset();
}
Ejemplo n.º 7
0
void MozBaseAssembler::WritePoolGuard(BufferOffset branch, Instruction* inst, BufferOffset dest) {
  int byteOffset = dest.getOffset() - branch.getOffset();
  VIXL_ASSERT(byteOffset % kInstructionSize == 0);

  int instOffset = byteOffset >> kInstructionSizeLog2;
  Assembler::b(inst, instOffset);
}
Ejemplo n.º 8
0
uint8_t* IdentifierToken::ToAddress(Debugger* debugger) const {
  VIXL_ASSERT(CanAddressMemory());
  const Instruction* pc_value = debugger->pc();
  uint8_t* address = NULL;
  memcpy(&address, &pc_value, sizeof(address));
  return address;
}
Ejemplo n.º 9
0
void Debugger::DoBreakpoint(const Instruction* instr) {
  VIXL_ASSERT(instr->Mask(ExceptionMask) == BRK);

  printf("Hit breakpoint at pc=%p.\n", reinterpret_cast<const void*>(instr));
  set_debug_parameters(debug_parameters() | DBG_BREAK | DBG_ACTIVE);
  // Make the shell point to the brk instruction.
  set_pc(instr);
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
void Assembler::adrp(const Register& rd, Label* label) {
  VIXL_ASSERT(AllowPageOffsetDependentCode());

  // Flush the instruction buffer if necessary before getting an offset.
  BufferOffset offset = Emit(0);
  Instruction* ins = getInstructionAt(offset);

  // Encode the relative offset.
  adrp(ins, rd, LinkAndGetPageOffsetTo(offset, label));
}
Ejemplo n.º 12
0
BufferOffset Assembler::b(Label* label, Condition cond) {
  // Flush the instruction buffer if necessary before getting an offset.
  BufferOffset branch = b(0, Always);
  Instruction* ins = getInstructionAt(branch);
  VIXL_ASSERT(ins->IsCondBranchImm());

  // Encode the relative offset.
  b(ins, LinkAndGetInstructionOffsetTo(branch, label), cond);
  return branch;
}
Ejemplo n.º 13
0
unsigned CountClearHalfWords(uint64_t imm, unsigned reg_size) {
  VIXL_ASSERT((reg_size % 8) == 0);
  int count = 0;
  for (unsigned i = 0; i < (reg_size / 16); i++) {
    if ((imm & 0xffff) == 0) {
      count++;
    }
    imm >>= 16;
  }
  return count;
}
Ejemplo n.º 14
0
bool StepCommand::Run(Debugger* debugger) {
  VIXL_ASSERT(debugger->IsDebuggerRunning());

  int64_t steps = count();
  if (steps < 0) {
    printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps);
  } else if (steps > 1) {
    debugger->set_steps(steps - 1);
  }

  return true;
}
Ejemplo n.º 15
0
BufferOffset Assembler::Logical(const Register& rd, const Register& rn,
                                const Operand& operand, LogicalOp op)
{
  VIXL_ASSERT(rd.size() == rn.size());
  if (operand.IsImmediate()) {
    int64_t immediate = operand.immediate();
    unsigned reg_size = rd.size();

    VIXL_ASSERT(immediate != 0);
    VIXL_ASSERT(immediate != -1);
    VIXL_ASSERT(rd.Is64Bits() || is_uint32(immediate));

    // If the operation is NOT, invert the operation and immediate.
    if ((op & NOT) == NOT) {
      op = static_cast<LogicalOp>(op & ~NOT);
      immediate = rd.Is64Bits() ? ~immediate : (~immediate & kWRegMask);
    }

    unsigned n, imm_s, imm_r;
    if (IsImmLogical(immediate, reg_size, &n, &imm_s, &imm_r)) {
      // Immediate can be encoded in the instruction.
      return LogicalImmediate(rd, rn, n, imm_s, imm_r, op);
    } else {
      // This case is handled in the macro assembler.
      VIXL_UNREACHABLE();
    }
  } else {
    VIXL_ASSERT(operand.IsShiftedRegister());
    VIXL_ASSERT(operand.reg().size() == rd.size());
    Instr dp_op = static_cast<Instr>(op | LogicalShiftedFixed);
    return DataProcShiftedRegister(rd, rn, operand, LeaveFlags, dp_op);
  }
}
Ejemplo n.º 16
0
bool ExamineCommand::Run(Debugger* debugger) {
  VIXL_ASSERT(debugger->IsDebuggerRunning());

  uint8_t* address = target()->ToAddress(debugger);
  int64_t  amount = count()->value();
  if (format()->type_code() == 'i') {
    debugger->PrintInstructions(address, amount);
  } else {
    debugger->PrintMemory(address, format(), amount);
  }

  return false;
}
Ejemplo n.º 17
0
void Simulator::ResetState() {
  // Reset the system registers.
  nzcv_ = SimSystemRegister::DefaultValueFor(NZCV);
  fpcr_ = SimSystemRegister::DefaultValueFor(FPCR);

  // Reset registers to 0.
  pc_ = NULL;
  pc_modified_ = false;
  for (unsigned i = 0; i < kNumberOfRegisters; i++) {
    set_xreg(i, 0xbadbeef);
  }
  // Set FP registers to a value that is a NaN in both 32-bit and 64-bit FP.
  uint64_t nan_bits = UINT64_C(0x7ff0dead7f8beef1);
  VIXL_ASSERT(IsSignallingNaN(rawbits_to_double(nan_bits & kDRegMask)));
  VIXL_ASSERT(IsSignallingNaN(rawbits_to_float(nan_bits & kSRegMask)));
  for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
    set_dreg_bits(i, nan_bits);
  }
  // Returning to address 0 exits the Simulator.
  set_lr(kEndOfSimAddress);
  set_resume_pc(nullptr);
}
Ejemplo n.º 18
0
bool HelpCommand::Run(Debugger* debugger) {
  VIXL_ASSERT(debugger->IsDebuggerRunning());
  USE(debugger);

  #define PRINT_HELP(Command)                     \
    DebugCommand::PrintHelp(Command::kAliases,    \
                            Command::kArguments,  \
                            Command::kHelp);
  DEBUG_COMMAND_LIST(PRINT_HELP);
  #undef PRINT_HELP
  printf("\n----\n\n");

  return false;
}
Ejemplo n.º 19
0
bool UnknownCommand::Run(Debugger* debugger) {
  VIXL_ASSERT(debugger->IsDebuggerRunning());
  USE(debugger);

  printf(" ** Unknown Command:");
  const int size = args_.size();
  for (int i = 0; i < size; ++i) {
    printf(" ");
    args_[i]->Print(stdout);
  }
  printf(" **\n");

  return false;
}
Ejemplo n.º 20
0
void Debugger::PrintRegister(const Register& target_reg,
                             const char* name,
                             const FormatToken* format) {
  const uint64_t reg_size = target_reg.size();
  const uint64_t format_size = format->SizeOf() * 8;
  const uint64_t count = reg_size / format_size;
  const uint64_t mask = 0xffffffffffffffff >> (64 - format_size);
  const uint64_t reg_value = reg<uint64_t>(target_reg.code(),
                                           Reg31IsStackPointer);
  VIXL_ASSERT(count > 0);

  printf("%s = ", name);
  for (uint64_t i = 1; i <= count; i++) {
    uint64_t data = reg_value >> (reg_size - (i * format_size));
    data &= mask;
    format->PrintData(&data);
    printf(" ");
  }
  printf("\n");
}
Ejemplo n.º 21
0
bool InvalidCommand::Run(Debugger* debugger) {
  VIXL_ASSERT(debugger->IsDebuggerRunning());
  USE(debugger);

  printf(" ** Invalid Command:");
  const int size = args_.size();
  for (int i = 0; i < size; ++i) {
    printf(" ");
    if (i == index_) {
      printf(">>");
      args_[i]->Print(stdout);
      printf("<<");
    } else {
      args_[i]->Print(stdout);
    }
  }
  printf(" **\n");
  printf(" ** %s\n", cause_);

  return false;
}
Ejemplo n.º 22
0
void Debugger::PrintFPRegister(const FPRegister& target_fpreg,
                               const FormatToken* format) {
  const uint64_t fpreg_size = target_fpreg.size();
  const uint64_t format_size = format->SizeOf() * 8;
  const uint64_t count = fpreg_size / format_size;
  const uint64_t mask = 0xffffffffffffffff >> (64 - format_size);
  const uint64_t fpreg_value = fpreg<uint64_t>(fpreg_size,
                                               target_fpreg.code());
  VIXL_ASSERT(count > 0);

  if (target_fpreg.Is32Bits()) {
    printf("s%u = ", target_fpreg.code());
  } else {
    printf("d%u = ", target_fpreg.code());
  }
  for (uint64_t i = 1; i <= count; i++) {
    uint64_t data = fpreg_value >> (fpreg_size - (i * format_size));
    data &= mask;
    format->PrintData(&data);
    printf(" ");
  }
  printf("\n");
}
Ejemplo n.º 23
0
 Header(uint32_t data)
   : data(data)
 {
   JS_STATIC_ASSERT(sizeof(Header) == sizeof(uint32_t));
   VIXL_ASSERT(ONES == 0xffff);
 }
Ejemplo n.º 24
0
 static RegisterToken* Cast(Token* tok) {
   VIXL_ASSERT(tok->IsRegister());
   return reinterpret_cast<RegisterToken*>(tok);
 }
Ejemplo n.º 25
0
void FPRegisterToken::Print(FILE* out) const {
  VIXL_ASSERT(value().IsValid());
  char prefix = value().Is32Bits() ? 's' : 'd';
  fprintf(out, "[FPRegister %c%" PRIu32 "]", prefix, value().code());
}
Ejemplo n.º 26
0
void RegisterToken::Print(FILE* out) const {
  VIXL_ASSERT(value().IsValid());
  fprintf(out, "[Register %s]", Name());
}
Ejemplo n.º 27
0
bool ContinueCommand::Run(Debugger* debugger) {
  VIXL_ASSERT(debugger->IsDebuggerRunning());

  debugger->set_debug_parameters(debugger->debug_parameters() & ~DBG_ACTIVE);
  return true;
}
Ejemplo n.º 28
0
 static FormatToken* Cast(Token* tok) {
   VIXL_ASSERT(tok->IsFormat());
   return reinterpret_cast<FormatToken*>(tok);
 }
Ejemplo n.º 29
0
 static IntegerToken* Cast(Token* tok) {
   VIXL_ASSERT(tok->IsInteger());
   return reinterpret_cast<IntegerToken*>(tok);
 }
Ejemplo n.º 30
0
 static AddressToken* Cast(Token* tok) {
   VIXL_ASSERT(tok->IsAddress());
   return reinterpret_cast<AddressToken*>(tok);
 }