Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: runtime/vm/simulator_mips.cc

Issue 12903006: Drops into Simulator Debugger only in a session that is already interactive. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 // Only build the simulator if not compiling for real MIPS hardware. 8 // Only build the simulator if not compiling for real MIPS hardware.
9 #if !defined(HOST_ARCH_MIPS) 9 #if !defined(HOST_ARCH_MIPS)
10 10
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 void SimulatorDebugger::RedoBreakpoints() { 212 void SimulatorDebugger::RedoBreakpoints() {
213 if (sim_->break_pc_ != NULL) { 213 if (sim_->break_pc_ != NULL) {
214 sim_->break_pc_->SetInstructionBits(Instr::kBreakPointInstruction); 214 sim_->break_pc_->SetInstructionBits(Instr::kBreakPointInstruction);
215 } 215 }
216 } 216 }
217 217
218 218
219 void SimulatorDebugger::Debug() { 219 void SimulatorDebugger::Debug() {
220 intptr_t last_pc = -1; 220 intptr_t last_pc = -1;
221 bool done = false; 221 bool done = false;
222 bool decoded = true;
223 222
224 #define COMMAND_SIZE 63 223 #define COMMAND_SIZE 63
225 #define ARG_SIZE 255 224 #define ARG_SIZE 255
226 225
227 #define STR(a) #a 226 #define STR(a) #a
228 #define XSTR(a) STR(a) 227 #define XSTR(a) STR(a)
229 228
230 char cmd[COMMAND_SIZE + 1]; 229 char cmd[COMMAND_SIZE + 1];
231 char arg1[ARG_SIZE + 1]; 230 char arg1[ARG_SIZE + 1];
232 char arg2[ARG_SIZE + 1]; 231 char arg2[ARG_SIZE + 1];
233 232
234 // make sure to have a proper terminating character if reaching the limit 233 // make sure to have a proper terminating character if reaching the limit
235 cmd[COMMAND_SIZE] = 0; 234 cmd[COMMAND_SIZE] = 0;
236 arg1[ARG_SIZE] = 0; 235 arg1[ARG_SIZE] = 0;
237 arg2[ARG_SIZE] = 0; 236 arg2[ARG_SIZE] = 0;
238 237
239 // Undo all set breakpoints while running in the debugger shell. This will 238 // Undo all set breakpoints while running in the debugger shell. This will
240 // make them invisible to all commands. 239 // make them invisible to all commands.
241 UndoBreakpoints(); 240 UndoBreakpoints();
242 241
243 while (!done) { 242 while (!done) {
244 if (last_pc != sim_->get_pc()) { 243 if (last_pc != sim_->get_pc()) {
245 last_pc = sim_->get_pc(); 244 last_pc = sim_->get_pc();
246 decoded = Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize); 245 Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
247 } 246 }
248 char* line = ReadLine("sim> "); 247 char* line = ReadLine("sim> ");
249 if (line == NULL) { 248 if (line == NULL) {
250 break; 249 FATAL("ReadLine failed");
251 } else { 250 } else {
252 // Use sscanf to parse the individual parts of the command line. At the 251 // Use sscanf to parse the individual parts of the command line. At the
253 // moment no command expects more than two parameters. 252 // moment no command expects more than two parameters.
254 int args = SScanF(line, 253 int args = SScanF(line,
255 "%" XSTR(COMMAND_SIZE) "s " 254 "%" XSTR(COMMAND_SIZE) "s "
256 "%" XSTR(ARG_SIZE) "s " 255 "%" XSTR(ARG_SIZE) "s "
257 "%" XSTR(ARG_SIZE) "s", 256 "%" XSTR(ARG_SIZE) "s",
258 cmd, arg1, arg2); 257 cmd, arg1, arg2);
259 if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { 258 if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
260 OS::Print("c/cont -- continue execution\n" 259 OS::Print("c/cont -- continue execution\n"
261 "disasm -- disassemble instrs at current pc location\n" 260 "disasm -- disassemble instrs at current pc location\n"
262 " other variants are:\n" 261 " other variants are:\n"
263 " disasm <address>\n" 262 " disasm <address>\n"
264 " disasm <address> <number_of_instructions>\n" 263 " disasm <address> <number_of_instructions>\n"
265 " by default 10 instrs are disassembled\n" 264 " by default 10 instrs are disassembled\n"
266 "del -- delete breakpoints\n" 265 "del -- delete breakpoints\n"
267 "gdb -- transfer control to gdb\n" 266 "gdb -- transfer control to gdb\n"
268 "h/help -- print this help string\n" 267 "h/help -- print this help string\n"
269 "break <address> -- set break point at specified address\n" 268 "break <address> -- set break point at specified address\n"
270 "p/print <reg or value or *addr> -- print integer value\n" 269 "p/print <reg or value or *addr> -- print integer value\n"
271 "pf/printfloat <freg or *addr> -- print float value\n" 270 "pf/printfloat <freg or *addr> -- print float value\n"
272 "po/printobject <*reg or *addr> -- print object\n" 271 "po/printobject <*reg or *addr> -- print object\n"
273 "si/stepi -- single step an instruction\n" 272 "si/stepi -- single step an instruction\n"
274 "unstop -- if current pc is a stop instr make it a nop\n" 273 "unstop -- if current pc is a stop instr make it a nop\n"
275 "q/quit -- Quit the debugger and exit the program\n"); 274 "q/quit -- Quit the debugger and exit the program\n");
276 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) { 275 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
277 OS::Print("Quitting\n"); 276 OS::Print("Quitting\n");
278 OS::Exit(0); 277 OS::Exit(0);
279 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 278 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
280 if (decoded) { 279 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
281 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
282 } else {
283 OS::Print("Instruction could not be decoded. Stepping disabled.\n");
284 }
285 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 280 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
286 if (decoded) { 281 // Execute the one instruction we broke at with breakpoints disabled.
287 // Execute the one instruction we broke at with breakpoints disabled. 282 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
288 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 283 // Leave the debugger shell.
289 // Leave the debugger shell. 284 done = true;
290 done = true;
291 } else {
292 OS::Print("Instruction could not be decoded. Cannot continue.\n");
293 }
294 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 285 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
295 if (args == 2) { 286 if (args == 2) {
296 uint32_t value; 287 uint32_t value;
297 if (GetValue(arg1, &value)) { 288 if (GetValue(arg1, &value)) {
298 OS::Print("%s: %u 0x%x\n", arg1, value, value); 289 OS::Print("%s: %u 0x%x\n", arg1, value, value);
299 } else { 290 } else {
300 OS::Print("%s unrecognized\n", arg1); 291 OS::Print("%s unrecognized\n", arg1);
301 } 292 }
302 } else { 293 } else {
303 OS::Print("print <reg or value or *addr>\n"); 294 OS::Print("print <reg or value or *addr>\n");
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 fregisters_[reg] = value; 545 fregisters_[reg] = value;
555 } 546 }
556 547
557 548
558 double Simulator::get_fregister(FRegister reg) const { 549 double Simulator::get_fregister(FRegister reg) const {
559 ASSERT((reg >= 0) && (reg < kNumberOfFRegisters)); 550 ASSERT((reg >= 0) && (reg < kNumberOfFRegisters));
560 return fregisters_[reg]; 551 return fregisters_[reg];
561 } 552 }
562 553
563 554
555 void Simulator::UnimplementedInstruction(Instr* instr) {
556 char buffer[64];
557 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
558 SimulatorDebugger dbg(this);
559 dbg.Stop(instr, buffer);
560 FATAL("Cannot continue execution after unimplemented instruction.");
561 }
562
563
564 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { 564 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
565 uword fault_pc = get_pc(); 565 uword fault_pc = get_pc();
566 // The debugger will not be able to single step past this instruction, but 566 // The debugger will not be able to single step past this instruction, but
567 // it will be possible to disassemble the code and inspect registers. 567 // it will be possible to disassemble the code and inspect registers.
568 char buffer[128]; 568 char buffer[128];
569 snprintf(buffer, sizeof(buffer), 569 snprintf(buffer, sizeof(buffer),
570 "illegal memory access at 0x%"Px", pc=0x%"Px"\n", 570 "illegal memory access at 0x%"Px", pc=0x%"Px"\n",
571 addr, fault_pc); 571 addr, fault_pc);
572 SimulatorDebugger dbg(this); 572 SimulatorDebugger dbg(this);
573 dbg.Stop(instr, buffer); 573 dbg.Stop(instr, buffer);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 case XOR: { 934 case XOR: {
935 ASSERT(instr->SaField() == 0); 935 ASSERT(instr->SaField() == 0);
936 // Format(instr, "xor 'rd, 'rs, 'rt"); 936 // Format(instr, "xor 'rd, 'rs, 'rt");
937 int32_t rs_val = get_register(instr->RsField()); 937 int32_t rs_val = get_register(instr->RsField());
938 int32_t rt_val = get_register(instr->RtField()); 938 int32_t rt_val = get_register(instr->RtField());
939 set_register(instr->RdField(), rs_val ^ rt_val); 939 set_register(instr->RdField(), rs_val ^ rt_val);
940 break; 940 break;
941 } 941 }
942 default: { 942 default: {
943 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits()); 943 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits());
944 UNIMPLEMENTED(); 944 UnimplementedInstruction(instr);
945 break; 945 break;
946 } 946 }
947 } 947 }
948 } 948 }
949 949
950 950
951 void Simulator::DecodeSpecial2(Instr* instr) { 951 void Simulator::DecodeSpecial2(Instr* instr) {
952 ASSERT(instr->OpcodeField() == SPECIAL2); 952 ASSERT(instr->OpcodeField() == SPECIAL2);
953 switch (instr->FunctionField()) { 953 switch (instr->FunctionField()) {
954 case CLO: { 954 case CLO: {
(...skipping 21 matching lines...) Expand all
976 rs_val <<= 1; 976 rs_val <<= 1;
977 } 977 }
978 } else { 978 } else {
979 bitcount = 32; 979 bitcount = 32;
980 } 980 }
981 set_register(instr->RdField(), bitcount); 981 set_register(instr->RdField(), bitcount);
982 break; 982 break;
983 } 983 }
984 default: { 984 default: {
985 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits()); 985 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits());
986 UNIMPLEMENTED(); 986 UnimplementedInstruction(instr);
987 break; 987 break;
988 } 988 }
989 } 989 }
990 } 990 }
991 991
992 992
993 void Simulator::InstructionDecode(Instr* instr) { 993 void Simulator::InstructionDecode(Instr* instr) {
994 switch (instr->OpcodeField()) { 994 switch (instr->OpcodeField()) {
995 case SPECIAL: { 995 case SPECIAL: {
996 DecodeSpecial(instr); 996 DecodeSpecial(instr);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 if (Simulator::IsIllegalAddress(addr)) { 1126 if (Simulator::IsIllegalAddress(addr)) {
1127 HandleIllegalAccess(addr, instr); 1127 HandleIllegalAccess(addr, instr);
1128 } else { 1128 } else {
1129 WriteW(addr, rt_val, instr); 1129 WriteW(addr, rt_val, instr);
1130 } 1130 }
1131 break; 1131 break;
1132 } 1132 }
1133 default: { 1133 default: {
1134 OS::PrintErr("Undecoded instruction: 0x%x at %p\n", 1134 OS::PrintErr("Undecoded instruction: 0x%x at %p\n",
1135 instr->InstructionBits(), instr); 1135 instr->InstructionBits(), instr);
1136 UNIMPLEMENTED(); 1136 UnimplementedInstruction(instr);
1137 break; 1137 break;
1138 } 1138 }
1139 } 1139 }
1140 pc_ += Instr::kInstrSize; 1140 pc_ += Instr::kInstrSize;
1141 } 1141 }
1142 1142
1143 1143
1144 void Simulator::ExecuteDelaySlot() { 1144 void Simulator::ExecuteDelaySlot() {
1145 ASSERT(pc_ != kEndSimulatingPC); 1145 ASSERT(pc_ != kEndSimulatingPC);
1146 delay_slot_ = true; 1146 delay_slot_ = true;
1147 icount_++; 1147 icount_++;
1148 Instr* instr = Instr::At(pc_ + Instr::kInstrSize);
1148 if (icount_ == FLAG_stop_sim_at) { 1149 if (icount_ == FLAG_stop_sim_at) {
1149 UNIMPLEMENTED(); 1150 SimulatorDebugger dbg(this);
1151 dbg.Stop(instr, "Instruction count reached");
1150 } 1152 }
1151 Instr* instr = Instr::At(pc_ + Instr::kInstrSize);
1152 InstructionDecode(instr); 1153 InstructionDecode(instr);
1153 delay_slot_ = false; 1154 delay_slot_ = false;
1154 } 1155 }
1155 1156
1156 1157
1157 void Simulator::Execute() { 1158 void Simulator::Execute() {
1158 if (FLAG_stop_sim_at == 0) { 1159 if (FLAG_stop_sim_at == 0) {
1159 // Fast version of the dispatch loop without checking whether the simulator 1160 // Fast version of the dispatch loop without checking whether the simulator
1160 // should be stopping at a particular executed instruction. 1161 // should be stopping at a particular executed instruction.
1161 while (pc_ != kEndSimulatingPC) { 1162 while (pc_ != kEndSimulatingPC) {
1162 icount_++; 1163 icount_++;
1163 Instr* instr = Instr::At(pc_); 1164 Instr* instr = Instr::At(pc_);
1164 InstructionDecode(instr); 1165 if (IsIllegalAddress(pc_)) {
1166 HandleIllegalAccess(pc_, instr);
1167 } else {
1168 InstructionDecode(instr);
1169 }
1165 } 1170 }
1166 } else { 1171 } else {
1167 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 1172 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
1168 // we reach the particular instruction count. 1173 // we reach the particular instruction count.
1169 while (pc_ != kEndSimulatingPC) { 1174 while (pc_ != kEndSimulatingPC) {
1170 icount_++; 1175 icount_++;
1176 Instr* instr = Instr::At(pc_);
1171 if (icount_ == FLAG_stop_sim_at) { 1177 if (icount_ == FLAG_stop_sim_at) {
1172 UNIMPLEMENTED(); 1178 SimulatorDebugger dbg(this);
1179 dbg.Stop(instr, "Instruction count reached");
1173 } else { 1180 } else {
1174 Instr* instr = Instr::At(pc_); 1181 if (IsIllegalAddress(pc_)) {
1175 InstructionDecode(instr); 1182 HandleIllegalAccess(pc_, instr);
1183 } else {
1184 InstructionDecode(instr);
1185 }
1176 } 1186 }
1177 } 1187 }
1178 } 1188 }
1179 } 1189 }
1180 1190
1181 1191
1182 int64_t Simulator::Call(int32_t entry, 1192 int64_t Simulator::Call(int32_t entry,
1183 int32_t parameter0, 1193 int32_t parameter0,
1184 int32_t parameter1, 1194 int32_t parameter1,
1185 int32_t parameter2, 1195 int32_t parameter2,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 // Restore the SP register and return R1:R0. 1268 // Restore the SP register and return R1:R0.
1259 set_register(SP, sp_before_call); 1269 set_register(SP, sp_before_call);
1260 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); 1270 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
1261 } 1271 }
1262 1272
1263 } // namespace dart 1273 } // namespace dart
1264 1274
1265 #endif // !defined(HOST_ARCH_MIPS) 1275 #endif // !defined(HOST_ARCH_MIPS)
1266 1276
1267 #endif // defined TARGET_ARCH_MIPS 1277 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698