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 TargetSP target_sp (target.GetSP()); 79 if (target_sp) 80 { 81 api_locker.Reset (target_sp->GetAPIMutex().GetMutex()); 82 target_sp->CalculateExecutionContext (exe_ctx); 83 exe_ctx.SetProcessSP(target_sp->GetProcessSP()); 84 } 85 return m_opaque_sp->GetMnemonic(exe_ctx.GetBestExecutionContextScope()); 86 } 87 return NULL; 88 } 89 90 const char * 91 SBInstruction::GetOperands(SBTarget target) 92 { 93 if (m_opaque_sp) 94 { 95 Mutex::Locker api_locker; 96 ExecutionContext exe_ctx; 97 TargetSP target_sp (target.GetSP()); 98 if (target_sp) 99 { 100 api_locker.Reset (target_sp->GetAPIMutex().GetMutex()); 101 target_sp->CalculateExecutionContext (exe_ctx); 102 exe_ctx.SetProcessSP(target_sp->GetProcessSP()); 103 } 104 return m_opaque_sp->GetOperands(exe_ctx.GetBestExecutionContextScope()); 105 } 106 return NULL; 107 } 108 109 const char * 110 SBInstruction::GetComment(SBTarget target) 111 { 112 if (m_opaque_sp) 113 { 114 Mutex::Locker api_locker; 115 ExecutionContext exe_ctx; 116 TargetSP target_sp (target.GetSP()); 117 if (target_sp) 118 { 119 api_locker.Reset (target_sp->GetAPIMutex().GetMutex()); 120 target_sp->CalculateExecutionContext (exe_ctx); 121 exe_ctx.SetProcessSP(target_sp->GetProcessSP()); 122 } 123 return m_opaque_sp->GetComment(exe_ctx.GetBestExecutionContextScope()); 124 } 125 return NULL; 126 } 127 128 size_t 129 SBInstruction::GetByteSize () 130 { 131 if (m_opaque_sp) 132 return m_opaque_sp->GetOpcode().GetByteSize(); 133 return 0; 134 } 135 136 SBData 137 SBInstruction::GetData (SBTarget target) 138 { 139 lldb::SBData sb_data; 140 if (m_opaque_sp) 141 { 142 const Opcode &opcode = m_opaque_sp->GetOpcode(); 143 const void *opcode_data = opcode.GetOpcodeBytes(); 144 const uint32_t opcode_data_size = opcode.GetByteSize(); 145 if (opcode_data && opcode_data_size > 0) 146 { 147 ByteOrder data_byte_order = opcode.GetDataByteOrder(); 148 TargetSP target_sp (target.GetSP()); 149 if (data_byte_order == eByteOrderInvalid && target_sp) 150 data_byte_order = target_sp->GetArchitecture().GetByteOrder(); 151 DataBufferSP data_buffer_sp (new DataBufferHeap (opcode_data, opcode_data_size)); 152 DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp, 153 data_byte_order, 154 target_sp ? target_sp->GetArchitecture().GetAddressByteSize() : sizeof(void*))); 155 sb_data.SetOpaque (data_extractor_sp); 156 } 157 } 158 return sb_data; 159 } 160 161 162 163 bool 164 SBInstruction::DoesBranch () 165 { 166 if (m_opaque_sp) 167 return m_opaque_sp->DoesBranch (); 168 return false; 169 } 170 171 void 172 SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp) 173 { 174 m_opaque_sp = inst_sp; 175 } 176 177 bool 178 SBInstruction::GetDescription (lldb::SBStream &s) 179 { 180 if (m_opaque_sp) 181 { 182 // Use the "ref()" instead of the "get()" accessor in case the SBStream 183 // didn't have a stream already created, one will get created... 184 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, false); 185 return true; 186 } 187 return false; 188 } 189 190 void 191 SBInstruction::Print (FILE *out) 192 { 193 if (out == NULL) 194 return; 195 196 if (m_opaque_sp) 197 { 198 StreamFile out_stream (out, false); 199 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, false); 200 } 201 } 202 203 bool 204 SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options) 205 { 206 if (m_opaque_sp) 207 { 208 lldb::StackFrameSP frame_sp (frame.GetFrameSP()); 209 210 if (frame_sp) 211 { 212 lldb_private::ExecutionContext exe_ctx; 213 frame_sp->CalculateExecutionContext (exe_ctx); 214 lldb_private::Target *target = exe_ctx.GetTargetPtr(); 215 lldb_private::ArchSpec arch = target->GetArchitecture(); 216 217 return m_opaque_sp->Emulate (arch, 218 evaluate_options, 219 (void *) frame_sp.get(), 220 &lldb_private::EmulateInstruction::ReadMemoryFrame, 221 &lldb_private::EmulateInstruction::WriteMemoryFrame, 222 &lldb_private::EmulateInstruction::ReadRegisterFrame, 223 &lldb_private::EmulateInstruction::WriteRegisterFrame); 224 } 225 } 226 return false; 227 } 228 229 bool 230 SBInstruction::DumpEmulation (const char *triple) 231 { 232 if (m_opaque_sp && triple) 233 { 234 lldb_private::ArchSpec arch (triple, NULL); 235 236 return m_opaque_sp->DumpEmulation (arch); 237 238 } 239 return false; 240 } 241 242 bool 243 SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file) 244 { 245 if (!m_opaque_sp.get()) 246 m_opaque_sp.reset (new PseudoInstruction()); 247 248 return m_opaque_sp->TestEmulation (output_stream.get(), test_file); 249 } 250