blob: 36be948018631a4f7e5f8aa49548cba525235912 [file] [log] [blame]
Chris Lattner30fdc8d2010-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 Clayton1d273162010-10-06 03:09:58 +000012#include "lldb/API/SBAddress.h"
Caroline Tice7c9dd3c2011-04-05 23:22:54 +000013#include "lldb/API/SBFrame.h"
Greg Clayton1d273162010-10-06 03:09:58 +000014#include "lldb/API/SBInstruction.h"
15#include "lldb/API/SBStream.h"
Caroline Tice7c9dd3c2011-04-05 23:22:54 +000016#include "lldb/API/SBTarget.h"
Greg Clayton1d273162010-10-06 03:09:58 +000017
Caroline Tice7c9dd3c2011-04-05 23:22:54 +000018#include "lldb/Core/ArchSpec.h"
Greg Clayton8f7180b2011-09-26 07:11:27 +000019#include "lldb/Core/DataBufferHeap.h"
Greg Clayton1f746072012-08-29 21:13:06 +000020#include "lldb/Core/DataExtractor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/Disassembler.h"
Caroline Tice7c9dd3c2011-04-05 23:22:54 +000022#include "lldb/Core/EmulateInstruction.h"
Jason Molendaaff1b352014-10-10 23:07:36 +000023#include "lldb/Core/Module.h"
Greg Clayton1d273162010-10-06 03:09:58 +000024#include "lldb/Core/StreamFile.h"
Caroline Tice7c9dd3c2011-04-05 23:22:54 +000025#include "lldb/Target/ExecutionContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000026#include "lldb/Target/StackFrame.h"
Caroline Tice7c9dd3c2011-04-05 23:22:54 +000027#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028
29using namespace lldb;
30using namespace lldb_private;
31
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032SBInstruction::SBInstruction ()
33{
34}
35
Greg Clayton1d273162010-10-06 03:09:58 +000036SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) :
37 m_opaque_sp (inst_sp)
38{
39}
40
Greg Claytonefabb122010-11-05 23:17:00 +000041SBInstruction::SBInstruction(const SBInstruction &rhs) :
42 m_opaque_sp (rhs.m_opaque_sp)
43{
44}
45
46const SBInstruction &
47SBInstruction::operator = (const SBInstruction &rhs)
48{
49 if (this != &rhs)
50 m_opaque_sp = rhs.m_opaque_sp;
51 return *this;
52}
53
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054SBInstruction::~SBInstruction ()
55{
56}
57
Greg Clayton1d273162010-10-06 03:09:58 +000058bool
59SBInstruction::IsValid()
60{
61 return (m_opaque_sp.get() != NULL);
62}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
Greg Clayton1d273162010-10-06 03:09:58 +000064SBAddress
65SBInstruction::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}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072
Greg Clayton8f7180b2011-09-26 07:11:27 +000073const char *
Greg Claytonfb0655e2011-09-27 00:58:45 +000074SBInstruction::GetMnemonic(SBTarget target)
Greg Clayton8f7180b2011-09-26 07:11:27 +000075{
76 if (m_opaque_sp)
77 {
78 Mutex::Locker api_locker;
79 ExecutionContext exe_ctx;
Greg Claytonb9556ac2012-01-30 07:41:31 +000080 TargetSP target_sp (target.GetSP());
81 if (target_sp)
Greg Clayton8f7180b2011-09-26 07:11:27 +000082 {
Jim Ingham10ebffa2012-05-04 23:02:50 +000083 api_locker.Lock (target_sp->GetAPIMutex());
Greg Claytonb9556ac2012-01-30 07:41:31 +000084 target_sp->CalculateExecutionContext (exe_ctx);
85 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
Greg Clayton8f7180b2011-09-26 07:11:27 +000086 }
Greg Claytonba812f42012-05-10 02:52:23 +000087 return m_opaque_sp->GetMnemonic(&exe_ctx);
Greg Clayton8f7180b2011-09-26 07:11:27 +000088 }
89 return NULL;
90}
91
92const char *
Greg Claytonfb0655e2011-09-27 00:58:45 +000093SBInstruction::GetOperands(SBTarget target)
Greg Clayton8f7180b2011-09-26 07:11:27 +000094{
95 if (m_opaque_sp)
96 {
97 Mutex::Locker api_locker;
98 ExecutionContext exe_ctx;
Greg Claytonb9556ac2012-01-30 07:41:31 +000099 TargetSP target_sp (target.GetSP());
100 if (target_sp)
Greg Clayton8f7180b2011-09-26 07:11:27 +0000101 {
Jim Ingham10ebffa2012-05-04 23:02:50 +0000102 api_locker.Lock (target_sp->GetAPIMutex());
Greg Claytonb9556ac2012-01-30 07:41:31 +0000103 target_sp->CalculateExecutionContext (exe_ctx);
104 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
Greg Clayton8f7180b2011-09-26 07:11:27 +0000105 }
Greg Claytonba812f42012-05-10 02:52:23 +0000106 return m_opaque_sp->GetOperands(&exe_ctx);
Greg Clayton8f7180b2011-09-26 07:11:27 +0000107 }
108 return NULL;
109}
110
111const char *
112SBInstruction::GetComment(SBTarget target)
113{
114 if (m_opaque_sp)
115 {
116 Mutex::Locker api_locker;
117 ExecutionContext exe_ctx;
Greg Claytonb9556ac2012-01-30 07:41:31 +0000118 TargetSP target_sp (target.GetSP());
119 if (target_sp)
Greg Clayton8f7180b2011-09-26 07:11:27 +0000120 {
Jim Ingham10ebffa2012-05-04 23:02:50 +0000121 api_locker.Lock (target_sp->GetAPIMutex());
Greg Claytonb9556ac2012-01-30 07:41:31 +0000122 target_sp->CalculateExecutionContext (exe_ctx);
123 exe_ctx.SetProcessSP(target_sp->GetProcessSP());
Greg Clayton8f7180b2011-09-26 07:11:27 +0000124 }
Greg Claytonba812f42012-05-10 02:52:23 +0000125 return m_opaque_sp->GetComment(&exe_ctx);
Greg Clayton8f7180b2011-09-26 07:11:27 +0000126 }
127 return NULL;
128}
129
Greg Clayton1d273162010-10-06 03:09:58 +0000130size_t
131SBInstruction::GetByteSize ()
132{
133 if (m_opaque_sp)
Greg Clayton1080edbc2011-03-25 18:03:16 +0000134 return m_opaque_sp->GetOpcode().GetByteSize();
Greg Clayton1d273162010-10-06 03:09:58 +0000135 return 0;
136}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137
Greg Clayton8f7180b2011-09-26 07:11:27 +0000138SBData
139SBInstruction::GetData (SBTarget target)
140{
141 lldb::SBData sb_data;
142 if (m_opaque_sp)
143 {
Greg Claytond1411e12012-04-11 21:13:31 +0000144 DataExtractorSP data_extractor_sp (new DataExtractor());
Greg Claytonba812f42012-05-10 02:52:23 +0000145 if (m_opaque_sp->GetData (*data_extractor_sp))
Greg Clayton8f7180b2011-09-26 07:11:27 +0000146 {
Greg Clayton8f7180b2011-09-26 07:11:27 +0000147 sb_data.SetOpaque (data_extractor_sp);
148 }
149 }
150 return sb_data;
151}
152
153
154
Greg Clayton1d273162010-10-06 03:09:58 +0000155bool
156SBInstruction::DoesBranch ()
157{
158 if (m_opaque_sp)
159 return m_opaque_sp->DoesBranch ();
160 return false;
161}
162
163void
164SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
165{
166 m_opaque_sp = inst_sp;
167}
168
169bool
170SBInstruction::GetDescription (lldb::SBStream &s)
171{
172 if (m_opaque_sp)
173 {
Jason Molendaaff1b352014-10-10 23:07:36 +0000174 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);
Greg Clayton1d273162010-10-06 03:09:58 +0000179 // Use the "ref()" instead of the "get()" accessor in case the SBStream
180 // didn't have a stream already created, one will get created...
Greg Clayton554f68d2015-02-04 22:00:53 +0000181 FormatEntity::Entry format;
182 FormatEntity::Parse("${addr}: ", format);
Jason Molendac980fa92015-02-13 23:24:21 +0000183 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, &format, 0);
Greg Clayton1d273162010-10-06 03:09:58 +0000184 return true;
185 }
186 return false;
187}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188
189void
190SBInstruction::Print (FILE *out)
191{
192 if (out == NULL)
193 return;
194
Greg Clayton1d273162010-10-06 03:09:58 +0000195 if (m_opaque_sp)
196 {
Jason Molendaaff1b352014-10-10 23:07:36 +0000197 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);
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000202 StreamFile out_stream (out, false);
Greg Clayton554f68d2015-02-04 22:00:53 +0000203 FormatEntity::Entry format;
204 FormatEntity::Parse("${addr}: ", format);
Jason Molendac980fa92015-02-13 23:24:21 +0000205 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, &format, 0);
Greg Clayton1d273162010-10-06 03:09:58 +0000206 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207}
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000208
209bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000210SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000211{
Greg Claytonb9556ac2012-01-30 07:41:31 +0000212 if (m_opaque_sp)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000213 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000214 lldb::StackFrameSP frame_sp (frame.GetFrameSP());
Greg Claytonb9556ac2012-01-30 07:41:31 +0000215
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 }
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000231 }
232 return false;
233}
234
235bool
236SBInstruction::DumpEmulation (const char *triple)
237{
238 if (m_opaque_sp && triple)
239 {
Greg Claytoneb0103f2011-04-07 22:46:35 +0000240 lldb_private::ArchSpec arch (triple, NULL);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000241
Caroline Tice25d61ac2011-04-08 23:33:06 +0000242 return m_opaque_sp->DumpEmulation (arch);
243
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000244 }
245 return false;
246}
247
Caroline Tice3ac67112011-04-19 23:30:03 +0000248bool
249SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file)
250{
251 if (!m_opaque_sp.get())
252 m_opaque_sp.reset (new PseudoInstruction());
253
Johnny Chenea80ba82011-04-21 20:27:45 +0000254 return m_opaque_sp->TestEmulation (output_stream.get(), test_file);
255}
Greg Claytonc8e0c242012-04-13 00:07:34 +0000256
257lldb::AddressClass
258SBInstruction::GetAddressClass ()
259{
260 if (m_opaque_sp.get())
261 return m_opaque_sp->GetAddressClass();
262 return eAddressClassInvalid;
263}