EmulateInstruction.cpp revision 296417
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 (lldb::RegisterKind 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 (lldb::RegisterKind 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                                   lldb::RegisterKind 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                                           lldb::RegisterKind 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    lldb::RegisterKind reg_kind;
396    uint32_t reg_num;
397    if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
398        reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
399    else
400        reg_value.SetUInt64(0);
401
402    return true;
403}
404
405bool
406EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
407                                          void *baton,
408                                          const Context &context,
409                                          const RegisterInfo *reg_info,
410                                          const RegisterValue &reg_value)
411{
412    StreamFile strm (stdout, false);
413    strm.Printf ("    Write to Register (name = %s, value = " , reg_info->name);
414    reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
415    strm.PutCString (", context = ");
416    context.Dump (strm, instruction);
417    strm.EOL();
418    return true;
419}
420
421void
422EmulateInstruction::Context::Dump (Stream &strm,
423                                   EmulateInstruction *instruction) const
424{
425    switch (type)
426    {
427        case eContextReadOpcode:
428            strm.PutCString ("reading opcode");
429            break;
430
431        case eContextImmediate:
432            strm.PutCString ("immediate");
433            break;
434
435        case eContextPushRegisterOnStack:
436            strm.PutCString ("push register");
437            break;
438
439        case eContextPopRegisterOffStack:
440            strm.PutCString ("pop register");
441            break;
442
443        case eContextAdjustStackPointer:
444            strm.PutCString ("adjust sp");
445            break;
446
447        case eContextSetFramePointer:
448            strm.PutCString ("set frame pointer");
449            break;
450
451        case eContextAdjustBaseRegister:
452            strm.PutCString ("adjusting (writing value back to) a base register");
453            break;
454
455        case eContextRegisterPlusOffset:
456            strm.PutCString ("register + offset");
457            break;
458
459        case eContextRegisterStore:
460            strm.PutCString ("store register");
461            break;
462
463        case eContextRegisterLoad:
464            strm.PutCString ("load register");
465            break;
466
467        case eContextRelativeBranchImmediate:
468            strm.PutCString ("relative branch immediate");
469            break;
470
471        case eContextAbsoluteBranchRegister:
472            strm.PutCString ("absolute branch register");
473            break;
474
475        case eContextSupervisorCall:
476            strm.PutCString ("supervisor call");
477            break;
478
479        case eContextTableBranchReadMemory:
480            strm.PutCString ("table branch read memory");
481            break;
482
483        case eContextWriteRegisterRandomBits:
484            strm.PutCString ("write random bits to a register");
485            break;
486
487        case eContextWriteMemoryRandomBits:
488            strm.PutCString ("write random bits to a memory address");
489            break;
490
491        case eContextArithmetic:
492            strm.PutCString ("arithmetic");
493            break;
494
495        case eContextReturnFromException:
496            strm.PutCString ("return from exception");
497            break;
498
499        default:
500            strm.PutCString ("unrecognized context.");
501            break;
502    }
503
504    switch (info_type)
505    {
506    case eInfoTypeRegisterPlusOffset:
507        {
508            strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")",
509                         info.RegisterPlusOffset.reg.name,
510                         info.RegisterPlusOffset.signed_offset);
511        }
512        break;
513
514    case eInfoTypeRegisterPlusIndirectOffset:
515        {
516            strm.Printf (" (reg_plus_reg = %s + %s)",
517                         info.RegisterPlusIndirectOffset.base_reg.name,
518                         info.RegisterPlusIndirectOffset.offset_reg.name);
519        }
520        break;
521
522    case eInfoTypeRegisterToRegisterPlusOffset:
523        {
524            strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
525                         info.RegisterToRegisterPlusOffset.base_reg.name,
526                         info.RegisterToRegisterPlusOffset.offset,
527                         info.RegisterToRegisterPlusOffset.data_reg.name);
528        }
529        break;
530
531    case eInfoTypeRegisterToRegisterPlusIndirectOffset:
532        {
533            strm.Printf (" (base_and_reg_offset = %s + %s, data_reg = %s)",
534                         info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
535                         info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
536                         info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
537        }
538        break;
539
540    case eInfoTypeRegisterRegisterOperands:
541        {
542            strm.Printf (" (register to register binary op: %s and %s)",
543                         info.RegisterRegisterOperands.operand1.name,
544                         info.RegisterRegisterOperands.operand2.name);
545        }
546        break;
547
548    case eInfoTypeOffset:
549        strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
550        break;
551
552    case eInfoTypeRegister:
553        strm.Printf (" (reg = %s)", info.reg.name);
554        break;
555
556    case eInfoTypeImmediate:
557        strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
558                     info.unsigned_immediate,
559                     info.unsigned_immediate);
560        break;
561
562    case eInfoTypeImmediateSigned:
563        strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
564                     info.signed_immediate,
565                     info.signed_immediate);
566        break;
567
568    case eInfoTypeAddress:
569        strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
570        break;
571
572    case eInfoTypeISAAndImmediate:
573        strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
574                     info.ISAAndImmediate.isa,
575                     info.ISAAndImmediate.unsigned_data32,
576                     info.ISAAndImmediate.unsigned_data32);
577        break;
578
579    case eInfoTypeISAAndImmediateSigned:
580        strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))",
581                     info.ISAAndImmediateSigned.isa,
582                     info.ISAAndImmediateSigned.signed_data32,
583                     info.ISAAndImmediateSigned.signed_data32);
584        break;
585
586    case eInfoTypeISA:
587        strm.Printf (" (isa = %u)", info.isa);
588        break;
589
590    case eInfoTypeNoArgs:
591        break;
592    }
593}
594
595bool
596EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
597{
598    m_opcode = opcode;
599    m_addr = LLDB_INVALID_ADDRESS;
600    if (inst_addr.IsValid())
601    {
602        if (target)
603            m_addr = inst_addr.GetLoadAddress (target);
604        if (m_addr == LLDB_INVALID_ADDRESS)
605            m_addr = inst_addr.GetFileAddress ();
606    }
607    return true;
608}
609
610bool
611EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
612                                                  lldb::RegisterKind &reg_kind,
613                                                  uint32_t &reg_num)
614{
615    // Generic and DWARF should be the two most popular register kinds when
616    // emulating instructions since they are the most platform agnostic...
617    reg_num = reg_info->kinds[eRegisterKindGeneric];
618    if (reg_num != LLDB_INVALID_REGNUM)
619    {
620        reg_kind = eRegisterKindGeneric;
621        return true;
622    }
623
624    reg_num = reg_info->kinds[eRegisterKindDWARF];
625    if (reg_num != LLDB_INVALID_REGNUM)
626    {
627        reg_kind = eRegisterKindDWARF;
628        return true;
629    }
630
631    reg_num = reg_info->kinds[eRegisterKindLLDB];
632    if (reg_num != LLDB_INVALID_REGNUM)
633    {
634        reg_kind = eRegisterKindLLDB;
635        return true;
636    }
637
638    reg_num = reg_info->kinds[eRegisterKindEHFrame];
639    if (reg_num != LLDB_INVALID_REGNUM)
640    {
641        reg_kind = eRegisterKindEHFrame;
642        return true;
643    }
644
645    reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
646    if (reg_num != LLDB_INVALID_REGNUM)
647    {
648        reg_kind = eRegisterKindProcessPlugin;
649        return true;
650    }
651    return false;
652}
653
654uint32_t
655EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
656{
657    lldb::RegisterKind reg_kind;
658    uint32_t reg_num;
659    if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
660        return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
661    return LLDB_INVALID_REGNUM;
662}
663
664
665bool
666EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
667{
668    unwind_plan.Clear();
669    return false;
670}
671
672
673