blob: ac149e020ec071dd01946c040ef6bd83eb562b17 [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 Clayton7349bd92011-05-09 20:18:18 +000017#include "lldb/Core/RegisterValue.h"
18#include "lldb/Core/StreamFile.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000019#include "lldb/Core/StreamString.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000020#include "lldb/Host/Endian.h"
Greg Clayton79ea8782011-04-26 23:48:45 +000021#include "lldb/Symbol/UnwindPlan.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000022#include "lldb/Target/Process.h"
23#include "lldb/Target/RegisterContext.h"
Greg Clayton2ed751b2011-04-26 04:39:08 +000024#include "lldb/Target/Target.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000025#include "lldb/Target/Thread.h"
26
Greg Clayton6da4ca82011-01-21 22:02:52 +000027using namespace lldb;
28using namespace lldb_private;
29
Greg Clayton4272cc72011-02-02 02:24:04 +000030EmulateInstruction*
Greg Clayton2ed751b2011-04-26 04:39:08 +000031EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
Greg Clayton4272cc72011-02-02 02:24:04 +000032{
33 EmulateInstructionCreateInstance create_callback = NULL;
34 if (plugin_name)
35 {
36 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
37 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
78EmulateInstruction::ReadRegister (uint32_t 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
87EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind,
88 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,
125 uint32_t reg_kind,
126 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,
138 uint32_t reg_kind,
139 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 {
190 uint32_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,
290 size_t length)
Caroline Ticead379efc2011-04-05 18:46:00 +0000291{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000292 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000293 return 0;
294
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000295
296 StackFrame *frame = (StackFrame *) baton;
297
Caroline Ticead379efc2011-04-05 18:46:00 +0000298 DataBufferSP data_sp (new DataBufferHeap (length, '\0'));
299 Error error;
300
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000301 size_t bytes_read = frame->GetThread().GetProcess().ReadMemory (addr, data_sp->GetBytes(), data_sp->GetByteSize(),
302 error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000303
304 if (bytes_read > 0)
305 ((DataBufferHeap *) data_sp.get())->CopyData (dst, length);
306
307 return bytes_read;
308}
309
310size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000311EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
312 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000313 const Context &context,
314 lldb::addr_t addr,
315 const void *dst,
316 size_t length)
Caroline Ticead379efc2011-04-05 18:46:00 +0000317{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000318 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000319 return 0;
320
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000321 StackFrame *frame = (StackFrame *) baton;
322
Caroline Ticead379efc2011-04-05 18:46:00 +0000323 lldb::DataBufferSP data_sp (new DataBufferHeap (dst, length));
324 if (data_sp)
325 {
326 length = data_sp->GetByteSize();
327 if (length > 0)
328 {
329 Error error;
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000330 size_t bytes_written = frame->GetThread().GetProcess().WriteMemory (addr, data_sp->GetBytes(), length,
331 error);
Caroline Ticead379efc2011-04-05 18:46:00 +0000332
333 return bytes_written;
334 }
335 }
336
337 return 0;
338}
339
340bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000341EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
342 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000343 const RegisterInfo *reg_info,
344 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000345{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000346 if (!baton)
Caroline Ticead379efc2011-04-05 18:46:00 +0000347 return false;
348
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000349 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000350 return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000351}
352
353bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000354EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
355 void *baton,
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000356 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000357 const RegisterInfo *reg_info,
358 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000359{
Caroline Tice3d50b2f2011-04-05 20:18:48 +0000360 if (!baton)
361 return false;
362
363 StackFrame *frame = (StackFrame *) baton;
Greg Clayton7349bd92011-05-09 20:18:18 +0000364 return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
Caroline Ticead379efc2011-04-05 18:46:00 +0000365}
366
367size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000368EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
369 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000370 const Context &context,
371 lldb::addr_t addr,
372 void *dst,
373 size_t length)
374{
Caroline Tice4a3533b2011-05-03 20:58:11 +0000375 fprintf (stdout, " Read from Memory (address = 0x%llx, length = %zu, context = ", addr, length);
Greg Clayton79ea8782011-04-26 23:48:45 +0000376 context.Dump (stdout, instruction);
Caroline Ticead379efc2011-04-05 18:46:00 +0000377 *((uint64_t *) dst) = 0xdeadbeef;
378 return length;
379}
380
381size_t
Greg Clayton2ed751b2011-04-26 04:39:08 +0000382EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
383 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000384 const Context &context,
385 lldb::addr_t addr,
386 const void *dst,
387 size_t length)
388{
Caroline Tice4a3533b2011-05-03 20:58:11 +0000389 fprintf (stdout, " Write to Memory (address = 0x%llx, length = %zu, context = ", addr, length);
Greg Clayton79ea8782011-04-26 23:48:45 +0000390 context.Dump (stdout, instruction);
Caroline Ticead379efc2011-04-05 18:46:00 +0000391 return length;
392}
393
394bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000395EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
396 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000397 const RegisterInfo *reg_info,
398 RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000399{
Greg Clayton7349bd92011-05-09 20:18:18 +0000400 fprintf (stdout, " Read Register (%s)\n", reg_info->name);
Greg Clayton79ea8782011-04-26 23:48:45 +0000401 uint32_t reg_kind, reg_num;
402 if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
Greg Clayton7349bd92011-05-09 20:18:18 +0000403 reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
Greg Clayton79ea8782011-04-26 23:48:45 +0000404 else
Greg Clayton7349bd92011-05-09 20:18:18 +0000405 reg_value.SetUInt64(0);
Greg Clayton79ea8782011-04-26 23:48:45 +0000406
Caroline Ticead379efc2011-04-05 18:46:00 +0000407 return true;
408}
409
410bool
Greg Clayton2ed751b2011-04-26 04:39:08 +0000411EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
412 void *baton,
Caroline Ticead379efc2011-04-05 18:46:00 +0000413 const Context &context,
Greg Clayton7349bd92011-05-09 20:18:18 +0000414 const RegisterInfo *reg_info,
415 const RegisterValue &reg_value)
Caroline Ticead379efc2011-04-05 18:46:00 +0000416{
Greg Clayton7349bd92011-05-09 20:18:18 +0000417 StreamFile strm (stdout, false);
418 strm.Printf (" Write to Register (name = %s, value = " , reg_info->name);
419 reg_value.Dump(&strm, reg_info, false);
420 strm.PutCString (", context = ");
Greg Clayton79ea8782011-04-26 23:48:45 +0000421 context.Dump (stdout, instruction);
Caroline Ticead379efc2011-04-05 18:46:00 +0000422 return true;
423}
424
425void
Greg Clayton79ea8782011-04-26 23:48:45 +0000426EmulateInstruction::Context::Dump (FILE *fh,
427 EmulateInstruction *instruction) const
Caroline Ticead379efc2011-04-05 18:46:00 +0000428{
Greg Clayton79ea8782011-04-26 23:48:45 +0000429 switch (type)
Caroline Ticead379efc2011-04-05 18:46:00 +0000430 {
431 case eContextReadOpcode:
Greg Clayton79ea8782011-04-26 23:48:45 +0000432 fprintf (fh, "reading opcode");
Caroline Ticead379efc2011-04-05 18:46:00 +0000433 break;
434
435 case eContextImmediate:
Greg Clayton79ea8782011-04-26 23:48:45 +0000436 fprintf (fh, "immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000437 break;
438
439 case eContextPushRegisterOnStack:
Greg Clayton79ea8782011-04-26 23:48:45 +0000440 fprintf (fh, "push register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000441 break;
442
443 case eContextPopRegisterOffStack:
Greg Clayton79ea8782011-04-26 23:48:45 +0000444 fprintf (fh, "pop register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000445 break;
446
447 case eContextAdjustStackPointer:
Greg Clayton79ea8782011-04-26 23:48:45 +0000448 fprintf (fh, "adjust sp");
Caroline Ticead379efc2011-04-05 18:46:00 +0000449 break;
450
451 case eContextAdjustBaseRegister:
Greg Clayton79ea8782011-04-26 23:48:45 +0000452 fprintf (fh, "adjusting (writing value back to) a base register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000453 break;
454
455 case eContextRegisterPlusOffset:
Greg Clayton79ea8782011-04-26 23:48:45 +0000456 fprintf (fh, "register + offset");
Caroline Ticead379efc2011-04-05 18:46:00 +0000457 break;
458
459 case eContextRegisterStore:
Greg Clayton79ea8782011-04-26 23:48:45 +0000460 fprintf (fh, "store register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000461 break;
462
463 case eContextRegisterLoad:
Greg Clayton79ea8782011-04-26 23:48:45 +0000464 fprintf (fh, "load register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000465 break;
466
467 case eContextRelativeBranchImmediate:
Greg Clayton79ea8782011-04-26 23:48:45 +0000468 fprintf (fh, "relative branch immediate");
Caroline Ticead379efc2011-04-05 18:46:00 +0000469 break;
470
471 case eContextAbsoluteBranchRegister:
Greg Clayton79ea8782011-04-26 23:48:45 +0000472 fprintf (fh, "absolute branch register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000473 break;
474
475 case eContextSupervisorCall:
Greg Clayton79ea8782011-04-26 23:48:45 +0000476 fprintf (fh, "supervisor call");
Caroline Ticead379efc2011-04-05 18:46:00 +0000477 break;
478
479 case eContextTableBranchReadMemory:
Greg Clayton79ea8782011-04-26 23:48:45 +0000480 fprintf (fh, "table branch read memory");
Caroline Ticead379efc2011-04-05 18:46:00 +0000481 break;
482
483 case eContextWriteRegisterRandomBits:
Greg Clayton79ea8782011-04-26 23:48:45 +0000484 fprintf (fh, "write random bits to a register");
Caroline Ticead379efc2011-04-05 18:46:00 +0000485 break;
486
487 case eContextWriteMemoryRandomBits:
Greg Clayton79ea8782011-04-26 23:48:45 +0000488 fprintf (fh, "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:
492 fprintf (fh, "arithmetic");
Caroline Ticead379efc2011-04-05 18:46:00 +0000493 break;
494
495 case eContextReturnFromException:
Greg Clayton79ea8782011-04-26 23:48:45 +0000496 fprintf (fh, "return from exception");
Caroline Ticead379efc2011-04-05 18:46:00 +0000497 break;
498
499 default:
Greg Clayton79ea8782011-04-26 23:48:45 +0000500 fprintf (fh, "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 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000508 fprintf (fh,
509 " (reg_plus_offset = %s%+lld)\n",
510 info.RegisterPlusOffset.reg.name,
511 info.RegisterPlusOffset.signed_offset);
Caroline Ticead379efc2011-04-05 18:46:00 +0000512 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000513 break;
514
515 case eInfoTypeRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000516 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000517 fprintf (fh, " (reg_plus_reg = %s + %s)\n",
518 info.RegisterPlusIndirectOffset.base_reg.name,
519 info.RegisterPlusIndirectOffset.offset_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000520 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000521 break;
522
523 case eInfoTypeRegisterToRegisterPlusOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000524 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000525 fprintf (fh, " (base_and_imm_offset = %s%+lld, data_reg = %s)\n",
526 info.RegisterToRegisterPlusOffset.base_reg.name,
527 info.RegisterToRegisterPlusOffset.offset,
528 info.RegisterToRegisterPlusOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000529 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000530 break;
531
532 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
Caroline Ticead379efc2011-04-05 18:46:00 +0000533 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000534 fprintf (fh, " (base_and_reg_offset = %s + %s, data_reg = %s)\n",
535 info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
536 info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
537 info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
Caroline Ticead379efc2011-04-05 18:46:00 +0000538 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000539 break;
540
541 case eInfoTypeRegisterRegisterOperands:
542 {
543 fprintf (fh, " (register to register binary op: %s and %s)\n",
544 info.RegisterRegisterOperands.operand1.name,
545 info.RegisterRegisterOperands.operand2.name);
546 }
547 break;
548
549 case eInfoTypeOffset:
550 fprintf (fh, " (signed_offset = %+lld)\n", info.signed_offset);
551 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000552
Greg Clayton79ea8782011-04-26 23:48:45 +0000553 case eInfoTypeRegister:
554 fprintf (fh, " (reg = %s)\n", info.reg.name);
555 break;
556
557 case eInfoTypeImmediate:
558 fprintf (fh,
559 " (unsigned_immediate = %llu (0x%16.16llx))\n",
560 info.unsigned_immediate,
561 info.unsigned_immediate);
562 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000563
Greg Clayton79ea8782011-04-26 23:48:45 +0000564 case eInfoTypeImmediateSigned:
565 fprintf (fh,
566 " (signed_immediate = %+lld (0x%16.16llx))\n",
567 info.signed_immediate,
568 info.signed_immediate);
569 break;
570
571 case eInfoTypeAddress:
572 fprintf (fh, " (address = 0x%llx)\n", info.address);
573 break;
574
575 case eInfoTypeISAAndImmediate:
576 fprintf (fh,
577 " (isa = %u, unsigned_immediate = %u (0x%8.8x))\n",
578 info.ISAAndImmediate.isa,
579 info.ISAAndImmediate.unsigned_data32,
580 info.ISAAndImmediate.unsigned_data32);
581 break;
582
583 case eInfoTypeISAAndImmediateSigned:
584 fprintf (fh,
585 " (isa = %u, signed_immediate = %i (0x%8.8x))\n",
586 info.ISAAndImmediateSigned.isa,
587 info.ISAAndImmediateSigned.signed_data32,
588 info.ISAAndImmediateSigned.signed_data32);
589 break;
590
591 case eInfoTypeISA:
592 fprintf (fh, " (isa = %u)\n", info.isa);
593 break;
594
595 case eInfoTypeNoArgs:
596 fprintf (fh, " \n");
597 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000598
Greg Clayton79ea8782011-04-26 23:48:45 +0000599 default:
600 fprintf (fh, " (unknown <info_type>)\n");
601 break;
Caroline Ticead379efc2011-04-05 18:46:00 +0000602 }
603}
604
Greg Clayton2ed751b2011-04-26 04:39:08 +0000605bool
606EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
Caroline Ticead379efc2011-04-05 18:46:00 +0000607{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000608 m_opcode = opcode;
Greg Claytone5b34982011-04-29 22:50:31 +0000609 m_addr = LLDB_INVALID_ADDRESS;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000610 if (inst_addr.IsValid())
Caroline Ticead379efc2011-04-05 18:46:00 +0000611 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000612 if (target)
Greg Claytone5b34982011-04-29 22:50:31 +0000613 m_addr = inst_addr.GetLoadAddress (target);
614 if (m_addr == LLDB_INVALID_ADDRESS)
615 m_addr = inst_addr.GetFileAddress ();
Caroline Ticead379efc2011-04-05 18:46:00 +0000616 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000617 return true;
Caroline Ticead379efc2011-04-05 18:46:00 +0000618}
619
Greg Clayton79ea8782011-04-26 23:48:45 +0000620bool
Greg Clayton7349bd92011-05-09 20:18:18 +0000621EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
Greg Clayton79ea8782011-04-26 23:48:45 +0000622 uint32_t &reg_kind,
623 uint32_t &reg_num)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000624{
Greg Clayton79ea8782011-04-26 23:48:45 +0000625 // Generic and DWARF should be the two most popular register kinds when
626 // emulating instructions since they are the most platform agnostic...
Greg Clayton7349bd92011-05-09 20:18:18 +0000627 reg_num = reg_info->kinds[eRegisterKindGeneric];
Greg Clayton79ea8782011-04-26 23:48:45 +0000628 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000629 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000630 reg_kind = eRegisterKindGeneric;
631 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000632 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000633
Greg Clayton7349bd92011-05-09 20:18:18 +0000634 reg_num = reg_info->kinds[eRegisterKindDWARF];
Greg Clayton79ea8782011-04-26 23:48:45 +0000635 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton2ed751b2011-04-26 04:39:08 +0000636 {
Greg Clayton79ea8782011-04-26 23:48:45 +0000637 reg_kind = eRegisterKindDWARF;
638 return true;
639 }
Greg Clayton2ed751b2011-04-26 04:39:08 +0000640
Greg Clayton7349bd92011-05-09 20:18:18 +0000641 reg_num = reg_info->kinds[eRegisterKindLLDB];
Greg Clayton79ea8782011-04-26 23:48:45 +0000642 if (reg_num != LLDB_INVALID_REGNUM)
643 {
644 reg_kind = eRegisterKindLLDB;
645 return true;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000646 }
Greg Clayton79ea8782011-04-26 23:48:45 +0000647
Greg Clayton7349bd92011-05-09 20:18:18 +0000648 reg_num = reg_info->kinds[eRegisterKindGCC];
Greg Clayton79ea8782011-04-26 23:48:45 +0000649 if (reg_num != LLDB_INVALID_REGNUM)
650 {
651 reg_kind = eRegisterKindGCC;
652 return true;
653 }
654
Greg Clayton7349bd92011-05-09 20:18:18 +0000655 reg_num = reg_info->kinds[eRegisterKindGDB];
Greg Clayton79ea8782011-04-26 23:48:45 +0000656 if (reg_num != LLDB_INVALID_REGNUM)
657 {
658 reg_kind = eRegisterKindGDB;
659 return true;
660 }
661 return false;
662}
663
664uint32_t
665EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
666{
667 uint32_t reg_kind, reg_num;
Greg Clayton7349bd92011-05-09 20:18:18 +0000668 if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
Greg Clayton79ea8782011-04-26 23:48:45 +0000669 return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
670 return LLDB_INVALID_REGNUM;
671}
672
673
674bool
675EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
676{
677 unwind_plan.Clear();
678 return false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000679}
680
Caroline Ticead379efc2011-04-05 18:46:00 +0000681