blob: 0faace6fd1f9ae294ba3e06ef0f975f32acbe99c [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
12#include "lldb/Core/DataExtractor.h"
Greg Clayton4272cc72011-02-02 02:24:04 +000013#include "lldb/Core/PluginManager.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000014#include "lldb/Core/StreamString.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000015#include "lldb/Host/Endian.h"
Greg Clayton6da4ca82011-01-21 22:02:52 +000016using namespace lldb;
17using namespace lldb_private;
18
Greg Clayton4272cc72011-02-02 02:24:04 +000019EmulateInstruction*
20EmulateInstruction::FindPlugin (const ConstString &triple, const char *plugin_name)
21{
22 EmulateInstructionCreateInstance create_callback = NULL;
23 if (plugin_name)
24 {
25 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
26 if (create_callback)
27 {
28 std::auto_ptr<EmulateInstruction> instance_ap(create_callback(triple));
29 if (instance_ap.get())
30 return instance_ap.release();
31 }
32 }
33 else
34 {
35 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
36 {
37 std::auto_ptr<EmulateInstruction> instance_ap(create_callback(triple));
38 if (instance_ap.get())
39 return instance_ap.release();
40 }
41 }
42 return NULL;
43}
Greg Clayton6da4ca82011-01-21 22:02:52 +000044
45EmulateInstruction::EmulateInstruction
46(
47 lldb::ByteOrder byte_order,
48 uint32_t addr_byte_size,
49 void *baton,
50 ReadMemory read_mem_callback,
51 WriteMemory write_mem_callback,
52 ReadRegister read_reg_callback,
53 WriteRegister write_reg_callback
54) :
Greg Clayton7fb56d02011-02-01 01:31:41 +000055 m_byte_order (endian::InlHostByteOrder()),
Greg Clayton6da4ca82011-01-21 22:02:52 +000056 m_addr_byte_size (sizeof (void *)),
57 m_baton (baton),
58 m_read_mem_callback (read_mem_callback),
59 m_write_mem_callback (write_mem_callback),
60 m_read_reg_callback (read_reg_callback),
61 m_write_reg_callback (write_reg_callback),
62 m_inst_pc (LLDB_INVALID_ADDRESS)
63{
Greg Clayton72b77eb2011-02-04 21:13:05 +000064 ::memset (&m_inst, 0, sizeof (m_inst));
Greg Clayton6da4ca82011-01-21 22:02:52 +000065}
66
67uint64_t
68EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
69{
70 uint64_t uval64 = 0;
71 bool success = m_read_reg_callback (m_baton, reg_kind, reg_num, uval64);
72 if (success_ptr)
73 *success_ptr = success;
74 if (!success)
75 uval64 = fail_value;
76 return uval64;
77}
78
79bool
80EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
81{
82 return m_write_reg_callback (m_baton, context, reg_kind, reg_num, reg_value);
83}
84
85uint64_t
86EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
87{
88 uint64_t uval64 = 0;
89 bool success = false;
90 if (byte_size <= 8)
91 {
92 uint8_t buf[sizeof(uint64_t)];
93 size_t bytes_read = m_read_mem_callback (m_baton, context, addr, buf, byte_size);
94 if (bytes_read == byte_size)
95 {
96 uint32_t offset = 0;
97 DataExtractor data (buf, byte_size, m_byte_order, m_addr_byte_size);
98 uval64 = data.GetMaxU64 (&offset, byte_size);
99 success = true;
100 }
101 }
102
103 if (success_ptr)
104 *success_ptr = success;
105
106 if (!success)
107 uval64 = fail_value;
108 return uval64;
109}
110
111
112bool
113EmulateInstruction::WriteMemoryUnsigned (const Context &context,
114 lldb::addr_t addr,
115 uint64_t uval,
116 size_t uval_byte_size)
117{
118 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
119 strm.PutMaxHex64 (uval, uval_byte_size);
120
121 size_t bytes_written = m_write_mem_callback (m_baton, context, addr, strm.GetData(), uval_byte_size);
122 if (bytes_written == uval_byte_size)
123 return true;
124 return false;
125}