blob: d730a5321797c37d197a98c56c00e88082bf3586 [file] [log] [blame]
Greg Clayton64c84432011-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 Clayton17f5afe2011-02-05 02:56:16 +000010#include "lldb/Core/EmulateInstruction.h"
Greg Clayton64c84432011-01-21 22:02:52 +000011
Greg Clayton888a7332011-04-26 04:39:08 +000012#include "lldb/Core/Address.h"
Caroline Tice080bf612011-04-05 18:46:00 +000013#include "lldb/Core/DataBufferHeap.h"
Greg Clayton64c84432011-01-21 22:02:52 +000014#include "lldb/Core/DataExtractor.h"
Caroline Tice080bf612011-04-05 18:46:00 +000015#include "lldb/Core/Error.h"
Greg Clayton52fd9842011-02-02 02:24:04 +000016#include "lldb/Core/PluginManager.h"
Greg Clayton64c84432011-01-21 22:02:52 +000017#include "lldb/Core/StreamString.h"
Greg Claytoncd548032011-02-01 01:31:41 +000018#include "lldb/Host/Endian.h"
Caroline Tice080bf612011-04-05 18:46:00 +000019#include "lldb/Target/Process.h"
20#include "lldb/Target/RegisterContext.h"
Greg Clayton888a7332011-04-26 04:39:08 +000021#include "lldb/Target/Target.h"
Caroline Tice080bf612011-04-05 18:46:00 +000022#include "lldb/Target/Thread.h"
23
24#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
25
Greg Clayton64c84432011-01-21 22:02:52 +000026using namespace lldb;
27using namespace lldb_private;
28
Greg Clayton52fd9842011-02-02 02:24:04 +000029EmulateInstruction*
Greg Clayton888a7332011-04-26 04:39:08 +000030EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
Greg Clayton52fd9842011-02-02 02:24:04 +000031{
32 EmulateInstructionCreateInstance create_callback = NULL;
33 if (plugin_name)
34 {
35 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
36 if (create_callback)
37 {
Greg Clayton888a7332011-04-26 04:39:08 +000038 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Tice080bf612011-04-05 18:46:00 +000039 if (emulate_insn_ptr)
40 return emulate_insn_ptr;
Greg Clayton52fd9842011-02-02 02:24:04 +000041 }
42 }
43 else
44 {
45 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
46 {
Greg Clayton888a7332011-04-26 04:39:08 +000047 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Tice080bf612011-04-05 18:46:00 +000048 if (emulate_insn_ptr)
49 return emulate_insn_ptr;
Greg Clayton52fd9842011-02-02 02:24:04 +000050 }
51 }
52 return NULL;
53}
Greg Clayton64c84432011-01-21 22:02:52 +000054
Greg Clayton888a7332011-04-26 04:39:08 +000055EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
Caroline Tice080bf612011-04-05 18:46:00 +000056 m_arch (arch),
57 m_baton (NULL),
58 m_read_mem_callback (&ReadMemoryDefault),
59 m_write_mem_callback (&WriteMemoryDefault),
60 m_read_reg_callback (&ReadRegisterDefault),
61 m_write_reg_callback (&WriteRegisterDefault),
Greg Clayton888a7332011-04-26 04:39:08 +000062 m_opcode_pc (LLDB_INVALID_ADDRESS)
Caroline Tice080bf612011-04-05 18:46:00 +000063{
64 ::memset (&m_opcode, 0, sizeof (m_opcode));
65}
66
Greg Clayton64c84432011-01-21 22:02:52 +000067uint64_t
68EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
69{
70 uint64_t uval64 = 0;
Greg Clayton888a7332011-04-26 04:39:08 +000071 bool success = m_read_reg_callback (this, m_baton, reg_kind, reg_num, uval64);
Greg Clayton64c84432011-01-21 22:02:52 +000072 if (success_ptr)
73 *success_ptr = success;
74 if (!success)
75 uval64 = fail_value;
76 return uval64;
77}
78
79bool
80EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
81{
Greg Clayton888a7332011-04-26 04:39:08 +000082 return m_write_reg_callback (this, m_baton, context, reg_kind, reg_num, reg_value);
Greg Clayton64c84432011-01-21 22:02:52 +000083}
84
85uint64_t
86EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
87{
88 uint64_t uval64 = 0;
89 bool success = false;
90 if (byte_size <= 8)
91 {
92 uint8_t buf[sizeof(uint64_t)];
Greg Clayton888a7332011-04-26 04:39:08 +000093 size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
Greg Clayton64c84432011-01-21 22:02:52 +000094 if (bytes_read == byte_size)
95 {
96 uint32_t offset = 0;
Greg Clayton888a7332011-04-26 04:39:08 +000097 DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
Greg Clayton64c84432011-01-21 22:02:52 +000098 uval64 = data.GetMaxU64 (&offset, byte_size);
99 success = true;
100 }
101 }
102
103 if (success_ptr)
104 *success_ptr = success;
105
106 if (!success)
107 uval64 = fail_value;
108 return uval64;
109}
110
111
112bool
113EmulateInstruction::WriteMemoryUnsigned (const Context &context,
114 lldb::addr_t addr,
115 uint64_t uval,
116 size_t uval_byte_size)
117{
118 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
119 strm.PutMaxHex64 (uval, uval_byte_size);
120
Greg Clayton888a7332011-04-26 04:39:08 +0000121 size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
Greg Clayton64c84432011-01-21 22:02:52 +0000122 if (bytes_written == uval_byte_size)
123 return true;
124 return false;
125}
Caroline Tice080bf612011-04-05 18:46:00 +0000126
127
128void
129EmulateInstruction::SetBaton (void *baton)
130{
131 m_baton = baton;
132}
133
134void
135EmulateInstruction::SetCallbacks (ReadMemory read_mem_callback,
136 WriteMemory write_mem_callback,
137 ReadRegister read_reg_callback,
138 WriteRegister write_reg_callback)
139{
140 m_read_mem_callback = read_mem_callback;
141 m_write_mem_callback = write_mem_callback;
142 m_read_reg_callback = read_reg_callback;
143 m_write_reg_callback = write_reg_callback;
144}
145
146void
147EmulateInstruction::SetReadMemCallback (ReadMemory read_mem_callback)
148{
149 m_read_mem_callback = read_mem_callback;
150}
151
152
153void
154EmulateInstruction::SetWriteMemCallback (WriteMemory write_mem_callback)
155{
156 m_write_mem_callback = write_mem_callback;
157}
158
159
160void
161EmulateInstruction::SetReadRegCallback (ReadRegister read_reg_callback)
162{
163 m_read_reg_callback = read_reg_callback;
164}
165
166
167void
168EmulateInstruction::SetWriteRegCallback (WriteRegister write_reg_callback)
169{
170 m_write_reg_callback = write_reg_callback;
171}
172
173
174
175//
176// Read & Write Memory and Registers callback functions.
177//
178
179size_t
Greg Clayton888a7332011-04-26 04:39:08 +0000180EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
181 void *baton,
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000182 const Context &context,
183 lldb::addr_t addr,
184 void *dst,
185 size_t length)
Caroline Tice080bf612011-04-05 18:46:00 +0000186{
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000187 if (!baton)
Caroline Tice080bf612011-04-05 18:46:00 +0000188 return 0;
189
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000190
191 StackFrame *frame = (StackFrame *) baton;
192
Caroline Tice080bf612011-04-05 18:46:00 +0000193 DataBufferSP data_sp (new DataBufferHeap (length, '\0'));
194 Error error;
195
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000196 size_t bytes_read = frame->GetThread().GetProcess().ReadMemory (addr, data_sp->GetBytes(), data_sp->GetByteSize(),
197 error);
Caroline Tice080bf612011-04-05 18:46:00 +0000198
199 if (bytes_read > 0)
200 ((DataBufferHeap *) data_sp.get())->CopyData (dst, length);
201
202 return bytes_read;
203}
204
205size_t
Greg Clayton888a7332011-04-26 04:39:08 +0000206EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
207 void *baton,
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000208 const Context &context,
209 lldb::addr_t addr,
210 const void *dst,
211 size_t length)
Caroline Tice080bf612011-04-05 18:46:00 +0000212{
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000213 if (!baton)
Caroline Tice080bf612011-04-05 18:46:00 +0000214 return 0;
215
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000216 StackFrame *frame = (StackFrame *) baton;
217
Caroline Tice080bf612011-04-05 18:46:00 +0000218 lldb::DataBufferSP data_sp (new DataBufferHeap (dst, length));
219 if (data_sp)
220 {
221 length = data_sp->GetByteSize();
222 if (length > 0)
223 {
224 Error error;
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000225 size_t bytes_written = frame->GetThread().GetProcess().WriteMemory (addr, data_sp->GetBytes(), length,
226 error);
Caroline Tice080bf612011-04-05 18:46:00 +0000227
228 return bytes_written;
229 }
230 }
231
232 return 0;
233}
234
235bool
Greg Clayton888a7332011-04-26 04:39:08 +0000236EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
237 void *baton,
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000238 uint32_t reg_kind,
239 uint32_t reg_num,
240 uint64_t &reg_value)
Caroline Tice080bf612011-04-05 18:46:00 +0000241{
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000242 if (!baton)
Caroline Tice080bf612011-04-05 18:46:00 +0000243 return false;
244
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000245 StackFrame *frame = (StackFrame *) baton;
246 RegisterContext *reg_context = frame->GetRegisterContext().get();
Caroline Tice080bf612011-04-05 18:46:00 +0000247 Scalar value;
248
Caroline Tice21f0d4b2011-04-06 23:30:18 +0000249 uint32_t internal_reg_num = reg_context->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
Caroline Tice080bf612011-04-05 18:46:00 +0000250
Caroline Tice21f0d4b2011-04-06 23:30:18 +0000251 if (internal_reg_num == LLDB_INVALID_REGNUM)
252 return false;
253
254 if (reg_context->ReadRegisterValue (internal_reg_num, value))
Caroline Tice080bf612011-04-05 18:46:00 +0000255 {
256 reg_value = value.GetRawBits64 (0);
257 return true;
258 }
259
260 return false;
261}
262
263bool
Greg Clayton888a7332011-04-26 04:39:08 +0000264EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
265 void *baton,
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000266 const Context &context,
267 uint32_t reg_kind,
268 uint32_t reg_num,
269 uint64_t reg_value)
Caroline Tice080bf612011-04-05 18:46:00 +0000270{
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000271 if (!baton)
272 return false;
273
274 StackFrame *frame = (StackFrame *) baton;
275 RegisterContext *reg_context = frame->GetRegisterContext().get();
Caroline Tice080bf612011-04-05 18:46:00 +0000276 Scalar value (reg_value);
277
Caroline Tice21f0d4b2011-04-06 23:30:18 +0000278 uint32_t internal_reg_num = reg_context->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
279 if (internal_reg_num != LLDB_INVALID_REGNUM)
280 return reg_context->WriteRegisterValue (internal_reg_num, value);
281 else
282 return false;
Caroline Tice080bf612011-04-05 18:46:00 +0000283}
284
285size_t
Greg Clayton888a7332011-04-26 04:39:08 +0000286EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
287 void *baton,
Caroline Tice080bf612011-04-05 18:46:00 +0000288 const Context &context,
289 lldb::addr_t addr,
290 void *dst,
291 size_t length)
292{
293 PrintContext ("Read from memory", context);
Greg Claytonf15996e2011-04-07 22:46:35 +0000294 fprintf (stdout, " Read from Memory (address = %p, length = %d)\n",(void *) addr, (uint32_t) length);
Caroline Tice080bf612011-04-05 18:46:00 +0000295
296 *((uint64_t *) dst) = 0xdeadbeef;
297 return length;
298}
299
300size_t
Greg Clayton888a7332011-04-26 04:39:08 +0000301EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
302 void *baton,
Caroline Tice080bf612011-04-05 18:46:00 +0000303 const Context &context,
304 lldb::addr_t addr,
305 const void *dst,
306 size_t length)
307{
308 PrintContext ("Write to memory", context);
Greg Claytonf15996e2011-04-07 22:46:35 +0000309 fprintf (stdout, " Write to Memory (address = %p, length = %d)\n", (void *) addr, (uint32_t) length);
Caroline Tice080bf612011-04-05 18:46:00 +0000310 return length;
311}
312
313bool
Greg Clayton888a7332011-04-26 04:39:08 +0000314EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
315 void *baton,
Caroline Tice080bf612011-04-05 18:46:00 +0000316 uint32_t reg_kind,
317 uint32_t reg_num,
318 uint64_t &reg_value)
319{
320 std::string reg_name;
321 TranslateRegister (reg_kind, reg_num, reg_name);
322 fprintf (stdout, " Read Register (%s)\n", reg_name.c_str());
323
324 reg_value = 24;
325 return true;
326}
327
328bool
Greg Clayton888a7332011-04-26 04:39:08 +0000329EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
330 void *baton,
Caroline Tice080bf612011-04-05 18:46:00 +0000331 const Context &context,
332 uint32_t reg_kind,
333 uint32_t reg_num,
334 uint64_t reg_value)
335{
336 PrintContext ("Write to register", context);
337 std::string reg_name;
338 TranslateRegister (reg_kind, reg_num, reg_name);
339 fprintf (stdout, " Write to Register (%s), value = 0x%llx\n", reg_name.c_str(), reg_value);
340 return true;
341}
342
343void
344EmulateInstruction::PrintContext (const char *context_type, const Context &context)
345{
346 switch (context.type)
347 {
348 case eContextReadOpcode:
349 fprintf (stdout, " %s context: Reading an Opcode\n", context_type);
350 break;
351
352 case eContextImmediate:
353 fprintf (stdout, " %s context: Immediate\n", context_type);
354 break;
355
356 case eContextPushRegisterOnStack:
357 fprintf (stdout, " %s context: Pushing a register onto the stack.\n", context_type);
358 break;
359
360 case eContextPopRegisterOffStack:
361 fprintf (stdout, " %s context: Popping a register off the stack.\n", context_type);
362 break;
363
364 case eContextAdjustStackPointer:
365 fprintf (stdout, " %s context: Adjusting the stack pointer.\n", context_type);
366 break;
367
368 case eContextAdjustBaseRegister:
369 fprintf (stdout, " %s context: Adjusting (writing value back to) a base register.\n", context_type);
370 break;
371
372 case eContextRegisterPlusOffset:
373 fprintf (stdout, " %s context: Register plus offset\n", context_type);
374 break;
375
376 case eContextRegisterStore:
377 fprintf (stdout, " %s context: Storing a register.\n", context_type);
378 break;
379
380 case eContextRegisterLoad:
381 fprintf (stdout, " %s context: Loading a register.\n", context_type);
382 break;
383
384 case eContextRelativeBranchImmediate:
385 fprintf (stdout, " %s context: Relative branch immediate\n", context_type);
386 break;
387
388 case eContextAbsoluteBranchRegister:
389 fprintf (stdout, " %s context: Absolute branch register\n", context_type);
390 break;
391
392 case eContextSupervisorCall:
393 fprintf (stdout, " %s context: Performing a supervisor call.\n", context_type);
394 break;
395
396 case eContextTableBranchReadMemory:
397 fprintf (stdout, " %s context: Table branch read memory\n", context_type);
398 break;
399
400 case eContextWriteRegisterRandomBits:
401 fprintf (stdout, " %s context: Write random bits to a register\n", context_type);
402 break;
403
404 case eContextWriteMemoryRandomBits:
405 fprintf (stdout, " %s context: Write random bits to a memory address\n", context_type);
406 break;
407
408 case eContextMultiplication:
409 fprintf (stdout, " %s context: Performing a multiplication\n", context_type);
410 break;
411
412 case eContextAddition:
413 fprintf (stdout, " %s context: Performing an addition\n", context_type);
414 break;
415
416 case eContextReturnFromException:
417 fprintf (stdout, " %s context: Returning from an exception\n", context_type);
418 break;
419
420 default:
421 fprintf (stdout, " %s context: Unrecognized context.\n", context_type);
422 break;
423 }
424
425 switch (context.info_type)
426 {
427 case eInfoTypeRegisterPlusOffset:
428 {
429 std::string reg_name;
430 TranslateRegister (context.info.RegisterPlusOffset.reg.kind,
431 context.info.RegisterPlusOffset.reg.num,
432 reg_name);
433 fprintf (stdout, " Info type: Register plus offset (%s +/- %lld)\n", reg_name.c_str(),
434 context.info.RegisterPlusOffset.signed_offset);
435 }
436 break;
437 case eInfoTypeRegisterPlusIndirectOffset:
438 {
439 std::string base_reg_name;
440 std::string offset_reg_name;
441 TranslateRegister (context.info.RegisterPlusIndirectOffset.base_reg.kind,
442 context.info.RegisterPlusIndirectOffset.base_reg.num,
443 base_reg_name);
444 TranslateRegister (context.info.RegisterPlusIndirectOffset.offset_reg.kind,
445 context.info.RegisterPlusIndirectOffset.offset_reg.num,
446 offset_reg_name);
447 fprintf (stdout, " Info type: Register plus indirect offset (%s +/- %s)\n",
448 base_reg_name.c_str(),
449 offset_reg_name.c_str());
450 }
451 break;
452 case eInfoTypeRegisterToRegisterPlusOffset:
453 {
454 std::string base_reg_name;
455 std::string data_reg_name;
456 TranslateRegister (context.info.RegisterToRegisterPlusOffset.base_reg.kind,
457 context.info.RegisterToRegisterPlusOffset.base_reg.num,
458 base_reg_name);
459 TranslateRegister (context.info.RegisterToRegisterPlusOffset.data_reg.kind,
460 context.info.RegisterToRegisterPlusOffset.data_reg.num,
461 data_reg_name);
462 fprintf (stdout, " Info type: Register plus offset (%s +/- %lld) and data register (%s)\n",
463 base_reg_name.c_str(), context.info.RegisterToRegisterPlusOffset.offset,
464 data_reg_name.c_str());
465 }
466 break;
467 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
468 {
469 std::string base_reg_name;
470 std::string offset_reg_name;
471 std::string data_reg_name;
472 TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.base_reg.kind,
473 context.info.RegisterToRegisterPlusIndirectOffset.base_reg.num,
474 base_reg_name);
475 TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.offset_reg.kind,
476 context.info.RegisterToRegisterPlusIndirectOffset.offset_reg.num,
477 offset_reg_name);
478 TranslateRegister (context.info.RegisterToRegisterPlusIndirectOffset.data_reg.kind,
479 context.info.RegisterToRegisterPlusIndirectOffset.data_reg.num,
480 data_reg_name);
481 fprintf (stdout, " Info type: Register plus indirect offset (%s +/- %s) and data register (%s)\n",
482 base_reg_name.c_str(), offset_reg_name.c_str(), data_reg_name.c_str());
483 }
484 break;
485
486 case eInfoTypeRegisterRegisterOperands:
487 {
488 std::string op1_reg_name;
489 std::string op2_reg_name;
490 TranslateRegister (context.info.RegisterRegisterOperands.operand1.kind,
491 context.info.RegisterRegisterOperands.operand1.num,
492 op1_reg_name);
493 TranslateRegister (context.info.RegisterRegisterOperands.operand2.kind,
494 context.info.RegisterRegisterOperands.operand2.num,
495 op2_reg_name);
496 fprintf (stdout, " Info type: Register operands for binary op (%s, %s)\n",
497 op1_reg_name.c_str(),
498 op2_reg_name.c_str());
499 }
500 break;
501 case eInfoTypeOffset:
502 fprintf (stdout, " Info type: signed offset (%lld)\n", context.info.signed_offset);
503 break;
504
505 case eInfoTypeRegister:
506 {
507 std::string reg_name;
508 TranslateRegister (context.info.reg.kind, context.info.reg.num, reg_name);
509 fprintf (stdout, " Info type: Register (%s)\n", reg_name.c_str());
510 }
511 break;
512
513 case eInfoTypeImmediate:
514 fprintf (stdout, " Info type: Immediate (%lld)\n", context.info.immediate);
515 break;
516
517 case eInfoTypeImmediateSigned:
518 fprintf (stdout, " Info type: Signed immediate (%lld)\n", context.info.signed_immediate);
519 break;
520
521 case eInfoTypeAddress:
522 fprintf (stdout, " Info type: Address (%p)\n", (void *) context.info.address);
523 break;
524
525 case eInfoTypeModeAndImmediate:
526 {
527 std::string mode_name;
528
529 if (context.info.ModeAndImmediate.mode == EmulateInstructionARM::eModeARM)
530 mode_name = "ARM";
531 else if (context.info.ModeAndImmediate.mode == EmulateInstructionARM::eModeThumb)
532 mode_name = "Thumb";
533 else
534 mode_name = "Unknown mode";
535
536 fprintf (stdout, " Info type: Mode (%s) and immediate (%d)\n", mode_name.c_str(),
537 context.info.ModeAndImmediate.data_value);
538 }
539 break;
540
541 case eInfoTypeModeAndImmediateSigned:
542 {
543 std::string mode_name;
544
545 if (context.info.ModeAndImmediateSigned.mode == EmulateInstructionARM::eModeARM)
546 mode_name = "ARM";
547 else if (context.info.ModeAndImmediateSigned.mode == EmulateInstructionARM::eModeThumb)
548 mode_name = "Thumb";
549 else
550 mode_name = "Unknown mode";
551
552 fprintf (stdout, " Info type: Mode (%s) and signed immediate (%d)\n", mode_name.c_str(),
553 context.info.ModeAndImmediateSigned.signed_data_value);
554 }
555 break;
556
557 case eInfoTypeMode:
558 {
559 std::string mode_name;
560
561 if (context.info.mode == EmulateInstructionARM::eModeARM)
562 mode_name = "ARM";
563 else if (context.info.mode == EmulateInstructionARM::eModeThumb)
564 mode_name = "Thumb";
565 else
566 mode_name = "Unknown mode";
567
568 fprintf (stdout, " Info type: Mode (%s)\n", mode_name.c_str());
569 }
570 break;
571
572 case eInfoTypeNoArgs:
573 fprintf (stdout, " Info type: no arguments\n");
574 break;
575
576 default:
577 break;
578 }
579}
580
Greg Clayton888a7332011-04-26 04:39:08 +0000581bool
582EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
Caroline Tice080bf612011-04-05 18:46:00 +0000583{
Greg Clayton888a7332011-04-26 04:39:08 +0000584 m_opcode = opcode;
585 m_opcode_pc = LLDB_INVALID_ADDRESS;
586 if (inst_addr.IsValid())
Caroline Tice080bf612011-04-05 18:46:00 +0000587 {
Greg Clayton888a7332011-04-26 04:39:08 +0000588 if (target)
589 m_opcode_pc = inst_addr.GetLoadAddress (target);
590 if (m_opcode_pc == LLDB_INVALID_ADDRESS)
591 m_opcode_pc = inst_addr.GetFileAddress ();
Caroline Tice080bf612011-04-05 18:46:00 +0000592 }
Greg Clayton888a7332011-04-26 04:39:08 +0000593 return true;
Caroline Tice080bf612011-04-05 18:46:00 +0000594}
595
596
Greg Clayton888a7332011-04-26 04:39:08 +0000597const char *
598EmulateInstruction::TranslateRegister (uint32_t kind, uint32_t num, std::string &name)
599{
600 if (kind == eRegisterKindGeneric)
601 {
602 switch (num)
603 {
604 case LLDB_REGNUM_GENERIC_PC: name = "pc"; break;
605 case LLDB_REGNUM_GENERIC_SP: name = "sp"; break;
606 case LLDB_REGNUM_GENERIC_FP: name = "fp"; break;
607 case LLDB_REGNUM_GENERIC_RA: name = "ra"; break;
608 case LLDB_REGNUM_GENERIC_FLAGS: name = "flags"; break;
609 default: name.clear(); break;
610 }
611 if (!name.empty())
612 return name.c_str();
613 }
614 const char *kind_cstr = NULL;
615
616 switch (kind)
617 {
618 case eRegisterKindGCC: // the register numbers seen in eh_frame
619 kind_cstr = "gcc";
620 break;
621
622 case eRegisterKindDWARF: // the register numbers seen DWARF
623 kind_cstr = "dwarf";
624 break;
625
626 case eRegisterKindGeneric: // insn ptr reg, stack ptr reg, etc not specific to any particular target
627 kind_cstr = "generic";
628 break;
629
630 case eRegisterKindGDB: // the register numbers gdb uses (matches stabs numbers?)
631 kind_cstr = "gdb";
632 break;
633
634 case eRegisterKindLLDB: // lldb's internal register numbers
635 kind_cstr = "lldb";
636 break;
637 }
638
639
640 StreamString sstr;
641 sstr.Printf ("%s(%u)", kind_cstr, num);
642 name.swap (sstr.GetString());
643 return name.c_str();
644}
645
Caroline Tice080bf612011-04-05 18:46:00 +0000646