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/Disassembler.h" 21 #include "lldb/Core/EmulateInstruction.h" 22 #include "lldb/Core/StreamFile.h" 23 #include "lldb/Target/ExecutionContext.h" 24 #include "lldb/Target/StackFrame.h" 25 #include "lldb/Target/Target.h" 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 SBInstruction::SBInstruction () 31 { 32 } 33 34 SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) : 35 m_opaque_sp (inst_sp) 36 { 37 } 38 39 SBInstruction::SBInstruction(const SBInstruction &rhs) : 40 m_opaque_sp (rhs.m_opaque_sp) 41 { 42 } 43 44 const SBInstruction & 45 SBInstruction::operator = (const SBInstruction &rhs) 46 { 47 if (this != &rhs) 48 m_opaque_sp = rhs.m_opaque_sp; 49 return *this; 50 } 51 52 SBInstruction::~SBInstruction () 53 { 54 } 55 56 bool 57 SBInstruction::IsValid() 58 { 59 return (m_opaque_sp.get() != NULL); 60 } 61 62 SBAddress 63 SBInstruction::GetAddress() 64 { 65 SBAddress sb_addr; 66 if (m_opaque_sp && m_opaque_sp->GetAddress().IsValid()) 67 sb_addr.SetAddress(&m_opaque_sp->GetAddress()); 68 return sb_addr; 69 } 70 71 const char * 72 SBInstruction::GetMnemonic(SBTarget target) 73 { 74 if (m_opaque_sp) 75 { 76 Mutex::Locker api_locker; 77 ExecutionContext exe_ctx; 78 if (target.IsValid()) 79 { 80 api_locker.Reset (target->GetAPIMutex().GetMutex()); 81 target->CalculateExecutionContext (exe_ctx); 82 exe_ctx.SetProcessSP(target->GetProcessSP()); 83 } 84 return m_opaque_sp->GetMnemonic(exe_ctx.GetBestExecutionContextScope()); 85 } 86 return NULL; 87 } 88 89 const char * 90 SBInstruction::GetOperands(SBTarget target) 91 { 92 if (m_opaque_sp) 93 { 94 Mutex::Locker api_locker; 95 ExecutionContext exe_ctx; 96 if (target.IsValid()) 97 { 98 api_locker.Reset (target->GetAPIMutex().GetMutex()); 99 target->CalculateExecutionContext (exe_ctx); 100 exe_ctx.SetProcessSP(target->GetProcessSP()); 101 } 102 return m_opaque_sp->GetOperands(exe_ctx.GetBestExecutionContextScope()); 103 } 104 return NULL; 105 } 106 107 const char * 108 SBInstruction::GetComment(SBTarget target) 109 { 110 if (m_opaque_sp) 111 { 112 Mutex::Locker api_locker; 113 ExecutionContext exe_ctx; 114 if (target.IsValid()) 115 { 116 api_locker.Reset (target->GetAPIMutex().GetMutex()); 117 target->CalculateExecutionContext (exe_ctx); 118 exe_ctx.SetProcessSP(target->GetProcessSP()); 119 } 120 return m_opaque_sp->GetComment(exe_ctx.GetBestExecutionContextScope()); 121 } 122 return NULL; 123 } 124 125 size_t 126 SBInstruction::GetByteSize () 127 { 128 if (m_opaque_sp) 129 return m_opaque_sp->GetOpcode().GetByteSize(); 130 return 0; 131 } 132 133 SBData 134 SBInstruction::GetData (SBTarget target) 135 { 136 lldb::SBData sb_data; 137 if (m_opaque_sp) 138 { 139 const Opcode &opcode = m_opaque_sp->GetOpcode(); 140 const void *opcode_data = opcode.GetOpcodeBytes(); 141 const uint32_t opcode_data_size = opcode.GetByteSize(); 142 if (opcode_data && opcode_data_size > 0) 143 { 144 ByteOrder data_byte_order = opcode.GetDataByteOrder(); 145 if (data_byte_order == eByteOrderInvalid) 146 data_byte_order = target->GetArchitecture().GetByteOrder(); 147 DataBufferSP data_buffer_sp (new DataBufferHeap (opcode_data, opcode_data_size)); 148 DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp, 149 data_byte_order, 150 target.IsValid() ? target->GetArchitecture().GetAddressByteSize() : sizeof(void*))); 151 sb_data.SetOpaque (data_extractor_sp); 152 } 153 } 154 return sb_data; 155 } 156 157 158 159 bool 160 SBInstruction::DoesBranch () 161 { 162 if (m_opaque_sp) 163 return m_opaque_sp->DoesBranch (); 164 return false; 165 } 166 167 void 168 SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp) 169 { 170 m_opaque_sp = inst_sp; 171 } 172 173 bool 174 SBInstruction::GetDescription (lldb::SBStream &s) 175 { 176 if (m_opaque_sp) 177 { 178 // Use the "ref()" instead of the "get()" accessor in case the SBStream 179 // didn't have a stream already created, one will get created... 180 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, false); 181 return true; 182 } 183 return false; 184 } 185 186 void 187 SBInstruction::Print (FILE *out) 188 { 189 if (out == NULL) 190 return; 191 192 if (m_opaque_sp) 193 { 194 StreamFile out_stream (out, false); 195 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, false); 196 } 197 } 198 199 bool 200 SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options) 201 { 202 if (m_opaque_sp && frame.get()) 203 { 204 lldb_private::ExecutionContext exe_ctx; 205 frame->CalculateExecutionContext (exe_ctx); 206 lldb_private::Target *target = exe_ctx.GetTargetPtr(); 207 lldb_private::ArchSpec arch = target->GetArchitecture(); 208 209 return m_opaque_sp->Emulate (arch, 210 evaluate_options, 211 (void *) frame.get(), 212 &lldb_private::EmulateInstruction::ReadMemoryFrame, 213 &lldb_private::EmulateInstruction::WriteMemoryFrame, 214 &lldb_private::EmulateInstruction::ReadRegisterFrame, 215 &lldb_private::EmulateInstruction::WriteRegisterFrame); 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