blob: 9ae9a1c16173a48e5ef352ec5d2161b90847c447 [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"
Caroline Ticead379efc2011-04-05 18:46:00 +000013#include "lldb/Core/DataBufferHeap.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000014#include "lldb/Core/DataExtractor.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000015#include "lldb/Core/Error.h"
Greg Clayton4272cc72011-02-02 02:24:04 +000016#include "lldb/Core/PluginManager.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000017#include "lldb/Core/StreamString.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000018#include "lldb/Host/Endian.h"
Greg Clayton79ea8782011-04-26 23:48:45 +000019#include "lldb/Symbol/UnwindPlan.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000020#include "lldb/Target/Process.h"
21#include "lldb/Target/RegisterContext.h"
Greg Clayton2ed751b2011-04-26 04:39:08 +000022#include "lldb/Target/Target.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000023#include "lldb/Target/Thread.h"
24
Greg Clayton6da4ca82011-01-21 22:02:52 +000025using namespace lldb;
26using namespace lldb_private;
27
Greg Clayton4272cc72011-02-02 02:24:04 +000028EmulateInstruction*
Greg Clayton2ed751b2011-04-26 04:39:08 +000029EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
Greg Clayton4272cc72011-02-02 02:24:04 +000030{
31 EmulateInstructionCreateInstance create_callback = NULL;
32 if (plugin_name)
33 {
34 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
35 if (create_callback)
36 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000037 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000038 if (emulate_insn_ptr)
39 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000040 }
41 }
42 else
43 {
44 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
45 {
Greg Clayton2ed751b2011-04-26 04:39:08 +000046 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Ticead379efc2011-04-05 18:46:00 +000047 if (emulate_insn_ptr)
48 return emulate_insn_ptr;
Greg Clayton4272cc72011-02-02 02:24:04 +000049 }
50 }
51 return NULL;
52}
Greg Clayton6da4ca82011-01-21 22:02:52 +000053
Greg Clayton2ed751b2011-04-26 04:39:08 +000054EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
Caroline Ticead379efc2011-04-05 18:46:00 +000055 m_arch (arch),
56 m_baton (NULL),
57 m_read_mem_callback (&ReadMemoryDefault),
58 m_write_mem_callback (&WriteMemoryDefault),
59 m_read_reg_callback (&ReadRegisterDefault),
60 m_write_reg_callback (&WriteRegisterDefault),
Greg Claytone5b34982011-04-29 22:50:31 +000061 m_addr (LLDB_INVALID_ADDRESS)
Caroline Ticead379efc2011-04-05 18:46:00 +000062{
63 ::memset (&m_opcode, 0, sizeof (m_opcode));
64}
65
Greg Clayton79ea8782011-04-26 23:48:45 +000066
Greg Clayton6da4ca82011-01-21 22:02:52 +000067uint64_t
68EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
69{
Greg Clayton79ea8782011-04-26 23:48:45 +000070 RegisterInfo reg_info;
71 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
72 return ReadRegisterUnsigned (reg_info, fail_value, success_ptr);
73 if (success_ptr)
74 *success_ptr = false;
75 return fail_value;
76}
77
78uint64_t
79EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo &reg_info, uint64_t fail_value, bool *success_ptr)
80{
Greg Clayton6da4ca82011-01-21 22:02:52 +000081 uint64_t uval64 = 0;
Greg Clayton79ea8782011-04-26 23:48:45 +000082 bool success = m_read_reg_callback (this, m_baton, reg_info, uval64);
Greg Clayton6da4ca82011-01-21 22:02:52 +000083 if (success_ptr)
84 *success_ptr = success;
85 if (!success)
86 uval64 = fail_value;
87 return uval64;
88}
89
90bool
91EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
92{
Greg Clayton79ea8782011-04-26 23:48:45 +000093 RegisterInfo reg_info;
94 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
95 return WriteRegisterUnsigned (context, reg_info, reg_value);
96 return false;
97}
98
99bool
100EmulateInstruction::WriteRegisterUnsigned (const Context &context, const RegisterInfo &reg_info, uint64_t reg_value)
101{
102 return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000103}
104
105uint64_t
106EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
107{
108 uint64_t uval64 = 0;
109 bool success = false;
110 if (byte_size <= 8)
111 {
112 uint8_t buf[sizeof(uint64_t)];
Greg Clayton2ed751b2011-04-26 04:39:08 +0000113 size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
Greg Clayton6da4ca82011-01-21 22:02:52 +0000114 if (bytes_read == byte_size)
115 {
116 uint32_t offset = 0;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000117 DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
Greg Clayton6da4ca82011-01-21 22:02:52 +0000118 uval64 = data.GetMaxU64 (&offset, byte_size);
119 success = true;
120 }
121 }
122
123 if (success_ptr)
124 *success_ptr = success;
125
126 if (!success)
127 uval64 = fail_value;
128 return uval64;
129}
130
131
132bool
133EmulateInstruction::WriteMemoryUnsigned (const Context &context,
134 lldb::addr_t addr,
135 uint64_t uval,
136 size_t uval_byte_size)
137{
138 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
139 strm.PutMaxHex64 (uval, uval_byte_size);
140
Greg Clayton2ed751b2011-04-26 04:39:08 +0000141 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 +0000142 if (bytes_written == uval_byte_size)
143 return true;
144 return false;
145}
Caroline Ticead379efc2011-04-05 18:46:00 +0000146
147
148void
149EmulateInstruction::SetBaton (void *baton)
150{
151 m_baton = baton;
152}
153
154void
155EmulateInstruction::SetCallbacks (ReadMemory read_mem_callback,
156 WriteMemory write_mem_callback,
157 ReadRegister read_reg_callback,
158 WriteRegister write_reg_callback)
159{
160 m_read_mem_callback = read_mem_callback;
161 m_write_mem_callback = write_mem_callback;
162 m_read_reg_callback = read_reg_callback;
163 m_write_reg_callback = write_reg_callback;
164}
165
166void
167EmulateInstruction::SetReadMemCallback (ReadMemory read_mem_callback)
168{
169 m_read_mem_callback = read_mem_callback;
170}
171
172
173void
174EmulateInstruction::SetWriteMemCallback (WriteMemory write_mem_callback)
175{
176 m_write_mem_callback = write_mem_callback;
177}
178
179
180void
181EmulateInstruction::SetReadRegCallback (ReadRegister read_reg_callback)
182{
183 m_read_reg_callback = read_reg_callback;
184}
185
186
187void
188EmulateInstruction::SetWriteRegCallback (WriteRegister write_reg_callback)
189{
190 m_write_reg_callback = write_reg_callback;
191}
192
193
194
195//
196// Read & Write Memory and Registers callback functions.
197//
198
199size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000200EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
201 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000202 const Context &context,
203 lldb::addr_t addr,
204 void *dst,
205 size_t length)
Caroline Ticead379efc2011-04-05 18:46:00 +0000206{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000207 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000208 return 0;
209
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000210
211 StackFrame *frame = (StackFrame *) baton;
212
Caroline Ticead379efc2011-04-05 18:46:00 +0000213 DataBufferSP data_sp (new DataBufferHeap (length, '\0'));
214 Error error;
215
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000216 size_t bytes_read = frame->GetThread().GetProcess().ReadMemory (addr, data_sp->GetBytes(), data_sp->GetByteSize(),
217 error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000218
219 if (bytes_read > 0)
220 ((DataBufferHeap *) data_sp.get())->CopyData (dst, length);
221
222 return bytes_read;
223}
224
225size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000226EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
227 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000228 const Context &context,
229 lldb::addr_t addr,
230 const void *dst,
231 size_t length)
Caroline Ticead379efc2011-04-05 18:46:00 +0000232{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000233 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000234 return 0;
235
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000236 StackFrame *frame = (StackFrame *) baton;
237
Caroline Ticead379efc2011-04-05 18:46:00 +0000238 lldb::DataBufferSP data_sp (new DataBufferHeap (dst, length));
239 if (data_sp)
240 {
241 length = data_sp->GetByteSize();
242 if (length > 0)
243 {
244 Error error;
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000245 size_t bytes_written = frame->GetThread().GetProcess().WriteMemory (addr, data_sp->GetBytes(), length,
246 error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000247
248 return bytes_written;
249 }
250 }
251
252 return 0;
253}
254
255bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000256EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
257 void *baton,
Greg Clayton79ea8782011-04-26 23:48:45 +0000258 const RegisterInfo &reg_info,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000259 uint64_t &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000260{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000261 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000262 return false;
263
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000264 StackFrame *frame = (StackFrame *) baton;
Greg Clayton79ea8782011-04-26 23:48:45 +0000265 RegisterContext *reg_ctx = frame->GetRegisterContext().get();
Caroline Ticead379efc2011-04-05 18:46:00 +0000266 Scalar value;
267
Greg Clayton79ea8782011-04-26 23:48:45 +0000268 const uint32_t internal_reg_num = GetInternalRegisterNumber (reg_ctx, reg_info);
Caroline Ticead379efc2011-04-05 18:46:00 +0000269
Greg Clayton79ea8782011-04-26 23:48:45 +0000270 if (internal_reg_num != LLDB_INVALID_REGNUM)
Caroline Ticead379efc2011-04-05 18:46:00 +0000271 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000272 if (reg_ctx->ReadRegisterValue (internal_reg_num, value))
273 {
274 reg_value = value.GetRawBits64 (0);
275 return true;
276 }
Caroline Ticead379efc2011-04-05 18:46:00 +0000277 }
Caroline Ticead379efc2011-04-05 18:46:00 +0000278 return false;
279}
280
281bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000282EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
283 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000284 const Context &context,
Greg Clayton79ea8782011-04-26 23:48:45 +0000285 const RegisterInfo &reg_info,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000286 uint64_t reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000287{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000288 if (!baton)
289 return false;
290
291 StackFrame *frame = (StackFrame *) baton;
Greg Clayton79ea8782011-04-26 23:48:45 +0000292 RegisterContext *reg_ctx = frame->GetRegisterContext().get();
Caroline Ticead379efc2011-04-05 18:46:00 +0000293 Scalar value (reg_value);
Greg Clayton79ea8782011-04-26 23:48:45 +0000294 const uint32_t internal_reg_num = GetInternalRegisterNumber (reg_ctx, reg_info);
Caroline Ticec1bcafd2011-04-06 23:30:18 +0000295 if (internal_reg_num != LLDB_INVALID_REGNUM)
Greg Clayton79ea8782011-04-26 23:48:45 +0000296 return reg_ctx->WriteRegisterValue (internal_reg_num, value);
297 return false;
Caroline Ticead379efc2011-04-05 18:46:00 +0000298}
299
300size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000301EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
302 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000303 const Context &context,
304 lldb::addr_t addr,
305 void *dst,
306 size_t length)
307{
Caroline Tice4a3533b2011-05-03 20:58:11 +0000308 fprintf (stdout, " Read from Memory (address = 0x%llx, length = %zu, context = ", addr, length);
Greg Clayton79ea8782011-04-26 23:48:45 +0000309 context.Dump (stdout, instruction);
Caroline Ticead379efc2011-04-05 18:46:00 +0000310 *((uint64_t *) dst) = 0xdeadbeef;
311 return length;
312}
313
314size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000315EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
316 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000317 const Context &context,
318 lldb::addr_t addr,
319 const void *dst,
320 size_t length)
321{
Caroline Tice4a3533b2011-05-03 20:58:11 +0000322 fprintf (stdout, " Write to Memory (address = 0x%llx, length = %zu, context = ", addr, length);
Greg Clayton79ea8782011-04-26 23:48:45 +0000323 context.Dump (stdout, instruction);
Caroline Ticead379efc2011-04-05 18:46:00 +0000324 return length;
325}
326
327bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000328EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
329 void *baton,
Greg Clayton79ea8782011-04-26 23:48:45 +0000330 const RegisterInfo &reg_info,
Caroline Ticead379efc2011-04-05 18:46:00 +0000331 uint64_t &reg_value)
332{
Greg Clayton79ea8782011-04-26 23:48:45 +0000333 fprintf (stdout, " Read Register (%s)\n", reg_info.name);
334 uint32_t reg_kind, reg_num;
335 if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
336 reg_value = (uint64_t)reg_kind << 24 | reg_num;
337 else
338 reg_value = 0;
339
Caroline Ticead379efc2011-04-05 18:46:00 +0000340 return true;
341}
342
343bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000344EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
345 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000346 const Context &context,
Greg Clayton79ea8782011-04-26 23:48:45 +0000347 const RegisterInfo &reg_info,
Caroline Ticead379efc2011-04-05 18:46:00 +0000348 uint64_t reg_value)
349{
Greg Clayton79ea8782011-04-26 23:48:45 +0000350 fprintf (stdout, " Write to Register (name = %s, value = 0x%llx, context = ", reg_info.name, reg_value);
351 context.Dump (stdout, instruction);
Caroline Ticead379efc2011-04-05 18:46:00 +0000352 return true;
353}
354
355void
Greg Clayton79ea8782011-04-26 23:48:45 +0000356EmulateInstruction::Context::Dump (FILE *fh,
357 EmulateInstruction *instruction) const
Caroline Ticead379efc2011-04-05 18:46:00 +0000358{
Greg Clayton79ea8782011-04-26 23:48:45 +0000359 switch (type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000360 {
361 case eContextReadOpcode:
Greg Clayton79ea8782011-04-26 23:48:45 +0000362 fprintf (fh, "reading opcode");
Caroline Ticead379efc2011-04-05 18:46:00 +0000363 break;
364
365 case eContextImmediate:
Greg Clayton79ea8782011-04-26 23:48:45 +0000366 fprintf (fh, "immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000367 break;
368
369 case eContextPushRegisterOnStack:
Greg Clayton79ea8782011-04-26 23:48:45 +0000370 fprintf (fh, "push register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000371 break;
372
373 case eContextPopRegisterOffStack:
Greg Clayton79ea8782011-04-26 23:48:45 +0000374 fprintf (fh, "pop register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000375 break;
376
377 case eContextAdjustStackPointer:
Greg Clayton79ea8782011-04-26 23:48:45 +0000378 fprintf (fh, "adjust sp");
Caroline Ticead379efc2011-04-05 18:46:00 +0000379 break;
380
381 case eContextAdjustBaseRegister:
Greg Clayton79ea8782011-04-26 23:48:45 +0000382 fprintf (fh, "adjusting (writing value back to) a base register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000383 break;
384
385 case eContextRegisterPlusOffset:
Greg Clayton79ea8782011-04-26 23:48:45 +0000386 fprintf (fh, "register + offset");
Caroline Ticead379efc2011-04-05 18:46:00 +0000387 break;
388
389 case eContextRegisterStore:
Greg Clayton79ea8782011-04-26 23:48:45 +0000390 fprintf (fh, "store register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000391 break;
392
393 case eContextRegisterLoad:
Greg Clayton79ea8782011-04-26 23:48:45 +0000394 fprintf (fh, "load register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000395 break;
396
397 case eContextRelativeBranchImmediate:
Greg Clayton79ea8782011-04-26 23:48:45 +0000398 fprintf (fh, "relative branch immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000399 break;
400
401 case eContextAbsoluteBranchRegister:
Greg Clayton79ea8782011-04-26 23:48:45 +0000402 fprintf (fh, "absolute branch register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000403 break;
404
405 case eContextSupervisorCall:
Greg Clayton79ea8782011-04-26 23:48:45 +0000406 fprintf (fh, "supervisor call");
Caroline Ticead379efc2011-04-05 18:46:00 +0000407 break;
408
409 case eContextTableBranchReadMemory:
Greg Clayton79ea8782011-04-26 23:48:45 +0000410 fprintf (fh, "table branch read memory");
Caroline Ticead379efc2011-04-05 18:46:00 +0000411 break;
412
413 case eContextWriteRegisterRandomBits:
Greg Clayton79ea8782011-04-26 23:48:45 +0000414 fprintf (fh, "write random bits to a register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000415 break;
416
417 case eContextWriteMemoryRandomBits:
Greg Clayton79ea8782011-04-26 23:48:45 +0000418 fprintf (fh, "write random bits to a memory address");
Caroline Ticead379efc2011-04-05 18:46:00 +0000419 break;
420
Greg Clayton79ea8782011-04-26 23:48:45 +0000421 case eContextArithmetic:
422 fprintf (fh, "arithmetic");
Caroline Ticead379efc2011-04-05 18:46:00 +0000423 break;
424
425 case eContextReturnFromException:
Greg Clayton79ea8782011-04-26 23:48:45 +0000426 fprintf (fh, "return from exception");
Caroline Ticead379efc2011-04-05 18:46:00 +0000427 break;
428
429 default:
Greg Clayton79ea8782011-04-26 23:48:45 +0000430 fprintf (fh, "unrecognized context.");
Caroline Ticead379efc2011-04-05 18:46:00 +0000431 break;
432 }
433
Greg Clayton79ea8782011-04-26 23:48:45 +0000434 switch (info_type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000435 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000436 case eInfoTypeRegisterPlusOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000437 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000438 fprintf (fh,
439 " (reg_plus_offset = %s%+lld)\n",
440 info.RegisterPlusOffset.reg.name,
441 info.RegisterPlusOffset.signed_offset);
Caroline Ticead379efc2011-04-05 18:46:00 +0000442 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000443 break;
444
445 case eInfoTypeRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000446 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000447 fprintf (fh, " (reg_plus_reg = %s + %s)\n",
448 info.RegisterPlusIndirectOffset.base_reg.name,
449 info.RegisterPlusIndirectOffset.offset_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000450 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000451 break;
452
453 case eInfoTypeRegisterToRegisterPlusOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000454 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000455 fprintf (fh, " (base_and_imm_offset = %s%+lld, data_reg = %s)\n",
456 info.RegisterToRegisterPlusOffset.base_reg.name,
457 info.RegisterToRegisterPlusOffset.offset,
458 info.RegisterToRegisterPlusOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000459 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000460 break;
461
462 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000463 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000464 fprintf (fh, " (base_and_reg_offset = %s + %s, data_reg = %s)\n",
465 info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
466 info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
467 info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000468 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000469 break;
470
471 case eInfoTypeRegisterRegisterOperands:
472 {
473 fprintf (fh, " (register to register binary op: %s and %s)\n",
474 info.RegisterRegisterOperands.operand1.name,
475 info.RegisterRegisterOperands.operand2.name);
476 }
477 break;
478
479 case eInfoTypeOffset:
480 fprintf (fh, " (signed_offset = %+lld)\n", info.signed_offset);
481 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000482
Greg Clayton79ea8782011-04-26 23:48:45 +0000483 case eInfoTypeRegister:
484 fprintf (fh, " (reg = %s)\n", info.reg.name);
485 break;
486
487 case eInfoTypeImmediate:
488 fprintf (fh,
489 " (unsigned_immediate = %llu (0x%16.16llx))\n",
490 info.unsigned_immediate,
491 info.unsigned_immediate);
492 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000493
Greg Clayton79ea8782011-04-26 23:48:45 +0000494 case eInfoTypeImmediateSigned:
495 fprintf (fh,
496 " (signed_immediate = %+lld (0x%16.16llx))\n",
497 info.signed_immediate,
498 info.signed_immediate);
499 break;
500
501 case eInfoTypeAddress:
502 fprintf (fh, " (address = 0x%llx)\n", info.address);
503 break;
504
505 case eInfoTypeISAAndImmediate:
506 fprintf (fh,
507 " (isa = %u, unsigned_immediate = %u (0x%8.8x))\n",
508 info.ISAAndImmediate.isa,
509 info.ISAAndImmediate.unsigned_data32,
510 info.ISAAndImmediate.unsigned_data32);
511 break;
512
513 case eInfoTypeISAAndImmediateSigned:
514 fprintf (fh,
515 " (isa = %u, signed_immediate = %i (0x%8.8x))\n",
516 info.ISAAndImmediateSigned.isa,
517 info.ISAAndImmediateSigned.signed_data32,
518 info.ISAAndImmediateSigned.signed_data32);
519 break;
520
521 case eInfoTypeISA:
522 fprintf (fh, " (isa = %u)\n", info.isa);
523 break;
524
525 case eInfoTypeNoArgs:
526 fprintf (fh, " \n");
527 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000528
Greg Clayton79ea8782011-04-26 23:48:45 +0000529 default:
530 fprintf (fh, " (unknown <info_type>)\n");
531 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000532 }
533}
534
Greg Clayton2ed751b2011-04-26 04:39:08 +0000535bool
536EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
Caroline Ticead379efc2011-04-05 18:46:00 +0000537{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000538 m_opcode = opcode;
Greg Claytone5b34982011-04-29 22:50:31 +0000539 m_addr = LLDB_INVALID_ADDRESS;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000540 if (inst_addr.IsValid())
Caroline Ticead379efc2011-04-05 18:46:00 +0000541 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000542 if (target)
Greg Claytone5b34982011-04-29 22:50:31 +0000543 m_addr = inst_addr.GetLoadAddress (target);
544 if (m_addr == LLDB_INVALID_ADDRESS)
545 m_addr = inst_addr.GetFileAddress ();
Caroline Ticead379efc2011-04-05 18:46:00 +0000546 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000547 return true;
Caroline Ticead379efc2011-04-05 18:46:00 +0000548}
549
Greg Clayton79ea8782011-04-26 23:48:45 +0000550bool
551EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo &reg_info,
552 uint32_t &reg_kind,
553 uint32_t &reg_num)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000554{
Greg Clayton79ea8782011-04-26 23:48:45 +0000555 // Generic and DWARF should be the two most popular register kinds when
556 // emulating instructions since they are the most platform agnostic...
557 reg_num = reg_info.kinds[eRegisterKindGeneric];
558 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000559 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000560 reg_kind = eRegisterKindGeneric;
561 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000562 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000563
Greg Clayton79ea8782011-04-26 23:48:45 +0000564 reg_num = reg_info.kinds[eRegisterKindDWARF];
565 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000566 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000567 reg_kind = eRegisterKindDWARF;
568 return true;
569 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000570
Greg Clayton79ea8782011-04-26 23:48:45 +0000571 reg_num = reg_info.kinds[eRegisterKindLLDB];
572 if (reg_num != LLDB_INVALID_REGNUM)
573 {
574 reg_kind = eRegisterKindLLDB;
575 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000576 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000577
578 reg_num = reg_info.kinds[eRegisterKindGCC];
579 if (reg_num != LLDB_INVALID_REGNUM)
580 {
581 reg_kind = eRegisterKindGCC;
582 return true;
583 }
584
585 reg_num = reg_info.kinds[eRegisterKindGDB];
586 if (reg_num != LLDB_INVALID_REGNUM)
587 {
588 reg_kind = eRegisterKindGDB;
589 return true;
590 }
591 return false;
592}
593
594uint32_t
595EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
596{
597 uint32_t reg_kind, reg_num;
598 if (reg_ctx && GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
599 return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
600 return LLDB_INVALID_REGNUM;
601}
602
603
604bool
605EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
606{
607 unwind_plan.Clear();
608 return false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000609}
610
Caroline Ticead379efc2011-04-05 18:46:00 +0000611