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
SBInstruction()32 SBInstruction::SBInstruction ()
33 {
34 }
35
SBInstruction(const lldb::InstructionSP & inst_sp)36 SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) :
37 m_opaque_sp (inst_sp)
38 {
39 }
40
SBInstruction(const SBInstruction & rhs)41 SBInstruction::SBInstruction(const SBInstruction &rhs) :
42 m_opaque_sp (rhs.m_opaque_sp)
43 {
44 }
45
46 const SBInstruction &
operator =(const SBInstruction & rhs)47 SBInstruction::operator = (const SBInstruction &rhs)
48 {
49 if (this != &rhs)
50 m_opaque_sp = rhs.m_opaque_sp;
51 return *this;
52 }
53
~SBInstruction()54 SBInstruction::~SBInstruction ()
55 {
56 }
57
58 bool
IsValid()59 SBInstruction::IsValid()
60 {
61 return (m_opaque_sp.get() != NULL);
62 }
63
64 SBAddress
GetAddress()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 *
GetMnemonic(SBTarget target)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 *
GetOperands(SBTarget target)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 *
GetComment(SBTarget target)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
GetByteSize()131 SBInstruction::GetByteSize ()
132 {
133 if (m_opaque_sp)
134 return m_opaque_sp->GetOpcode().GetByteSize();
135 return 0;
136 }
137
138 SBData
GetData(SBTarget target)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
DoesBranch()156 SBInstruction::DoesBranch ()
157 {
158 if (m_opaque_sp)
159 return m_opaque_sp->DoesBranch ();
160 return false;
161 }
162
163 void
SetOpaque(const lldb::InstructionSP & inst_sp)164 SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
165 {
166 m_opaque_sp = inst_sp;
167 }
168
169 bool
GetDescription(lldb::SBStream & s)170 SBInstruction::GetDescription (lldb::SBStream &s)
171 {
172 if (m_opaque_sp)
173 {
174 SymbolContext sc;
175 const Address &addr = m_opaque_sp->GetAddress();
176 ModuleSP module_sp (addr.GetModule());
177 if (module_sp)
178 module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
179 // Use the "ref()" instead of the "get()" accessor in case the SBStream
180 // didn't have a stream already created, one will get created...
181 FormatEntity::Entry format;
182 FormatEntity::Parse("${addr}: ", format);
183 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, &format, 0);
184 return true;
185 }
186 return false;
187 }
188
189 void
Print(FILE * out)190 SBInstruction::Print (FILE *out)
191 {
192 if (out == NULL)
193 return;
194
195 if (m_opaque_sp)
196 {
197 SymbolContext sc;
198 const Address &addr = m_opaque_sp->GetAddress();
199 ModuleSP module_sp (addr.GetModule());
200 if (module_sp)
201 module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
202 StreamFile out_stream (out, false);
203 FormatEntity::Entry format;
204 FormatEntity::Parse("${addr}: ", format);
205 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, &format, 0);
206 }
207 }
208
209 bool
EmulateWithFrame(lldb::SBFrame & frame,uint32_t evaluate_options)210 SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
211 {
212 if (m_opaque_sp)
213 {
214 lldb::StackFrameSP frame_sp (frame.GetFrameSP());
215
216 if (frame_sp)
217 {
218 lldb_private::ExecutionContext exe_ctx;
219 frame_sp->CalculateExecutionContext (exe_ctx);
220 lldb_private::Target *target = exe_ctx.GetTargetPtr();
221 lldb_private::ArchSpec arch = target->GetArchitecture();
222
223 return m_opaque_sp->Emulate (arch,
224 evaluate_options,
225 (void *) frame_sp.get(),
226 &lldb_private::EmulateInstruction::ReadMemoryFrame,
227 &lldb_private::EmulateInstruction::WriteMemoryFrame,
228 &lldb_private::EmulateInstruction::ReadRegisterFrame,
229 &lldb_private::EmulateInstruction::WriteRegisterFrame);
230 }
231 }
232 return false;
233 }
234
235 bool
DumpEmulation(const char * triple)236 SBInstruction::DumpEmulation (const char *triple)
237 {
238 if (m_opaque_sp && triple)
239 {
240 lldb_private::ArchSpec arch (triple, NULL);
241
242 return m_opaque_sp->DumpEmulation (arch);
243
244 }
245 return false;
246 }
247
248 bool
TestEmulation(lldb::SBStream & output_stream,const char * test_file)249 SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file)
250 {
251 if (!m_opaque_sp.get())
252 m_opaque_sp.reset (new PseudoInstruction());
253
254 return m_opaque_sp->TestEmulation (output_stream.get(), test_file);
255 }
256
257 lldb::AddressClass
GetAddressClass()258 SBInstruction::GetAddressClass ()
259 {
260 if (m_opaque_sp.get())
261 return m_opaque_sp->GetAddressClass();
262 return eAddressClassInvalid;
263 }
264