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

Side by Side Diff: src/arm/simulator-arm.cc

Issue 191004: Fix the debugger in the ARM simulator (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 3 months 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 | « no previous file | 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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 void Debug(); 63 void Debug();
64 64
65 private: 65 private:
66 static const instr_t kBreakpointInstr = 66 static const instr_t kBreakpointInstr =
67 ((AL << 28) | (7 << 25) | (1 << 24) | break_point); 67 ((AL << 28) | (7 << 25) | (1 << 24) | break_point);
68 static const instr_t kNopInstr = 68 static const instr_t kNopInstr =
69 ((AL << 28) | (13 << 21)); 69 ((AL << 28) | (13 << 21));
70 70
71 Simulator* sim_; 71 Simulator* sim_;
72 72
73 bool GetValue(char* desc, int32_t* value); 73 bool GetValue(const char* desc, int32_t* value);
74 74
75 // Set or delete a breakpoint. Returns true if successful. 75 // Set or delete a breakpoint. Returns true if successful.
76 bool SetBreakpoint(Instr* breakpc); 76 bool SetBreakpoint(Instr* breakpc);
77 bool DeleteBreakpoint(Instr* breakpc); 77 bool DeleteBreakpoint(Instr* breakpc);
78 78
79 // Undo and redo all breakpoints. This is needed to bracket disassembly and 79 // Undo and redo all breakpoints. This is needed to bracket disassembly and
80 // execution to skip past breakpoints when run from the debugger. 80 // execution to skip past breakpoints when run from the debugger.
81 void UndoBreakpoints(); 81 void UndoBreakpoints();
82 void RedoBreakpoints(); 82 void RedoBreakpoints();
83 }; 83 };
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 125
126 void Debugger::Stop(Instr* instr) { 126 void Debugger::Stop(Instr* instr) {
127 const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff); 127 const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff);
128 PrintF("Simulator hit %s\n", str); 128 PrintF("Simulator hit %s\n", str);
129 sim_->set_pc(sim_->get_pc() + Instr::kInstrSize); 129 sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
130 Debug(); 130 Debug();
131 } 131 }
132 #endif 132 #endif
133 133
134 134
135 // The order of these are important, see the handling of the 'print all'
136 // debugger command.
135 static const char* reg_names[] = { "r0", "r1", "r2", "r3", 137 static const char* reg_names[] = { "r0", "r1", "r2", "r3",
136 "r4", "r5", "r6", "r7", 138 "r4", "r5", "r6", "r7",
137 "r8", "r9", "r10", "r11", 139 "r8", "r9", "r10", "r11",
138 "r12", "r13", "r14", "r15", 140 "r12", "r13", "r14", "r15",
139 "pc", "lr", "sp", "ip", 141 "pc", "lr", "sp", "ip",
140 "fp", "sl", ""}; 142 "fp", "sl", ""};
141 143
142 static int reg_nums[] = { 0, 1, 2, 3, 144 static int reg_nums[] = { 0, 1, 2, 3,
143 4, 5, 6, 7, 145 4, 5, 6, 7,
144 8, 9, 10, 11, 146 8, 9, 10, 11,
145 12, 13, 14, 15, 147 12, 13, 14, 15,
146 15, 14, 13, 12, 148 15, 14, 13, 12,
147 11, 10}; 149 11, 10};
148 150
149 151
150 static int RegNameToRegNum(char* name) { 152 static int RegNameToRegNum(const char* name) {
151 int reg = 0; 153 int reg = 0;
152 while (*reg_names[reg] != 0) { 154 while (*reg_names[reg] != 0) {
153 if (strcmp(reg_names[reg], name) == 0) { 155 if (strcmp(reg_names[reg], name) == 0) {
154 return reg_nums[reg]; 156 return reg_nums[reg];
155 } 157 }
156 reg++; 158 reg++;
157 } 159 }
158 return -1; 160 return -1;
159 } 161 }
160 162
161 163
162 bool Debugger::GetValue(char* desc, int32_t* value) { 164 bool Debugger::GetValue(const char* desc, int32_t* value) {
163 int regnum = RegNameToRegNum(desc); 165 int regnum = RegNameToRegNum(desc);
164 if (regnum >= 0) { 166 if (regnum >= 0) {
165 if (regnum == 15) { 167 if (regnum == 15) {
166 *value = sim_->get_pc(); 168 *value = sim_->get_pc();
167 } else { 169 } else {
168 *value = sim_->get_register(regnum); 170 *value = sim_->get_register(regnum);
169 } 171 }
170 return true; 172 return true;
171 } else { 173 } else {
172 return SScanF(desc, "%i", value) == 1; 174 return SScanF(desc, "%i", value) == 1;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 265 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
264 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 266 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
265 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 267 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
266 // Execute the one instruction we broke at with breakpoints disabled. 268 // Execute the one instruction we broke at with breakpoints disabled.
267 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 269 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
268 // Leave the debugger shell. 270 // Leave the debugger shell.
269 done = true; 271 done = true;
270 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 272 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
271 if (args == 2) { 273 if (args == 2) {
272 int32_t value; 274 int32_t value;
273 if (GetValue(arg1, &value)) { 275 if (strcmp(arg1, "all") == 0) {
274 PrintF("%s: %d 0x%x\n", arg1, value, value); 276 for (int i = 0; i <= 15; i++) {
iposva 2009/09/04 05:30:24 Please use named constants here.
277 if (GetValue(reg_names[i], &value)) {
278 if (i <= 10) {
iposva 2009/09/04 05:30:24 and here.
279 PrintF("%s: 08x%x %d\n", reg_names[i], value, value);
280 } else {
281 PrintF("%s: 08x%x %d\n", reg_names[15 + 16 - i], value, value) ;
iposva 2009/09/04 05:30:24 and here. Better yet, abstract the register to na
282 }
283 }
284 }
275 } else { 285 } else {
276 PrintF("%s unrecognized\n", arg1); 286 if (GetValue(arg1, &value)) {
287 PrintF("%s: 08x%x %d \n", arg1, value, value);
288 } else {
289 PrintF("%s unrecognized\n", arg1);
290 }
277 } 291 }
278 } else { 292 } else {
279 PrintF("print value\n"); 293 PrintF("print <register>\n");
280 } 294 }
281 } else if ((strcmp(cmd, "po") == 0) 295 } else if ((strcmp(cmd, "po") == 0)
282 || (strcmp(cmd, "printobject") == 0)) { 296 || (strcmp(cmd, "printobject") == 0)) {
283 if (args == 2) { 297 if (args == 2) {
284 int32_t value; 298 int32_t value;
285 if (GetValue(arg1, &value)) { 299 if (GetValue(arg1, &value)) {
286 Object* obj = reinterpret_cast<Object*>(value); 300 Object* obj = reinterpret_cast<Object*>(value);
287 USE(obj); 301 USE(obj);
iposva 2009/09/04 05:30:24 This USE can be dropped now, that obj is used in D
288 PrintF("%s: \n", arg1); 302 PrintF("%s: \n", arg1);
289 #if defined(DEBUG) 303 #ifdef DEBUG
290 obj->PrintLn(); 304 obj->PrintLn();
291 #endif // defined(DEBUG) 305 #else
306 obj->ShortPrint();
307 PrintF("\n");
308 #endif
292 } else { 309 } else {
293 PrintF("%s unrecognized\n", arg1); 310 PrintF("%s unrecognized\n", arg1);
294 } 311 }
295 } else { 312 } else {
296 PrintF("printobject value\n"); 313 PrintF("printobject <value>\n");
297 } 314 }
298 } else if (strcmp(cmd, "disasm") == 0) { 315 } else if (strcmp(cmd, "disasm") == 0) {
299 disasm::NameConverter converter; 316 disasm::NameConverter converter;
300 disasm::Disassembler dasm(converter); 317 disasm::Disassembler dasm(converter);
301 // use a reasonably large buffer 318 // use a reasonably large buffer
302 v8::internal::EmbeddedVector<char, 256> buffer; 319 v8::internal::EmbeddedVector<char, 256> buffer;
303 320
304 byte* cur = NULL; 321 byte* cur = NULL;
305 byte* end = NULL; 322 byte* end = NULL;
306 323
(...skipping 29 matching lines...) Expand all
336 if (args == 2) { 353 if (args == 2) {
337 int32_t value; 354 int32_t value;
338 if (GetValue(arg1, &value)) { 355 if (GetValue(arg1, &value)) {
339 if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) { 356 if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) {
340 PrintF("setting breakpoint failed\n"); 357 PrintF("setting breakpoint failed\n");
341 } 358 }
342 } else { 359 } else {
343 PrintF("%s unrecognized\n", arg1); 360 PrintF("%s unrecognized\n", arg1);
344 } 361 }
345 } else { 362 } else {
346 PrintF("break addr\n"); 363 PrintF("break <address>\n");
347 } 364 }
348 } else if (strcmp(cmd, "del") == 0) { 365 } else if (strcmp(cmd, "del") == 0) {
349 if (!DeleteBreakpoint(NULL)) { 366 if (!DeleteBreakpoint(NULL)) {
350 PrintF("deleting breakpoint failed\n"); 367 PrintF("deleting breakpoint failed\n");
351 } 368 }
352 } else if (strcmp(cmd, "flags") == 0) { 369 } else if (strcmp(cmd, "flags") == 0) {
353 PrintF("N flag: %d; ", sim_->n_flag_); 370 PrintF("N flag: %d; ", sim_->n_flag_);
354 PrintF("Z flag: %d; ", sim_->z_flag_); 371 PrintF("Z flag: %d; ", sim_->z_flag_);
355 PrintF("C flag: %d; ", sim_->c_flag_); 372 PrintF("C flag: %d; ", sim_->c_flag_);
356 PrintF("V flag: %d\n", sim_->v_flag_); 373 PrintF("V flag: %d\n", sim_->v_flag_);
357 } else if (strcmp(cmd, "unstop") == 0) { 374 } else if (strcmp(cmd, "unstop") == 0) {
358 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; 375 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
359 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); 376 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
360 if (stop_instr->ConditionField() == special_condition) { 377 if (stop_instr->ConditionField() == special_condition) {
361 stop_instr->SetInstructionBits(kNopInstr); 378 stop_instr->SetInstructionBits(kNopInstr);
362 } else { 379 } else {
363 PrintF("Not at debugger stop."); 380 PrintF("Not at debugger stop.");
364 } 381 }
382 } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
383 PrintF("print <register>\n");
Erik Corry 2009/09/02 14:22:44 It would be nice to include si/stepi and c/cont as
Søren Thygesen Gjesse 2009/09/02 14:47:19 Added missing commands and description and alias a
384 PrintF("printobject <register>\n");
385 PrintF("flags\n");
386 PrintF("disasm <value>\n");
387 PrintF("gdb\n");
388 PrintF("break <address>\n");
389 PrintF("del\n");
390 PrintF("unstop\n");
365 } else { 391 } else {
366 PrintF("Unknown command: %s\n", cmd); 392 PrintF("Unknown command: %s\n", cmd);
367 } 393 }
368 } 394 }
369 DeleteArray(line); 395 DeleteArray(line);
370 } 396 }
371 397
372 // Add all the breakpoints back to stop execution and enter the debugger 398 // Add all the breakpoints back to stop execution and enter the debugger
373 // shell when hit. 399 // shell when hit.
374 RedoBreakpoints(); 400 RedoBreakpoints();
(...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 default: { 1745 default: {
1720 // The PU field is a 2-bit field. 1746 // The PU field is a 2-bit field.
1721 UNREACHABLE(); 1747 UNREACHABLE();
1722 break; 1748 break;
1723 } 1749 }
1724 } 1750 }
1725 // Not sign extending, so load as unsigned. 1751 // Not sign extending, so load as unsigned.
1726 uint16_t halfword = ReadH(addr, instr); 1752 uint16_t halfword = ReadH(addr, instr);
1727 set_register(rd, halfword); 1753 set_register(rd, halfword);
1728 } else { 1754 } else {
1729 UNIMPLEMENTED(); 1755 Debugger dbg(this);
1756 dbg.Stop(instr);
1730 } 1757 }
1731 } 1758 }
1732 1759
1733 1760
1734 // Executes the current instruction. 1761 // Executes the current instruction.
1735 void Simulator::InstructionDecode(Instr* instr) { 1762 void Simulator::InstructionDecode(Instr* instr) {
1736 pc_modified_ = false; 1763 pc_modified_ = false;
1737 if (::v8::internal::FLAG_trace_sim) { 1764 if (::v8::internal::FLAG_trace_sim) {
1738 disasm::NameConverter converter; 1765 disasm::NameConverter converter;
1739 disasm::Disassembler dasm(converter); 1766 disasm::Disassembler dasm(converter);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 CHECK_EQ(entry_stack, get_register(sp)); 1933 CHECK_EQ(entry_stack, get_register(sp));
1907 set_register(sp, original_stack); 1934 set_register(sp, original_stack);
1908 1935
1909 int32_t result = get_register(r0); 1936 int32_t result = get_register(r0);
1910 return result; 1937 return result;
1911 } 1938 }
1912 1939
1913 } } // namespace assembler::arm 1940 } } // namespace assembler::arm
1914 1941
1915 #endif // !defined(__arm__) 1942 #endif // !defined(__arm__)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698