| Index: runtime/vm/simulator_mips.cc
|
| ===================================================================
|
| --- runtime/vm/simulator_mips.cc (revision 20321)
|
| +++ runtime/vm/simulator_mips.cc (working copy)
|
| @@ -33,6 +33,11 @@
|
| explicit SimulatorDebugger(Simulator* sim);
|
| ~SimulatorDebugger();
|
|
|
| + // Enter interactive debugging, and attach to the simulator.
|
| + void Attach(Instr* instr, const char *message);
|
| +
|
| + // Enter interactive debugging if debugging is already attached to
|
| + // the simulator, and otherwise return immediately.
|
| void Stop(Instr* instr, const char* message);
|
| void Debug();
|
| char* ReadLine(const char* prompt);
|
| @@ -63,6 +68,12 @@
|
| }
|
|
|
|
|
| +void SimulatorDebugger::Attach(Instr* instr, const char* message) {
|
| + sim_->set_debugger_attached(true);
|
| + Stop(instr, message);
|
| +}
|
| +
|
| +
|
| void SimulatorDebugger::Stop(Instr* instr, const char* message) {
|
| OS::Print("Simulator hit %s\n", message);
|
| Debug();
|
| @@ -219,7 +230,6 @@
|
| void SimulatorDebugger::Debug() {
|
| intptr_t last_pc = -1;
|
| bool done = false;
|
| - bool decoded = true;
|
|
|
| #define COMMAND_SIZE 63
|
| #define ARG_SIZE 255
|
| @@ -231,6 +241,12 @@
|
| char arg1[ARG_SIZE + 1];
|
| char arg2[ARG_SIZE + 1];
|
|
|
| + // If the simulator does not already have debugging attached, then return---
|
| + // we aren't in interactive mode.
|
| + if (!sim_->debugger_attached()) {
|
| + return;
|
| + }
|
| +
|
| // make sure to have a proper terminating character if reaching the limit
|
| cmd[COMMAND_SIZE] = 0;
|
| arg1[ARG_SIZE] = 0;
|
| @@ -243,7 +259,7 @@
|
| while (!done) {
|
| if (last_pc != sim_->get_pc()) {
|
| last_pc = sim_->get_pc();
|
| - decoded = Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
|
| + Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
|
| }
|
| char* line = ReadLine("sim> ");
|
| if (line == NULL) {
|
| @@ -277,20 +293,12 @@
|
| OS::Print("Quitting\n");
|
| OS::Exit(0);
|
| } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
|
| - if (decoded) {
|
| - sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| - } else {
|
| - OS::Print("Instruction could not be decoded. Stepping disabled.\n");
|
| - }
|
| + sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
|
| - if (decoded) {
|
| - // Execute the one instruction we broke at with breakpoints disabled.
|
| - sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| - // Leave the debugger shell.
|
| - done = true;
|
| - } else {
|
| - OS::Print("Instruction could not be decoded. Cannot continue.\n");
|
| - }
|
| + // Execute the one instruction we broke at with breakpoints disabled.
|
| + sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| + // Leave the debugger shell.
|
| + done = true;
|
| } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
|
| if (args == 2) {
|
| uint32_t value;
|
| @@ -499,6 +507,8 @@
|
| break_pc_ = NULL;
|
| break_instr_ = 0;
|
|
|
| + debugger_attached_ = false;
|
| +
|
| // Setup architecture state.
|
| // All registers are initialized to zero to start with.
|
| for (int i = 0; i < kNumberOfCpuRegisters; i++) {
|
| @@ -561,6 +571,15 @@
|
| }
|
|
|
|
|
| +void Simulator::UnimplementedInstruction(Instr* instr) {
|
| + char buffer[64];
|
| + snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
|
| + SimulatorDebugger dbg(this);
|
| + dbg.Stop(instr, buffer);
|
| + FATAL("Cannot continue execution after unimplemented instruction.");
|
| +}
|
| +
|
| +
|
| void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
|
| uword fault_pc = get_pc();
|
| // The debugger will not be able to single step past this instruction, but
|
| @@ -712,7 +731,7 @@
|
| }
|
| case BREAK: {
|
| SimulatorDebugger dbg(this);
|
| - dbg.Stop(instr, "breakpoint");
|
| + dbg.Attach(instr, "breakpoint");
|
| break;
|
| }
|
| case DIV: {
|
| @@ -941,7 +960,7 @@
|
| }
|
| default: {
|
| OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits());
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -983,7 +1002,7 @@
|
| }
|
| default: {
|
| OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits());
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -1133,7 +1152,7 @@
|
| default: {
|
| OS::PrintErr("Undecoded instruction: 0x%x at %p\n",
|
| instr->InstructionBits(), instr);
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -1145,10 +1164,11 @@
|
| ASSERT(pc_ != kEndSimulatingPC);
|
| delay_slot_ = true;
|
| icount_++;
|
| + Instr* instr = Instr::At(pc_ + Instr::kInstrSize);
|
| if (icount_ == FLAG_stop_sim_at) {
|
| - UNIMPLEMENTED();
|
| + SimulatorDebugger dbg(this);
|
| + dbg.Attach(instr, "Instruction count reached");
|
| }
|
| - Instr* instr = Instr::At(pc_ + Instr::kInstrSize);
|
| InstructionDecode(instr);
|
| delay_slot_ = false;
|
| }
|
| @@ -1161,18 +1181,27 @@
|
| while (pc_ != kEndSimulatingPC) {
|
| icount_++;
|
| Instr* instr = Instr::At(pc_);
|
| - InstructionDecode(instr);
|
| + if (IsIllegalAddress(pc_)) {
|
| + HandleIllegalAccess(pc_, instr);
|
| + } else {
|
| + InstructionDecode(instr);
|
| + }
|
| }
|
| } else {
|
| // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
|
| // we reach the particular instruction count.
|
| while (pc_ != kEndSimulatingPC) {
|
| icount_++;
|
| + Instr* instr = Instr::At(pc_);
|
| if (icount_ == FLAG_stop_sim_at) {
|
| - UNIMPLEMENTED();
|
| + SimulatorDebugger dbg(this);
|
| + dbg.Attach(instr, "Instruction count reached");
|
| } else {
|
| - Instr* instr = Instr::At(pc_);
|
| - InstructionDecode(instr);
|
| + if (IsIllegalAddress(pc_)) {
|
| + HandleIllegalAccess(pc_, instr);
|
| + } else {
|
| + InstructionDecode(instr);
|
| + }
|
| }
|
| }
|
| }
|
|
|