blob: e46cfb2d89453fa078bb1c46bb221fb776100a43 [file] [log] [blame]
Greg Clayton6da4ca82011-01-21 22:02:52 +00001//===-- EmulateInstruction.h ------------------------------------*- 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
Greg Clayton95e31422011-02-05 02:56:16 +000010#include "lldb/Core/EmulateInstruction.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000011
Eugene Zelenko34ede342016-03-03 00:51:40 +000012// C Includes
13// C++ Includes
14#include <cstring>
15
16// Other libraries and framework includes
17// Project includes
Greg Clayton2ed751b2011-04-26 04:39:08 +000018#include "lldb/Core/Address.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000019#include "lldb/Core/DataExtractor.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000020#include "lldb/Core/Error.h"
Greg Clayton4272cc72011-02-02 02:24:04 +000021#include "lldb/Core/PluginManager.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000022#include "lldb/Core/RegisterValue.h"
23#include "lldb/Core/StreamFile.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000024#include "lldb/Core/StreamString.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000025#include "lldb/Host/Endian.h"
Greg Clayton79ea8782011-04-26 23:48:45 +000026#include "lldb/Symbol/UnwindPlan.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000027#include "lldb/Target/Process.h"
28#include "lldb/Target/RegisterContext.h"
Greg Clayton2ed751b2011-04-26 04:39:08 +000029#include "lldb/Target/Target.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000030#include "lldb/Target/Thread.h"
31
Greg Clayton6da4ca82011-01-21 22:02:52 +000032using namespace lldb;
33using namespace lldb_private;
34
Greg Clayton4272cc72011-02-02 02:24:04 +000035EmulateInstruction*
Greg Clayton2ed751b2011-04-26 04:39:08 +000036EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
Greg Clayton4272cc72011-02-02 02:24:04 +000037{
Eugene Zelenko34ede342016-03-03 00:51:40 +000038 EmulateInstructionCreateInstance create_callback = nullptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000039 if (plugin_name)
40 {
Greg Clayton57abc5d2013-05-10 21:47:16 +000041 ConstString const_plugin_name (plugin_name);
42 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name);
Greg Clayton4272cc72011-02-02 02:24:04 +000043 if (create_callback)
44 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000045 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000046 if (emulate_insn_ptr)
47 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000048 }
49 }
50 else
51 {
Eugene Zelenko34ede342016-03-03 00:51:40 +000052 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != nullptr; ++idx)
Greg Clayton4272cc72011-02-02 02:24:04 +000053 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000054 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000055 if (emulate_insn_ptr)
56 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000057 }
58 }
Eugene Zelenko34ede342016-03-03 00:51:40 +000059 return nullptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000060}
Greg Clayton6da4ca82011-01-21 22:02:52 +000061
Greg Clayton2ed751b2011-04-26 04:39:08 +000062EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
Eugene Zelenko34ede342016-03-03 00:51:40 +000063 m_arch(arch),
64 m_baton(nullptr),
65 m_read_mem_callback(&ReadMemoryDefault),
66 m_write_mem_callback(&WriteMemoryDefault),
67 m_read_reg_callback(&ReadRegisterDefault),
68 m_write_reg_callback(&WriteRegisterDefault),
69 m_addr(LLDB_INVALID_ADDRESS)
Caroline Ticead379efc2011-04-05 18:46:00 +000070{
71 ::memset (&m_opcode, 0, sizeof (m_opcode));
72}
73
Greg Clayton7349bd92011-05-09 20:18:18 +000074bool
75EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
76{
Eugene Zelenko34ede342016-03-03 00:51:40 +000077 if (m_read_reg_callback != nullptr)
Greg Clayton7349bd92011-05-09 20:18:18 +000078 return m_read_reg_callback (this, m_baton, reg_info, reg_value);
79 return false;
80}
81
82bool
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +000083EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value)
Greg Clayton6da4ca82011-01-21 22:02:52 +000084{
Greg Clayton79ea8782011-04-26 23:48:45 +000085 RegisterInfo reg_info;
86 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
Greg Clayton7349bd92011-05-09 20:18:18 +000087 return ReadRegister (&reg_info, reg_value);
88 return false;
89}
90
91uint64_t
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +000092EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind,
Greg Clayton7349bd92011-05-09 20:18:18 +000093 uint32_t reg_num,
94 uint64_t fail_value,
95 bool *success_ptr)
96{
97 RegisterValue reg_value;
98 if (ReadRegister (reg_kind, reg_num, reg_value))
99 return reg_value.GetAsUInt64(fail_value, success_ptr);
Greg Clayton79ea8782011-04-26 23:48:45 +0000100 if (success_ptr)
101 *success_ptr = false;
102 return fail_value;
103}
104
105uint64_t
Greg Clayton7349bd92011-05-09 20:18:18 +0000106EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
107 uint64_t fail_value,
108 bool *success_ptr)
Greg Clayton79ea8782011-04-26 23:48:45 +0000109{
Greg Clayton7349bd92011-05-09 20:18:18 +0000110 RegisterValue reg_value;
111 if (ReadRegister (reg_info, reg_value))
112 return reg_value.GetAsUInt64(fail_value, success_ptr);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000113 if (success_ptr)
Greg Clayton7349bd92011-05-09 20:18:18 +0000114 *success_ptr = false;
115 return fail_value;
Greg Clayton6da4ca82011-01-21 22:02:52 +0000116}
117
118bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000119EmulateInstruction::WriteRegister (const Context &context,
120 const RegisterInfo *reg_info,
121 const RegisterValue& reg_value)
Greg Clayton6da4ca82011-01-21 22:02:52 +0000122{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000123 if (m_write_reg_callback != nullptr)
Greg Clayton7349bd92011-05-09 20:18:18 +0000124 return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
Greg Clayton79ea8782011-04-26 23:48:45 +0000125 return false;
126}
127
128bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000129EmulateInstruction::WriteRegister (const Context &context,
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000130 lldb::RegisterKind reg_kind,
Greg Clayton7349bd92011-05-09 20:18:18 +0000131 uint32_t reg_num,
132 const RegisterValue& reg_value)
Greg Clayton79ea8782011-04-26 23:48:45 +0000133{
Greg Clayton7349bd92011-05-09 20:18:18 +0000134 RegisterInfo reg_info;
135 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
136 return WriteRegister (context, &reg_info, reg_value);
137 return false;
138}
139
Greg Clayton7349bd92011-05-09 20:18:18 +0000140bool
141EmulateInstruction::WriteRegisterUnsigned (const Context &context,
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000142 lldb::RegisterKind reg_kind,
Greg Clayton7349bd92011-05-09 20:18:18 +0000143 uint32_t reg_num,
144 uint64_t uint_value)
145{
Greg Clayton7349bd92011-05-09 20:18:18 +0000146 RegisterInfo reg_info;
147 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
148 {
149 RegisterValue reg_value;
150 if (reg_value.SetUInt(uint_value, reg_info.byte_size))
151 return WriteRegister (context, &reg_info, reg_value);
152 }
153 return false;
154}
155
156bool
157EmulateInstruction::WriteRegisterUnsigned (const Context &context,
158 const RegisterInfo *reg_info,
159 uint64_t uint_value)
160{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000161 if (reg_info != nullptr)
Greg Clayton7349bd92011-05-09 20:18:18 +0000162 {
163 RegisterValue reg_value;
164 if (reg_value.SetUInt(uint_value, reg_info->byte_size))
165 return WriteRegister (context, reg_info, reg_value);
166 }
167 return false;
168}
169
170size_t
171EmulateInstruction::ReadMemory (const Context &context,
172 lldb::addr_t addr,
173 void *dst,
174 size_t dst_len)
175{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000176 if (m_read_mem_callback != nullptr)
Greg Clayton7349bd92011-05-09 20:18:18 +0000177 return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
178 return false;
Greg Clayton6da4ca82011-01-21 22:02:52 +0000179}
180
181uint64_t
182EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
183{
184 uint64_t uval64 = 0;
185 bool success = false;
186 if (byte_size <= 8)
187 {
188 uint8_t buf[sizeof(uint64_t)];
Greg Clayton2ed751b2011-04-26 04:39:08 +0000189 size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000190 if (bytes_read == byte_size)
191 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000192 lldb::offset_t offset = 0;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000193 DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
Greg Clayton6da4ca82011-01-21 22:02:52 +0000194 uval64 = data.GetMaxU64 (&offset, byte_size);
195 success = true;
196 }
197 }
198
199 if (success_ptr)
200 *success_ptr = success;
201
202 if (!success)
203 uval64 = fail_value;
204 return uval64;
205}
206
Greg Clayton6da4ca82011-01-21 22:02:52 +0000207bool
208EmulateInstruction::WriteMemoryUnsigned (const Context &context,
209 lldb::addr_t addr,
210 uint64_t uval,
211 size_t uval_byte_size)
212{
213 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
214 strm.PutMaxHex64 (uval, uval_byte_size);
215
Greg Clayton2ed751b2011-04-26 04:39:08 +0000216 size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
Eugene Zelenko34ede342016-03-03 00:51:40 +0000217 return (bytes_written == uval_byte_size);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000218}
Caroline Ticead379efc2011-04-05 18:46:00 +0000219
Greg Clayton7349bd92011-05-09 20:18:18 +0000220bool
221EmulateInstruction::WriteMemory (const Context &context,
222 lldb::addr_t addr,
223 const void *src,
224 size_t src_len)
225{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000226 if (m_write_mem_callback != nullptr)
Greg Clayton7349bd92011-05-09 20:18:18 +0000227 return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
228 return false;
229}
230
Caroline Ticead379efc2011-04-05 18:46:00 +0000231void
232EmulateInstruction::SetBaton (void *baton)
233{
234 m_baton = baton;
235}
236
237void
Greg Clayton7349bd92011-05-09 20:18:18 +0000238EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
239 WriteMemoryCallback write_mem_callback,
240 ReadRegisterCallback read_reg_callback,
241 WriteRegisterCallback write_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000242{
243 m_read_mem_callback = read_mem_callback;
244 m_write_mem_callback = write_mem_callback;
245 m_read_reg_callback = read_reg_callback;
246 m_write_reg_callback = write_reg_callback;
247}
248
249void
Greg Clayton7349bd92011-05-09 20:18:18 +0000250EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000251{
252 m_read_mem_callback = read_mem_callback;
253}
254
Caroline Ticead379efc2011-04-05 18:46:00 +0000255void
Greg Clayton7349bd92011-05-09 20:18:18 +0000256EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000257{
258 m_write_mem_callback = write_mem_callback;
259}
260
Caroline Ticead379efc2011-04-05 18:46:00 +0000261void
Greg Clayton7349bd92011-05-09 20:18:18 +0000262EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000263{
264 m_read_reg_callback = read_reg_callback;
265}
266
Caroline Ticead379efc2011-04-05 18:46:00 +0000267void
Greg Clayton7349bd92011-05-09 20:18:18 +0000268EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000269{
270 m_write_reg_callback = write_reg_callback;
271}
272
Caroline Ticead379efc2011-04-05 18:46:00 +0000273//
274// Read & Write Memory and Registers callback functions.
275//
276
277size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000278EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
279 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000280 const Context &context,
281 lldb::addr_t addr,
282 void *dst,
Greg Claytond9e416c2012-02-18 05:35:26 +0000283 size_t dst_len)
Caroline Ticead379efc2011-04-05 18:46:00 +0000284{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000285 if (baton == nullptr || dst == nullptr || dst_len == 0)
Caroline Ticead379efc2011-04-05 18:46:00 +0000286 return 0;
Greg Claytond9e416c2012-02-18 05:35:26 +0000287
Jason Molendab57e4a12013-11-04 09:33:30 +0000288 StackFrame *frame = (StackFrame *) baton;
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000289
Greg Claytond9e416c2012-02-18 05:35:26 +0000290 ProcessSP process_sp (frame->CalculateProcess());
291 if (process_sp)
292 {
293 Error error;
294 return process_sp->ReadMemory (addr, dst, dst_len, error);
295 }
296 return 0;
Caroline Ticead379efc2011-04-05 18:46:00 +0000297}
298
299size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000300EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
301 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000302 const Context &context,
303 lldb::addr_t addr,
Greg Claytond9e416c2012-02-18 05:35:26 +0000304 const void *src,
305 size_t src_len)
Caroline Ticead379efc2011-04-05 18:46:00 +0000306{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000307 if (baton == nullptr || src == nullptr || src_len == 0)
Caroline Ticead379efc2011-04-05 18:46:00 +0000308 return 0;
309
Jason Molendab57e4a12013-11-04 09:33:30 +0000310 StackFrame *frame = (StackFrame *) baton;
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000311
Greg Claytond9e416c2012-02-18 05:35:26 +0000312 ProcessSP process_sp (frame->CalculateProcess());
313 if (process_sp)
Caroline Ticead379efc2011-04-05 18:46:00 +0000314 {
Greg Claytond9e416c2012-02-18 05:35:26 +0000315 Error error;
316 return process_sp->WriteMemory (addr, src, src_len, error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000317 }
318
319 return 0;
320}
321
322bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000323EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
324 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000325 const RegisterInfo *reg_info,
326 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000327{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000328 if (baton == nullptr)
Caroline Ticead379efc2011-04-05 18:46:00 +0000329 return false;
330
Jason Molendab57e4a12013-11-04 09:33:30 +0000331 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000332 return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000333}
334
335bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000336EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
337 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000338 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000339 const RegisterInfo *reg_info,
340 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000341{
Eugene Zelenko34ede342016-03-03 00:51:40 +0000342 if (baton == nullptr)
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000343 return false;
344
Jason Molendab57e4a12013-11-04 09:33:30 +0000345 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000346 return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000347}
348
349size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000350EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
351 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000352 const Context &context,
353 lldb::addr_t addr,
354 void *dst,
355 size_t length)
356{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000357 StreamFile strm (stdout, false);
Daniel Malead01b2952012-11-29 21:49:15 +0000358 strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000359 context.Dump (strm, instruction);
360 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000361 *((uint64_t *) dst) = 0xdeadbeef;
362 return length;
363}
364
365size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000366EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
367 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000368 const Context &context,
369 lldb::addr_t addr,
370 const void *dst,
371 size_t length)
372{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000373 StreamFile strm (stdout, false);
Daniel Malead01b2952012-11-29 21:49:15 +0000374 strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000375 context.Dump (strm, instruction);
376 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000377 return length;
378}
379
380bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000381EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
382 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000383 const RegisterInfo *reg_info,
384 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000385{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000386 StreamFile strm (stdout, false);
387 strm.Printf (" Read Register (%s)\n", reg_info->name);
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000388 lldb::RegisterKind reg_kind;
389 uint32_t reg_num;
Greg Clayton79ea8782011-04-26 23:48:45 +0000390 if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
Greg Clayton7349bd92011-05-09 20:18:18 +0000391 reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
Greg Clayton79ea8782011-04-26 23:48:45 +0000392 else
Greg Clayton7349bd92011-05-09 20:18:18 +0000393 reg_value.SetUInt64(0);
Greg Clayton79ea8782011-04-26 23:48:45 +0000394
Caroline Ticead379efc2011-04-05 18:46:00 +0000395 return true;
396}
397
398bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000399EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
400 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000401 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000402 const RegisterInfo *reg_info,
403 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000404{
Greg Clayton7349bd92011-05-09 20:18:18 +0000405 StreamFile strm (stdout, false);
406 strm.Printf (" Write to Register (name = %s, value = " , reg_info->name);
Greg Clayton9a8fa912011-05-15 04:12:07 +0000407 reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
Greg Clayton7349bd92011-05-09 20:18:18 +0000408 strm.PutCString (", context = ");
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000409 context.Dump (strm, instruction);
410 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000411 return true;
412}
413
414void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000415EmulateInstruction::Context::Dump (Stream &strm,
Greg Clayton79ea8782011-04-26 23:48:45 +0000416 EmulateInstruction *instruction) const
Caroline Ticead379efc2011-04-05 18:46:00 +0000417{
Greg Clayton79ea8782011-04-26 23:48:45 +0000418 switch (type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000419 {
420 case eContextReadOpcode:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000421 strm.PutCString ("reading opcode");
Caroline Ticead379efc2011-04-05 18:46:00 +0000422 break;
423
424 case eContextImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000425 strm.PutCString ("immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000426 break;
427
428 case eContextPushRegisterOnStack:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000429 strm.PutCString ("push register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000430 break;
431
432 case eContextPopRegisterOffStack:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000433 strm.PutCString ("pop register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000434 break;
435
436 case eContextAdjustStackPointer:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000437 strm.PutCString ("adjust sp");
Caroline Ticead379efc2011-04-05 18:46:00 +0000438 break;
439
Greg Claytona658fd22011-06-04 01:26:29 +0000440 case eContextSetFramePointer:
441 strm.PutCString ("set frame pointer");
442 break;
443
Caroline Ticead379efc2011-04-05 18:46:00 +0000444 case eContextAdjustBaseRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000445 strm.PutCString ("adjusting (writing value back to) a base register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000446 break;
447
448 case eContextRegisterPlusOffset:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000449 strm.PutCString ("register + offset");
Caroline Ticead379efc2011-04-05 18:46:00 +0000450 break;
451
452 case eContextRegisterStore:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000453 strm.PutCString ("store register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000454 break;
455
456 case eContextRegisterLoad:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000457 strm.PutCString ("load register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000458 break;
459
460 case eContextRelativeBranchImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000461 strm.PutCString ("relative branch immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000462 break;
463
464 case eContextAbsoluteBranchRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000465 strm.PutCString ("absolute branch register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000466 break;
467
468 case eContextSupervisorCall:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000469 strm.PutCString ("supervisor call");
Caroline Ticead379efc2011-04-05 18:46:00 +0000470 break;
471
472 case eContextTableBranchReadMemory:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000473 strm.PutCString ("table branch read memory");
Caroline Ticead379efc2011-04-05 18:46:00 +0000474 break;
475
476 case eContextWriteRegisterRandomBits:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000477 strm.PutCString ("write random bits to a register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000478 break;
479
480 case eContextWriteMemoryRandomBits:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000481 strm.PutCString ("write random bits to a memory address");
Caroline Ticead379efc2011-04-05 18:46:00 +0000482 break;
483
Greg Clayton79ea8782011-04-26 23:48:45 +0000484 case eContextArithmetic:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000485 strm.PutCString ("arithmetic");
Caroline Ticead379efc2011-04-05 18:46:00 +0000486 break;
487
488 case eContextReturnFromException:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000489 strm.PutCString ("return from exception");
Caroline Ticead379efc2011-04-05 18:46:00 +0000490 break;
491
492 default:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000493 strm.PutCString ("unrecognized context.");
Caroline Ticead379efc2011-04-05 18:46:00 +0000494 break;
495 }
496
Greg Clayton79ea8782011-04-26 23:48:45 +0000497 switch (info_type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000498 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000499 case eInfoTypeRegisterPlusOffset:
Eugene Zelenko34ede342016-03-03 00:51:40 +0000500 strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
501 info.RegisterPlusOffset.reg.name,
502 info.RegisterPlusOffset.signed_offset);
Greg Clayton79ea8782011-04-26 23:48:45 +0000503 break;
504
505 case eInfoTypeRegisterPlusIndirectOffset:
Eugene Zelenko34ede342016-03-03 00:51:40 +0000506 strm.Printf(" (reg_plus_reg = %s + %s)",
507 info.RegisterPlusIndirectOffset.base_reg.name,
508 info.RegisterPlusIndirectOffset.offset_reg.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000509 break;
510
511 case eInfoTypeRegisterToRegisterPlusOffset:
Eugene Zelenko34ede342016-03-03 00:51:40 +0000512 strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
513 info.RegisterToRegisterPlusOffset.base_reg.name,
514 info.RegisterToRegisterPlusOffset.offset,
515 info.RegisterToRegisterPlusOffset.data_reg.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000516 break;
517
518 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
Eugene Zelenko34ede342016-03-03 00:51:40 +0000519 strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
520 info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
521 info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
522 info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000523 break;
524
525 case eInfoTypeRegisterRegisterOperands:
Eugene Zelenko34ede342016-03-03 00:51:40 +0000526 strm.Printf(" (register to register binary op: %s and %s)",
527 info.RegisterRegisterOperands.operand1.name,
528 info.RegisterRegisterOperands.operand2.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000529 break;
530
531 case eInfoTypeOffset:
Daniel Malead01b2952012-11-29 21:49:15 +0000532 strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
Greg Clayton79ea8782011-04-26 23:48:45 +0000533 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000534
Greg Clayton79ea8782011-04-26 23:48:45 +0000535 case eInfoTypeRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000536 strm.Printf (" (reg = %s)", info.reg.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000537 break;
538
539 case eInfoTypeImmediate:
Daniel Malead01b2952012-11-29 21:49:15 +0000540 strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000541 info.unsigned_immediate,
542 info.unsigned_immediate);
Greg Clayton79ea8782011-04-26 23:48:45 +0000543 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000544
Greg Clayton79ea8782011-04-26 23:48:45 +0000545 case eInfoTypeImmediateSigned:
Daniel Malead01b2952012-11-29 21:49:15 +0000546 strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000547 info.signed_immediate,
548 info.signed_immediate);
Greg Clayton79ea8782011-04-26 23:48:45 +0000549 break;
550
551 case eInfoTypeAddress:
Daniel Malead01b2952012-11-29 21:49:15 +0000552 strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
Greg Clayton79ea8782011-04-26 23:48:45 +0000553 break;
554
555 case eInfoTypeISAAndImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000556 strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
557 info.ISAAndImmediate.isa,
558 info.ISAAndImmediate.unsigned_data32,
559 info.ISAAndImmediate.unsigned_data32);
Greg Clayton79ea8782011-04-26 23:48:45 +0000560 break;
561
562 case eInfoTypeISAAndImmediateSigned:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000563 strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))",
564 info.ISAAndImmediateSigned.isa,
565 info.ISAAndImmediateSigned.signed_data32,
566 info.ISAAndImmediateSigned.signed_data32);
Greg Clayton79ea8782011-04-26 23:48:45 +0000567 break;
568
569 case eInfoTypeISA:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000570 strm.Printf (" (isa = %u)", info.isa);
Greg Clayton79ea8782011-04-26 23:48:45 +0000571 break;
572
573 case eInfoTypeNoArgs:
Greg Clayton79ea8782011-04-26 23:48:45 +0000574 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000575 }
576}
577
Greg Clayton2ed751b2011-04-26 04:39:08 +0000578bool
579EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
Caroline Ticead379efc2011-04-05 18:46:00 +0000580{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000581 m_opcode = opcode;
Greg Claytone5b34982011-04-29 22:50:31 +0000582 m_addr = LLDB_INVALID_ADDRESS;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000583 if (inst_addr.IsValid())
Caroline Ticead379efc2011-04-05 18:46:00 +0000584 {
Eugene Zelenko34ede342016-03-03 00:51:40 +0000585 if (target != nullptr)
Greg Claytone5b34982011-04-29 22:50:31 +0000586 m_addr = inst_addr.GetLoadAddress (target);
587 if (m_addr == LLDB_INVALID_ADDRESS)
588 m_addr = inst_addr.GetFileAddress ();
Caroline Ticead379efc2011-04-05 18:46:00 +0000589 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000590 return true;
Caroline Ticead379efc2011-04-05 18:46:00 +0000591}
592
Greg Clayton79ea8782011-04-26 23:48:45 +0000593bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000594EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000595 lldb::RegisterKind &reg_kind,
Greg Clayton79ea8782011-04-26 23:48:45 +0000596 uint32_t &reg_num)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000597{
Greg Clayton79ea8782011-04-26 23:48:45 +0000598 // Generic and DWARF should be the two most popular register kinds when
599 // emulating instructions since they are the most platform agnostic...
Greg Clayton7349bd92011-05-09 20:18:18 +0000600 reg_num = reg_info->kinds[eRegisterKindGeneric];
Greg Clayton79ea8782011-04-26 23:48:45 +0000601 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000602 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000603 reg_kind = eRegisterKindGeneric;
604 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000605 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000606
Greg Clayton7349bd92011-05-09 20:18:18 +0000607 reg_num = reg_info->kinds[eRegisterKindDWARF];
Greg Clayton79ea8782011-04-26 23:48:45 +0000608 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000609 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000610 reg_kind = eRegisterKindDWARF;
611 return true;
612 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000613
Greg Clayton7349bd92011-05-09 20:18:18 +0000614 reg_num = reg_info->kinds[eRegisterKindLLDB];
Greg Clayton79ea8782011-04-26 23:48:45 +0000615 if (reg_num != LLDB_INVALID_REGNUM)
616 {
617 reg_kind = eRegisterKindLLDB;
618 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000619 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000620
Jason Molendaa18f7072015-08-15 01:21:01 +0000621 reg_num = reg_info->kinds[eRegisterKindEHFrame];
Greg Clayton79ea8782011-04-26 23:48:45 +0000622 if (reg_num != LLDB_INVALID_REGNUM)
623 {
Jason Molendaa18f7072015-08-15 01:21:01 +0000624 reg_kind = eRegisterKindEHFrame;
Greg Clayton79ea8782011-04-26 23:48:45 +0000625 return true;
626 }
627
Jason Molenda63bd0db2015-09-15 23:20:34 +0000628 reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
Greg Clayton79ea8782011-04-26 23:48:45 +0000629 if (reg_num != LLDB_INVALID_REGNUM)
630 {
Jason Molenda63bd0db2015-09-15 23:20:34 +0000631 reg_kind = eRegisterKindProcessPlugin;
Greg Clayton79ea8782011-04-26 23:48:45 +0000632 return true;
633 }
634 return false;
635}
636
637uint32_t
638EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
639{
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000640 lldb::RegisterKind reg_kind;
641 uint32_t reg_num;
Greg Clayton7349bd92011-05-09 20:18:18 +0000642 if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
Greg Clayton79ea8782011-04-26 23:48:45 +0000643 return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
644 return LLDB_INVALID_REGNUM;
645}
646
Greg Clayton79ea8782011-04-26 23:48:45 +0000647bool
648EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
649{
650 unwind_plan.Clear();
651 return false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000652}