blob: 0e94e67b8d8e8942e1d74ac6ec4ca43b565ea8ad [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 {
35 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
36 if (create_callback)
37 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000038 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000039 if (emulate_insn_ptr)
40 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000041 }
42 }
43 else
44 {
45 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
46 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000047 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000048 if (emulate_insn_ptr)
49 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000050 }
51 }
52 return NULL;
53}
Greg Clayton6da4ca82011-01-21 22:02:52 +000054
Greg Clayton2ed751b2011-04-26 04:39:08 +000055EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
Caroline Ticead379efc2011-04-05 18:46:00 +000056 m_arch (arch),
57 m_baton (NULL),
58 m_read_mem_callback (&ReadMemoryDefault),
59 m_write_mem_callback (&WriteMemoryDefault),
60 m_read_reg_callback (&ReadRegisterDefault),
61 m_write_reg_callback (&WriteRegisterDefault),
Greg Claytone5b34982011-04-29 22:50:31 +000062 m_addr (LLDB_INVALID_ADDRESS)
Caroline Ticead379efc2011-04-05 18:46:00 +000063{
64 ::memset (&m_opcode, 0, sizeof (m_opcode));
65}
66
Greg Clayton79ea8782011-04-26 23:48:45 +000067
Greg Clayton7349bd92011-05-09 20:18:18 +000068bool
69EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
70{
71 if (m_read_reg_callback)
72 return m_read_reg_callback (this, m_baton, reg_info, reg_value);
73 return false;
74}
75
76bool
77EmulateInstruction::ReadRegister (uint32_t reg_kind, uint32_t reg_num, RegisterValue& reg_value)
Greg Clayton6da4ca82011-01-21 22:02:52 +000078{
Greg Clayton79ea8782011-04-26 23:48:45 +000079 RegisterInfo reg_info;
80 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
Greg Clayton7349bd92011-05-09 20:18:18 +000081 return ReadRegister (&reg_info, reg_value);
82 return false;
83}
84
85uint64_t
86EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind,
87 uint32_t reg_num,
88 uint64_t fail_value,
89 bool *success_ptr)
90{
91 RegisterValue reg_value;
92 if (ReadRegister (reg_kind, reg_num, reg_value))
93 return reg_value.GetAsUInt64(fail_value, success_ptr);
Greg Clayton79ea8782011-04-26 23:48:45 +000094 if (success_ptr)
95 *success_ptr = false;
96 return fail_value;
97}
98
99uint64_t
Greg Clayton7349bd92011-05-09 20:18:18 +0000100EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
101 uint64_t fail_value,
102 bool *success_ptr)
Greg Clayton79ea8782011-04-26 23:48:45 +0000103{
Greg Clayton7349bd92011-05-09 20:18:18 +0000104 RegisterValue reg_value;
105 if (ReadRegister (reg_info, reg_value))
106 return reg_value.GetAsUInt64(fail_value, success_ptr);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000107 if (success_ptr)
Greg Clayton7349bd92011-05-09 20:18:18 +0000108 *success_ptr = false;
109 return fail_value;
Greg Clayton6da4ca82011-01-21 22:02:52 +0000110}
111
112bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000113EmulateInstruction::WriteRegister (const Context &context,
114 const RegisterInfo *reg_info,
115 const RegisterValue& reg_value)
Greg Clayton6da4ca82011-01-21 22:02:52 +0000116{
Greg Clayton7349bd92011-05-09 20:18:18 +0000117 if (m_write_reg_callback)
118 return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
Greg Clayton79ea8782011-04-26 23:48:45 +0000119 return false;
120}
121
122bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000123EmulateInstruction::WriteRegister (const Context &context,
124 uint32_t reg_kind,
125 uint32_t reg_num,
126 const RegisterValue& reg_value)
Greg Clayton79ea8782011-04-26 23:48:45 +0000127{
Greg Clayton7349bd92011-05-09 20:18:18 +0000128 RegisterInfo reg_info;
129 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
130 return WriteRegister (context, &reg_info, reg_value);
131 return false;
132}
133
134
135bool
136EmulateInstruction::WriteRegisterUnsigned (const Context &context,
137 uint32_t reg_kind,
138 uint32_t reg_num,
139 uint64_t uint_value)
140{
141
142 RegisterInfo reg_info;
143 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
144 {
145 RegisterValue reg_value;
146 if (reg_value.SetUInt(uint_value, reg_info.byte_size))
147 return WriteRegister (context, &reg_info, reg_value);
148 }
149 return false;
150}
151
152bool
153EmulateInstruction::WriteRegisterUnsigned (const Context &context,
154 const RegisterInfo *reg_info,
155 uint64_t uint_value)
156{
157
158 if (reg_info)
159 {
160 RegisterValue reg_value;
161 if (reg_value.SetUInt(uint_value, reg_info->byte_size))
162 return WriteRegister (context, reg_info, reg_value);
163 }
164 return false;
165}
166
167size_t
168EmulateInstruction::ReadMemory (const Context &context,
169 lldb::addr_t addr,
170 void *dst,
171 size_t dst_len)
172{
173 if (m_read_mem_callback)
174 return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
175 return false;
Greg Clayton6da4ca82011-01-21 22:02:52 +0000176}
177
178uint64_t
179EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
180{
181 uint64_t uval64 = 0;
182 bool success = false;
183 if (byte_size <= 8)
184 {
185 uint8_t buf[sizeof(uint64_t)];
Greg Clayton2ed751b2011-04-26 04:39:08 +0000186 size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000187 if (bytes_read == byte_size)
188 {
189 uint32_t offset = 0;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000190 DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
Greg Clayton6da4ca82011-01-21 22:02:52 +0000191 uval64 = data.GetMaxU64 (&offset, byte_size);
192 success = true;
193 }
194 }
195
196 if (success_ptr)
197 *success_ptr = success;
198
199 if (!success)
200 uval64 = fail_value;
201 return uval64;
202}
203
204
205bool
206EmulateInstruction::WriteMemoryUnsigned (const Context &context,
207 lldb::addr_t addr,
208 uint64_t uval,
209 size_t uval_byte_size)
210{
211 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
212 strm.PutMaxHex64 (uval, uval_byte_size);
213
Greg Clayton2ed751b2011-04-26 04:39:08 +0000214 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 +0000215 if (bytes_written == uval_byte_size)
216 return true;
217 return false;
218}
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{
226 if (m_write_mem_callback)
227 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 +0000231
232void
233EmulateInstruction::SetBaton (void *baton)
234{
235 m_baton = baton;
236}
237
238void
Greg Clayton7349bd92011-05-09 20:18:18 +0000239EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
240 WriteMemoryCallback write_mem_callback,
241 ReadRegisterCallback read_reg_callback,
242 WriteRegisterCallback write_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000243{
244 m_read_mem_callback = read_mem_callback;
245 m_write_mem_callback = write_mem_callback;
246 m_read_reg_callback = read_reg_callback;
247 m_write_reg_callback = write_reg_callback;
248}
249
250void
Greg Clayton7349bd92011-05-09 20:18:18 +0000251EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000252{
253 m_read_mem_callback = read_mem_callback;
254}
255
256
257void
Greg Clayton7349bd92011-05-09 20:18:18 +0000258EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000259{
260 m_write_mem_callback = write_mem_callback;
261}
262
263
264void
Greg Clayton7349bd92011-05-09 20:18:18 +0000265EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000266{
267 m_read_reg_callback = read_reg_callback;
268}
269
270
271void
Greg Clayton7349bd92011-05-09 20:18:18 +0000272EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
Caroline Ticead379efc2011-04-05 18:46:00 +0000273{
274 m_write_reg_callback = write_reg_callback;
275}
276
277
278
279//
280// Read & Write Memory and Registers callback functions.
281//
282
283size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000284EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
285 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000286 const Context &context,
287 lldb::addr_t addr,
288 void *dst,
Greg Claytond9e416c2012-02-18 05:35:26 +0000289 size_t dst_len)
Caroline Ticead379efc2011-04-05 18:46:00 +0000290{
Greg Claytond9e416c2012-02-18 05:35:26 +0000291 if (!baton || dst == NULL || dst_len == 0)
Caroline Ticead379efc2011-04-05 18:46:00 +0000292 return 0;
Greg Claytond9e416c2012-02-18 05:35:26 +0000293
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000294 StackFrame *frame = (StackFrame *) baton;
295
Greg Claytond9e416c2012-02-18 05:35:26 +0000296 ProcessSP process_sp (frame->CalculateProcess());
297 if (process_sp)
298 {
299 Error error;
300 return process_sp->ReadMemory (addr, dst, dst_len, error);
301 }
302 return 0;
Caroline Ticead379efc2011-04-05 18:46:00 +0000303}
304
305size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000306EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
307 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000308 const Context &context,
309 lldb::addr_t addr,
Greg Claytond9e416c2012-02-18 05:35:26 +0000310 const void *src,
311 size_t src_len)
Caroline Ticead379efc2011-04-05 18:46:00 +0000312{
Greg Claytond9e416c2012-02-18 05:35:26 +0000313 if (!baton || src == NULL || src_len == 0)
Caroline Ticead379efc2011-04-05 18:46:00 +0000314 return 0;
315
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000316 StackFrame *frame = (StackFrame *) baton;
317
Greg Claytond9e416c2012-02-18 05:35:26 +0000318 ProcessSP process_sp (frame->CalculateProcess());
319 if (process_sp)
Caroline Ticead379efc2011-04-05 18:46:00 +0000320 {
Greg Claytond9e416c2012-02-18 05:35:26 +0000321 Error error;
322 return process_sp->WriteMemory (addr, src, src_len, error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000323 }
324
325 return 0;
326}
327
328bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000329EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
330 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000331 const RegisterInfo *reg_info,
332 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000333{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000334 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000335 return false;
336
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000337 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000338 return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000339}
340
341bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000342EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
343 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000344 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000345 const RegisterInfo *reg_info,
346 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000347{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000348 if (!baton)
349 return false;
350
351 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000352 return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000353}
354
355size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000356EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
357 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000358 const Context &context,
359 lldb::addr_t addr,
360 void *dst,
361 size_t length)
362{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000363 StreamFile strm (stdout, false);
Greg Clayton43e0af02012-09-18 18:04:04 +0000364 strm.Printf (" Read from Memory (address = 0x%llx, length = %llu, context = ", addr, (uint64_t)length);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000365 context.Dump (strm, instruction);
366 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000367 *((uint64_t *) dst) = 0xdeadbeef;
368 return length;
369}
370
371size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000372EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
373 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000374 const Context &context,
375 lldb::addr_t addr,
376 const void *dst,
377 size_t length)
378{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000379 StreamFile strm (stdout, false);
Greg Clayton43e0af02012-09-18 18:04:04 +0000380 strm.Printf (" Write to Memory (address = 0x%llx, length = %llu, context = ", addr, (uint64_t)length);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000381 context.Dump (strm, instruction);
382 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000383 return length;
384}
385
386bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000387EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
388 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000389 const RegisterInfo *reg_info,
390 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000391{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000392 StreamFile strm (stdout, false);
393 strm.Printf (" Read Register (%s)\n", reg_info->name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000394 uint32_t reg_kind, reg_num;
395 if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
Greg Clayton7349bd92011-05-09 20:18:18 +0000396 reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
Greg Clayton79ea8782011-04-26 23:48:45 +0000397 else
Greg Clayton7349bd92011-05-09 20:18:18 +0000398 reg_value.SetUInt64(0);
Greg Clayton79ea8782011-04-26 23:48:45 +0000399
Caroline Ticead379efc2011-04-05 18:46:00 +0000400 return true;
401}
402
403bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000404EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
405 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000406 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000407 const RegisterInfo *reg_info,
408 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000409{
Greg Clayton7349bd92011-05-09 20:18:18 +0000410 StreamFile strm (stdout, false);
411 strm.Printf (" Write to Register (name = %s, value = " , reg_info->name);
Greg Clayton9a8fa912011-05-15 04:12:07 +0000412 reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
Greg Clayton7349bd92011-05-09 20:18:18 +0000413 strm.PutCString (", context = ");
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000414 context.Dump (strm, instruction);
415 strm.EOL();
Caroline Ticead379efc2011-04-05 18:46:00 +0000416 return true;
417}
418
419void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000420EmulateInstruction::Context::Dump (Stream &strm,
Greg Clayton79ea8782011-04-26 23:48:45 +0000421 EmulateInstruction *instruction) const
Caroline Ticead379efc2011-04-05 18:46:00 +0000422{
Greg Clayton79ea8782011-04-26 23:48:45 +0000423 switch (type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000424 {
425 case eContextReadOpcode:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000426 strm.PutCString ("reading opcode");
Caroline Ticead379efc2011-04-05 18:46:00 +0000427 break;
428
429 case eContextImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000430 strm.PutCString ("immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000431 break;
432
433 case eContextPushRegisterOnStack:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000434 strm.PutCString ("push register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000435 break;
436
437 case eContextPopRegisterOffStack:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000438 strm.PutCString ("pop register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000439 break;
440
441 case eContextAdjustStackPointer:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000442 strm.PutCString ("adjust sp");
Caroline Ticead379efc2011-04-05 18:46:00 +0000443 break;
444
Greg Claytona658fd22011-06-04 01:26:29 +0000445 case eContextSetFramePointer:
446 strm.PutCString ("set frame pointer");
447 break;
448
Caroline Ticead379efc2011-04-05 18:46:00 +0000449 case eContextAdjustBaseRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000450 strm.PutCString ("adjusting (writing value back to) a base register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000451 break;
452
453 case eContextRegisterPlusOffset:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000454 strm.PutCString ("register + offset");
Caroline Ticead379efc2011-04-05 18:46:00 +0000455 break;
456
457 case eContextRegisterStore:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000458 strm.PutCString ("store register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000459 break;
460
461 case eContextRegisterLoad:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000462 strm.PutCString ("load register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000463 break;
464
465 case eContextRelativeBranchImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000466 strm.PutCString ("relative branch immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000467 break;
468
469 case eContextAbsoluteBranchRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000470 strm.PutCString ("absolute branch register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000471 break;
472
473 case eContextSupervisorCall:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000474 strm.PutCString ("supervisor call");
Caroline Ticead379efc2011-04-05 18:46:00 +0000475 break;
476
477 case eContextTableBranchReadMemory:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000478 strm.PutCString ("table branch read memory");
Caroline Ticead379efc2011-04-05 18:46:00 +0000479 break;
480
481 case eContextWriteRegisterRandomBits:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000482 strm.PutCString ("write random bits to a register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000483 break;
484
485 case eContextWriteMemoryRandomBits:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000486 strm.PutCString ("write random bits to a memory address");
Caroline Ticead379efc2011-04-05 18:46:00 +0000487 break;
488
Greg Clayton79ea8782011-04-26 23:48:45 +0000489 case eContextArithmetic:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000490 strm.PutCString ("arithmetic");
Caroline Ticead379efc2011-04-05 18:46:00 +0000491 break;
492
493 case eContextReturnFromException:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000494 strm.PutCString ("return from exception");
Caroline Ticead379efc2011-04-05 18:46:00 +0000495 break;
496
497 default:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000498 strm.PutCString ("unrecognized context.");
Caroline Ticead379efc2011-04-05 18:46:00 +0000499 break;
500 }
501
Greg Clayton79ea8782011-04-26 23:48:45 +0000502 switch (info_type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000503 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000504 case eInfoTypeRegisterPlusOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000505 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000506 strm.Printf (" (reg_plus_offset = %s%+lld)",
507 info.RegisterPlusOffset.reg.name,
508 info.RegisterPlusOffset.signed_offset);
Caroline Ticead379efc2011-04-05 18:46:00 +0000509 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000510 break;
511
512 case eInfoTypeRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000513 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000514 strm.Printf (" (reg_plus_reg = %s + %s)",
515 info.RegisterPlusIndirectOffset.base_reg.name,
516 info.RegisterPlusIndirectOffset.offset_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000517 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000518 break;
519
520 case eInfoTypeRegisterToRegisterPlusOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000521 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000522 strm.Printf (" (base_and_imm_offset = %s%+lld, data_reg = %s)",
523 info.RegisterToRegisterPlusOffset.base_reg.name,
524 info.RegisterToRegisterPlusOffset.offset,
525 info.RegisterToRegisterPlusOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000526 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000527 break;
528
529 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000530 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000531 strm.Printf (" (base_and_reg_offset = %s + %s, data_reg = %s)",
532 info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
533 info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
534 info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000535 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000536 break;
537
538 case eInfoTypeRegisterRegisterOperands:
539 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000540 strm.Printf (" (register to register binary op: %s and %s)",
541 info.RegisterRegisterOperands.operand1.name,
542 info.RegisterRegisterOperands.operand2.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000543 }
544 break;
545
546 case eInfoTypeOffset:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000547 strm.Printf (" (signed_offset = %+lld)", info.signed_offset);
Greg Clayton79ea8782011-04-26 23:48:45 +0000548 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000549
Greg Clayton79ea8782011-04-26 23:48:45 +0000550 case eInfoTypeRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000551 strm.Printf (" (reg = %s)", info.reg.name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000552 break;
553
554 case eInfoTypeImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000555 strm.Printf (" (unsigned_immediate = %llu (0x%16.16llx))",
556 info.unsigned_immediate,
557 info.unsigned_immediate);
Greg Clayton79ea8782011-04-26 23:48:45 +0000558 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000559
Greg Clayton79ea8782011-04-26 23:48:45 +0000560 case eInfoTypeImmediateSigned:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000561 strm.Printf (" (signed_immediate = %+lld (0x%16.16llx))",
562 info.signed_immediate,
563 info.signed_immediate);
Greg Clayton79ea8782011-04-26 23:48:45 +0000564 break;
565
566 case eInfoTypeAddress:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000567 strm.Printf (" (address = 0x%llx)", info.address);
Greg Clayton79ea8782011-04-26 23:48:45 +0000568 break;
569
570 case eInfoTypeISAAndImmediate:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000571 strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
572 info.ISAAndImmediate.isa,
573 info.ISAAndImmediate.unsigned_data32,
574 info.ISAAndImmediate.unsigned_data32);
Greg Clayton79ea8782011-04-26 23:48:45 +0000575 break;
576
577 case eInfoTypeISAAndImmediateSigned:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000578 strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))",
579 info.ISAAndImmediateSigned.isa,
580 info.ISAAndImmediateSigned.signed_data32,
581 info.ISAAndImmediateSigned.signed_data32);
Greg Clayton79ea8782011-04-26 23:48:45 +0000582 break;
583
584 case eInfoTypeISA:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000585 strm.Printf (" (isa = %u)", info.isa);
Greg Clayton79ea8782011-04-26 23:48:45 +0000586 break;
587
588 case eInfoTypeNoArgs:
Greg Clayton79ea8782011-04-26 23:48:45 +0000589 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000590
Greg Clayton79ea8782011-04-26 23:48:45 +0000591 default:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000592 strm.Printf (" (unknown <info_type>)");
Greg Clayton79ea8782011-04-26 23:48:45 +0000593 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000594 }
595}
596
Greg Clayton2ed751b2011-04-26 04:39:08 +0000597bool
598EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
Caroline Ticead379efc2011-04-05 18:46:00 +0000599{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000600 m_opcode = opcode;
Greg Claytone5b34982011-04-29 22:50:31 +0000601 m_addr = LLDB_INVALID_ADDRESS;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000602 if (inst_addr.IsValid())
Caroline Ticead379efc2011-04-05 18:46:00 +0000603 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000604 if (target)
Greg Claytone5b34982011-04-29 22:50:31 +0000605 m_addr = inst_addr.GetLoadAddress (target);
606 if (m_addr == LLDB_INVALID_ADDRESS)
607 m_addr = inst_addr.GetFileAddress ();
Caroline Ticead379efc2011-04-05 18:46:00 +0000608 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000609 return true;
Caroline Ticead379efc2011-04-05 18:46:00 +0000610}
611
Greg Clayton79ea8782011-04-26 23:48:45 +0000612bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000613EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
Greg Clayton79ea8782011-04-26 23:48:45 +0000614 uint32_t &reg_kind,
615 uint32_t &reg_num)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000616{
Greg Clayton79ea8782011-04-26 23:48:45 +0000617 // Generic and DWARF should be the two most popular register kinds when
618 // emulating instructions since they are the most platform agnostic...
Greg Clayton7349bd92011-05-09 20:18:18 +0000619 reg_num = reg_info->kinds[eRegisterKindGeneric];
Greg Clayton79ea8782011-04-26 23:48:45 +0000620 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000621 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000622 reg_kind = eRegisterKindGeneric;
623 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000624 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000625
Greg Clayton7349bd92011-05-09 20:18:18 +0000626 reg_num = reg_info->kinds[eRegisterKindDWARF];
Greg Clayton79ea8782011-04-26 23:48:45 +0000627 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000628 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000629 reg_kind = eRegisterKindDWARF;
630 return true;
631 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000632
Greg Clayton7349bd92011-05-09 20:18:18 +0000633 reg_num = reg_info->kinds[eRegisterKindLLDB];
Greg Clayton79ea8782011-04-26 23:48:45 +0000634 if (reg_num != LLDB_INVALID_REGNUM)
635 {
636 reg_kind = eRegisterKindLLDB;
637 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000638 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000639
Greg Clayton7349bd92011-05-09 20:18:18 +0000640 reg_num = reg_info->kinds[eRegisterKindGCC];
Greg Clayton79ea8782011-04-26 23:48:45 +0000641 if (reg_num != LLDB_INVALID_REGNUM)
642 {
643 reg_kind = eRegisterKindGCC;
644 return true;
645 }
646
Greg Clayton7349bd92011-05-09 20:18:18 +0000647 reg_num = reg_info->kinds[eRegisterKindGDB];
Greg Clayton79ea8782011-04-26 23:48:45 +0000648 if (reg_num != LLDB_INVALID_REGNUM)
649 {
650 reg_kind = eRegisterKindGDB;
651 return true;
652 }
653 return false;
654}
655
656uint32_t
657EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
658{
659 uint32_t reg_kind, reg_num;
Greg Clayton7349bd92011-05-09 20:18:18 +0000660 if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
Greg Clayton79ea8782011-04-26 23:48:45 +0000661 return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
662 return LLDB_INVALID_REGNUM;
663}
664
665
666bool
667EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
668{
669 unwind_plan.Clear();
670 return false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000671}
672
Caroline Ticead379efc2011-04-05 18:46:00 +0000673