OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #if V8_TARGET_ARCH_PPC | 9 #if V8_TARGET_ARCH_PPC |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... |
29 // SScanF not being implemented in a platform independent way through | 29 // SScanF not being implemented in a platform independent way through |
30 // ::v8::internal::OS in the same way as SNPrintF is that the | 30 // ::v8::internal::OS in the same way as SNPrintF is that the |
31 // Windows C Run-Time Library does not provide vsscanf. | 31 // Windows C Run-Time Library does not provide vsscanf. |
32 #define SScanF sscanf // NOLINT | 32 #define SScanF sscanf // NOLINT |
33 | 33 |
34 // The PPCDebugger class is used by the simulator while debugging simulated | 34 // The PPCDebugger class is used by the simulator while debugging simulated |
35 // PowerPC code. | 35 // PowerPC code. |
36 class PPCDebugger { | 36 class PPCDebugger { |
37 public: | 37 public: |
38 explicit PPCDebugger(Simulator* sim) : sim_(sim) {} | 38 explicit PPCDebugger(Simulator* sim) : sim_(sim) {} |
39 ~PPCDebugger(); | |
40 | 39 |
41 void Stop(Instruction* instr); | 40 void Stop(Instruction* instr); |
42 void Debug(); | 41 void Debug(); |
43 | 42 |
44 private: | 43 private: |
45 static const Instr kBreakpointInstr = (TWI | 0x1f * B21); | 44 static const Instr kBreakpointInstr = (TWI | 0x1f * B21); |
46 static const Instr kNopInstr = (ORI); // ori, 0,0,0 | 45 static const Instr kNopInstr = (ORI); // ori, 0,0,0 |
47 | 46 |
48 Simulator* sim_; | 47 Simulator* sim_; |
49 | 48 |
50 intptr_t GetRegisterValue(int regnum); | 49 intptr_t GetRegisterValue(int regnum); |
51 double GetRegisterPairDoubleValue(int regnum); | 50 double GetRegisterPairDoubleValue(int regnum); |
52 double GetFPDoubleRegisterValue(int regnum); | 51 double GetFPDoubleRegisterValue(int regnum); |
53 bool GetValue(const char* desc, intptr_t* value); | 52 bool GetValue(const char* desc, intptr_t* value); |
54 bool GetFPDoubleValue(const char* desc, double* value); | 53 bool GetFPDoubleValue(const char* desc, double* value); |
55 | 54 |
56 // Set or delete a breakpoint. Returns true if successful. | 55 // Set or delete a breakpoint. Returns true if successful. |
57 bool SetBreakpoint(Instruction* break_pc); | 56 bool SetBreakpoint(Instruction* break_pc); |
58 bool DeleteBreakpoint(Instruction* break_pc); | 57 bool DeleteBreakpoint(Instruction* break_pc); |
59 | 58 |
60 // Undo and redo all breakpoints. This is needed to bracket disassembly and | 59 // Undo and redo all breakpoints. This is needed to bracket disassembly and |
61 // execution to skip past breakpoints when run from the debugger. | 60 // execution to skip past breakpoints when run from the debugger. |
62 void UndoBreakpoints(); | 61 void UndoBreakpoints(); |
63 void RedoBreakpoints(); | 62 void RedoBreakpoints(); |
64 }; | 63 }; |
65 | 64 |
66 | |
67 PPCDebugger::~PPCDebugger() {} | |
68 | |
69 | |
70 #ifdef GENERATED_CODE_COVERAGE | |
71 static FILE* coverage_log = NULL; | |
72 | |
73 | |
74 static void InitializeCoverage() { | |
75 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); | |
76 if (file_name != NULL) { | |
77 coverage_log = fopen(file_name, "aw+"); | |
78 } | |
79 } | |
80 | |
81 | |
82 void PPCDebugger::Stop(Instruction* instr) { | |
83 // Get the stop code. | |
84 uint32_t code = instr->SvcValue() & kStopCodeMask; | |
85 // Retrieve the encoded address, which comes just after this stop. | |
86 char** msg_address = | |
87 reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize); | |
88 char* msg = *msg_address; | |
89 DCHECK(msg != NULL); | |
90 | |
91 // Update this stop description. | |
92 if (isWatchedStop(code) && !watched_stops_[code].desc) { | |
93 watched_stops_[code].desc = msg; | |
94 } | |
95 | |
96 if (strlen(msg) > 0) { | |
97 if (coverage_log != NULL) { | |
98 fprintf(coverage_log, "%s\n", msg); | |
99 fflush(coverage_log); | |
100 } | |
101 // Overwrite the instruction and address with nops. | |
102 instr->SetInstructionBits(kNopInstr); | |
103 reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr); | |
104 } | |
105 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); | |
106 } | |
107 | |
108 #else // ndef GENERATED_CODE_COVERAGE | |
109 | |
110 static void InitializeCoverage() {} | |
111 | |
112 | |
113 void PPCDebugger::Stop(Instruction* instr) { | 65 void PPCDebugger::Stop(Instruction* instr) { |
114 // Get the stop code. | 66 // Get the stop code. |
115 // use of kStopCodeMask not right on PowerPC | 67 // use of kStopCodeMask not right on PowerPC |
116 uint32_t code = instr->SvcValue() & kStopCodeMask; | 68 uint32_t code = instr->SvcValue() & kStopCodeMask; |
117 // Retrieve the encoded address, which comes just after this stop. | 69 // Retrieve the encoded address, which comes just after this stop. |
118 char* msg = | 70 char* msg = |
119 *reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize); | 71 *reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize); |
120 // Update this stop description. | 72 // Update this stop description. |
121 if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) { | 73 if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) { |
122 sim_->watched_stops_[code].desc = msg; | 74 sim_->watched_stops_[code].desc = msg; |
123 } | 75 } |
124 // Print the stop message and code if it is not the default code. | 76 // Print the stop message and code if it is not the default code. |
125 if (code != kMaxStopCode) { | 77 if (code != kMaxStopCode) { |
126 PrintF("Simulator hit stop %u: %s\n", code, msg); | 78 PrintF("Simulator hit stop %u: %s\n", code, msg); |
127 } else { | 79 } else { |
128 PrintF("Simulator hit %s\n", msg); | 80 PrintF("Simulator hit %s\n", msg); |
129 } | 81 } |
130 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); | 82 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); |
131 Debug(); | 83 Debug(); |
132 } | 84 } |
133 #endif | |
134 | |
135 | 85 |
136 intptr_t PPCDebugger::GetRegisterValue(int regnum) { | 86 intptr_t PPCDebugger::GetRegisterValue(int regnum) { |
137 return sim_->get_register(regnum); | 87 return sim_->get_register(regnum); |
138 } | 88 } |
139 | 89 |
140 | 90 |
141 double PPCDebugger::GetRegisterPairDoubleValue(int regnum) { | 91 double PPCDebugger::GetRegisterPairDoubleValue(int regnum) { |
142 return sim_->get_double_from_register_pair(regnum); | 92 return sim_->get_double_from_register_pair(regnum); |
143 } | 93 } |
144 | 94 |
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 // Initializing FP registers. | 769 // Initializing FP registers. |
820 for (int i = 0; i < kNumFPRs; i++) { | 770 for (int i = 0; i < kNumFPRs; i++) { |
821 fp_registers_[i] = 0.0; | 771 fp_registers_[i] = 0.0; |
822 } | 772 } |
823 | 773 |
824 // The sp is initialized to point to the bottom (high address) of the | 774 // The sp is initialized to point to the bottom (high address) of the |
825 // allocated stack area. To be safe in potential stack underflows we leave | 775 // allocated stack area. To be safe in potential stack underflows we leave |
826 // some buffer below. | 776 // some buffer below. |
827 registers_[sp] = | 777 registers_[sp] = |
828 reinterpret_cast<intptr_t>(stack_) + stack_size - stack_protection_size_; | 778 reinterpret_cast<intptr_t>(stack_) + stack_size - stack_protection_size_; |
829 InitializeCoverage(); | |
830 | 779 |
831 last_debugger_input_ = NULL; | 780 last_debugger_input_ = NULL; |
832 } | 781 } |
833 | 782 |
834 | 783 |
835 Simulator::~Simulator() { free(stack_); } | 784 Simulator::~Simulator() { free(stack_); } |
836 | 785 |
837 | 786 |
838 // When the generated code calls an external reference we need to catch that in | 787 // When the generated code calls an external reference we need to catch that in |
839 // the simulator. The external reference will be a function compiled for the | 788 // the simulator. The external reference will be a function compiled for the |
(...skipping 3290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4130 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 4079 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
4131 uintptr_t address = *stack_slot; | 4080 uintptr_t address = *stack_slot; |
4132 set_register(sp, current_sp + sizeof(uintptr_t)); | 4081 set_register(sp, current_sp + sizeof(uintptr_t)); |
4133 return address; | 4082 return address; |
4134 } | 4083 } |
4135 } // namespace internal | 4084 } // namespace internal |
4136 } // namespace v8 | 4085 } // namespace v8 |
4137 | 4086 |
4138 #endif // USE_SIMULATOR | 4087 #endif // USE_SIMULATOR |
4139 #endif // V8_TARGET_ARCH_PPC | 4088 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |