blob: 2334cc0d124a8764af03c7480269f0fbf4b197a1 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
Greg Clayton5c4c7462010-10-06 03:09:58 +000012#include "lldb/API/SBAddress.h"
Caroline Ticeaf591802011-04-05 23:22:54 +000013#include "lldb/API/SBFrame.h"
Greg Clayton5c4c7462010-10-06 03:09:58 +000014#include "lldb/API/SBInstruction.h"
15#include "lldb/API/SBStream.h"
Caroline Ticeaf591802011-04-05 23:22:54 +000016#include "lldb/API/SBTarget.h"
Greg Clayton5c4c7462010-10-06 03:09:58 +000017
Caroline Ticeaf591802011-04-05 23:22:54 +000018#include "lldb/Core/ArchSpec.h"
Greg Clayton23b8abb2011-09-26 07:11:27 +000019#include "lldb/Core/DataBufferHeap.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000020#include "lldb/Core/DataExtractor.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Disassembler.h"
Caroline Ticeaf591802011-04-05 23:22:54 +000022#include "lldb/Core/EmulateInstruction.h"
Greg Clayton5c4c7462010-10-06 03:09:58 +000023#include "lldb/Core/StreamFile.h"
Caroline Ticeaf591802011-04-05 23:22:54 +000024#include "lldb/Target/ExecutionContext.h"
25#include "lldb/Target/StackFrame.h"
26#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027
28using namespace lldb;
29using namespace lldb_private;
30
Chris Lattner24943d22010-06-08 16:52:24 +000031SBInstruction::SBInstruction ()
32{
33}
34
Greg Clayton5c4c7462010-10-06 03:09:58 +000035SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) :
36 m_opaque_sp (inst_sp)
37{
38}
39
Greg Clayton538eb822010-11-05 23:17:00 +000040SBInstruction::SBInstruction(const SBInstruction &rhs) :
41 m_opaque_sp (rhs.m_opaque_sp)
42{
43}
44
45const SBInstruction &
46SBInstruction::operator = (const SBInstruction &rhs)
47{
48 if (this != &rhs)
49 m_opaque_sp = rhs.m_opaque_sp;
50 return *this;
51}
52
Chris Lattner24943d22010-06-08 16:52:24 +000053SBInstruction::~SBInstruction ()
54{
55}
56
Greg Clayton5c4c7462010-10-06 03:09:58 +000057bool
58SBInstruction::IsValid()
59{
60 return (m_opaque_sp.get() != NULL);
61}
Chris Lattner24943d22010-06-08 16:52:24 +000062
Greg Clayton5c4c7462010-10-06 03:09:58 +000063SBAddress
64SBInstruction::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}
Chris Lattner24943d22010-06-08 16:52:24 +000071
Greg Clayton23b8abb2011-09-26 07:11:27 +000072const char *
Greg Claytond9b44252011-09-27 00:58:45 +000073SBInstruction::GetMnemonic(SBTarget target)
Greg Clayton23b8abb2011-09-26 07:11:27 +000074{
75 if (m_opaque_sp)
76 {
77 Mutex::Locker api_locker;
78 ExecutionContext exe_ctx;
Greg Clayton334d33a2012-01-30 07:41:31 +000079 TargetSP target_sp (target.GetSP());
80 if (target_sp)
Greg Clayton23b8abb2011-09-26 07:11:27 +000081 {
Jim Ingham1b584eb2012-05-04 23:02:50 +000082 api_locker.Lock (target_sp->GetAPIMutex());
Greg Clayton334d33a2012-01-30 07:41:31 +000083 target_sp->CalculateExecutionContext (exe_ctx);
84 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
Greg Clayton23b8abb2011-09-26 07:11:27 +000085 }
Greg Clayton0fef9682012-05-10 02:52:23 +000086 return m_opaque_sp->GetMnemonic(&exe_ctx);
Greg Clayton23b8abb2011-09-26 07:11:27 +000087 }
88 return NULL;
89}
90
91const char *
Greg Claytond9b44252011-09-27 00:58:45 +000092SBInstruction::GetOperands(SBTarget target)
Greg Clayton23b8abb2011-09-26 07:11:27 +000093{
94 if (m_opaque_sp)
95 {
96 Mutex::Locker api_locker;
97 ExecutionContext exe_ctx;
Greg Clayton334d33a2012-01-30 07:41:31 +000098 TargetSP target_sp (target.GetSP());
99 if (target_sp)
Greg Clayton23b8abb2011-09-26 07:11:27 +0000100 {
Jim Ingham1b584eb2012-05-04 23:02:50 +0000101 api_locker.Lock (target_sp->GetAPIMutex());
Greg Clayton334d33a2012-01-30 07:41:31 +0000102 target_sp->CalculateExecutionContext (exe_ctx);
103 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
Greg Clayton23b8abb2011-09-26 07:11:27 +0000104 }
Greg Clayton0fef9682012-05-10 02:52:23 +0000105 return m_opaque_sp->GetOperands(&exe_ctx);
Greg Clayton23b8abb2011-09-26 07:11:27 +0000106 }
107 return NULL;
108}
109
110const char *
111SBInstruction::GetComment(SBTarget target)
112{
113 if (m_opaque_sp)
114 {
115 Mutex::Locker api_locker;
116 ExecutionContext exe_ctx;
Greg Clayton334d33a2012-01-30 07:41:31 +0000117 TargetSP target_sp (target.GetSP());
118 if (target_sp)
Greg Clayton23b8abb2011-09-26 07:11:27 +0000119 {
Jim Ingham1b584eb2012-05-04 23:02:50 +0000120 api_locker.Lock (target_sp->GetAPIMutex());
Greg Clayton334d33a2012-01-30 07:41:31 +0000121 target_sp->CalculateExecutionContext (exe_ctx);
122 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
Greg Clayton23b8abb2011-09-26 07:11:27 +0000123 }
Greg Clayton0fef9682012-05-10 02:52:23 +0000124 return m_opaque_sp->GetComment(&exe_ctx);
Greg Clayton23b8abb2011-09-26 07:11:27 +0000125 }
126 return NULL;
127}
128
Greg Clayton5c4c7462010-10-06 03:09:58 +0000129size_t
130SBInstruction::GetByteSize ()
131{
132 if (m_opaque_sp)
Greg Clayton149731c2011-03-25 18:03:16 +0000133 return m_opaque_sp->GetOpcode().GetByteSize();
Greg Clayton5c4c7462010-10-06 03:09:58 +0000134 return 0;
135}
Chris Lattner24943d22010-06-08 16:52:24 +0000136
Greg Clayton23b8abb2011-09-26 07:11:27 +0000137SBData
138SBInstruction::GetData (SBTarget target)
139{
140 lldb::SBData sb_data;
141 if (m_opaque_sp)
142 {
Greg Clayton50561692012-04-11 21:13:31 +0000143 DataExtractorSP data_extractor_sp (new DataExtractor());
Greg Clayton0fef9682012-05-10 02:52:23 +0000144 if (m_opaque_sp->GetData (*data_extractor_sp))
Greg Clayton23b8abb2011-09-26 07:11:27 +0000145 {
Greg Clayton23b8abb2011-09-26 07:11:27 +0000146 sb_data.SetOpaque (data_extractor_sp);
147 }
148 }
149 return sb_data;
150}
151
152
153
Greg Clayton5c4c7462010-10-06 03:09:58 +0000154bool
155SBInstruction::DoesBranch ()
156{
157 if (m_opaque_sp)
158 return m_opaque_sp->DoesBranch ();
159 return false;
160}
161
162void
163SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
164{
165 m_opaque_sp = inst_sp;
166}
167
168bool
169SBInstruction::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...
Greg Clayton0fef9682012-05-10 02:52:23 +0000175 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL);
Greg Clayton5c4c7462010-10-06 03:09:58 +0000176 return true;
177 }
178 return false;
179}
Chris Lattner24943d22010-06-08 16:52:24 +0000180
181void
182SBInstruction::Print (FILE *out)
183{
184 if (out == NULL)
185 return;
186
Greg Clayton5c4c7462010-10-06 03:09:58 +0000187 if (m_opaque_sp)
188 {
Greg Clayton58928562011-02-09 01:08:52 +0000189 StreamFile out_stream (out, false);
Greg Clayton0fef9682012-05-10 02:52:23 +0000190 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL);
Greg Clayton5c4c7462010-10-06 03:09:58 +0000191 }
Chris Lattner24943d22010-06-08 16:52:24 +0000192}
Caroline Ticeaf591802011-04-05 23:22:54 +0000193
194bool
Greg Clayton888a7332011-04-26 04:39:08 +0000195SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
Caroline Ticeaf591802011-04-05 23:22:54 +0000196{
Greg Clayton334d33a2012-01-30 07:41:31 +0000197 if (m_opaque_sp)
Caroline Ticeaf591802011-04-05 23:22:54 +0000198 {
Greg Clayton334d33a2012-01-30 07:41:31 +0000199 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 }
Caroline Ticeaf591802011-04-05 23:22:54 +0000216 }
217 return false;
218}
219
220bool
221SBInstruction::DumpEmulation (const char *triple)
222{
223 if (m_opaque_sp && triple)
224 {
Greg Claytonf15996e2011-04-07 22:46:35 +0000225 lldb_private::ArchSpec arch (triple, NULL);
Caroline Ticeaf591802011-04-05 23:22:54 +0000226
Caroline Tice0fe5a532011-04-08 23:33:06 +0000227 return m_opaque_sp->DumpEmulation (arch);
228
Caroline Ticeaf591802011-04-05 23:22:54 +0000229 }
230 return false;
231}
232
Caroline Tice6b8d3b52011-04-19 23:30:03 +0000233bool
234SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file)
235{
236 if (!m_opaque_sp.get())
237 m_opaque_sp.reset (new PseudoInstruction());
238
Johnny Chen09008d02011-04-21 20:27:45 +0000239 return m_opaque_sp->TestEmulation (output_stream.get(), test_file);
240}
Greg Clayton7fb14302012-04-13 00:07:34 +0000241
242lldb::AddressClass
243SBInstruction::GetAddressClass ()
244{
245 if (m_opaque_sp.get())
246 return m_opaque_sp->GetAddressClass();
247 return eAddressClassInvalid;
248}