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/StreamFile.h"
24 #include "lldb/Target/ExecutionContext.h"
25 #include "lldb/Target/StackFrame.h"
26 #include "lldb/Target/Target.h"
27
28 using namespace lldb;
29 using namespace lldb_private;
30
SBInstruction()31 SBInstruction::SBInstruction ()
32 {
33 }
34
SBInstruction(const lldb::InstructionSP & inst_sp)35 SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) :
36 m_opaque_sp (inst_sp)
37 {
38 }
39
SBInstruction(const SBInstruction & rhs)40 SBInstruction::SBInstruction(const SBInstruction &rhs) :
41 m_opaque_sp (rhs.m_opaque_sp)
42 {
43 }
44
45 const SBInstruction &
operator =(const SBInstruction & rhs)46 SBInstruction::operator = (const SBInstruction &rhs)
47 {
48 if (this != &rhs)
49 m_opaque_sp = rhs.m_opaque_sp;
50 return *this;
51 }
52
~SBInstruction()53 SBInstruction::~SBInstruction ()
54 {
55 }
56
57 bool
IsValid()58 SBInstruction::IsValid()
59 {
60 return (m_opaque_sp.get() != NULL);
61 }
62
63 SBAddress
GetAddress()64 SBInstruction::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 }
71
72 const char *
GetMnemonic(SBTarget target)73 SBInstruction::GetMnemonic(SBTarget target)
74 {
75 if (m_opaque_sp)
76 {
77 Mutex::Locker api_locker;
78 ExecutionContext exe_ctx;
79 TargetSP target_sp (target.GetSP());
80 if (target_sp)
81 {
82 api_locker.Lock (target_sp->GetAPIMutex());
83 target_sp->CalculateExecutionContext (exe_ctx);
84 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
85 }
86 return m_opaque_sp->GetMnemonic(&exe_ctx);
87 }
88 return NULL;
89 }
90
91 const char *
GetOperands(SBTarget target)92 SBInstruction::GetOperands(SBTarget target)
93 {
94 if (m_opaque_sp)
95 {
96 Mutex::Locker api_locker;
97 ExecutionContext exe_ctx;
98 TargetSP target_sp (target.GetSP());
99 if (target_sp)
100 {
101 api_locker.Lock (target_sp->GetAPIMutex());
102 target_sp->CalculateExecutionContext (exe_ctx);
103 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
104 }
105 return m_opaque_sp->GetOperands(&exe_ctx);
106 }
107 return NULL;
108 }
109
110 const char *
GetComment(SBTarget target)111 SBInstruction::GetComment(SBTarget target)
112 {
113 if (m_opaque_sp)
114 {
115 Mutex::Locker api_locker;
116 ExecutionContext exe_ctx;
117 TargetSP target_sp (target.GetSP());
118 if (target_sp)
119 {
120 api_locker.Lock (target_sp->GetAPIMutex());
121 target_sp->CalculateExecutionContext (exe_ctx);
122 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
123 }
124 return m_opaque_sp->GetComment(&exe_ctx);
125 }
126 return NULL;
127 }
128
129 size_t
GetByteSize()130 SBInstruction::GetByteSize ()
131 {
132 if (m_opaque_sp)
133 return m_opaque_sp->GetOpcode().GetByteSize();
134 return 0;
135 }
136
137 SBData
GetData(SBTarget target)138 SBInstruction::GetData (SBTarget target)
139 {
140 lldb::SBData sb_data;
141 if (m_opaque_sp)
142 {
143 DataExtractorSP data_extractor_sp (new DataExtractor());
144 if (m_opaque_sp->GetData (*data_extractor_sp))
145 {
146 sb_data.SetOpaque (data_extractor_sp);
147 }
148 }
149 return sb_data;
150 }
151
152
153
154 bool
DoesBranch()155 SBInstruction::DoesBranch ()
156 {
157 if (m_opaque_sp)
158 return m_opaque_sp->DoesBranch ();
159 return false;
160 }
161
162 void
SetOpaque(const lldb::InstructionSP & inst_sp)163 SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
164 {
165 m_opaque_sp = inst_sp;
166 }
167
168 bool
GetDescription(lldb::SBStream & s)169 SBInstruction::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...
175 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL);
176 return true;
177 }
178 return false;
179 }
180
181 void
Print(FILE * out)182 SBInstruction::Print (FILE *out)
183 {
184 if (out == NULL)
185 return;
186
187 if (m_opaque_sp)
188 {
189 StreamFile out_stream (out, false);
190 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL);
191 }
192 }
193
194 bool
EmulateWithFrame(lldb::SBFrame & frame,uint32_t evaluate_options)195 SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
196 {
197 if (m_opaque_sp)
198 {
199 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 }
216 }
217 return false;
218 }
219
220 bool
DumpEmulation(const char * triple)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
TestEmulation(lldb::SBStream & output_stream,const char * test_file)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
242 lldb::AddressClass
GetAddressClass()243 SBInstruction::GetAddressClass ()
244 {
245 if (m_opaque_sp.get())
246 return m_opaque_sp->GetAddressClass();
247 return eAddressClassInvalid;
248 }
249