blob: 73763f5ceec9295cad4decdb2805110c14a828d2 [file] [log] [blame]
Greg Clayton64c84432011-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 Clayton17f5afe2011-02-05 02:56:16 +000010#include "lldb/Core/EmulateInstruction.h"
Greg Clayton64c84432011-01-21 22:02:52 +000011
Greg Clayton888a7332011-04-26 04:39:08 +000012#include "lldb/Core/Address.h"
Greg Clayton64c84432011-01-21 22:02:52 +000013#include "lldb/Core/DataExtractor.h"
Caroline Tice080bf612011-04-05 18:46:00 +000014#include "lldb/Core/Error.h"
Greg Clayton52fd9842011-02-02 02:24:04 +000015#include "lldb/Core/PluginManager.h"
Greg Clayton061b79d2011-05-09 20:18:18 +000016#include "lldb/Core/RegisterValue.h"
17#include "lldb/Core/StreamFile.h"
Greg Clayton64c84432011-01-21 22:02:52 +000018#include "lldb/Core/StreamString.h"
Greg Claytoncd548032011-02-01 01:31:41 +000019#include "lldb/Host/Endian.h"
Greg Claytonc07d4512011-04-26 23:48:45 +000020#include "lldb/Symbol/UnwindPlan.h"
Caroline Tice080bf612011-04-05 18:46:00 +000021#include "lldb/Target/Process.h"
22#include "lldb/Target/RegisterContext.h"
Greg Clayton888a7332011-04-26 04:39:08 +000023#include "lldb/Target/Target.h"
Caroline Tice080bf612011-04-05 18:46:00 +000024#include "lldb/Target/Thread.h"
25
Greg Clayton64c84432011-01-21 22:02:52 +000026using namespace lldb;
27using namespace lldb_private;
28
Greg Clayton52fd9842011-02-02 02:24:04 +000029EmulateInstruction*
Greg Clayton888a7332011-04-26 04:39:08 +000030EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
Greg Clayton52fd9842011-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 Clayton888a7332011-04-26 04:39:08 +000038 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Tice080bf612011-04-05 18:46:00 +000039 if (emulate_insn_ptr)
40 return emulate_insn_ptr;
Greg Clayton52fd9842011-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 Clayton888a7332011-04-26 04:39:08 +000047 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
Caroline Tice080bf612011-04-05 18:46:00 +000048 if (emulate_insn_ptr)
49 return emulate_insn_ptr;
Greg Clayton52fd9842011-02-02 02:24:04 +000050 }
51 }
52 return NULL;
53}
Greg Clayton64c84432011-01-21 22:02:52 +000054
Greg Clayton888a7332011-04-26 04:39:08 +000055EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
Caroline Tice080bf612011-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 Clayton3063c952011-04-29 22:50:31 +000062 m_addr (LLDB_INVALID_ADDRESS)
Caroline Tice080bf612011-04-05 18:46:00 +000063{
64 ::memset (&m_opcode, 0, sizeof (m_opcode));
65}
66
Greg Claytonc07d4512011-04-26 23:48:45 +000067
Greg Clayton061b79d2011-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 Clayton64c84432011-01-21 22:02:52 +000078{
Greg Claytonc07d4512011-04-26 23:48:45 +000079 RegisterInfo reg_info;
80 if (GetRegisterInfo(reg_kind, reg_num, reg_info))
Greg Clayton061b79d2011-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 Claytonc07d4512011-04-26 23:48:45 +000094 if (success_ptr)
95 *success_ptr = false;
96 return fail_value;
97}
98
99uint64_t
Greg Clayton061b79d2011-05-09 20:18:18 +0000100EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
101 uint64_t fail_value,
102 bool *success_ptr)
Greg Claytonc07d4512011-04-26 23:48:45 +0000103{
Greg Clayton061b79d2011-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 Clayton64c84432011-01-21 22:02:52 +0000107 if (success_ptr)
Greg Clayton061b79d2011-05-09 20:18:18 +0000108 *success_ptr = false;
109 return fail_value;
Greg Clayton64c84432011-01-21 22:02:52 +0000110}
111
112bool
Greg Clayton061b79d2011-05-09 20:18:18 +0000113EmulateInstruction::WriteRegister (const Context &context,
114 const RegisterInfo *reg_info,
115 const RegisterValue& reg_value)
Greg Clayton64c84432011-01-21 22:02:52 +0000116{
Greg Clayton061b79d2011-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 Claytonc07d4512011-04-26 23:48:45 +0000119 return false;
120}
121
122bool
Greg Clayton061b79d2011-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 Claytonc07d4512011-04-26 23:48:45 +0000127{
Greg Clayton061b79d2011-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 Clayton64c84432011-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 Clayton888a7332011-04-26 04:39:08 +0000186 size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
Greg Clayton64c84432011-01-21 22:02:52 +0000187 if (bytes_read == byte_size)
188 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000189 lldb::offset_t offset = 0;
Greg Clayton888a7332011-04-26 04:39:08 +0000190 DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
Greg Clayton64c84432011-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 Clayton888a7332011-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 Clayton64c84432011-01-21 22:02:52 +0000215 if (bytes_written == uval_byte_size)
216 return true;
217 return false;
218}
Caroline Tice080bf612011-04-05 18:46:00 +0000219
Greg Clayton061b79d2011-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 Tice080bf612011-04-05 18:46:00 +0000231
232void
233EmulateInstruction::SetBaton (void *baton)
234{
235 m_baton = baton;
236}
237
238void
Greg Clayton061b79d2011-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 Tice080bf612011-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 Clayton061b79d2011-05-09 20:18:18 +0000251EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
Caroline Tice080bf612011-04-05 18:46:00 +0000252{
253 m_read_mem_callback = read_mem_callback;
254}
255
256
257void
Greg Clayton061b79d2011-05-09 20:18:18 +0000258EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
Caroline Tice080bf612011-04-05 18:46:00 +0000259{
260 m_write_mem_callback = write_mem_callback;
261}
262
263
264void
Greg Clayton061b79d2011-05-09 20:18:18 +0000265EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
Caroline Tice080bf612011-04-05 18:46:00 +0000266{
267 m_read_reg_callback = read_reg_callback;
268}
269
270
271void
Greg Clayton061b79d2011-05-09 20:18:18 +0000272EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
Caroline Tice080bf612011-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 Clayton888a7332011-04-26 04:39:08 +0000284EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
285 void *baton,
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000286 const Context &context,
287 lldb::addr_t addr,
288 void *dst,
Greg Clayton289afcb2012-02-18 05:35:26 +0000289 size_t dst_len)
Caroline Tice080bf612011-04-05 18:46:00 +0000290{
Greg Clayton289afcb2012-02-18 05:35:26 +0000291 if (!baton || dst == NULL || dst_len == 0)
Caroline Tice080bf612011-04-05 18:46:00 +0000292 return 0;
Greg Clayton289afcb2012-02-18 05:35:26 +0000293
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000294 StackFrame *frame = (StackFrame *) baton;
295
Greg Clayton289afcb2012-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 Tice080bf612011-04-05 18:46:00 +0000303}
304
305size_t
Greg Clayton888a7332011-04-26 04:39:08 +0000306EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
307 void *baton,
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000308 const Context &context,
309 lldb::addr_t addr,
Greg Clayton289afcb2012-02-18 05:35:26 +0000310 const void *src,
311 size_t src_len)
Caroline Tice080bf612011-04-05 18:46:00 +0000312{
Greg Clayton289afcb2012-02-18 05:35:26 +0000313 if (!baton || src == NULL || src_len == 0)
Caroline Tice080bf612011-04-05 18:46:00 +0000314 return 0;
315
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000316 StackFrame *frame = (StackFrame *) baton;
317
Greg Clayton289afcb2012-02-18 05:35:26 +0000318 ProcessSP process_sp (frame->CalculateProcess());
319 if (process_sp)
Caroline Tice080bf612011-04-05 18:46:00 +0000320 {
Greg Clayton289afcb2012-02-18 05:35:26 +0000321 Error error;
322 return process_sp->WriteMemory (addr, src, src_len, error);
Caroline Tice080bf612011-04-05 18:46:00 +0000323 }
324
325 return 0;
326}
327
328bool
Greg Clayton888a7332011-04-26 04:39:08 +0000329EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
330 void *baton,
Greg Clayton061b79d2011-05-09 20:18:18 +0000331 const RegisterInfo *reg_info,
332 RegisterValue &reg_value)
Caroline Tice080bf612011-04-05 18:46:00 +0000333{
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000334 if (!baton)
Caroline Tice080bf612011-04-05 18:46:00 +0000335 return false;
336
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000337 StackFrame *frame = (StackFrame *) baton;
Greg Clayton061b79d2011-05-09 20:18:18 +0000338 return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
Caroline Tice080bf612011-04-05 18:46:00 +0000339}
340
341bool
Greg Clayton888a7332011-04-26 04:39:08 +0000342EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
343 void *baton,
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000344 const Context &context,
Greg Clayton061b79d2011-05-09 20:18:18 +0000345 const RegisterInfo *reg_info,
346 const RegisterValue &reg_value)
Caroline Tice080bf612011-04-05 18:46:00 +0000347{
Caroline Ticeea69d6d2011-04-05 20:18:48 +0000348 if (!baton)
349 return false;
350
351 StackFrame *frame = (StackFrame *) baton;
Greg Clayton061b79d2011-05-09 20:18:18 +0000352 return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
Caroline Tice080bf612011-04-05 18:46:00 +0000353}
354
355size_t
Greg Clayton888a7332011-04-26 04:39:08 +0000356EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
357 void *baton,
Caroline Tice080bf612011-04-05 18:46:00 +0000358 const Context &context,
359 lldb::addr_t addr,
360 void *dst,
361 size_t length)
362{
Greg Clayton75906e42011-05-11 18:39:18 +0000363 StreamFile strm (stdout, false);
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000364 strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
Greg Clayton75906e42011-05-11 18:39:18 +0000365 context.Dump (strm, instruction);
366 strm.EOL();
Caroline Tice080bf612011-04-05 18:46:00 +0000367 *((uint64_t *) dst) = 0xdeadbeef;
368 return length;
369}
370
371size_t
Greg Clayton888a7332011-04-26 04:39:08 +0000372EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
373 void *baton,
Caroline Tice080bf612011-04-05 18:46:00 +0000374 const Context &context,
375 lldb::addr_t addr,
376 const void *dst,
377 size_t length)
378{
Greg Clayton75906e42011-05-11 18:39:18 +0000379 StreamFile strm (stdout, false);
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000380 strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
Greg Clayton75906e42011-05-11 18:39:18 +0000381 context.Dump (strm, instruction);
382 strm.EOL();
Caroline Tice080bf612011-04-05 18:46:00 +0000383 return length;
384}
385
386bool
Greg Clayton888a7332011-04-26 04:39:08 +0000387EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
388 void *baton,
Greg Clayton061b79d2011-05-09 20:18:18 +0000389 const RegisterInfo *reg_info,
390 RegisterValue &reg_value)
Caroline Tice080bf612011-04-05 18:46:00 +0000391{
Greg Clayton75906e42011-05-11 18:39:18 +0000392 StreamFile strm (stdout, false);
393 strm.Printf (" Read Register (%s)\n", reg_info->name);
Greg Claytonc07d4512011-04-26 23:48:45 +0000394 uint32_t reg_kind, reg_num;
395 if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
Greg Clayton061b79d2011-05-09 20:18:18 +0000396 reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
Greg Claytonc07d4512011-04-26 23:48:45 +0000397 else
Greg Clayton061b79d2011-05-09 20:18:18 +0000398 reg_value.SetUInt64(0);
Greg Claytonc07d4512011-04-26 23:48:45 +0000399
Caroline Tice080bf612011-04-05 18:46:00 +0000400 return true;
401}
402
403bool
Greg Clayton888a7332011-04-26 04:39:08 +0000404EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
405 void *baton,
Caroline Tice080bf612011-04-05 18:46:00 +0000406 const Context &context,
Greg Clayton061b79d2011-05-09 20:18:18 +0000407 const RegisterInfo *reg_info,
408 const RegisterValue &reg_value)
Caroline Tice080bf612011-04-05 18:46:00 +0000409{
Greg Clayton061b79d2011-05-09 20:18:18 +0000410 StreamFile strm (stdout, false);
411 strm.Printf (" Write to Register (name = %s, value = " , reg_info->name);
Greg Clayton997b1e82011-05-15 04:12:07 +0000412 reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
Greg Clayton061b79d2011-05-09 20:18:18 +0000413 strm.PutCString (", context = ");
Greg Clayton75906e42011-05-11 18:39:18 +0000414 context.Dump (strm, instruction);
415 strm.EOL();
Caroline Tice080bf612011-04-05 18:46:00 +0000416 return true;
417}
418
419void
Greg Clayton75906e42011-05-11 18:39:18 +0000420EmulateInstruction::Context::Dump (Stream &strm,
Greg Claytonc07d4512011-04-26 23:48:45 +0000421 EmulateInstruction *instruction) const
Caroline Tice080bf612011-04-05 18:46:00 +0000422{
Greg Claytonc07d4512011-04-26 23:48:45 +0000423 switch (type)
Caroline Tice080bf612011-04-05 18:46:00 +0000424 {
425 case eContextReadOpcode:
Greg Clayton75906e42011-05-11 18:39:18 +0000426 strm.PutCString ("reading opcode");
Caroline Tice080bf612011-04-05 18:46:00 +0000427 break;
428
429 case eContextImmediate:
Greg Clayton75906e42011-05-11 18:39:18 +0000430 strm.PutCString ("immediate");
Caroline Tice080bf612011-04-05 18:46:00 +0000431 break;
432
433 case eContextPushRegisterOnStack:
Greg Clayton75906e42011-05-11 18:39:18 +0000434 strm.PutCString ("push register");
Caroline Tice080bf612011-04-05 18:46:00 +0000435 break;
436
437 case eContextPopRegisterOffStack:
Greg Clayton75906e42011-05-11 18:39:18 +0000438 strm.PutCString ("pop register");
Caroline Tice080bf612011-04-05 18:46:00 +0000439 break;
440
441 case eContextAdjustStackPointer:
Greg Clayton75906e42011-05-11 18:39:18 +0000442 strm.PutCString ("adjust sp");
Caroline Tice080bf612011-04-05 18:46:00 +0000443 break;
444
Greg Clayton65611552011-06-04 01:26:29 +0000445 case eContextSetFramePointer:
446 strm.PutCString ("set frame pointer");
447 break;
448
Caroline Tice080bf612011-04-05 18:46:00 +0000449 case eContextAdjustBaseRegister:
Greg Clayton75906e42011-05-11 18:39:18 +0000450 strm.PutCString ("adjusting (writing value back to) a base register");
Caroline Tice080bf612011-04-05 18:46:00 +0000451 break;
452
453 case eContextRegisterPlusOffset:
Greg Clayton75906e42011-05-11 18:39:18 +0000454 strm.PutCString ("register + offset");
Caroline Tice080bf612011-04-05 18:46:00 +0000455 break;
456
457 case eContextRegisterStore:
Greg Clayton75906e42011-05-11 18:39:18 +0000458 strm.PutCString ("store register");
Caroline Tice080bf612011-04-05 18:46:00 +0000459 break;
460
461 case eContextRegisterLoad:
Greg Clayton75906e42011-05-11 18:39:18 +0000462 strm.PutCString ("load register");
Caroline Tice080bf612011-04-05 18:46:00 +0000463 break;
464
465 case eContextRelativeBranchImmediate:
Greg Clayton75906e42011-05-11 18:39:18 +0000466 strm.PutCString ("relative branch immediate");
Caroline Tice080bf612011-04-05 18:46:00 +0000467 break;
468
469 case eContextAbsoluteBranchRegister:
Greg Clayton75906e42011-05-11 18:39:18 +0000470 strm.PutCString ("absolute branch register");
Caroline Tice080bf612011-04-05 18:46:00 +0000471 break;
472
473 case eContextSupervisorCall:
Greg Clayton75906e42011-05-11 18:39:18 +0000474 strm.PutCString ("supervisor call");
Caroline Tice080bf612011-04-05 18:46:00 +0000475 break;
476
477 case eContextTableBranchReadMemory:
Greg Clayton75906e42011-05-11 18:39:18 +0000478 strm.PutCString ("table branch read memory");
Caroline Tice080bf612011-04-05 18:46:00 +0000479 break;
480
481 case eContextWriteRegisterRandomBits:
Greg Clayton75906e42011-05-11 18:39:18 +0000482 strm.PutCString ("write random bits to a register");
Caroline Tice080bf612011-04-05 18:46:00 +0000483 break;
484
485 case eContextWriteMemoryRandomBits:
Greg Clayton75906e42011-05-11 18:39:18 +0000486 strm.PutCString ("write random bits to a memory address");
Caroline Tice080bf612011-04-05 18:46:00 +0000487 break;
488
Greg Claytonc07d4512011-04-26 23:48:45 +0000489 case eContextArithmetic:
Greg Clayton75906e42011-05-11 18:39:18 +0000490 strm.PutCString ("arithmetic");
Caroline Tice080bf612011-04-05 18:46:00 +0000491 break;
492
493 case eContextReturnFromException:
Greg Clayton75906e42011-05-11 18:39:18 +0000494 strm.PutCString ("return from exception");
Caroline Tice080bf612011-04-05 18:46:00 +0000495 break;
496
497 default:
Greg Clayton75906e42011-05-11 18:39:18 +0000498 strm.PutCString ("unrecognized context.");
Caroline Tice080bf612011-04-05 18:46:00 +0000499 break;
500 }
501
Greg Claytonc07d4512011-04-26 23:48:45 +0000502 switch (info_type)
Caroline Tice080bf612011-04-05 18:46:00 +0000503 {
Greg Claytonc07d4512011-04-26 23:48:45 +0000504 case eInfoTypeRegisterPlusOffset:
Caroline Tice080bf612011-04-05 18:46:00 +0000505 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000506 strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")",
Greg Clayton75906e42011-05-11 18:39:18 +0000507 info.RegisterPlusOffset.reg.name,
508 info.RegisterPlusOffset.signed_offset);
Caroline Tice080bf612011-04-05 18:46:00 +0000509 }
Greg Claytonc07d4512011-04-26 23:48:45 +0000510 break;
511
512 case eInfoTypeRegisterPlusIndirectOffset:
Caroline Tice080bf612011-04-05 18:46:00 +0000513 {
Greg Clayton75906e42011-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 Tice080bf612011-04-05 18:46:00 +0000517 }
Greg Claytonc07d4512011-04-26 23:48:45 +0000518 break;
519
520 case eInfoTypeRegisterToRegisterPlusOffset:
Caroline Tice080bf612011-04-05 18:46:00 +0000521 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000522 strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
Greg Clayton75906e42011-05-11 18:39:18 +0000523 info.RegisterToRegisterPlusOffset.base_reg.name,
524 info.RegisterToRegisterPlusOffset.offset,
525 info.RegisterToRegisterPlusOffset.data_reg.name);
Caroline Tice080bf612011-04-05 18:46:00 +0000526 }
Greg Claytonc07d4512011-04-26 23:48:45 +0000527 break;
528
529 case eInfoTypeRegisterToRegisterPlusIndirectOffset:
Caroline Tice080bf612011-04-05 18:46:00 +0000530 {
Greg Clayton75906e42011-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 Tice080bf612011-04-05 18:46:00 +0000535 }
Greg Claytonc07d4512011-04-26 23:48:45 +0000536 break;
537
538 case eInfoTypeRegisterRegisterOperands:
539 {
Greg Clayton75906e42011-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 Claytonc07d4512011-04-26 23:48:45 +0000543 }
544 break;
545
546 case eInfoTypeOffset:
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000547 strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
Greg Claytonc07d4512011-04-26 23:48:45 +0000548 break;
Caroline Tice080bf612011-04-05 18:46:00 +0000549
Greg Claytonc07d4512011-04-26 23:48:45 +0000550 case eInfoTypeRegister:
Greg Clayton75906e42011-05-11 18:39:18 +0000551 strm.Printf (" (reg = %s)", info.reg.name);
Greg Claytonc07d4512011-04-26 23:48:45 +0000552 break;
553
554 case eInfoTypeImmediate:
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000555 strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
Greg Clayton75906e42011-05-11 18:39:18 +0000556 info.unsigned_immediate,
557 info.unsigned_immediate);
Greg Claytonc07d4512011-04-26 23:48:45 +0000558 break;
Caroline Tice080bf612011-04-05 18:46:00 +0000559
Greg Claytonc07d4512011-04-26 23:48:45 +0000560 case eInfoTypeImmediateSigned:
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000561 strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
Greg Clayton75906e42011-05-11 18:39:18 +0000562 info.signed_immediate,
563 info.signed_immediate);
Greg Claytonc07d4512011-04-26 23:48:45 +0000564 break;
565
566 case eInfoTypeAddress:
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000567 strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
Greg Claytonc07d4512011-04-26 23:48:45 +0000568 break;
569
570 case eInfoTypeISAAndImmediate:
Greg Clayton75906e42011-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 Claytonc07d4512011-04-26 23:48:45 +0000575 break;
576
577 case eInfoTypeISAAndImmediateSigned:
Greg Clayton75906e42011-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 Claytonc07d4512011-04-26 23:48:45 +0000582 break;
583
584 case eInfoTypeISA:
Greg Clayton75906e42011-05-11 18:39:18 +0000585 strm.Printf (" (isa = %u)", info.isa);
Greg Claytonc07d4512011-04-26 23:48:45 +0000586 break;
587
588 case eInfoTypeNoArgs:
Greg Claytonc07d4512011-04-26 23:48:45 +0000589 break;
Caroline Tice080bf612011-04-05 18:46:00 +0000590 }
591}
592
Greg Clayton888a7332011-04-26 04:39:08 +0000593bool
594EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
Caroline Tice080bf612011-04-05 18:46:00 +0000595{
Greg Clayton888a7332011-04-26 04:39:08 +0000596 m_opcode = opcode;
Greg Clayton3063c952011-04-29 22:50:31 +0000597 m_addr = LLDB_INVALID_ADDRESS;
Greg Clayton888a7332011-04-26 04:39:08 +0000598 if (inst_addr.IsValid())
Caroline Tice080bf612011-04-05 18:46:00 +0000599 {
Greg Clayton888a7332011-04-26 04:39:08 +0000600 if (target)
Greg Clayton3063c952011-04-29 22:50:31 +0000601 m_addr = inst_addr.GetLoadAddress (target);
602 if (m_addr == LLDB_INVALID_ADDRESS)
603 m_addr = inst_addr.GetFileAddress ();
Caroline Tice080bf612011-04-05 18:46:00 +0000604 }
Greg Clayton888a7332011-04-26 04:39:08 +0000605 return true;
Caroline Tice080bf612011-04-05 18:46:00 +0000606}
607
Greg Claytonc07d4512011-04-26 23:48:45 +0000608bool
Greg Clayton061b79d2011-05-09 20:18:18 +0000609EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
Greg Claytonc07d4512011-04-26 23:48:45 +0000610 uint32_t &reg_kind,
611 uint32_t &reg_num)
Greg Clayton888a7332011-04-26 04:39:08 +0000612{
Greg Claytonc07d4512011-04-26 23:48:45 +0000613 // Generic and DWARF should be the two most popular register kinds when
614 // emulating instructions since they are the most platform agnostic...
Greg Clayton061b79d2011-05-09 20:18:18 +0000615 reg_num = reg_info->kinds[eRegisterKindGeneric];
Greg Claytonc07d4512011-04-26 23:48:45 +0000616 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton888a7332011-04-26 04:39:08 +0000617 {
Greg Claytonc07d4512011-04-26 23:48:45 +0000618 reg_kind = eRegisterKindGeneric;
619 return true;
Greg Clayton888a7332011-04-26 04:39:08 +0000620 }
Greg Clayton888a7332011-04-26 04:39:08 +0000621
Greg Clayton061b79d2011-05-09 20:18:18 +0000622 reg_num = reg_info->kinds[eRegisterKindDWARF];
Greg Claytonc07d4512011-04-26 23:48:45 +0000623 if (reg_num != LLDB_INVALID_REGNUM)
Greg Clayton888a7332011-04-26 04:39:08 +0000624 {
Greg Claytonc07d4512011-04-26 23:48:45 +0000625 reg_kind = eRegisterKindDWARF;
626 return true;
627 }
Greg Clayton888a7332011-04-26 04:39:08 +0000628
Greg Clayton061b79d2011-05-09 20:18:18 +0000629 reg_num = reg_info->kinds[eRegisterKindLLDB];
Greg Claytonc07d4512011-04-26 23:48:45 +0000630 if (reg_num != LLDB_INVALID_REGNUM)
631 {
632 reg_kind = eRegisterKindLLDB;
633 return true;
Greg Clayton888a7332011-04-26 04:39:08 +0000634 }
Greg Claytonc07d4512011-04-26 23:48:45 +0000635
Greg Clayton061b79d2011-05-09 20:18:18 +0000636 reg_num = reg_info->kinds[eRegisterKindGCC];
Greg Claytonc07d4512011-04-26 23:48:45 +0000637 if (reg_num != LLDB_INVALID_REGNUM)
638 {
639 reg_kind = eRegisterKindGCC;
640 return true;
641 }
642
Greg Clayton061b79d2011-05-09 20:18:18 +0000643 reg_num = reg_info->kinds[eRegisterKindGDB];
Greg Claytonc07d4512011-04-26 23:48:45 +0000644 if (reg_num != LLDB_INVALID_REGNUM)
645 {
646 reg_kind = eRegisterKindGDB;
647 return true;
648 }
649 return false;
650}
651
652uint32_t
653EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
654{
655 uint32_t reg_kind, reg_num;
Greg Clayton061b79d2011-05-09 20:18:18 +0000656 if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
Greg Claytonc07d4512011-04-26 23:48:45 +0000657 return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
658 return LLDB_INVALID_REGNUM;
659}
660
661
662bool
663EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
664{
665 unwind_plan.Clear();
666 return false;
Greg Clayton888a7332011-04-26 04:39:08 +0000667}
668
Caroline Tice080bf612011-04-05 18:46:00 +0000669