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