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