blob: eccc4e29aadf0b7e85bac4c21b82c38d597bf982 [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...
Jason Molendaaff1b352014-10-10 23:07:36 +0000181 const char *disassemble_format = "${addr-file-or-load}: ";
182 m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, disassemble_format);
Greg Clayton1d273162010-10-06 03:09:58 +0000183 return true;
184 }
185 return false;
186}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187
188void
189SBInstruction::Print (FILE *out)
190{
191 if (out == NULL)
192 return;
193
Greg Clayton1d273162010-10-06 03:09:58 +0000194 if (m_opaque_sp)
195 {
Jason Molendaaff1b352014-10-10 23:07:36 +0000196 SymbolContext sc;
197 const Address &addr = m_opaque_sp->GetAddress();
198 ModuleSP module_sp (addr.GetModule());
199 if (module_sp)
200 module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000201 StreamFile out_stream (out, false);
Jason Molendaaff1b352014-10-10 23:07:36 +0000202 const char *disassemble_format = "${addr-file-or-load}: ";
203 m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, disassemble_format);
Greg Clayton1d273162010-10-06 03:09:58 +0000204 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205}
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000206
207bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000208SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000209{
Greg Claytonb9556ac2012-01-30 07:41:31 +0000210 if (m_opaque_sp)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000211 {
Jason Molendab57e4a12013-11-04 09:33:30 +0000212 lldb::StackFrameSP frame_sp (frame.GetFrameSP());
Greg Claytonb9556ac2012-01-30 07:41:31 +0000213
214 if (frame_sp)
215 {
216 lldb_private::ExecutionContext exe_ctx;
217 frame_sp->CalculateExecutionContext (exe_ctx);
218 lldb_private::Target *target = exe_ctx.GetTargetPtr();
219 lldb_private::ArchSpec arch = target->GetArchitecture();
220
221 return m_opaque_sp->Emulate (arch,
222 evaluate_options,
223 (void *) frame_sp.get(),
224 &lldb_private::EmulateInstruction::ReadMemoryFrame,
225 &lldb_private::EmulateInstruction::WriteMemoryFrame,
226 &lldb_private::EmulateInstruction::ReadRegisterFrame,
227 &lldb_private::EmulateInstruction::WriteRegisterFrame);
228 }
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000229 }
230 return false;
231}
232
233bool
234SBInstruction::DumpEmulation (const char *triple)
235{
236 if (m_opaque_sp && triple)
237 {
Greg Claytoneb0103f2011-04-07 22:46:35 +0000238 lldb_private::ArchSpec arch (triple, NULL);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000239
Caroline Tice25d61ac2011-04-08 23:33:06 +0000240 return m_opaque_sp->DumpEmulation (arch);
241
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000242 }
243 return false;
244}
245
Caroline Tice3ac67112011-04-19 23:30:03 +0000246bool
247SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file)
248{
249 if (!m_opaque_sp.get())
250 m_opaque_sp.reset (new PseudoInstruction());
251
Johnny Chenea80ba82011-04-21 20:27:45 +0000252 return m_opaque_sp->TestEmulation (output_stream.get(), test_file);
253}
Greg Claytonc8e0c242012-04-13 00:07:34 +0000254
255lldb::AddressClass
256SBInstruction::GetAddressClass ()
257{
258 if (m_opaque_sp.get())
259 return m_opaque_sp->GetAddressClass();
260 return eAddressClassInvalid;
261}