blob: 8349f54de4c7ca928120ad0476445ee957e0bb63 [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
Greg Clayton2ed751b2011-04-26 04:39:08 +000012#include "lldb/Core/Address.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000013#include "lldb/Core/DataExtractor.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000014#include "lldb/Core/Error.h"
Greg Clayton4272cc72011-02-02 02:24:04 +000015#include "lldb/Core/PluginManager.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000016#include "lldb/Core/RegisterValue.h"
17#include "lldb/Core/StreamFile.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000018#include "lldb/Core/StreamString.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000019#include "lldb/Host/Endian.h"
Greg Clayton79ea8782011-04-26 23:48:45 +000020#include "lldb/Symbol/UnwindPlan.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000021#include "lldb/Target/Process.h"
22#include "lldb/Target/RegisterContext.h"
Greg Clayton2ed751b2011-04-26 04:39:08 +000023#include "lldb/Target/Target.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000024#include "lldb/Target/Thread.h"
25
Greg Clayton6da4ca82011-01-21 22:02:52 +000026using namespace lldb;
27using namespace lldb_private;
28
Greg Clayton4272cc72011-02-02 02:24:04 +000029EmulateInstruction*
Greg Clayton2ed751b2011-04-26 04:39:08 +000030EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
Greg Clayton4272cc72011-02-02 02:24:04 +000031{
32 EmulateInstructionCreateInstance create_callback = NULL;
33 if (plugin_name)
34 {
Greg Clayton57abc5d2013-05-10 21:47:16 +000035 ConstString const_plugin_name (plugin_name);
36 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name);
Greg Clayton4272cc72011-02-02 02:24:04 +000037 if (create_callback)
38 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000039 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000040 if (emulate_insn_ptr)
41 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000042 }
43 }
44 else
45 {
46 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
47 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000048 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000049 if (emulate_insn_ptr)
50 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000051 }
52 }
53 return NULL;
54}
Greg Clayton6da4ca82011-01-21 22:02:52 +000055
Greg Clayton2ed751b2011-04-26 04:39:08 +000056EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
Caroline Ticead379efc2011-04-05 18:46:00 +000057 m_arch (arch),
58 m_baton (NULL),
59 m_read_mem_callback (&ReadMemoryDefault),
60 m_write_mem_callback (&WriteMemoryDefault),
61 m_read_reg_callback (&ReadRegisterDefault),
62 m_write_reg_callback (&WriteRegisterDefault),
Greg Claytone5b34982011-04-29 22:50:31 +000063 m_addr (LLDB_INVALID_ADDRESS)
Caroline Ticead379efc2011-04-05 18:46:00 +000064{
65 ::memset (&m_opcode, 0, sizeof (m_opcode));
66}
67
Greg Clayton79ea8782011-04-26 23:48:45 +000068
Greg Clayton7349bd92011-05-09 20:18:18 +000069bool
70EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
71{
72 if (m_read_reg_callback)
73 return m_read_reg_callback (this, m_baton, reg_info, reg_value);
74 return false;
75}
76
77bool
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +000078EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value)
Greg Clayton6da4ca82011-01-21 22:02:52 +000079{
Greg Clayton79ea8782011-04-26 23:48:45 +000080 RegisterInfo reg_info;
81 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
Greg Clayton7349bd92011-05-09 20:18:18 +000082 return ReadRegister (&reg_info, reg_value);
83 return false;
84}
85
86uint64_t
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +000087EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind,
Greg Clayton7349bd92011-05-09 20:18:18 +000088 uint32_t reg_num,
89 uint64_t fail_value,
90 bool *success_ptr)
91{
92 RegisterValue reg_value;
93 if (ReadRegister (reg_kind, reg_num, reg_value))
94 return reg_value.GetAsUInt64(fail_value, success_ptr);
Greg Clayton79ea8782011-04-26 23:48:45 +000095 if (success_ptr)
96 *success_ptr = false;
97 return fail_value;
98}
99
100uint64_t
Greg Clayton7349bd92011-05-09 20:18:18 +0000101EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
102 uint64_t fail_value,
103 bool *success_ptr)
Greg Clayton79ea8782011-04-26 23:48:45 +0000104{
Greg Clayton7349bd92011-05-09 20:18:18 +0000105 RegisterValue reg_value;
106 if (ReadRegister (reg_info, reg_value))
107 return reg_value.GetAsUInt64(fail_value, success_ptr);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000108 if (success_ptr)
Greg Clayton7349bd92011-05-09 20:18:18 +0000109 *success_ptr = false;
110 return fail_value;
Greg Clayton6da4ca82011-01-21 22:02:52 +0000111}
112
113bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000114EmulateInstruction::WriteRegister (const Context &context,
115 const RegisterInfo *reg_info,
116 const RegisterValue& reg_value)
Greg Clayton6da4ca82011-01-21 22:02:52 +0000117{
Greg Clayton7349bd92011-05-09 20:18:18 +0000118 if (m_write_reg_callback)
119 return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
Greg Clayton79ea8782011-04-26 23:48:45 +0000120 return false;
121}
122
123bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000124EmulateInstruction::WriteRegister (const Context &context,
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000125 lldb::RegisterKind reg_kind,
Greg Clayton7349bd92011-05-09 20:18:18 +0000126 uint32_t reg_num,
127 const RegisterValue& reg_value)
Greg Clayton79ea8782011-04-26 23:48:45 +0000128{
Greg Clayton7349bd92011-05-09 20:18:18 +0000129 RegisterInfo reg_info;
130 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
131 return WriteRegister (context, &reg_info, reg_value);
132 return false;
133}
134
135
136bool
137EmulateInstruction::WriteRegisterUnsigned (const Context &context,
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000138 lldb::RegisterKind reg_kind,
Greg Clayton7349bd92011-05-09 20:18:18 +0000139 uint32_t reg_num,
140 uint64_t uint_value)
141{
142
143 RegisterInfo reg_info;
144 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
145 {
146 RegisterValue reg_value;
147 if (reg_value.SetUInt(uint_value, reg_info.byte_size))
148 return WriteRegister (context, &reg_info, reg_value);
149 }
150 return false;
151}
152
153bool
154EmulateInstruction::WriteRegisterUnsigned (const Context &context,
155 const RegisterInfo *reg_info,
156 uint64_t uint_value)
157{
158
159 if (reg_info)
160 {
161 RegisterValue reg_value;
162 if (reg_value.SetUInt(uint_value, reg_info->byte_size))
163 return WriteRegister (context, reg_info, reg_value);
164 }
165 return false;
166}
167
168size_t
169EmulateInstruction::ReadMemory (const Context &context,
170 lldb::addr_t addr,
171 void *dst,
172 size_t dst_len)
173{
174 if (m_read_mem_callback)
175 return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
176 return false;
Greg Clayton6da4ca82011-01-21 22:02:52 +0000177}
178
179uint64_t
180EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
181{
182 uint64_t uval64 = 0;
183 bool success = false;
184 if (byte_size <= 8)
185 {
186 uint8_t buf[sizeof(uint64_t)];
Greg Clayton2ed751b2011-04-26 04:39:08 +0000187 size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000188 if (bytes_read == byte_size)
189 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000190 lldb::offset_t offset = 0;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000191 DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
Greg Clayton6da4ca82011-01-21 22:02:52 +0000192 uval64 = data.GetMaxU64 (&offset, byte_size);
193 success = true;
194 }
195 }
196
197 if (success_ptr)
198 *success_ptr = success;
199
200 if (!success)
201 uval64 = fail_value;
202 return uval64;
203}
204
205
206bool
207EmulateInstruction::WriteMemoryUnsigned (const Context &context,
208 lldb::addr_t addr,
209 uint64_t uval,
210 size_t uval_byte_size)
211{
212 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
213 strm.PutMaxHex64 (uval, uval_byte_size);
214
Greg Clayton2ed751b2011-04-26 04:39:08 +0000215 size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000216 if (bytes_written == uval_byte_size)
217 return true;
218 return false;
219}
Caroline Ticead379efc2011-04-05 18:46:00 +0000220
Greg Clayton7349bd92011-05-09 20:18:18 +0000221bool
222EmulateInstruction::WriteMemory (const Context &context,
223 lldb::addr_t addr,
224 const void *src,
225 size_t src_len)
226{
227 if (m_write_mem_callback)
228 return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
229 return false;
230}
231
Caroline Ticead379efc2011-04-05 18:46:00 +0000232
233void
234EmulateInstruction::SetBaton (void *baton)
235{
236 m_baton = baton;
237}
238
239void
Greg Clayton7349bd92011-05-09 20:18:18 +0000240EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
241 WriteMemoryCallback write_mem_callback,
242 ReadRegisterCallback read_reg_callback,
243 WriteRegisterCallback write_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000244{
245 m_read_mem_callback = read_mem_callback;
246 m_write_mem_callback = write_mem_callback;
247 m_read_reg_callback = read_reg_callback;
248 m_write_reg_callback = write_reg_callback;
249}
250
251void
Greg Clayton7349bd92011-05-09 20:18:18 +0000252EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000253{
254 m_read_mem_callback = read_mem_callback;
255}
256
257
258void
Greg Clayton7349bd92011-05-09 20:18:18 +0000259EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000260{
261 m_write_mem_callback = write_mem_callback;
262}
263
264
265void
Greg Clayton7349bd92011-05-09 20:18:18 +0000266EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000267{
268 m_read_reg_callback = read_reg_callback;
269}
270
271
272void
Greg Clayton7349bd92011-05-09 20:18:18 +0000273EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000274{
275 m_write_reg_callback = write_reg_callback;
276}
277
278
279
280//
281// Read & Write Memory and Registers callback functions.
282//
283
284size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000285EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
286 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000287 const Context &context,
288 lldb::addr_t addr,
289 void *dst,
Greg Claytond9e416c2012-02-18 05:35:26 +0000290 size_t dst_len)
Caroline Ticead379efc2011-04-05 18:46:00 +0000291{
Greg Claytond9e416c2012-02-18 05:35:26 +0000292 if (!baton || dst == NULL || dst_len == 0)
Caroline Ticead379efc2011-04-05 18:46:00 +0000293 return 0;
Greg Claytond9e416c2012-02-18 05:35:26 +0000294
Jason Molendab57e4a12013-11-04 09:33:30 +0000295 StackFrame *frame = (StackFrame *) baton;
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000296
Greg Claytond9e416c2012-02-18 05:35:26 +0000297 ProcessSP process_sp (frame->CalculateProcess());
298 if (process_sp)
299 {
300 Error error;
301 return process_sp->ReadMemory (addr, dst, dst_len, error);
302 }
303 return 0;
Caroline Ticead379efc2011-04-05 18:46:00 +0000304}
305
306size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000307EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
308 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000309 const Context &context,
310 lldb::addr_t addr,
Greg Claytond9e416c2012-02-18 05:35:26 +0000311 const void *src,
312 size_t src_len)
Caroline Ticead379efc2011-04-05 18:46:00 +0000313{
Greg Claytond9e416c2012-02-18 05:35:26 +0000314 if (!baton || src == NULL || src_len == 0)
Caroline Ticead379efc2011-04-05 18:46:00 +0000315 return 0;
316
Jason Molendab57e4a12013-11-04 09:33:30 +0000317 StackFrame *frame = (StackFrame *) baton;
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000318
Greg Claytond9e416c2012-02-18 05:35:26 +0000319 ProcessSP process_sp (frame->CalculateProcess());
320 if (process_sp)
Caroline Ticead379efc2011-04-05 18:46:00 +0000321 {
Greg Claytond9e416c2012-02-18 05:35:26 +0000322 Error error;
323 return process_sp->WriteMemory (addr, src, src_len, error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000324 }
325
326 return 0;
327}
328
329bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000330EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
331 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000332 const RegisterInfo *reg_info,
333 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000334{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000335 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000336 return false;
337
Jason Molendab57e4a12013-11-04 09:33:30 +0000338 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000339 return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000340}
341
342bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000343EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
344 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000345 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000346 const RegisterInfo *reg_info,
347 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000348{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000349 if (!baton)
350 return false;
351
Jason Molendab57e4a12013-11-04 09:33:30 +0000352 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000353 return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000354}
355
356size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000357EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
358 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000359 const Context &context,
360 lldb::addr_t addr,
361 void *dst,
362 size_t length)
363{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000364 StreamFile strm (stdout, false);
Daniel Malead01b2952012-11-29 21:49:15 +0000365 strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000366 context.Dump (strm, instruction);
367 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000368 *((uint64_t *) dst) = 0xdeadbeef;
369 return length;
370}
371
372size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000373EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
374 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000375 const Context &context,
376 lldb::addr_t addr,
377 const void *dst,
378 size_t length)
379{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000380 StreamFile strm (stdout, false);
Daniel Malead01b2952012-11-29 21:49:15 +0000381 strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000382 context.Dump (strm, instruction);
383 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000384 return length;
385}
386
387bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000388EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
389 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000390 const RegisterInfo *reg_info,
391 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000392{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000393 StreamFile strm (stdout, false);
394 strm.Printf (" Read Register (%s)\n", reg_info->name);
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000395 lldb::RegisterKind reg_kind;
396 uint32_t reg_num;
Greg Clayton79ea8782011-04-26 23:48:45 +0000397 if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
Greg Clayton7349bd92011-05-09 20:18:18 +0000398 reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
Greg Clayton79ea8782011-04-26 23:48:45 +0000399 else
Greg Clayton7349bd92011-05-09 20:18:18 +0000400 reg_value.SetUInt64(0);
Greg Clayton79ea8782011-04-26 23:48:45 +0000401
Caroline Ticead379efc2011-04-05 18:46:00 +0000402 return true;
403}
404
405bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000406EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
407 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000408 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000409 const RegisterInfo *reg_info,
410 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000411{
Greg Clayton7349bd92011-05-09 20:18:18 +0000412 StreamFile strm (stdout, false);
413 strm.Printf (" Write to Register (name = %s, value = " , reg_info->name);
Greg Clayton9a8fa912011-05-15 04:12:07 +0000414 reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
Greg Clayton7349bd92011-05-09 20:18:18 +0000415 strm.PutCString (", context = ");
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000416 context.Dump (strm, instruction);
417 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000418 return true;
419}
420
421void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000422EmulateInstruction::Context::Dump (Stream &strm,
Greg Clayton79ea8782011-04-26 23:48:45 +0000423 EmulateInstruction *instruction) const
Caroline Ticead379efc2011-04-05 18:46:00 +0000424{
Greg Clayton79ea8782011-04-26 23:48:45 +0000425 switch (type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000426 {
427 case eContextReadOpcode:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000428 strm.PutCString ("reading opcode");
Caroline Ticead379efc2011-04-05 18:46:00 +0000429 break;
430
431 case eContextImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000432 strm.PutCString ("immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000433 break;
434
435 case eContextPushRegisterOnStack:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000436 strm.PutCString ("push register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000437 break;
438
439 case eContextPopRegisterOffStack:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000440 strm.PutCString ("pop register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000441 break;
442
443 case eContextAdjustStackPointer:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000444 strm.PutCString ("adjust sp");
Caroline Ticead379efc2011-04-05 18:46:00 +0000445 break;
446
Greg Claytona658fd22011-06-04 01:26:29 +0000447 case eContextSetFramePointer:
448 strm.PutCString ("set frame pointer");
449 break;
450
Caroline Ticead379efc2011-04-05 18:46:00 +0000451 case eContextAdjustBaseRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000452 strm.PutCString ("adjusting (writing value back to) a base register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000453 break;
454
455 case eContextRegisterPlusOffset:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000456 strm.PutCString ("register + offset");
Caroline Ticead379efc2011-04-05 18:46:00 +0000457 break;
458
459 case eContextRegisterStore:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000460 strm.PutCString ("store register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000461 break;
462
463 case eContextRegisterLoad:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000464 strm.PutCString ("load register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000465 break;
466
467 case eContextRelativeBranchImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000468 strm.PutCString ("relative branch immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000469 break;
470
471 case eContextAbsoluteBranchRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000472 strm.PutCString ("absolute branch register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000473 break;
474
475 case eContextSupervisorCall:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000476 strm.PutCString ("supervisor call");
Caroline Ticead379efc2011-04-05 18:46:00 +0000477 break;
478
479 case eContextTableBranchReadMemory:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000480 strm.PutCString ("table branch read memory");
Caroline Ticead379efc2011-04-05 18:46:00 +0000481 break;
482
483 case eContextWriteRegisterRandomBits:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000484 strm.PutCString ("write random bits to a register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000485 break;
486
487 case eContextWriteMemoryRandomBits:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000488 strm.PutCString ("write random bits to a memory address");
Caroline Ticead379efc2011-04-05 18:46:00 +0000489 break;
490
Greg Clayton79ea8782011-04-26 23:48:45 +0000491 case eContextArithmetic:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000492 strm.PutCString ("arithmetic");
Caroline Ticead379efc2011-04-05 18:46:00 +0000493 break;
494
495 case eContextReturnFromException:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000496 strm.PutCString ("return from exception");
Caroline Ticead379efc2011-04-05 18:46:00 +0000497 break;
498
499 default:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000500 strm.PutCString ("unrecognized context.");
Caroline Ticead379efc2011-04-05 18:46:00 +0000501 break;
502 }
503
Greg Clayton79ea8782011-04-26 23:48:45 +0000504 switch (info_type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000505 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000506 case eInfoTypeRegisterPlusOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000507 {
Daniel Malead01b2952012-11-29 21:49:15 +0000508 strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")",
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000509 info.RegisterPlusOffset.reg.name,
510 info.RegisterPlusOffset.signed_offset);
Caroline Ticead379efc2011-04-05 18:46:00 +0000511 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000512 break;
513
514 case eInfoTypeRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000515 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000516 strm.Printf (" (reg_plus_reg = %s + %s)",
517 info.RegisterPlusIndirectOffset.base_reg.name,
518 info.RegisterPlusIndirectOffset.offset_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000519 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000520 break;
521
522 case eInfoTypeRegisterToRegisterPlusOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000523 {
Daniel Malead01b2952012-11-29 21:49:15 +0000524 strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000525 info.RegisterToRegisterPlusOffset.base_reg.name,
526 info.RegisterToRegisterPlusOffset.offset,
527 info.RegisterToRegisterPlusOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000528 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000529 break;
530
531 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000532 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000533 strm.Printf (" (base_and_reg_offset = %s + %s, data_reg = %s)",
534 info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
535 info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
536 info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000537 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000538 break;
539
540 case eInfoTypeRegisterRegisterOperands:
541 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000542 strm.Printf (" (register to register binary op: %s and %s)",
543 info.RegisterRegisterOperands.operand1.name,
544 info.RegisterRegisterOperands.operand2.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000545 }
546 break;
547
548 case eInfoTypeOffset:
Daniel Malead01b2952012-11-29 21:49:15 +0000549 strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
Greg Clayton79ea8782011-04-26 23:48:45 +0000550 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000551
Greg Clayton79ea8782011-04-26 23:48:45 +0000552 case eInfoTypeRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000553 strm.Printf (" (reg = %s)", info.reg.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000554 break;
555
556 case eInfoTypeImmediate:
Daniel Malead01b2952012-11-29 21:49:15 +0000557 strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000558 info.unsigned_immediate,
559 info.unsigned_immediate);
Greg Clayton79ea8782011-04-26 23:48:45 +0000560 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000561
Greg Clayton79ea8782011-04-26 23:48:45 +0000562 case eInfoTypeImmediateSigned:
Daniel Malead01b2952012-11-29 21:49:15 +0000563 strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000564 info.signed_immediate,
565 info.signed_immediate);
Greg Clayton79ea8782011-04-26 23:48:45 +0000566 break;
567
568 case eInfoTypeAddress:
Daniel Malead01b2952012-11-29 21:49:15 +0000569 strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
Greg Clayton79ea8782011-04-26 23:48:45 +0000570 break;
571
572 case eInfoTypeISAAndImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000573 strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
574 info.ISAAndImmediate.isa,
575 info.ISAAndImmediate.unsigned_data32,
576 info.ISAAndImmediate.unsigned_data32);
Greg Clayton79ea8782011-04-26 23:48:45 +0000577 break;
578
579 case eInfoTypeISAAndImmediateSigned:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000580 strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))",
581 info.ISAAndImmediateSigned.isa,
582 info.ISAAndImmediateSigned.signed_data32,
583 info.ISAAndImmediateSigned.signed_data32);
Greg Clayton79ea8782011-04-26 23:48:45 +0000584 break;
585
586 case eInfoTypeISA:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000587 strm.Printf (" (isa = %u)", info.isa);
Greg Clayton79ea8782011-04-26 23:48:45 +0000588 break;
589
590 case eInfoTypeNoArgs:
Greg Clayton79ea8782011-04-26 23:48:45 +0000591 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000592 }
593}
594
Greg Clayton2ed751b2011-04-26 04:39:08 +0000595bool
596EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
Caroline Ticead379efc2011-04-05 18:46:00 +0000597{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000598 m_opcode = opcode;
Greg Claytone5b34982011-04-29 22:50:31 +0000599 m_addr = LLDB_INVALID_ADDRESS;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000600 if (inst_addr.IsValid())
Caroline Ticead379efc2011-04-05 18:46:00 +0000601 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000602 if (target)
Greg Claytone5b34982011-04-29 22:50:31 +0000603 m_addr = inst_addr.GetLoadAddress (target);
604 if (m_addr == LLDB_INVALID_ADDRESS)
605 m_addr = inst_addr.GetFileAddress ();
Caroline Ticead379efc2011-04-05 18:46:00 +0000606 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000607 return true;
Caroline Ticead379efc2011-04-05 18:46:00 +0000608}
609
Greg Clayton79ea8782011-04-26 23:48:45 +0000610bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000611EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000612 lldb::RegisterKind &reg_kind,
Greg Clayton79ea8782011-04-26 23:48:45 +0000613 uint32_t &reg_num)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000614{
Greg Clayton79ea8782011-04-26 23:48:45 +0000615 // Generic and DWARF should be the two most popular register kinds when
616 // emulating instructions since they are the most platform agnostic...
Greg Clayton7349bd92011-05-09 20:18:18 +0000617 reg_num = reg_info->kinds[eRegisterKindGeneric];
Greg Clayton79ea8782011-04-26 23:48:45 +0000618 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000619 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000620 reg_kind = eRegisterKindGeneric;
621 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000622 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000623
Greg Clayton7349bd92011-05-09 20:18:18 +0000624 reg_num = reg_info->kinds[eRegisterKindDWARF];
Greg Clayton79ea8782011-04-26 23:48:45 +0000625 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000626 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000627 reg_kind = eRegisterKindDWARF;
628 return true;
629 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000630
Greg Clayton7349bd92011-05-09 20:18:18 +0000631 reg_num = reg_info->kinds[eRegisterKindLLDB];
Greg Clayton79ea8782011-04-26 23:48:45 +0000632 if (reg_num != LLDB_INVALID_REGNUM)
633 {
634 reg_kind = eRegisterKindLLDB;
635 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000636 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000637
Greg Clayton7349bd92011-05-09 20:18:18 +0000638 reg_num = reg_info->kinds[eRegisterKindGCC];
Greg Clayton79ea8782011-04-26 23:48:45 +0000639 if (reg_num != LLDB_INVALID_REGNUM)
640 {
641 reg_kind = eRegisterKindGCC;
642 return true;
643 }
644
Greg Clayton7349bd92011-05-09 20:18:18 +0000645 reg_num = reg_info->kinds[eRegisterKindGDB];
Greg Clayton79ea8782011-04-26 23:48:45 +0000646 if (reg_num != LLDB_INVALID_REGNUM)
647 {
648 reg_kind = eRegisterKindGDB;
649 return true;
650 }
651 return false;
652}
653
654uint32_t
655EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
656{
Jean-Daniel Dupase7c7c3d2014-07-02 09:51:28 +0000657 lldb::RegisterKind reg_kind;
658 uint32_t reg_num;
Greg Clayton7349bd92011-05-09 20:18:18 +0000659 if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
Greg Clayton79ea8782011-04-26 23:48:45 +0000660 return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
661 return LLDB_INVALID_REGNUM;
662}
663
664
665bool
666EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
667{
668 unwind_plan.Clear();
669 return false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000670}
671
Caroline Ticead379efc2011-04-05 18:46:00 +0000672