blob: 93c2bcc07060d163a447a68cb8c2110b207df3cd [file] [log] [blame]
Greg Clayton6da4ca82011-01-21 22:02:52 +00001//===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Greg Clayton95e31422011-02-05 02:56:16 +000010#include "lldb/Core/EmulateInstruction.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000011
Caroline Ticead379efc2011-04-05 18:46:00 +000012#include "lldb/Core/DataBufferHeap.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000013#include "lldb/Core/DataExtractor.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000014#include "lldb/Core/Error.h"
Greg Clayton4272cc72011-02-02 02:24:04 +000015#include "lldb/Core/PluginManager.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000016#include "lldb/Core/StreamString.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000017#include "lldb/Host/Endian.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000018#include "lldb/Target/Process.h"
19#include "lldb/Target/RegisterContext.h"
20#include "lldb/Target/Thread.h"
21
22#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
23
Greg Clayton6da4ca82011-01-21 22:02:52 +000024using namespace lldb;
25using namespace lldb_private;
26
Greg Clayton4272cc72011-02-02 02:24:04 +000027EmulateInstruction*
Greg Clayton514487e2011-02-15 21:59:32 +000028EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Greg Clayton4272cc72011-02-02 02:24:04 +000029{
30 EmulateInstructionCreateInstance create_callback = NULL;
31 if (plugin_name)
32 {
33 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
34 if (create_callback)
35 {
Caroline Ticead379efc2011-04-05 18:46:00 +000036 EmulateInstruction *emulate_insn_ptr = create_callback(arch);
37 if (emulate_insn_ptr)
38 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000039 }
40 }
41 else
42 {
43 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
44 {
Caroline Ticead379efc2011-04-05 18:46:00 +000045 EmulateInstruction *emulate_insn_ptr = create_callback(arch);
46 if (emulate_insn_ptr)
47 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000048 }
49 }
50 return NULL;
51}
Greg Clayton6da4ca82011-01-21 22:02:52 +000052
53EmulateInstruction::EmulateInstruction
54(
55 lldb::ByteOrder byte_order,
56 uint32_t addr_byte_size,
Caroline Ticead379efc2011-04-05 18:46:00 +000057 const ArchSpec &arch,
Greg Clayton6da4ca82011-01-21 22:02:52 +000058 void *baton,
59 ReadMemory read_mem_callback,
60 WriteMemory write_mem_callback,
61 ReadRegister read_reg_callback,
62 WriteRegister write_reg_callback
63) :
Greg Clayton7fb56d02011-02-01 01:31:41 +000064 m_byte_order (endian::InlHostByteOrder()),
Caroline Ticead379efc2011-04-05 18:46:00 +000065 m_addr_byte_size (addr_byte_size),
66 m_arch (arch),
Greg Clayton6da4ca82011-01-21 22:02:52 +000067 m_baton (baton),
68 m_read_mem_callback (read_mem_callback),
69 m_write_mem_callback (write_mem_callback),
70 m_read_reg_callback (read_reg_callback),
71 m_write_reg_callback (write_reg_callback),
Greg Clayton0ae96272011-03-24 23:53:38 +000072 m_opcode (),
Greg Claytone0d378b2011-03-24 21:19:54 +000073 m_opcode_pc (LLDB_INVALID_ADDRESS)
Greg Clayton6da4ca82011-01-21 22:02:52 +000074{
Greg Clayton6da4ca82011-01-21 22:02:52 +000075}
76
Caroline Ticead379efc2011-04-05 18:46:00 +000077EmulateInstruction::EmulateInstruction
78(
79 lldb::ByteOrder byte_order,
80 uint32_t addr_byte_size,
81 const ArchSpec &arch
82) :
83 m_byte_order (endian::InlHostByteOrder()),
84 m_addr_byte_size (addr_byte_size),
85 m_arch (arch),
86 m_baton (NULL),
87 m_read_mem_callback (&ReadMemoryDefault),
88 m_write_mem_callback (&WriteMemoryDefault),
89 m_read_reg_callback (&ReadRegisterDefault),
90 m_write_reg_callback (&WriteRegisterDefault),
91 m_opcode_pc (LLDB_INVALID_ADDRESS)
92{
93 ::memset (&m_opcode, 0, sizeof (m_opcode));
94}
95
Greg Clayton6da4ca82011-01-21 22:02:52 +000096uint64_t
97EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
98{
99 uint64_t uval64 = 0;
100 bool success = m_read_reg_callback (m_baton, reg_kind, reg_num, uval64);
101 if (success_ptr)
102 *success_ptr = success;
103 if (!success)
104 uval64 = fail_value;
105 return uval64;
106}
107
108bool
109EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
110{
111 return m_write_reg_callback (m_baton, context, reg_kind, reg_num, reg_value);
112}
113
114uint64_t
115EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
116{
117 uint64_t uval64 = 0;
118 bool success = false;
119 if (byte_size <= 8)
120 {
121 uint8_t buf[sizeof(uint64_t)];
122 size_t bytes_read = m_read_mem_callback (m_baton, context, addr, buf, byte_size);
123 if (bytes_read == byte_size)
124 {
125 uint32_t offset = 0;
126 DataExtractor data (buf, byte_size, m_byte_order, m_addr_byte_size);
127 uval64 = data.GetMaxU64 (&offset, byte_size);
128 success = true;
129 }
130 }
131
132 if (success_ptr)
133 *success_ptr = success;
134
135 if (!success)
136 uval64 = fail_value;
137 return uval64;
138}
139
140
141bool
142EmulateInstruction::WriteMemoryUnsigned (const Context &context,
143 lldb::addr_t addr,
144 uint64_t uval,
145 size_t uval_byte_size)
146{
147 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
148 strm.PutMaxHex64 (uval, uval_byte_size);
149
150 size_t bytes_written = m_write_mem_callback (m_baton, context, addr, strm.GetData(), uval_byte_size);
151 if (bytes_written == uval_byte_size)
152 return true;
153 return false;
154}
Caroline Ticead379efc2011-04-05 18:46:00 +0000155
156
157void
158EmulateInstruction::SetBaton (void *baton)
159{
160 m_baton = baton;
161}
162
163void
164EmulateInstruction::SetCallbacks (ReadMemory read_mem_callback,
165 WriteMemory write_mem_callback,
166 ReadRegister read_reg_callback,
167 WriteRegister write_reg_callback)
168{
169 m_read_mem_callback = read_mem_callback;
170 m_write_mem_callback = write_mem_callback;
171 m_read_reg_callback = read_reg_callback;
172 m_write_reg_callback = write_reg_callback;
173}
174
175void
176EmulateInstruction::SetReadMemCallback (ReadMemory read_mem_callback)
177{
178 m_read_mem_callback = read_mem_callback;
179}
180
181
182void
183EmulateInstruction::SetWriteMemCallback (WriteMemory write_mem_callback)
184{
185 m_write_mem_callback = write_mem_callback;
186}
187
188
189void
190EmulateInstruction::SetReadRegCallback (ReadRegister read_reg_callback)
191{
192 m_read_reg_callback = read_reg_callback;
193}
194
195
196void
197EmulateInstruction::SetWriteRegCallback (WriteRegister write_reg_callback)
198{
199 m_write_reg_callback = write_reg_callback;
200}
201
202
203
204//
205// Read & Write Memory and Registers callback functions.
206//
207
208size_t
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000209EmulateInstruction::ReadMemoryFrame (void *baton,
210 const Context &context,
211 lldb::addr_t addr,
212 void *dst,
213 size_t length)
Caroline Ticead379efc2011-04-05 18:46:00 +0000214{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000215 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000216 return 0;
217
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000218
219 StackFrame *frame = (StackFrame *) baton;
220
Caroline Ticead379efc2011-04-05 18:46:00 +0000221 DataBufferSP data_sp (new DataBufferHeap (length, '\0'));
222 Error error;
223
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000224 size_t bytes_read = frame->GetThread().GetProcess().ReadMemory (addr, data_sp->GetBytes(), data_sp->GetByteSize(),
225 error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000226
227 if (bytes_read > 0)
228 ((DataBufferHeap *) data_sp.get())->CopyData (dst, length);
229
230 return bytes_read;
231}
232
233size_t
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000234EmulateInstruction::WriteMemoryFrame (void *baton,
235 const Context &context,
236 lldb::addr_t addr,
237 const void *dst,
238 size_t length)
Caroline Ticead379efc2011-04-05 18:46:00 +0000239{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000240 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000241 return 0;
242
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000243 StackFrame *frame = (StackFrame *) baton;
244
Caroline Ticead379efc2011-04-05 18:46:00 +0000245 lldb::DataBufferSP data_sp (new DataBufferHeap (dst, length));
246 if (data_sp)
247 {
248 length = data_sp->GetByteSize();
249 if (length > 0)
250 {
251 Error error;
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000252 size_t bytes_written = frame->GetThread().GetProcess().WriteMemory (addr, data_sp->GetBytes(), length,
253 error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000254
255 return bytes_written;
256 }
257 }
258
259 return 0;
260}
261
262bool
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000263EmulateInstruction::ReadRegisterFrame (void *baton,
264 uint32_t reg_kind,
265 uint32_t reg_num,
266 uint64_t &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000267{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000268 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000269 return false;
270
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000271 StackFrame *frame = (StackFrame *) baton;
272 RegisterContext *reg_context = frame->GetRegisterContext().get();
Caroline Ticead379efc2011-04-05 18:46:00 +0000273 Scalar value;
274
275
276 if (reg_context->ReadRegisterValue (reg_num, value))
277 {
278 reg_value = value.GetRawBits64 (0);
279 return true;
280 }
281
282 return false;
283}
284
285bool
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000286EmulateInstruction::WriteRegisterFrame (void *baton,
287 const Context &context,
288 uint32_t reg_kind,
289 uint32_t reg_num,
290 uint64_t reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000291{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000292 if (!baton)
293 return false;
294
295 StackFrame *frame = (StackFrame *) baton;
296 RegisterContext *reg_context = frame->GetRegisterContext().get();
Caroline Ticead379efc2011-04-05 18:46:00 +0000297 Scalar value (reg_value);
298
299 return reg_context->WriteRegisterValue (reg_num, value);
300}
301
302size_t
303EmulateInstruction::ReadMemoryDefault (void *baton,
304 const Context &context,
305 lldb::addr_t addr,
306 void *dst,
307 size_t length)
308{
309 PrintContext ("Read from memory", context);
310 fprintf (stdout, " Read from Memory (address = %p, length = %d)\n",(void *) addr, (uint) length);
311
312 *((uint64_t *) dst) = 0xdeadbeef;
313 return length;
314}
315
316size_t
317EmulateInstruction::WriteMemoryDefault (void *baton,
318 const Context &context,
319 lldb::addr_t addr,
320 const void *dst,
321 size_t length)
322{
323 PrintContext ("Write to memory", context);
324 fprintf (stdout, " Write to Memory (address = %p, length = %d)\n", (void *) addr, (uint) length);
325 return length;
326}
327
328bool
329EmulateInstruction::ReadRegisterDefault (void *baton,
330 uint32_t reg_kind,
331 uint32_t reg_num,
332 uint64_t &reg_value)
333{
334 std::string reg_name;
335 TranslateRegister (reg_kind, reg_num, reg_name);
336 fprintf (stdout, " Read Register (%s)\n", reg_name.c_str());
337
338 reg_value = 24;
339 return true;
340}
341
342bool
343EmulateInstruction::WriteRegisterDefault (void *baton,
344 const Context &context,
345 uint32_t reg_kind,
346 uint32_t reg_num,
347 uint64_t reg_value)
348{
349 PrintContext ("Write to register", context);
350 std::string reg_name;
351 TranslateRegister (reg_kind, reg_num, reg_name);
352 fprintf (stdout, " Write to Register (%s), value = 0x%llx\n", reg_name.c_str(), reg_value);
353 return true;
354}
355
356void
357EmulateInstruction::PrintContext (const char *context_type, const Context &context)
358{
359 switch (context.type)
360 {
361 case eContextReadOpcode:
362 fprintf (stdout, " %s context: Reading an Opcode\n", context_type);
363 break;
364
365 case eContextImmediate:
366 fprintf (stdout, " %s context: Immediate\n", context_type);
367 break;
368
369 case eContextPushRegisterOnStack:
370 fprintf (stdout, " %s context: Pushing a register onto the stack.\n", context_type);
371 break;
372
373 case eContextPopRegisterOffStack:
374 fprintf (stdout, " %s context: Popping a register off the stack.\n", context_type);
375 break;
376
377 case eContextAdjustStackPointer:
378 fprintf (stdout, " %s context: Adjusting the stack pointer.\n", context_type);
379 break;
380
381 case eContextAdjustBaseRegister:
382 fprintf (stdout, " %s context: Adjusting (writing value back to) a base register.\n", context_type);
383 break;
384
385 case eContextRegisterPlusOffset:
386 fprintf (stdout, " %s context: Register plus offset\n", context_type);
387 break;
388
389 case eContextRegisterStore:
390 fprintf (stdout, " %s context: Storing a register.\n", context_type);
391 break;
392
393 case eContextRegisterLoad:
394 fprintf (stdout, " %s context: Loading a register.\n", context_type);
395 break;
396
397 case eContextRelativeBranchImmediate:
398 fprintf (stdout, " %s context: Relative branch immediate\n", context_type);
399 break;
400
401 case eContextAbsoluteBranchRegister:
402 fprintf (stdout, " %s context: Absolute branch register\n", context_type);
403 break;
404
405 case eContextSupervisorCall:
406 fprintf (stdout, " %s context: Performing a supervisor call.\n", context_type);
407 break;
408
409 case eContextTableBranchReadMemory:
410 fprintf (stdout, " %s context: Table branch read memory\n", context_type);
411 break;
412
413 case eContextWriteRegisterRandomBits:
414 fprintf (stdout, " %s context: Write random bits to a register\n", context_type);
415 break;
416
417 case eContextWriteMemoryRandomBits:
418 fprintf (stdout, " %s context: Write random bits to a memory address\n", context_type);
419 break;
420
421 case eContextMultiplication:
422 fprintf (stdout, " %s context: Performing a multiplication\n", context_type);
423 break;
424
425 case eContextAddition:
426 fprintf (stdout, " %s context: Performing an addition\n", context_type);
427 break;
428
429 case eContextReturnFromException:
430 fprintf (stdout, " %s context: Returning from an exception\n", context_type);
431 break;
432
433 default:
434 fprintf (stdout, " %s context: Unrecognized context.\n", context_type);
435 break;
436 }
437
438 switch (context.info_type)
439 {
440 case eInfoTypeRegisterPlusOffset:
441 {
442 std::string reg_name;
443 TranslateRegister (context.info.RegisterPlusOffset.reg.kind,
444 context.info.RegisterPlusOffset.reg.num,
445 reg_name);
446 fprintf (stdout, " Info type: Register plus offset (%s +/- %lld)\n", reg_name.c_str(),
447 context.info.RegisterPlusOffset.signed_offset);
448 }
449 break;
450 case eInfoTypeRegisterPlusIndirectOffset:
451 {
452 std::string base_reg_name;
453 std::string offset_reg_name;
454 TranslateRegister (context.info.RegisterPlusIndirectOffset.base_reg.kind,
455 context.info.RegisterPlusIndirectOffset.base_reg.num,
456 base_reg_name);
457 TranslateRegister (context.info.RegisterPlusIndirectOffset.offset_reg.kind,
458 context.info.RegisterPlusIndirectOffset.offset_reg.num,
459 offset_reg_name);
460 fprintf (stdout, " Info type: Register plus indirect offset (%s +/- %s)\n",
461 base_reg_name.c_str(),
462 offset_reg_name.c_str());
463 }
464 break;
465 case eInfoTypeRegisterToRegisterPlusOffset:
466 {
467 std::string base_reg_name;
468 std::string data_reg_name;
469 TranslateRegister (context.info.RegisterToRegisterPlusOffset.base_reg.kind,
470 context.info.RegisterToRegisterPlusOffset.base_reg.num,
471 base_reg_name);
472 TranslateRegister (context.info.RegisterToRegisterPlusOffset.data_reg.kind,
473 context.info.RegisterToRegisterPlusOffset.data_reg.num,
474 data_reg_name);
475 fprintf (stdout, " Info type: Register plus offset (%s +/- %lld) and data register (%s)\n",
476 base_reg_name.c_str(), context.info.RegisterToRegisterPlusOffset.offset,
477 data_reg_name.c_str());
478 }
479 break;
480 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
481 {
482 std::string base_reg_name;
483 std::string offset_reg_name;
484 std::string data_reg_name;
485 TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.base_reg.kind,
486 context.info.RegisterToRegisterPlusIndirectOffset.base_reg.num,
487 base_reg_name);
488 TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.offset_reg.kind,
489 context.info.RegisterToRegisterPlusIndirectOffset.offset_reg.num,
490 offset_reg_name);
491 TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.data_reg.kind,
492 context.info.RegisterToRegisterPlusIndirectOffset.data_reg.num,
493 data_reg_name);
494 fprintf (stdout, " Info type: Register plus indirect offset (%s +/- %s) and data register (%s)\n",
495 base_reg_name.c_str(), offset_reg_name.c_str(), data_reg_name.c_str());
496 }
497 break;
498
499 case eInfoTypeRegisterRegisterOperands:
500 {
501 std::string op1_reg_name;
502 std::string op2_reg_name;
503 TranslateRegister (context.info.RegisterRegisterOperands.operand1.kind,
504 context.info.RegisterRegisterOperands.operand1.num,
505 op1_reg_name);
506 TranslateRegister (context.info.RegisterRegisterOperands.operand2.kind,
507 context.info.RegisterRegisterOperands.operand2.num,
508 op2_reg_name);
509 fprintf (stdout, " Info type: Register operands for binary op (%s, %s)\n",
510 op1_reg_name.c_str(),
511 op2_reg_name.c_str());
512 }
513 break;
514 case eInfoTypeOffset:
515 fprintf (stdout, " Info type: signed offset (%lld)\n", context.info.signed_offset);
516 break;
517
518 case eInfoTypeRegister:
519 {
520 std::string reg_name;
521 TranslateRegister (context.info.reg.kind, context.info.reg.num, reg_name);
522 fprintf (stdout, " Info type: Register (%s)\n", reg_name.c_str());
523 }
524 break;
525
526 case eInfoTypeImmediate:
527 fprintf (stdout, " Info type: Immediate (%lld)\n", context.info.immediate);
528 break;
529
530 case eInfoTypeImmediateSigned:
531 fprintf (stdout, " Info type: Signed immediate (%lld)\n", context.info.signed_immediate);
532 break;
533
534 case eInfoTypeAddress:
535 fprintf (stdout, " Info type: Address (%p)\n", (void *) context.info.address);
536 break;
537
538 case eInfoTypeModeAndImmediate:
539 {
540 std::string mode_name;
541
542 if (context.info.ModeAndImmediate.mode == EmulateInstructionARM::eModeARM)
543 mode_name = "ARM";
544 else if (context.info.ModeAndImmediate.mode == EmulateInstructionARM::eModeThumb)
545 mode_name = "Thumb";
546 else
547 mode_name = "Unknown mode";
548
549 fprintf (stdout, " Info type: Mode (%s) and immediate (%d)\n", mode_name.c_str(),
550 context.info.ModeAndImmediate.data_value);
551 }
552 break;
553
554 case eInfoTypeModeAndImmediateSigned:
555 {
556 std::string mode_name;
557
558 if (context.info.ModeAndImmediateSigned.mode == EmulateInstructionARM::eModeARM)
559 mode_name = "ARM";
560 else if (context.info.ModeAndImmediateSigned.mode == EmulateInstructionARM::eModeThumb)
561 mode_name = "Thumb";
562 else
563 mode_name = "Unknown mode";
564
565 fprintf (stdout, " Info type: Mode (%s) and signed immediate (%d)\n", mode_name.c_str(),
566 context.info.ModeAndImmediateSigned.signed_data_value);
567 }
568 break;
569
570 case eInfoTypeMode:
571 {
572 std::string mode_name;
573
574 if (context.info.mode == EmulateInstructionARM::eModeARM)
575 mode_name = "ARM";
576 else if (context.info.mode == EmulateInstructionARM::eModeThumb)
577 mode_name = "Thumb";
578 else
579 mode_name = "Unknown mode";
580
581 fprintf (stdout, " Info type: Mode (%s)\n", mode_name.c_str());
582 }
583 break;
584
585 case eInfoTypeNoArgs:
586 fprintf (stdout, " Info type: no arguments\n");
587 break;
588
589 default:
590 break;
591 }
592}
593
594void
595EmulateInstruction::TranslateRegister (uint32_t kind, uint32_t num, std::string &name)
596{
597 if (kind == eRegisterKindDWARF)
598 {
599 if (num == 13) //dwarf_sp NOTE: This is ARM-SPECIFIC
600 name = "sp";
601 else if (num == 14) //dwarf_lr NOTE: This is ARM-SPECIFIC
602 name = "lr";
603 else if (num == 15) //dwarf_pc NOTE: This is ARM-SPECIFIC
604 name = "pc";
605 else if (num == 16) //dwarf_cpsr NOTE: This is ARM-SPECIFIC
606 name = "cpsr";
607 else
608 {
609 StreamString sstr;
610
611 sstr.Printf ("r%d", num);
612 name = sstr.GetData();
613 }
614
615 }
616 else if (kind == eRegisterKindGeneric)
617 {
618 if (num == LLDB_REGNUM_GENERIC_SP)
619 name = "sp";
620 else if (num == LLDB_REGNUM_GENERIC_FLAGS)
621 name = "cpsr";
622 else if (num == LLDB_REGNUM_GENERIC_PC)
623 name = "pc";
624 else if (num == LLDB_REGNUM_GENERIC_RA)
625 name = "lr";
626 else
627 {
628 StreamString sstr;
629
630 sstr.Printf ("r%d", num);
631 name = sstr.GetData();
632 }
633 }
634 else
635 {
636 StreamString sstr;
637
638 sstr.Printf ("r%d", num);
639 name = sstr.GetData();
640 }
641}
642
643
644