| 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 |