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

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

Issue 789903002: Complete and clean up breakpoint support in all 3 debuggers embedded in MIPS, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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_arm64.cc ('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 <setjmp.h> 5 #include <setjmp.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 7
8 #include "vm/globals.h" 8 #include "vm/globals.h"
9 #if defined(TARGET_ARCH_MIPS) 9 #if defined(TARGET_ARCH_MIPS)
10 10
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 98
99 static intptr_t GetApproximateTokenIndex(const Code& code, uword pc); 99 static intptr_t GetApproximateTokenIndex(const Code& code, uword pc);
100 100
101 static void PrintDartFrame(uword pc, uword fp, uword sp, 101 static void PrintDartFrame(uword pc, uword fp, uword sp,
102 const Function& function, 102 const Function& function,
103 intptr_t token_pos, 103 intptr_t token_pos,
104 bool is_optimized, 104 bool is_optimized,
105 bool is_inlined); 105 bool is_inlined);
106 void PrintBacktrace(); 106 void PrintBacktrace();
107 107
108 static const int32_t kSimulatorBreakpointInstruction =
109 Instr::kBreakPointInstruction |
110 (Instr::kSimulatorBreakCode << kBreakCodeShift);
111
112 // Set or delete a breakpoint. Returns true if successful. 108 // Set or delete a breakpoint. Returns true if successful.
113 bool SetBreakpoint(Instr* breakpc); 109 bool SetBreakpoint(Instr* breakpc);
114 bool DeleteBreakpoint(Instr* breakpc); 110 bool DeleteBreakpoint(Instr* breakpc);
115 111
116 // Undo and redo all breakpoints. This is needed to bracket disassembly and 112 // Undo and redo all breakpoints. This is needed to bracket disassembly and
117 // execution to skip past breakpoints when run from the debugger. 113 // execution to skip past breakpoints when run from the debugger.
118 void UndoBreakpoints(); 114 void UndoBreakpoints();
119 void RedoBreakpoints(); 115 void RedoBreakpoints();
120 }; 116 };
121 117
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 382
387 void SimulatorDebugger::UndoBreakpoints() { 383 void SimulatorDebugger::UndoBreakpoints() {
388 if (sim_->break_pc_ != NULL) { 384 if (sim_->break_pc_ != NULL) {
389 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 385 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
390 } 386 }
391 } 387 }
392 388
393 389
394 void SimulatorDebugger::RedoBreakpoints() { 390 void SimulatorDebugger::RedoBreakpoints() {
395 if (sim_->break_pc_ != NULL) { 391 if (sim_->break_pc_ != NULL) {
396 sim_->break_pc_->SetInstructionBits(kSimulatorBreakpointInstruction); 392 sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction);
397 } 393 }
398 } 394 }
399 395
400 396
401 void SimulatorDebugger::Debug() { 397 void SimulatorDebugger::Debug() {
402 intptr_t last_pc = -1; 398 intptr_t last_pc = -1;
403 bool done = false; 399 bool done = false;
404 400
405 #define COMMAND_SIZE 63 401 #define COMMAND_SIZE 63
406 #define ARG_SIZE 255 402 #define ARG_SIZE 255
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 OS::Print("printobject <*reg or *addr>\n"); 529 OS::Print("printobject <*reg or *addr>\n");
534 } 530 }
535 } else if (strcmp(cmd, "disasm") == 0) { 531 } else if (strcmp(cmd, "disasm") == 0) {
536 uint32_t start = 0; 532 uint32_t start = 0;
537 uint32_t end = 0; 533 uint32_t end = 0;
538 if (args == 1) { 534 if (args == 1) {
539 start = sim_->get_pc(); 535 start = sim_->get_pc();
540 end = start + (10 * Instr::kInstrSize); 536 end = start + (10 * Instr::kInstrSize);
541 } else if (args == 2) { 537 } else if (args == 2) {
542 if (GetValue(arg1, &start)) { 538 if (GetValue(arg1, &start)) {
543 // no length parameter passed, assume 10 instructions 539 // No length parameter passed, assume 10 instructions.
544 if (Simulator::IsIllegalAddress(start)) { 540 if (Simulator::IsIllegalAddress(start)) {
545 // If start isn't a valid address, warn and use PC instead 541 // If start isn't a valid address, warn and use PC instead.
546 OS::Print("First argument yields invalid address: 0x%x\n", start); 542 OS::Print("First argument yields invalid address: 0x%x\n", start);
547 OS::Print("Using PC instead"); 543 OS::Print("Using PC instead\n");
548 start = sim_->get_pc(); 544 start = sim_->get_pc();
549 } 545 }
550 end = start + (10 * Instr::kInstrSize); 546 end = start + (10 * Instr::kInstrSize);
551 } 547 }
552 } else { 548 } else {
553 uint32_t length; 549 uint32_t length;
554 if (GetValue(arg1, &start) && GetValue(arg2, &length)) { 550 if (GetValue(arg1, &start) && GetValue(arg2, &length)) {
555 if (Simulator::IsIllegalAddress(start)) { 551 if (Simulator::IsIllegalAddress(start)) {
556 // If start isn't a valid address, warn and use PC instead 552 // If start isn't a valid address, warn and use PC instead.
557 OS::Print("First argument yields invalid address: 0x%x\n", start); 553 OS::Print("First argument yields invalid address: 0x%x\n", start);
558 OS::Print("Using PC instead\n"); 554 OS::Print("Using PC instead\n");
559 start = sim_->get_pc(); 555 start = sim_->get_pc();
560 } 556 }
561 end = start + (length * Instr::kInstrSize); 557 end = start + (length * Instr::kInstrSize);
562 } 558 }
563 } 559 }
564 560 if ((start > 0) && (end > start)) {
565 Disassembler::Disassemble(start, end); 561 Disassembler::Disassemble(start, end);
562 } else {
563 OS::Print("disasm [<address> [<number_of_instructions>]]\n");
564 }
566 } else if (strcmp(cmd, "gdb") == 0) { 565 } else if (strcmp(cmd, "gdb") == 0) {
567 OS::Print("relinquishing control to gdb\n"); 566 OS::Print("relinquishing control to gdb\n");
568 OS::DebugBreak(); 567 OS::DebugBreak();
569 OS::Print("regaining control from gdb\n"); 568 OS::Print("regaining control from gdb\n");
570 } else if (strcmp(cmd, "break") == 0) { 569 } else if (strcmp(cmd, "break") == 0) {
571 if (args == 2) { 570 if (args == 2) {
572 uint32_t addr; 571 uint32_t addr;
573 if (GetValue(arg1, &addr)) { 572 if (GetValue(arg1, &addr)) {
574 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) { 573 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) {
575 OS::Print("setting breakpoint failed\n"); 574 OS::Print("setting breakpoint failed\n");
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 Redirection* current; 773 Redirection* current;
775 for (current = list_; current != NULL; current = current->next_) { 774 for (current = list_; current != NULL; current = current->next_) {
776 if (current->address_of_break_instruction() == address_of_break) { 775 if (current->address_of_break_instruction() == address_of_break) {
777 return current->external_function_; 776 return current->external_function_;
778 } 777 }
779 } 778 }
780 return 0; 779 return 0;
781 } 780 }
782 781
783 private: 782 private:
784 static const int32_t kRedirectInstruction =
785 Instr::kBreakPointInstruction | (Instr::kRedirectCode << kBreakCodeShift);
786
787 Redirection(uword external_function, 783 Redirection(uword external_function,
788 Simulator::CallKind call_kind, 784 Simulator::CallKind call_kind,
789 int argument_count) 785 int argument_count)
790 : external_function_(external_function), 786 : external_function_(external_function),
791 call_kind_(call_kind), 787 call_kind_(call_kind),
792 argument_count_(argument_count), 788 argument_count_(argument_count),
793 break_instruction_(kRedirectInstruction), 789 break_instruction_(Instr::kSimulatorRedirectInstruction),
794 next_(list_) { 790 next_(list_) {
795 list_ = this; 791 list_ = this;
796 } 792 }
797 793
798 uword external_function_; 794 uword external_function_;
799 Simulator::CallKind call_kind_; 795 Simulator::CallKind call_kind_;
800 int argument_count_; 796 int argument_count_;
801 uint32_t break_instruction_; 797 uint32_t break_instruction_;
802 Redirection* next_; 798 Redirection* next_;
803 static Redirection* list_; 799 static Redirection* list_;
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 1107
1112 1108
1113 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { 1109 bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
1114 Isolate* isolate = Isolate::Current(); 1110 Isolate* isolate = Isolate::Current();
1115 ASSERT(isolate != NULL); 1111 ASSERT(isolate != NULL);
1116 ASSERT(addr != 0); 1112 ASSERT(addr != 0);
1117 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); 1113 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate);
1118 bool result = false; 1114 bool result = false;
1119 for (int i = 0; i < kNumAddressTags; i++) { 1115 for (int i = 0; i < kNumAddressTags; i++) {
1120 if (exclusive_access_state_[i].isolate == isolate) { 1116 if (exclusive_access_state_[i].isolate == isolate) {
1121 // Check whether the current isolates address reservation matches. 1117 // Check whether the current isolate's address reservation matches.
1122 if (exclusive_access_state_[i].addr == addr) { 1118 if (exclusive_access_state_[i].addr == addr) {
1123 result = true; 1119 result = true;
1124 } 1120 }
1125 exclusive_access_state_[i].addr = 0; 1121 exclusive_access_state_[i].addr = 0;
1126 } else if (exclusive_access_state_[i].addr == addr) { 1122 } else if (exclusive_access_state_[i].addr == addr) {
1127 // Other isolates with matching address lose their reservations. 1123 // Other isolates with matching address lose their reservations.
1128 exclusive_access_state_[i].addr = 0; 1124 exclusive_access_state_[i].addr = 0;
1129 } 1125 }
1130 } 1126 }
1131 return result; 1127 return result;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 ASSERT(instr->OpcodeField() == SPECIAL); 1192 ASSERT(instr->OpcodeField() == SPECIAL);
1197 ASSERT(instr->FunctionField() == BREAK); 1193 ASSERT(instr->FunctionField() == BREAK);
1198 if (instr->BreakCodeField() == Instr::kStopMessageCode) { 1194 if (instr->BreakCodeField() == Instr::kStopMessageCode) {
1199 SimulatorDebugger dbg(this); 1195 SimulatorDebugger dbg(this);
1200 const char* message = *reinterpret_cast<const char**>( 1196 const char* message = *reinterpret_cast<const char**>(
1201 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); 1197 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
1202 set_pc(get_pc() + Instr::kInstrSize); 1198 set_pc(get_pc() + Instr::kInstrSize);
1203 dbg.Stop(instr, message); 1199 dbg.Stop(instr, message);
1204 // Adjust for extra pc increment. 1200 // Adjust for extra pc increment.
1205 set_pc(get_pc() - Instr::kInstrSize); 1201 set_pc(get_pc() - Instr::kInstrSize);
1206 } else if (instr->BreakCodeField() == Instr::kMsgMessageCode) { 1202 } else if (instr->BreakCodeField() == Instr::kSimulatorMessageCode) {
1207 const char* message = *reinterpret_cast<const char**>( 1203 const char* message = *reinterpret_cast<const char**>(
1208 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); 1204 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
1209 if (FLAG_trace_sim) { 1205 if (FLAG_trace_sim) {
1210 OS::Print("Message: %s\n", message); 1206 OS::Print("Message: %s\n", message);
1211 } else { 1207 } else {
1212 OS::PrintErr("Bad break code: 0x%x\n", instr->InstructionBits()); 1208 OS::PrintErr("Bad break code: 0x%x\n", instr->InstructionBits());
1213 UnimplementedInstruction(instr); 1209 UnimplementedInstruction(instr);
1214 } 1210 }
1215 } else if (instr->BreakCodeField() == Instr::kRedirectCode) { 1211 } else if (instr->BreakCodeField() == Instr::kSimulatorRedirectCode) {
1216 SimulatorSetjmpBuffer buffer(this); 1212 SimulatorSetjmpBuffer buffer(this);
1217 1213
1218 if (!setjmp(buffer.buffer_)) { 1214 if (!setjmp(buffer.buffer_)) {
1219 int32_t saved_ra = get_register(RA); 1215 int32_t saved_ra = get_register(RA);
1220 Redirection* redirection = Redirection::FromBreakInstruction(instr); 1216 Redirection* redirection = Redirection::FromBreakInstruction(instr);
1221 uword external = redirection->external_function(); 1217 uword external = redirection->external_function();
1222 if (FLAG_trace_sim) { 1218 if (FLAG_trace_sim) {
1223 OS::Print("Call to host function at 0x%" Pd "\n", external); 1219 OS::Print("Call to host function at 0x%" Pd "\n", external);
1224 } 1220 }
1225 1221
(...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 if (IsIllegalAddress(pc_)) { 2288 if (IsIllegalAddress(pc_)) {
2293 HandleIllegalAccess(pc_, instr); 2289 HandleIllegalAccess(pc_, instr);
2294 } else { 2290 } else {
2295 InstructionDecode(instr); 2291 InstructionDecode(instr);
2296 } 2292 }
2297 } 2293 }
2298 } else { 2294 } else {
2299 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 2295 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
2300 // we reach the particular instruction count or address. 2296 // we reach the particular instruction count or address.
2301 while (pc_ != kEndSimulatingPC) { 2297 while (pc_ != kEndSimulatingPC) {
2298 Instr* instr = Instr::At(pc_);
2302 icount_++; 2299 icount_++;
2303 Instr* instr = Instr::At(pc_); 2300 if (static_cast<intptr_t>(icount_) == FLAG_stop_sim_at) {
2304 if (static_cast<int>(icount_) == FLAG_stop_sim_at) {
2305 SimulatorDebugger dbg(this); 2301 SimulatorDebugger dbg(this);
2306 dbg.Stop(instr, "Instruction count reached"); 2302 dbg.Stop(instr, "Instruction count reached");
2307 } else if (reinterpret_cast<int>(instr) == FLAG_stop_sim_at) { 2303 } else if (reinterpret_cast<intptr_t>(instr) == FLAG_stop_sim_at) {
2308 SimulatorDebugger dbg(this); 2304 SimulatorDebugger dbg(this);
2309 dbg.Stop(instr, "Instruction address reached"); 2305 dbg.Stop(instr, "Instruction address reached");
2306 } else if (IsIllegalAddress(pc_)) {
2307 HandleIllegalAccess(pc_, instr);
2310 } else { 2308 } else {
2311 if (IsIllegalAddress(pc_)) { 2309 InstructionDecode(instr);
2312 HandleIllegalAccess(pc_, instr);
2313 } else {
2314 InstructionDecode(instr);
2315 }
2316 } 2310 }
2317 } 2311 }
2318 } 2312 }
2319 } 2313 }
2320 2314
2321 2315
2322 int64_t Simulator::Call(int32_t entry, 2316 int64_t Simulator::Call(int32_t entry,
2323 int32_t parameter0, 2317 int32_t parameter0,
2324 int32_t parameter1, 2318 int32_t parameter1,
2325 int32_t parameter2, 2319 int32_t parameter2,
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2480 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); 2474 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
2481 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 2475 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
2482 buf->Longjmp(); 2476 buf->Longjmp();
2483 } 2477 }
2484 2478
2485 } // namespace dart 2479 } // namespace dart
2486 2480
2487 #endif // !defined(HOST_ARCH_MIPS) 2481 #endif // !defined(HOST_ARCH_MIPS)
2488 2482
2489 #endif // defined TARGET_ARCH_MIPS 2483 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698