SBInstruction.cpp revision 50561699a9a14c716d1099ae1d38be2f31534b67
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 27using namespace lldb; 28using namespace lldb_private; 29 30SBInstruction::SBInstruction () 31{ 32} 33 34SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) : 35 m_opaque_sp (inst_sp) 36{ 37} 38 39SBInstruction::SBInstruction(const SBInstruction &rhs) : 40 m_opaque_sp (rhs.m_opaque_sp) 41{ 42} 43 44const SBInstruction & 45SBInstruction::operator = (const SBInstruction &rhs) 46{ 47 if (this != &rhs) 48 m_opaque_sp = rhs.m_opaque_sp; 49 return *this; 50} 51 52SBInstruction::~SBInstruction () 53{ 54} 55 56bool 57SBInstruction::IsValid() 58{ 59 return (m_opaque_sp.get() != NULL); 60} 61 62SBAddress 63SBInstruction::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 71const char * 72SBInstruction::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.Lock (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 90const char * 91SBInstruction::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.Lock (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 109const char * 110SBInstruction::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.Lock (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 128size_t 129SBInstruction::GetByteSize () 130{ 131 if (m_opaque_sp) 132 return m_opaque_sp->GetOpcode().GetByteSize(); 133 return 0; 134} 135 136SBData 137SBInstruction::GetData (SBTarget target) 138{ 139 lldb::SBData sb_data; 140 if (m_opaque_sp) 141 { 142 DataExtractorSP data_extractor_sp (new DataExtractor()); 143 if (m_opaque_sp->GetOpcode().GetData (*data_extractor_sp)) 144 { 145 sb_data.SetOpaque (data_extractor_sp); 146 } 147 } 148 return sb_data; 149} 150 151 152 153bool 154SBInstruction::DoesBranch () 155{ 156 if (m_opaque_sp) 157 return m_opaque_sp->DoesBranch (); 158 return false; 159} 160 161void 162SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp) 163{ 164 m_opaque_sp = inst_sp; 165} 166 167bool 168SBInstruction::GetDescription (lldb::SBStream &s) 169{ 170 if (m_opaque_sp) 171 { 172 // Use the "ref()" instead of the "get()" accessor in case the SBStream 173 // didn't have a stream already created, one will get created... 174 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, false); 175 return true; 176 } 177 return false; 178} 179 180void 181SBInstruction::Print (FILE *out) 182{ 183 if (out == NULL) 184 return; 185 186 if (m_opaque_sp) 187 { 188 StreamFile out_stream (out, false); 189 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, false); 190 } 191} 192 193bool 194SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options) 195{ 196 if (m_opaque_sp) 197 { 198 lldb::StackFrameSP frame_sp (frame.GetFrameSP()); 199 200 if (frame_sp) 201 { 202 lldb_private::ExecutionContext exe_ctx; 203 frame_sp->CalculateExecutionContext (exe_ctx); 204 lldb_private::Target *target = exe_ctx.GetTargetPtr(); 205 lldb_private::ArchSpec arch = target->GetArchitecture(); 206 207 return m_opaque_sp->Emulate (arch, 208 evaluate_options, 209 (void *) frame_sp.get(), 210 &lldb_private::EmulateInstruction::ReadMemoryFrame, 211 &lldb_private::EmulateInstruction::WriteMemoryFrame, 212 &lldb_private::EmulateInstruction::ReadRegisterFrame, 213 &lldb_private::EmulateInstruction::WriteRegisterFrame); 214 } 215 } 216 return false; 217} 218 219bool 220SBInstruction::DumpEmulation (const char *triple) 221{ 222 if (m_opaque_sp && triple) 223 { 224 lldb_private::ArchSpec arch (triple, NULL); 225 226 return m_opaque_sp->DumpEmulation (arch); 227 228 } 229 return false; 230} 231 232bool 233SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file) 234{ 235 if (!m_opaque_sp.get()) 236 m_opaque_sp.reset (new PseudoInstruction()); 237 238 return m_opaque_sp->TestEmulation (output_stream.get(), test_file); 239} 240