OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 | |
565 Disassembler::Disassemble(start, end); | 560 Disassembler::Disassemble(start, end); |
zra
2014/12/09 18:50:41
Same comment.
regis
2014/12/09 19:23:25
Done.
| |
566 } else if (strcmp(cmd, "gdb") == 0) { | 561 } else if (strcmp(cmd, "gdb") == 0) { |
567 OS::Print("relinquishing control to gdb\n"); | 562 OS::Print("relinquishing control to gdb\n"); |
568 OS::DebugBreak(); | 563 OS::DebugBreak(); |
569 OS::Print("regaining control from gdb\n"); | 564 OS::Print("regaining control from gdb\n"); |
570 } else if (strcmp(cmd, "break") == 0) { | 565 } else if (strcmp(cmd, "break") == 0) { |
571 if (args == 2) { | 566 if (args == 2) { |
572 uint32_t addr; | 567 uint32_t addr; |
573 if (GetValue(arg1, &addr)) { | 568 if (GetValue(arg1, &addr)) { |
574 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) { | 569 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) { |
575 OS::Print("setting breakpoint failed\n"); | 570 OS::Print("setting breakpoint failed\n"); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
774 Redirection* current; | 769 Redirection* current; |
775 for (current = list_; current != NULL; current = current->next_) { | 770 for (current = list_; current != NULL; current = current->next_) { |
776 if (current->address_of_break_instruction() == address_of_break) { | 771 if (current->address_of_break_instruction() == address_of_break) { |
777 return current->external_function_; | 772 return current->external_function_; |
778 } | 773 } |
779 } | 774 } |
780 return 0; | 775 return 0; |
781 } | 776 } |
782 | 777 |
783 private: | 778 private: |
784 static const int32_t kRedirectInstruction = | |
785 Instr::kBreakPointInstruction | (Instr::kRedirectCode << kBreakCodeShift); | |
786 | |
787 Redirection(uword external_function, | 779 Redirection(uword external_function, |
788 Simulator::CallKind call_kind, | 780 Simulator::CallKind call_kind, |
789 int argument_count) | 781 int argument_count) |
790 : external_function_(external_function), | 782 : external_function_(external_function), |
791 call_kind_(call_kind), | 783 call_kind_(call_kind), |
792 argument_count_(argument_count), | 784 argument_count_(argument_count), |
793 break_instruction_(kRedirectInstruction), | 785 break_instruction_(Instr::kSimulatorRedirectInstruction), |
794 next_(list_) { | 786 next_(list_) { |
795 list_ = this; | 787 list_ = this; |
796 } | 788 } |
797 | 789 |
798 uword external_function_; | 790 uword external_function_; |
799 Simulator::CallKind call_kind_; | 791 Simulator::CallKind call_kind_; |
800 int argument_count_; | 792 int argument_count_; |
801 uint32_t break_instruction_; | 793 uint32_t break_instruction_; |
802 Redirection* next_; | 794 Redirection* next_; |
803 static Redirection* list_; | 795 static Redirection* list_; |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1111 | 1103 |
1112 | 1104 |
1113 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { | 1105 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { |
1114 Isolate* isolate = Isolate::Current(); | 1106 Isolate* isolate = Isolate::Current(); |
1115 ASSERT(isolate != NULL); | 1107 ASSERT(isolate != NULL); |
1116 ASSERT(addr != 0); | 1108 ASSERT(addr != 0); |
1117 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1109 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); |
1118 bool result = false; | 1110 bool result = false; |
1119 for (int i = 0; i < kNumAddressTags; i++) { | 1111 for (int i = 0; i < kNumAddressTags; i++) { |
1120 if (exclusive_access_state_[i].isolate == isolate) { | 1112 if (exclusive_access_state_[i].isolate == isolate) { |
1121 // Check whether the current isolates address reservation matches. | 1113 // Check whether the current isolate's address reservation matches. |
1122 if (exclusive_access_state_[i].addr == addr) { | 1114 if (exclusive_access_state_[i].addr == addr) { |
1123 result = true; | 1115 result = true; |
1124 } | 1116 } |
1125 exclusive_access_state_[i].addr = 0; | 1117 exclusive_access_state_[i].addr = 0; |
1126 } else if (exclusive_access_state_[i].addr == addr) { | 1118 } else if (exclusive_access_state_[i].addr == addr) { |
1127 // Other isolates with matching address lose their reservations. | 1119 // Other isolates with matching address lose their reservations. |
1128 exclusive_access_state_[i].addr = 0; | 1120 exclusive_access_state_[i].addr = 0; |
1129 } | 1121 } |
1130 } | 1122 } |
1131 return result; | 1123 return result; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1196 ASSERT(instr->OpcodeField() == SPECIAL); | 1188 ASSERT(instr->OpcodeField() == SPECIAL); |
1197 ASSERT(instr->FunctionField() == BREAK); | 1189 ASSERT(instr->FunctionField() == BREAK); |
1198 if (instr->BreakCodeField() == Instr::kStopMessageCode) { | 1190 if (instr->BreakCodeField() == Instr::kStopMessageCode) { |
1199 SimulatorDebugger dbg(this); | 1191 SimulatorDebugger dbg(this); |
1200 const char* message = *reinterpret_cast<const char**>( | 1192 const char* message = *reinterpret_cast<const char**>( |
1201 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); | 1193 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); |
1202 set_pc(get_pc() + Instr::kInstrSize); | 1194 set_pc(get_pc() + Instr::kInstrSize); |
1203 dbg.Stop(instr, message); | 1195 dbg.Stop(instr, message); |
1204 // Adjust for extra pc increment. | 1196 // Adjust for extra pc increment. |
1205 set_pc(get_pc() - Instr::kInstrSize); | 1197 set_pc(get_pc() - Instr::kInstrSize); |
1206 } else if (instr->BreakCodeField() == Instr::kMsgMessageCode) { | 1198 } else if (instr->BreakCodeField() == Instr::kSimulatorMessageCode) { |
1207 const char* message = *reinterpret_cast<const char**>( | 1199 const char* message = *reinterpret_cast<const char**>( |
1208 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); | 1200 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); |
1209 if (FLAG_trace_sim) { | 1201 if (FLAG_trace_sim) { |
1210 OS::Print("Message: %s\n", message); | 1202 OS::Print("Message: %s\n", message); |
1211 } else { | 1203 } else { |
1212 OS::PrintErr("Bad break code: 0x%x\n", instr->InstructionBits()); | 1204 OS::PrintErr("Bad break code: 0x%x\n", instr->InstructionBits()); |
1213 UnimplementedInstruction(instr); | 1205 UnimplementedInstruction(instr); |
1214 } | 1206 } |
1215 } else if (instr->BreakCodeField() == Instr::kRedirectCode) { | 1207 } else if (instr->BreakCodeField() == Instr::kSimulatorRedirectCode) { |
1216 SimulatorSetjmpBuffer buffer(this); | 1208 SimulatorSetjmpBuffer buffer(this); |
1217 | 1209 |
1218 if (!setjmp(buffer.buffer_)) { | 1210 if (!setjmp(buffer.buffer_)) { |
1219 int32_t saved_ra = get_register(RA); | 1211 int32_t saved_ra = get_register(RA); |
1220 Redirection* redirection = Redirection::FromBreakInstruction(instr); | 1212 Redirection* redirection = Redirection::FromBreakInstruction(instr); |
1221 uword external = redirection->external_function(); | 1213 uword external = redirection->external_function(); |
1222 if (FLAG_trace_sim) { | 1214 if (FLAG_trace_sim) { |
1223 OS::Print("Call to host function at 0x%" Pd "\n", external); | 1215 OS::Print("Call to host function at 0x%" Pd "\n", external); |
1224 } | 1216 } |
1225 | 1217 |
(...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2292 if (IsIllegalAddress(pc_)) { | 2284 if (IsIllegalAddress(pc_)) { |
2293 HandleIllegalAccess(pc_, instr); | 2285 HandleIllegalAccess(pc_, instr); |
2294 } else { | 2286 } else { |
2295 InstructionDecode(instr); | 2287 InstructionDecode(instr); |
2296 } | 2288 } |
2297 } | 2289 } |
2298 } else { | 2290 } else { |
2299 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when | 2291 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when |
2300 // we reach the particular instruction count or address. | 2292 // we reach the particular instruction count or address. |
2301 while (pc_ != kEndSimulatingPC) { | 2293 while (pc_ != kEndSimulatingPC) { |
2294 Instr* instr = Instr::At(pc_); | |
2302 icount_++; | 2295 icount_++; |
2303 Instr* instr = Instr::At(pc_); | 2296 if (static_cast<intptr_t>(icount_) == FLAG_stop_sim_at) { |
2304 if (static_cast<int>(icount_) == FLAG_stop_sim_at) { | |
2305 SimulatorDebugger dbg(this); | 2297 SimulatorDebugger dbg(this); |
2306 dbg.Stop(instr, "Instruction count reached"); | 2298 dbg.Stop(instr, "Instruction count reached"); |
2307 } else if (reinterpret_cast<int>(instr) == FLAG_stop_sim_at) { | 2299 } else if (reinterpret_cast<intptr_t>(instr) == FLAG_stop_sim_at) { |
2308 SimulatorDebugger dbg(this); | 2300 SimulatorDebugger dbg(this); |
2309 dbg.Stop(instr, "Instruction address reached"); | 2301 dbg.Stop(instr, "Instruction address reached"); |
2302 } else if (IsIllegalAddress(pc_)) { | |
2303 HandleIllegalAccess(pc_, instr); | |
2310 } else { | 2304 } else { |
2311 if (IsIllegalAddress(pc_)) { | 2305 InstructionDecode(instr); |
2312 HandleIllegalAccess(pc_, instr); | |
2313 } else { | |
2314 InstructionDecode(instr); | |
2315 } | |
2316 } | 2306 } |
2317 } | 2307 } |
2318 } | 2308 } |
2319 } | 2309 } |
2320 | 2310 |
2321 | 2311 |
2322 int64_t Simulator::Call(int32_t entry, | 2312 int64_t Simulator::Call(int32_t entry, |
2323 int32_t parameter0, | 2313 int32_t parameter0, |
2324 int32_t parameter1, | 2314 int32_t parameter1, |
2325 int32_t parameter2, | 2315 int32_t parameter2, |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2480 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); | 2470 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
2481 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 2471 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
2482 buf->Longjmp(); | 2472 buf->Longjmp(); |
2483 } | 2473 } |
2484 | 2474 |
2485 } // namespace dart | 2475 } // namespace dart |
2486 | 2476 |
2487 #endif // !defined(HOST_ARCH_MIPS) | 2477 #endif // !defined(HOST_ARCH_MIPS) |
2488 | 2478 |
2489 #endif // defined TARGET_ARCH_MIPS | 2479 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |