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/Address.h"
13#include "lldb/Core/DataExtractor.h"
14#include "lldb/Core/Error.h"
15#include "lldb/Core/PluginManager.h"
16#include "lldb/Core/RegisterValue.h"
17#include "lldb/Core/StreamFile.h"
18#include "lldb/Core/StreamString.h"
19#include "lldb/Host/Endian.h"
20#include "lldb/Symbol/UnwindPlan.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/RegisterContext.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Target/Thread.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29EmulateInstruction*
30EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
31{
32    EmulateInstructionCreateInstance create_callback = NULL;
33    if (plugin_name)
34    {
35        ConstString const_plugin_name (plugin_name);
36        create_callback  = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name);
37        if (create_callback)
38        {
39           	EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
40            if (emulate_insn_ptr)
41                return emulate_insn_ptr;
42        }
43    }
44    else
45    {
46        for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
47        {
48            EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
49            if (emulate_insn_ptr)
50                return emulate_insn_ptr;
51        }
52    }
53    return NULL;
54}
55
56EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
57    m_arch (arch),
58    m_baton (NULL),
59    m_read_mem_callback (&ReadMemoryDefault),
60    m_write_mem_callback (&WriteMemoryDefault),
61    m_read_reg_callback (&ReadRegisterDefault),
62    m_write_reg_callback (&WriteRegisterDefault),
63    m_addr (LLDB_INVALID_ADDRESS)
64{
65    ::memset (&m_opcode, 0, sizeof (m_opcode));
66}
67
68
69bool
70EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
71{
72    if (m_read_reg_callback)
73        return m_read_reg_callback (this, m_baton, reg_info, reg_value);
74    return false;
75}
76
77bool
78EmulateInstruction::ReadRegister (uint32_t reg_kind, uint32_t reg_num, RegisterValue& reg_value)
79{
80    RegisterInfo reg_info;
81    if (GetRegisterInfo(reg_kind, reg_num, reg_info))
82        return ReadRegister (&reg_info, reg_value);
83    return false;
84}
85
86uint64_t
87EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind,
88                                          uint32_t reg_num,
89                                          uint64_t fail_value,
90                                          bool *success_ptr)
91{
92    RegisterValue reg_value;
93    if (ReadRegister (reg_kind, reg_num, reg_value))
94        return reg_value.GetAsUInt64(fail_value, success_ptr);
95    if (success_ptr)
96        *success_ptr = false;
97    return fail_value;
98}
99
100uint64_t
101EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
102                                          uint64_t fail_value,
103                                          bool *success_ptr)
104{
105    RegisterValue reg_value;
106    if (ReadRegister (reg_info, reg_value))
107        return reg_value.GetAsUInt64(fail_value, success_ptr);
108    if (success_ptr)
109        *success_ptr = false;
110    return fail_value;
111}
112
113bool
114EmulateInstruction::WriteRegister (const Context &context,
115                                   const RegisterInfo *reg_info,
116                                   const RegisterValue& reg_value)
117{
118    if (m_write_reg_callback)
119        return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
120    return false;
121}
122
123bool
124EmulateInstruction::WriteRegister (const Context &context,
125                                   uint32_t reg_kind,
126                                   uint32_t reg_num,
127                                   const RegisterValue& reg_value)
128{
129    RegisterInfo reg_info;
130    if (GetRegisterInfo(reg_kind, reg_num, reg_info))
131        return WriteRegister (context, &reg_info, reg_value);
132    return false;
133}
134
135
136bool
137EmulateInstruction::WriteRegisterUnsigned (const Context &context,
138                                           uint32_t reg_kind,
139                                           uint32_t reg_num,
140                                           uint64_t uint_value)
141{
142
143    RegisterInfo reg_info;
144    if (GetRegisterInfo(reg_kind, reg_num, reg_info))
145    {
146        RegisterValue reg_value;
147        if (reg_value.SetUInt(uint_value, reg_info.byte_size))
148            return WriteRegister (context, &reg_info, reg_value);
149    }
150    return false;
151}
152
153bool
154EmulateInstruction::WriteRegisterUnsigned (const Context &context,
155                                           const RegisterInfo *reg_info,
156                                           uint64_t uint_value)
157{
158
159    if (reg_info)
160    {
161        RegisterValue reg_value;
162        if (reg_value.SetUInt(uint_value, reg_info->byte_size))
163                return WriteRegister (context, reg_info, reg_value);
164    }
165    return false;
166}
167
168size_t
169EmulateInstruction::ReadMemory (const Context &context,
170                                lldb::addr_t addr,
171                                void *dst,
172                                size_t dst_len)
173{
174    if (m_read_mem_callback)
175        return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
176    return false;
177}
178
179uint64_t
180EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
181{
182    uint64_t uval64 = 0;
183    bool success = false;
184    if (byte_size <= 8)
185    {
186        uint8_t buf[sizeof(uint64_t)];
187        size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
188        if (bytes_read == byte_size)
189        {
190            lldb::offset_t offset = 0;
191            DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
192            uval64 = data.GetMaxU64 (&offset, byte_size);
193            success = true;
194        }
195    }
196
197    if (success_ptr)
198        *success_ptr = success;
199
200    if (!success)
201        uval64 = fail_value;
202    return uval64;
203}
204
205
206bool
207EmulateInstruction::WriteMemoryUnsigned (const Context &context,
208                                         lldb::addr_t addr,
209                                         uint64_t uval,
210                                         size_t uval_byte_size)
211{
212    StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
213    strm.PutMaxHex64 (uval, uval_byte_size);
214
215    size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
216    if (bytes_written == uval_byte_size)
217        return true;
218    return false;
219}
220
221bool
222EmulateInstruction::WriteMemory (const Context &context,
223                                 lldb::addr_t addr,
224                                 const void *src,
225                                 size_t src_len)
226{
227    if (m_write_mem_callback)
228        return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
229    return false;
230}
231
232
233void
234EmulateInstruction::SetBaton (void *baton)
235{
236    m_baton = baton;
237}
238
239void
240EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
241                                  WriteMemoryCallback write_mem_callback,
242                                  ReadRegisterCallback read_reg_callback,
243                                  WriteRegisterCallback write_reg_callback)
244{
245    m_read_mem_callback = read_mem_callback;
246    m_write_mem_callback = write_mem_callback;
247    m_read_reg_callback = read_reg_callback;
248    m_write_reg_callback = write_reg_callback;
249}
250
251void
252EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
253{
254    m_read_mem_callback = read_mem_callback;
255}
256
257
258void
259EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
260{
261    m_write_mem_callback = write_mem_callback;
262}
263
264
265void
266EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
267{
268    m_read_reg_callback = read_reg_callback;
269}
270
271
272void
273EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
274{
275    m_write_reg_callback = write_reg_callback;
276}
277
278
279
280//
281//  Read & Write Memory and Registers callback functions.
282//
283
284size_t
285EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
286                                     void *baton,
287                                     const Context &context,
288                                     lldb::addr_t addr,
289                                     void *dst,
290                                     size_t dst_len)
291{
292    if (!baton || dst == NULL || dst_len == 0)
293        return 0;
294
295    StackFrame *frame = (StackFrame *) baton;
296
297    ProcessSP process_sp (frame->CalculateProcess());
298    if (process_sp)
299    {
300        Error error;
301        return process_sp->ReadMemory (addr, dst, dst_len, error);
302    }
303    return 0;
304}
305
306size_t
307EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
308                                      void *baton,
309                                      const Context &context,
310                                      lldb::addr_t addr,
311                                      const void *src,
312                                      size_t src_len)
313{
314    if (!baton || src == NULL || src_len == 0)
315        return 0;
316
317    StackFrame *frame = (StackFrame *) baton;
318
319    ProcessSP process_sp (frame->CalculateProcess());
320    if (process_sp)
321    {
322        Error error;
323        return process_sp->WriteMemory (addr, src, src_len, error);
324    }
325
326    return 0;
327}
328
329bool
330EmulateInstruction::ReadRegisterFrame  (EmulateInstruction *instruction,
331                                        void *baton,
332                                        const RegisterInfo *reg_info,
333                                        RegisterValue &reg_value)
334{
335    if (!baton)
336        return false;
337
338    StackFrame *frame = (StackFrame *) baton;
339    return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
340}
341
342bool
343EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
344                                        void *baton,
345                                        const Context &context,
346                                        const RegisterInfo *reg_info,
347                                        const RegisterValue &reg_value)
348{
349    if (!baton)
350        return false;
351
352    StackFrame *frame = (StackFrame *) baton;
353    return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
354}
355
356size_t
357EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
358                                       void *baton,
359                                       const Context &context,
360                                       lldb::addr_t addr,
361                                       void *dst,
362                                       size_t length)
363{
364    StreamFile strm (stdout, false);
365    strm.Printf ("    Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
366    context.Dump (strm, instruction);
367    strm.EOL();
368    *((uint64_t *) dst) = 0xdeadbeef;
369    return length;
370}
371
372size_t
373EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
374                                        void *baton,
375                                        const Context &context,
376                                        lldb::addr_t addr,
377                                        const void *dst,
378                                        size_t length)
379{
380    StreamFile strm (stdout, false);
381    strm.Printf ("    Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
382    context.Dump (strm, instruction);
383    strm.EOL();
384    return length;
385}
386
387bool
388EmulateInstruction::ReadRegisterDefault  (EmulateInstruction *instruction,
389                                          void *baton,
390                                          const RegisterInfo *reg_info,
391                                          RegisterValue &reg_value)
392{
393    StreamFile strm (stdout, false);
394    strm.Printf ("  Read Register (%s)\n", reg_info->name);
395    uint32_t reg_kind, reg_num;
396    if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
397        reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
398    else
399        reg_value.SetUInt64(0);
400
401    return true;
402}
403
404bool
405EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
406                                          void *baton,
407                                          const Context &context,
408                                          const RegisterInfo *reg_info,
409                                          const RegisterValue &reg_value)
410{
411    StreamFile strm (stdout, false);
412    strm.Printf ("    Write to Register (name = %s, value = " , reg_info->name);
413    reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
414    strm.PutCString (", context = ");
415    context.Dump (strm, instruction);
416    strm.EOL();
417    return true;
418}
419
420void
421EmulateInstruction::Context::Dump (Stream &strm,
422                                   EmulateInstruction *instruction) const
423{
424    switch (type)
425    {
426        case eContextReadOpcode:
427            strm.PutCString ("reading opcode");
428            break;
429
430        case eContextImmediate:
431            strm.PutCString ("immediate");
432            break;
433
434        case eContextPushRegisterOnStack:
435            strm.PutCString ("push register");
436            break;
437
438        case eContextPopRegisterOffStack:
439            strm.PutCString ("pop register");
440            break;
441
442        case eContextAdjustStackPointer:
443            strm.PutCString ("adjust sp");
444            break;
445
446        case eContextSetFramePointer:
447            strm.PutCString ("set frame pointer");
448            break;
449
450        case eContextAdjustBaseRegister:
451            strm.PutCString ("adjusting (writing value back to) a base register");
452            break;
453
454        case eContextRegisterPlusOffset:
455            strm.PutCString ("register + offset");
456            break;
457
458        case eContextRegisterStore:
459            strm.PutCString ("store register");
460            break;
461
462        case eContextRegisterLoad:
463            strm.PutCString ("load register");
464            break;
465
466        case eContextRelativeBranchImmediate:
467            strm.PutCString ("relative branch immediate");
468            break;
469
470        case eContextAbsoluteBranchRegister:
471            strm.PutCString ("absolute branch register");
472            break;
473
474        case eContextSupervisorCall:
475            strm.PutCString ("supervisor call");
476            break;
477
478        case eContextTableBranchReadMemory:
479            strm.PutCString ("table branch read memory");
480            break;
481
482        case eContextWriteRegisterRandomBits:
483            strm.PutCString ("write random bits to a register");
484            break;
485
486        case eContextWriteMemoryRandomBits:
487            strm.PutCString ("write random bits to a memory address");
488            break;
489
490        case eContextArithmetic:
491            strm.PutCString ("arithmetic");
492            break;
493
494        case eContextReturnFromException:
495            strm.PutCString ("return from exception");
496            break;
497
498        default:
499            strm.PutCString ("unrecognized context.");
500            break;
501    }
502
503    switch (info_type)
504    {
505    case eInfoTypeRegisterPlusOffset:
506        {
507            strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")",
508                         info.RegisterPlusOffset.reg.name,
509                         info.RegisterPlusOffset.signed_offset);
510        }
511        break;
512
513    case eInfoTypeRegisterPlusIndirectOffset:
514        {
515            strm.Printf (" (reg_plus_reg = %s + %s)",
516                         info.RegisterPlusIndirectOffset.base_reg.name,
517                         info.RegisterPlusIndirectOffset.offset_reg.name);
518        }
519        break;
520
521    case eInfoTypeRegisterToRegisterPlusOffset:
522        {
523            strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
524                         info.RegisterToRegisterPlusOffset.base_reg.name,
525                         info.RegisterToRegisterPlusOffset.offset,
526                         info.RegisterToRegisterPlusOffset.data_reg.name);
527        }
528        break;
529
530    case eInfoTypeRegisterToRegisterPlusIndirectOffset:
531        {
532            strm.Printf (" (base_and_reg_offset = %s + %s, data_reg = %s)",
533                         info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
534                         info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
535                         info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
536        }
537        break;
538
539    case eInfoTypeRegisterRegisterOperands:
540        {
541            strm.Printf (" (register to register binary op: %s and %s)",
542                         info.RegisterRegisterOperands.operand1.name,
543                         info.RegisterRegisterOperands.operand2.name);
544        }
545        break;
546
547    case eInfoTypeOffset:
548        strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
549        break;
550
551    case eInfoTypeRegister:
552        strm.Printf (" (reg = %s)", info.reg.name);
553        break;
554
555    case eInfoTypeImmediate:
556        strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
557                     info.unsigned_immediate,
558                     info.unsigned_immediate);
559        break;
560
561    case eInfoTypeImmediateSigned:
562        strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
563                     info.signed_immediate,
564                     info.signed_immediate);
565        break;
566
567    case eInfoTypeAddress:
568        strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
569        break;
570
571    case eInfoTypeISAAndImmediate:
572        strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
573                     info.ISAAndImmediate.isa,
574                     info.ISAAndImmediate.unsigned_data32,
575                     info.ISAAndImmediate.unsigned_data32);
576        break;
577
578    case eInfoTypeISAAndImmediateSigned:
579        strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))",
580                     info.ISAAndImmediateSigned.isa,
581                     info.ISAAndImmediateSigned.signed_data32,
582                     info.ISAAndImmediateSigned.signed_data32);
583        break;
584
585    case eInfoTypeISA:
586        strm.Printf (" (isa = %u)", info.isa);
587        break;
588
589    case eInfoTypeNoArgs:
590        break;
591    }
592}
593
594bool
595EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
596{
597    m_opcode = opcode;
598    m_addr = LLDB_INVALID_ADDRESS;
599    if (inst_addr.IsValid())
600    {
601        if (target)
602            m_addr = inst_addr.GetLoadAddress (target);
603        if (m_addr == LLDB_INVALID_ADDRESS)
604            m_addr = inst_addr.GetFileAddress ();
605    }
606    return true;
607}
608
609bool
610EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
611                                                  uint32_t &reg_kind,
612                                                  uint32_t &reg_num)
613{
614    // Generic and DWARF should be the two most popular register kinds when
615    // emulating instructions since they are the most platform agnostic...
616    reg_num = reg_info->kinds[eRegisterKindGeneric];
617    if (reg_num != LLDB_INVALID_REGNUM)
618    {
619        reg_kind = eRegisterKindGeneric;
620        return true;
621    }
622
623    reg_num = reg_info->kinds[eRegisterKindDWARF];
624    if (reg_num != LLDB_INVALID_REGNUM)
625    {
626        reg_kind = eRegisterKindDWARF;
627        return true;
628    }
629
630    reg_num = reg_info->kinds[eRegisterKindLLDB];
631    if (reg_num != LLDB_INVALID_REGNUM)
632    {
633        reg_kind = eRegisterKindLLDB;
634        return true;
635    }
636
637    reg_num = reg_info->kinds[eRegisterKindGCC];
638    if (reg_num != LLDB_INVALID_REGNUM)
639    {
640        reg_kind = eRegisterKindGCC;
641        return true;
642    }
643
644    reg_num = reg_info->kinds[eRegisterKindGDB];
645    if (reg_num != LLDB_INVALID_REGNUM)
646    {
647        reg_kind = eRegisterKindGDB;
648        return true;
649    }
650    return false;
651}
652
653uint32_t
654EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
655{
656    uint32_t reg_kind, reg_num;
657    if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
658        return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
659    return LLDB_INVALID_REGNUM;
660}
661
662
663bool
664EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
665{
666    unwind_plan.Clear();
667    return false;
668}
669
670
671