Home | History | Annotate | Download | only in Core
      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 
     26 using namespace lldb;
     27 using namespace lldb_private;
     28 
     29 EmulateInstruction*
     30 EmulateInstruction::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 
     56 EmulateInstruction::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 
     69 bool
     70 EmulateInstruction::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 
     77 bool
     78 EmulateInstruction::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 
     86 uint64_t
     87 EmulateInstruction::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 
    100 uint64_t
    101 EmulateInstruction::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 
    113 bool
    114 EmulateInstruction::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 
    123 bool
    124 EmulateInstruction::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 
    136 bool
    137 EmulateInstruction::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 
    153 bool
    154 EmulateInstruction::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 
    168 size_t
    169 EmulateInstruction::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 
    179 uint64_t
    180 EmulateInstruction::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 
    206 bool
    207 EmulateInstruction::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 
    221 bool
    222 EmulateInstruction::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 
    233 void
    234 EmulateInstruction::SetBaton (void *baton)
    235 {
    236     m_baton = baton;
    237 }
    238 
    239 void
    240 EmulateInstruction::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 
    251 void
    252 EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
    253 {
    254     m_read_mem_callback = read_mem_callback;
    255 }
    256 
    257 
    258 void
    259 EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
    260 {
    261     m_write_mem_callback = write_mem_callback;
    262 }
    263 
    264 
    265 void
    266 EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
    267 {
    268     m_read_reg_callback = read_reg_callback;
    269 }
    270 
    271 
    272 void
    273 EmulateInstruction::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 
    284 size_t
    285 EmulateInstruction::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 
    306 size_t
    307 EmulateInstruction::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 
    329 bool
    330 EmulateInstruction::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 
    342 bool
    343 EmulateInstruction::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 
    356 size_t
    357 EmulateInstruction::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 
    372 size_t
    373 EmulateInstruction::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 
    387 bool
    388 EmulateInstruction::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 
    404 bool
    405 EmulateInstruction::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 
    420 void
    421 EmulateInstruction::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 
    594 bool
    595 EmulateInstruction::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 
    609 bool
    610 EmulateInstruction::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 
    653 uint32_t
    654 EmulateInstruction::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 
    663 bool
    664 EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
    665 {
    666     unwind_plan.Clear();
    667     return false;
    668 }
    669 
    670 
    671