Chromium Code Reviews| Index: runtime/vm/simulator_arm.cc |
| =================================================================== |
| --- runtime/vm/simulator_arm.cc (revision 20300) |
| +++ runtime/vm/simulator_arm.cc (working copy) |
| @@ -93,8 +93,14 @@ |
| 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); |
| private: |
| @@ -129,6 +135,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(); |
| @@ -293,7 +305,6 @@ |
| void SimulatorDebugger::Debug() { |
| intptr_t last_pc = -1; |
| bool done = false; |
| - bool decoded = true; |
| #define COMMAND_SIZE 63 |
| #define ARG_SIZE 255 |
| @@ -305,6 +316,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; |
| @@ -317,7 +334,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) { |
| @@ -353,20 +370,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; |
| @@ -668,6 +677,8 @@ |
| fp_z_flag_ = false; |
| fp_c_flag_ = false; |
| fp_v_flag_ = false; |
| + |
| + debugger_attached_ = false; |
| } |
| @@ -845,6 +856,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."); |
| +} |
| + |
| + |
| int Simulator::ReadW(uword addr, Instr* instr) { |
| static StatsCounter counter_read_w("Simulated word reads"); |
| counter_read_w.Increment(); |
| @@ -1086,8 +1106,7 @@ |
| if (instr->Bit(4) == 0) { |
| // by immediate |
| if ((shift == ROR) && (shift_amount == 0)) { |
| - UNIMPLEMENTED(); |
| - return result; |
| + UnimplementedInstruction(instr); |
| } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) { |
| shift_amount = 32; |
| } |
| @@ -1135,7 +1154,7 @@ |
| } |
| case ROR: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| @@ -1207,7 +1226,7 @@ |
| } |
| case ROR: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| @@ -1391,7 +1410,8 @@ |
| } |
| case kBreakpointSvcCode: { |
| SimulatorDebugger dbg(this); |
| - dbg.Stop(instr, "breakpoint"); |
| + set_debugger_attached(true); |
| + dbg.Attach(instr, "breakpoint"); |
| break; |
| } |
| case kStopMessageSvcCode: { |
| @@ -1399,7 +1419,7 @@ |
| const char* message = *reinterpret_cast<const char**>( |
| reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); |
| set_pc(get_pc() + Instr::kInstrSize); |
| - dbg.Stop(instr, message); |
| + dbg.Attach(instr, message); |
|
Ivan Posva
2013/03/21 18:23:36
What will happen if a test with nobody watching on
|
| break; |
| } |
| case kWordSpillMarkerSvcCode: { |
| @@ -1471,15 +1491,15 @@ |
| set_pc(get_pc() + Instr::kInstrSize); |
| char buffer[32]; |
| snprintf(buffer, sizeof(buffer), "bkpt #0x%x", instr->BkptField()); |
| - dbg.Stop(instr, buffer); |
| + dbg.Attach(instr, buffer); |
| } else { |
| // Format(instr, "smc'cond"); |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| break; |
| } |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| } |
| @@ -1539,7 +1559,7 @@ |
| break; |
| } |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| } |
| @@ -1569,7 +1589,7 @@ |
| break; |
| } |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| } |
| @@ -1594,12 +1614,12 @@ |
| if ((instr->Bits(16, 4) == 0) && (instr->Bits(0, 8) == 0)) { |
| // Format(instr, "nop'cond"); |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| break; |
| } |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| } |
| @@ -1727,7 +1747,7 @@ |
| set_register(rd1, val_high); |
| } |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| } |
| } |
| @@ -1856,7 +1876,7 @@ |
| SetNZFlags(alu_out); |
| SetCFlag(shifter_carry_out); |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| break; |
| } |
| @@ -1869,7 +1889,7 @@ |
| SetNZFlags(alu_out); |
| SetCFlag(shifter_carry_out); |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| break; |
| } |
| @@ -1883,7 +1903,7 @@ |
| SetCFlag(!BorrowFrom(rn_val, shifter_operand)); |
| SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false)); |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| break; |
| } |
| @@ -1897,7 +1917,7 @@ |
| SetCFlag(CarryFrom(rn_val, shifter_operand)); |
| SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true)); |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| break; |
| } |
| @@ -2281,7 +2301,7 @@ |
| } |
| } |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| } |
| @@ -2317,7 +2337,7 @@ |
| switch (instr->Bits(20, 4) & 0xb) { |
| case 1: // vnmla, vnmls, vnmul |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| case 0: { // vmla, vmls floating-point |
| @@ -2419,7 +2439,7 @@ |
| break; |
| } |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| } |
| @@ -2448,7 +2468,7 @@ |
| break; |
| } |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| } |
| @@ -2457,7 +2477,7 @@ |
| case 4: // vcmp, vcmpe |
| case 5: { // vcmp #0.0, vcmpe #0.0 |
| if (instr->Bit(7) == 1) { // vcmpe |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } else { |
| fp_n_flag_ = false; |
| fp_z_flag_ = false; |
| @@ -2560,7 +2580,7 @@ |
| // flags, because we do not use them. |
| if (instr->Bit(7) == 0) { |
| // We only support round-to-zero mode |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| int32_t id_val = 0; |
| @@ -2624,7 +2644,7 @@ |
| case 14: // vcvt between floating-point and fixed-point |
| case 15: // vcvt between floating-point and fixed-point |
| default: { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| break; |
| } |
| } |
| @@ -2651,7 +2671,7 @@ |
| c_flag_ = fp_c_flag_; |
| v_flag_ = fp_v_flag_; |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| } |
| } else if (instr->IsMrcIdIsar0()) { |
| @@ -2663,7 +2683,7 @@ |
| set_register(rd, 0x00100010); // simulator has only bkpt and clz. |
| } |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| } |
| @@ -2681,7 +2701,7 @@ |
| // Format(instr, "clrex"); |
| ClearExclusive(); |
| } else { |
| - UNIMPLEMENTED(); |
| + UnimplementedInstruction(instr); |
| } |
| } else if (ConditionallyExecute(instr)) { |
| switch (instr->TypeField()) { |
| @@ -2715,7 +2735,8 @@ |
| break; |
| } |
| default: { |
| - UNIMPLEMENTED(); |
| + // Type field is three bits. |
| + UNREACHABLE(); |
| break; |
| } |
| } |
| @@ -2756,7 +2777,7 @@ |
| counter_instructions.Increment(); |
| if (icount_ == FLAG_stop_sim_at) { |
| SimulatorDebugger dbg(this); |
| - dbg.Debug(); |
| + dbg.Attach(instr, "Instruction count reached"); |
| } else if (IsIllegalAddress(program_counter)) { |
| HandleIllegalAccess(program_counter, instr); |
| } else { |