Home | History | Annotate | Download | only in API
      1 //===-- SBInstruction.cpp ---------------------------------------*- 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/API/SBInstruction.h"
     11 
     12 #include "lldb/API/SBAddress.h"
     13 #include "lldb/API/SBFrame.h"
     14 #include "lldb/API/SBInstruction.h"
     15 #include "lldb/API/SBStream.h"
     16 #include "lldb/API/SBTarget.h"
     17 
     18 #include "lldb/Core/ArchSpec.h"
     19 #include "lldb/Core/DataBufferHeap.h"
     20 #include "lldb/Core/DataExtractor.h"
     21 #include "lldb/Core/Disassembler.h"
     22 #include "lldb/Core/EmulateInstruction.h"
     23 #include "lldb/Core/StreamFile.h"
     24 #include "lldb/Target/ExecutionContext.h"
     25 #include "lldb/Target/StackFrame.h"
     26 #include "lldb/Target/Target.h"
     27 
     28 using namespace lldb;
     29 using namespace lldb_private;
     30 
     31 SBInstruction::SBInstruction ()
     32 {
     33 }
     34 
     35 SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) :
     36     m_opaque_sp (inst_sp)
     37 {
     38 }
     39 
     40 SBInstruction::SBInstruction(const SBInstruction &rhs) :
     41     m_opaque_sp (rhs.m_opaque_sp)
     42 {
     43 }
     44 
     45 const SBInstruction &
     46 SBInstruction::operator = (const SBInstruction &rhs)
     47 {
     48     if (this != &rhs)
     49         m_opaque_sp = rhs.m_opaque_sp;
     50     return *this;
     51 }
     52 
     53 SBInstruction::~SBInstruction ()
     54 {
     55 }
     56 
     57 bool
     58 SBInstruction::IsValid()
     59 {
     60     return (m_opaque_sp.get() != NULL);
     61 }
     62 
     63 SBAddress
     64 SBInstruction::GetAddress()
     65 {
     66     SBAddress sb_addr;
     67     if (m_opaque_sp && m_opaque_sp->GetAddress().IsValid())
     68         sb_addr.SetAddress(&m_opaque_sp->GetAddress());
     69     return sb_addr;
     70 }
     71 
     72 const char *
     73 SBInstruction::GetMnemonic(SBTarget target)
     74 {
     75     if (m_opaque_sp)
     76     {
     77         Mutex::Locker api_locker;
     78         ExecutionContext exe_ctx;
     79         TargetSP target_sp (target.GetSP());
     80         if (target_sp)
     81         {
     82             api_locker.Lock (target_sp->GetAPIMutex());
     83             target_sp->CalculateExecutionContext (exe_ctx);
     84             exe_ctx.SetProcessSP(target_sp->GetProcessSP());
     85         }
     86         return m_opaque_sp->GetMnemonic(&exe_ctx);
     87     }
     88     return NULL;
     89 }
     90 
     91 const char *
     92 SBInstruction::GetOperands(SBTarget target)
     93 {
     94     if (m_opaque_sp)
     95     {
     96         Mutex::Locker api_locker;
     97         ExecutionContext exe_ctx;
     98         TargetSP target_sp (target.GetSP());
     99         if (target_sp)
    100         {
    101             api_locker.Lock (target_sp->GetAPIMutex());
    102             target_sp->CalculateExecutionContext (exe_ctx);
    103             exe_ctx.SetProcessSP(target_sp->GetProcessSP());
    104         }
    105         return m_opaque_sp->GetOperands(&exe_ctx);
    106     }
    107     return NULL;
    108 }
    109 
    110 const char *
    111 SBInstruction::GetComment(SBTarget target)
    112 {
    113     if (m_opaque_sp)
    114     {
    115         Mutex::Locker api_locker;
    116         ExecutionContext exe_ctx;
    117         TargetSP target_sp (target.GetSP());
    118         if (target_sp)
    119         {
    120             api_locker.Lock (target_sp->GetAPIMutex());
    121             target_sp->CalculateExecutionContext (exe_ctx);
    122             exe_ctx.SetProcessSP(target_sp->GetProcessSP());
    123         }
    124         return m_opaque_sp->GetComment(&exe_ctx);
    125     }
    126     return NULL;
    127 }
    128 
    129 size_t
    130 SBInstruction::GetByteSize ()
    131 {
    132     if (m_opaque_sp)
    133         return m_opaque_sp->GetOpcode().GetByteSize();
    134     return 0;
    135 }
    136 
    137 SBData
    138 SBInstruction::GetData (SBTarget target)
    139 {
    140     lldb::SBData sb_data;
    141     if (m_opaque_sp)
    142     {
    143         DataExtractorSP data_extractor_sp (new DataExtractor());
    144         if (m_opaque_sp->GetData (*data_extractor_sp))
    145         {
    146             sb_data.SetOpaque (data_extractor_sp);
    147         }
    148     }
    149     return sb_data;
    150 }
    151 
    152 
    153 
    154 bool
    155 SBInstruction::DoesBranch ()
    156 {
    157     if (m_opaque_sp)
    158         return m_opaque_sp->DoesBranch ();
    159     return false;
    160 }
    161 
    162 void
    163 SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
    164 {
    165     m_opaque_sp = inst_sp;
    166 }
    167 
    168 bool
    169 SBInstruction::GetDescription (lldb::SBStream &s)
    170 {
    171     if (m_opaque_sp)
    172     {
    173         // Use the "ref()" instead of the "get()" accessor in case the SBStream
    174         // didn't have a stream already created, one will get created...
    175         m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL);
    176         return true;
    177     }
    178     return false;
    179 }
    180 
    181 void
    182 SBInstruction::Print (FILE *out)
    183 {
    184     if (out == NULL)
    185         return;
    186 
    187     if (m_opaque_sp)
    188     {
    189         StreamFile out_stream (out, false);
    190         m_opaque_sp->Dump (&out_stream, 0, true, false, NULL);
    191     }
    192 }
    193 
    194 bool
    195 SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
    196 {
    197     if (m_opaque_sp)
    198     {
    199         lldb::StackFrameSP frame_sp (frame.GetFrameSP());
    200 
    201         if (frame_sp)
    202         {
    203             lldb_private::ExecutionContext exe_ctx;
    204             frame_sp->CalculateExecutionContext (exe_ctx);
    205             lldb_private::Target *target = exe_ctx.GetTargetPtr();
    206             lldb_private::ArchSpec arch = target->GetArchitecture();
    207 
    208             return m_opaque_sp->Emulate (arch,
    209                                          evaluate_options,
    210                                          (void *) frame_sp.get(),
    211                                          &lldb_private::EmulateInstruction::ReadMemoryFrame,
    212                                          &lldb_private::EmulateInstruction::WriteMemoryFrame,
    213                                          &lldb_private::EmulateInstruction::ReadRegisterFrame,
    214                                          &lldb_private::EmulateInstruction::WriteRegisterFrame);
    215         }
    216     }
    217     return false;
    218 }
    219 
    220 bool
    221 SBInstruction::DumpEmulation (const char *triple)
    222 {
    223     if (m_opaque_sp && triple)
    224     {
    225         lldb_private::ArchSpec arch (triple, NULL);
    226 
    227         return m_opaque_sp->DumpEmulation (arch);
    228 
    229     }
    230     return false;
    231 }
    232 
    233 bool
    234 SBInstruction::TestEmulation (lldb::SBStream &output_stream,  const char *test_file)
    235 {
    236     if (!m_opaque_sp.get())
    237         m_opaque_sp.reset (new PseudoInstruction());
    238 
    239     return m_opaque_sp->TestEmulation (output_stream.get(), test_file);
    240 }
    241 
    242 lldb::AddressClass
    243 SBInstruction::GetAddressClass ()
    244 {
    245     if (m_opaque_sp.get())
    246         return m_opaque_sp->GetAddressClass();
    247     return eAddressClassInvalid;
    248 }
    249