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