OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 | 146 |
147 bool Debugger::GetValue(const char* desc, int32_t* value) { | 147 bool Debugger::GetValue(const char* desc, int32_t* value) { |
148 int regnum = Registers::Number(desc); | 148 int regnum = Registers::Number(desc); |
149 if (regnum != kNoRegister) { | 149 if (regnum != kNoRegister) { |
150 *value = GetRegisterValue(regnum); | 150 *value = GetRegisterValue(regnum); |
151 return true; | 151 return true; |
152 } else { | 152 } else { |
153 return SScanF(desc, "%i", value) == 1; | 153 if (strncmp(desc, "0x", 2) == 0) { |
| 154 return SScanF(desc + 2, "%x", reinterpret_cast<uint32_t*>(value)) == 1; |
| 155 } else { |
| 156 return SScanF(desc, "%u", reinterpret_cast<uint32_t*>(value)) == 1; |
| 157 } |
154 } | 158 } |
155 return false; | 159 return false; |
156 } | 160 } |
157 | 161 |
158 | 162 |
159 bool Debugger::GetVFPSingleValue(const char* desc, float* value) { | 163 bool Debugger::GetVFPSingleValue(const char* desc, float* value) { |
160 bool is_double; | 164 bool is_double; |
161 int regnum = VFPRegisters::Number(desc, &is_double); | 165 int regnum = VFPRegisters::Number(desc, &is_double); |
162 if (regnum != kNoRegister && !is_double) { | 166 if (regnum != kNoRegister && !is_double) { |
163 *value = sim_->get_float_from_s_register(regnum); | 167 *value = sim_->get_float_from_s_register(regnum); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 228 |
225 #define COMMAND_SIZE 63 | 229 #define COMMAND_SIZE 63 |
226 #define ARG_SIZE 255 | 230 #define ARG_SIZE 255 |
227 | 231 |
228 #define STR(a) #a | 232 #define STR(a) #a |
229 #define XSTR(a) STR(a) | 233 #define XSTR(a) STR(a) |
230 | 234 |
231 char cmd[COMMAND_SIZE + 1]; | 235 char cmd[COMMAND_SIZE + 1]; |
232 char arg1[ARG_SIZE + 1]; | 236 char arg1[ARG_SIZE + 1]; |
233 char arg2[ARG_SIZE + 1]; | 237 char arg2[ARG_SIZE + 1]; |
| 238 char* argv[3] = { cmd, arg1, arg2 }; |
234 | 239 |
235 // make sure to have a proper terminating character if reaching the limit | 240 // make sure to have a proper terminating character if reaching the limit |
236 cmd[COMMAND_SIZE] = 0; | 241 cmd[COMMAND_SIZE] = 0; |
237 arg1[ARG_SIZE] = 0; | 242 arg1[ARG_SIZE] = 0; |
238 arg2[ARG_SIZE] = 0; | 243 arg2[ARG_SIZE] = 0; |
239 | 244 |
240 // Undo all set breakpoints while running in the debugger shell. This will | 245 // Undo all set breakpoints while running in the debugger shell. This will |
241 // make them invisible to all commands. | 246 // make them invisible to all commands. |
242 UndoBreakpoints(); | 247 UndoBreakpoints(); |
243 | 248 |
244 while (!done) { | 249 while (!done) { |
245 if (last_pc != sim_->get_pc()) { | 250 if (last_pc != sim_->get_pc()) { |
246 disasm::NameConverter converter; | 251 disasm::NameConverter converter; |
247 disasm::Disassembler dasm(converter); | 252 disasm::Disassembler dasm(converter); |
248 // use a reasonably large buffer | 253 // use a reasonably large buffer |
249 v8::internal::EmbeddedVector<char, 256> buffer; | 254 v8::internal::EmbeddedVector<char, 256> buffer; |
250 dasm.InstructionDecode(buffer, | 255 dasm.InstructionDecode(buffer, |
251 reinterpret_cast<byte*>(sim_->get_pc())); | 256 reinterpret_cast<byte*>(sim_->get_pc())); |
252 PrintF(" 0x%08x %s\n", sim_->get_pc(), buffer.start()); | 257 PrintF(" 0x%08x %s\n", sim_->get_pc(), buffer.start()); |
253 last_pc = sim_->get_pc(); | 258 last_pc = sim_->get_pc(); |
254 } | 259 } |
255 char* line = ReadLine("sim> "); | 260 char* line = ReadLine("sim> "); |
256 if (line == NULL) { | 261 if (line == NULL) { |
257 break; | 262 break; |
258 } else { | 263 } else { |
259 // Use sscanf to parse the individual parts of the command line. At the | 264 // Use sscanf to parse the individual parts of the command line. At the |
260 // moment no command expects more than two parameters. | 265 // moment no command expects more than two parameters. |
261 int args = SScanF(line, | 266 int argc = SScanF(line, |
262 "%" XSTR(COMMAND_SIZE) "s " | 267 "%" XSTR(COMMAND_SIZE) "s " |
263 "%" XSTR(ARG_SIZE) "s " | 268 "%" XSTR(ARG_SIZE) "s " |
264 "%" XSTR(ARG_SIZE) "s", | 269 "%" XSTR(ARG_SIZE) "s", |
265 cmd, arg1, arg2); | 270 cmd, arg1, arg2); |
266 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { | 271 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { |
267 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); | 272 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); |
268 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { | 273 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { |
269 // Execute the one instruction we broke at with breakpoints disabled. | 274 // Execute the one instruction we broke at with breakpoints disabled. |
270 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); | 275 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); |
271 // Leave the debugger shell. | 276 // Leave the debugger shell. |
272 done = true; | 277 done = true; |
273 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { | 278 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { |
274 if (args == 2) { | 279 if (argc == 2) { |
275 int32_t value; | 280 int32_t value; |
276 float svalue; | 281 float svalue; |
277 double dvalue; | 282 double dvalue; |
278 if (strcmp(arg1, "all") == 0) { | 283 if (strcmp(arg1, "all") == 0) { |
279 for (int i = 0; i < kNumRegisters; i++) { | 284 for (int i = 0; i < kNumRegisters; i++) { |
280 value = GetRegisterValue(i); | 285 value = GetRegisterValue(i); |
281 PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value); | 286 PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value); |
282 } | 287 } |
283 } else { | 288 } else { |
284 if (GetValue(arg1, &value)) { | 289 if (GetValue(arg1, &value)) { |
285 PrintF("%s: 0x%08x %d \n", arg1, value, value); | 290 PrintF("%s: 0x%08x %d \n", arg1, value, value); |
286 } else if (GetVFPSingleValue(arg1, &svalue)) { | 291 } else if (GetVFPSingleValue(arg1, &svalue)) { |
287 PrintF("%s: %f \n", arg1, svalue); | 292 PrintF("%s: %f \n", arg1, svalue); |
288 } else if (GetVFPDoubleValue(arg1, &dvalue)) { | 293 } else if (GetVFPDoubleValue(arg1, &dvalue)) { |
289 PrintF("%s: %lf \n", arg1, dvalue); | 294 PrintF("%s: %lf \n", arg1, dvalue); |
290 } else { | 295 } else { |
291 PrintF("%s unrecognized\n", arg1); | 296 PrintF("%s unrecognized\n", arg1); |
292 } | 297 } |
293 } | 298 } |
294 } else { | 299 } else { |
295 PrintF("print <register>\n"); | 300 PrintF("print <register>\n"); |
296 } | 301 } |
297 } else if ((strcmp(cmd, "po") == 0) | 302 } else if ((strcmp(cmd, "po") == 0) |
298 || (strcmp(cmd, "printobject") == 0)) { | 303 || (strcmp(cmd, "printobject") == 0)) { |
299 if (args == 2) { | 304 if (argc == 2) { |
300 int32_t value; | 305 int32_t value; |
301 if (GetValue(arg1, &value)) { | 306 if (GetValue(arg1, &value)) { |
302 Object* obj = reinterpret_cast<Object*>(value); | 307 Object* obj = reinterpret_cast<Object*>(value); |
303 PrintF("%s: \n", arg1); | 308 PrintF("%s: \n", arg1); |
304 #ifdef DEBUG | 309 #ifdef DEBUG |
305 obj->PrintLn(); | 310 obj->PrintLn(); |
306 #else | 311 #else |
307 obj->ShortPrint(); | 312 obj->ShortPrint(); |
308 PrintF("\n"); | 313 PrintF("\n"); |
309 #endif | 314 #endif |
310 } else { | 315 } else { |
311 PrintF("%s unrecognized\n", arg1); | 316 PrintF("%s unrecognized\n", arg1); |
312 } | 317 } |
313 } else { | 318 } else { |
314 PrintF("printobject <value>\n"); | 319 PrintF("printobject <value>\n"); |
315 } | 320 } |
| 321 } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) { |
| 322 |
| 323 int32_t* cur = NULL; |
| 324 int32_t* end = NULL; |
| 325 int next_arg = 1; |
| 326 |
| 327 if (strcmp(cmd, "stack") == 0) { |
| 328 cur = reinterpret_cast<int32_t*>(sim_->get_register(Simulator::sp)); |
| 329 } else { // "mem" |
| 330 int32_t value; |
| 331 if (!GetValue(arg1, &value)) { |
| 332 PrintF("%s unrecognized\n", arg1); |
| 333 continue; |
| 334 } |
| 335 cur = reinterpret_cast<int32_t*>(value); |
| 336 next_arg++; |
| 337 } |
| 338 |
| 339 int32_t words; |
| 340 if (argc == next_arg) { |
| 341 words = 10; |
| 342 } else if (argc == next_arg + 1) { |
| 343 if (!GetValue(argv[next_arg], &words)) { |
| 344 words = 10; |
| 345 } |
| 346 } |
| 347 end = cur + words; |
| 348 |
| 349 while (cur < end) { |
| 350 PrintF(" 0x%08x: 0x%08x %10d\n", cur, *cur, *cur); |
| 351 cur++; |
| 352 } |
316 } else if (strcmp(cmd, "disasm") == 0) { | 353 } else if (strcmp(cmd, "disasm") == 0) { |
317 disasm::NameConverter converter; | 354 disasm::NameConverter converter; |
318 disasm::Disassembler dasm(converter); | 355 disasm::Disassembler dasm(converter); |
319 // use a reasonably large buffer | 356 // use a reasonably large buffer |
320 v8::internal::EmbeddedVector<char, 256> buffer; | 357 v8::internal::EmbeddedVector<char, 256> buffer; |
321 | 358 |
322 byte* cur = NULL; | 359 byte* cur = NULL; |
323 byte* end = NULL; | 360 byte* end = NULL; |
324 | 361 |
325 if (args == 1) { | 362 if (argc == 1) { |
326 cur = reinterpret_cast<byte*>(sim_->get_pc()); | 363 cur = reinterpret_cast<byte*>(sim_->get_pc()); |
327 end = cur + (10 * Instr::kInstrSize); | 364 end = cur + (10 * Instr::kInstrSize); |
328 } else if (args == 2) { | 365 } else if (argc == 2) { |
329 int32_t value; | 366 int32_t value; |
330 if (GetValue(arg1, &value)) { | 367 if (GetValue(arg1, &value)) { |
331 cur = reinterpret_cast<byte*>(value); | 368 cur = reinterpret_cast<byte*>(value); |
332 // no length parameter passed, assume 10 instructions | 369 // no length parameter passed, assume 10 instructions |
333 end = cur + (10 * Instr::kInstrSize); | 370 end = cur + (10 * Instr::kInstrSize); |
334 } | 371 } |
335 } else { | 372 } else { |
336 int32_t value1; | 373 int32_t value1; |
337 int32_t value2; | 374 int32_t value2; |
338 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { | 375 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { |
339 cur = reinterpret_cast<byte*>(value1); | 376 cur = reinterpret_cast<byte*>(value1); |
340 end = cur + (value2 * Instr::kInstrSize); | 377 end = cur + (value2 * Instr::kInstrSize); |
341 } | 378 } |
342 } | 379 } |
343 | 380 |
344 while (cur < end) { | 381 while (cur < end) { |
345 dasm.InstructionDecode(buffer, cur); | 382 dasm.InstructionDecode(buffer, cur); |
346 PrintF(" 0x%08x %s\n", cur, buffer.start()); | 383 PrintF(" 0x%08x %s\n", cur, buffer.start()); |
347 cur += Instr::kInstrSize; | 384 cur += Instr::kInstrSize; |
348 } | 385 } |
349 } else if (strcmp(cmd, "gdb") == 0) { | 386 } else if (strcmp(cmd, "gdb") == 0) { |
350 PrintF("relinquishing control to gdb\n"); | 387 PrintF("relinquishing control to gdb\n"); |
351 v8::internal::OS::DebugBreak(); | 388 v8::internal::OS::DebugBreak(); |
352 PrintF("regaining control from gdb\n"); | 389 PrintF("regaining control from gdb\n"); |
353 } else if (strcmp(cmd, "break") == 0) { | 390 } else if (strcmp(cmd, "break") == 0) { |
354 if (args == 2) { | 391 if (argc == 2) { |
355 int32_t value; | 392 int32_t value; |
356 if (GetValue(arg1, &value)) { | 393 if (GetValue(arg1, &value)) { |
357 if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) { | 394 if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) { |
358 PrintF("setting breakpoint failed\n"); | 395 PrintF("setting breakpoint failed\n"); |
359 } | 396 } |
360 } else { | 397 } else { |
361 PrintF("%s unrecognized\n", arg1); | 398 PrintF("%s unrecognized\n", arg1); |
362 } | 399 } |
363 } else { | 400 } else { |
364 PrintF("break <address>\n"); | 401 PrintF("break <address>\n"); |
(...skipping 29 matching lines...) Expand all Loading... |
394 PrintF(" continue execution (alias 'c')\n"); | 431 PrintF(" continue execution (alias 'c')\n"); |
395 PrintF("stepi\n"); | 432 PrintF("stepi\n"); |
396 PrintF(" step one instruction (alias 'si')\n"); | 433 PrintF(" step one instruction (alias 'si')\n"); |
397 PrintF("print <register>\n"); | 434 PrintF("print <register>\n"); |
398 PrintF(" print register content (alias 'p')\n"); | 435 PrintF(" print register content (alias 'p')\n"); |
399 PrintF(" use register name 'all' to print all registers\n"); | 436 PrintF(" use register name 'all' to print all registers\n"); |
400 PrintF("printobject <register>\n"); | 437 PrintF("printobject <register>\n"); |
401 PrintF(" print an object from a register (alias 'po')\n"); | 438 PrintF(" print an object from a register (alias 'po')\n"); |
402 PrintF("flags\n"); | 439 PrintF("flags\n"); |
403 PrintF(" print flags\n"); | 440 PrintF(" print flags\n"); |
| 441 PrintF("stack [<words>]\n"); |
| 442 PrintF(" dump stack content, default dump 10 words)\n"); |
| 443 PrintF("mem <address> [<words>]\n"); |
| 444 PrintF(" dump memory content, default dump 10 words)\n"); |
404 PrintF("disasm [<instructions>]\n"); | 445 PrintF("disasm [<instructions>]\n"); |
405 PrintF("disasm [[<address>] <instructions>]\n"); | 446 PrintF("disasm [[<address>] <instructions>]\n"); |
406 PrintF(" disassemble code, default is 10 instructions from pc\n"); | 447 PrintF(" disassemble code, default is 10 instructions from pc\n"); |
407 PrintF("gdb\n"); | 448 PrintF("gdb\n"); |
408 PrintF(" enter gdb\n"); | 449 PrintF(" enter gdb\n"); |
409 PrintF("break <address>\n"); | 450 PrintF("break <address>\n"); |
410 PrintF(" set a break point on the address\n"); | 451 PrintF(" set a break point on the address\n"); |
411 PrintF("del\n"); | 452 PrintF("del\n"); |
412 PrintF(" delete the breakpoint\n"); | 453 PrintF(" delete the breakpoint\n"); |
413 PrintF("unstop\n"); | 454 PrintF("unstop\n"); |
414 PrintF(" ignore the stop instruction at the current location"); | 455 PrintF(" ignore the stop instruction at the current location"); |
415 PrintF(" from now on\n"); | 456 PrintF(" from now on\n"); |
416 PrintF("trace (alias 't')\n"); | 457 PrintF("trace (alias 't')\n"); |
417 PrintF(" toogle the tracing of all executed statements"); | 458 PrintF(" toogle the tracing of all executed statements\n"); |
418 } else { | 459 } else { |
419 PrintF("Unknown command: %s\n", cmd); | 460 PrintF("Unknown command: %s\n", cmd); |
420 } | 461 } |
421 } | 462 } |
422 DeleteArray(line); | 463 DeleteArray(line); |
423 } | 464 } |
424 | 465 |
425 // Add all the breakpoints back to stop execution and enter the debugger | 466 // Add all the breakpoints back to stop execution and enter the debugger |
426 // shell when hit. | 467 // shell when hit. |
427 RedoBreakpoints(); | 468 RedoBreakpoints(); |
(...skipping 2050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2478 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 2519 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
2479 uintptr_t address = *stack_slot; | 2520 uintptr_t address = *stack_slot; |
2480 set_register(sp, current_sp + sizeof(uintptr_t)); | 2521 set_register(sp, current_sp + sizeof(uintptr_t)); |
2481 return address; | 2522 return address; |
2482 } | 2523 } |
2483 | 2524 |
2484 | 2525 |
2485 } } // namespace assembler::arm | 2526 } } // namespace assembler::arm |
2486 | 2527 |
2487 #endif // !defined(__arm__) | 2528 #endif // !defined(__arm__) |
OLD | NEW |