1cfca06d7SDimitry Andric //===-- EmulateInstruction.cpp --------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "lldb/Core/EmulateInstruction.h"
10f034231aSEd Maste
11f034231aSEd Maste #include "lldb/Core/Address.h"
12f73363f1SDimitry Andric #include "lldb/Core/DumpRegisterValue.h"
13f034231aSEd Maste #include "lldb/Core/PluginManager.h"
14b1c73532SDimitry Andric #include "lldb/Host/StreamFile.h"
15f034231aSEd Maste #include "lldb/Symbol/UnwindPlan.h"
16f034231aSEd Maste #include "lldb/Target/Process.h"
17f034231aSEd Maste #include "lldb/Target/RegisterContext.h"
1894994d37SDimitry Andric #include "lldb/Target/StackFrame.h"
1994994d37SDimitry Andric #include "lldb/Utility/ConstString.h"
2074a628f7SDimitry Andric #include "lldb/Utility/DataExtractor.h"
2194994d37SDimitry Andric #include "lldb/Utility/RegisterValue.h"
22b76161e4SDimitry Andric #include "lldb/Utility/Status.h"
2394994d37SDimitry Andric #include "lldb/Utility/Stream.h"
2474a628f7SDimitry Andric #include "lldb/Utility/StreamString.h"
2594994d37SDimitry Andric #include "lldb/lldb-forward.h"
2694994d37SDimitry Andric #include "lldb/lldb-private-interfaces.h"
2774a628f7SDimitry Andric
2894994d37SDimitry Andric #include "llvm/ADT/StringRef.h"
2974a628f7SDimitry Andric
3074a628f7SDimitry Andric #include <cstring>
3194994d37SDimitry Andric #include <memory>
32e3b55780SDimitry Andric #include <optional>
3374a628f7SDimitry Andric
34344a3780SDimitry Andric #include <cinttypes>
35344a3780SDimitry Andric #include <cstdio>
3674a628f7SDimitry Andric
3774a628f7SDimitry Andric namespace lldb_private {
3874a628f7SDimitry Andric class Target;
3974a628f7SDimitry Andric }
40f034231aSEd Maste
41f034231aSEd Maste using namespace lldb;
42f034231aSEd Maste using namespace lldb_private;
43f034231aSEd Maste
44f034231aSEd Maste EmulateInstruction *
FindPlugin(const ArchSpec & arch,InstructionType supported_inst_type,const char * plugin_name)4514f1b3e8SDimitry Andric EmulateInstruction::FindPlugin(const ArchSpec &arch,
4614f1b3e8SDimitry Andric InstructionType supported_inst_type,
4714f1b3e8SDimitry Andric const char *plugin_name) {
48f3fbd1c0SDimitry Andric EmulateInstructionCreateInstance create_callback = nullptr;
4914f1b3e8SDimitry Andric if (plugin_name) {
5014f1b3e8SDimitry Andric create_callback =
5114f1b3e8SDimitry Andric PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
52c0981da4SDimitry Andric plugin_name);
5314f1b3e8SDimitry Andric if (create_callback) {
5414f1b3e8SDimitry Andric EmulateInstruction *emulate_insn_ptr =
5514f1b3e8SDimitry Andric create_callback(arch, supported_inst_type);
56f034231aSEd Maste if (emulate_insn_ptr)
57f034231aSEd Maste return emulate_insn_ptr;
58f034231aSEd Maste }
5914f1b3e8SDimitry Andric } else {
6014f1b3e8SDimitry Andric for (uint32_t idx = 0;
6114f1b3e8SDimitry Andric (create_callback =
6214f1b3e8SDimitry Andric PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) !=
6314f1b3e8SDimitry Andric nullptr;
6414f1b3e8SDimitry Andric ++idx) {
6514f1b3e8SDimitry Andric EmulateInstruction *emulate_insn_ptr =
6614f1b3e8SDimitry Andric create_callback(arch, supported_inst_type);
67f034231aSEd Maste if (emulate_insn_ptr)
68f034231aSEd Maste return emulate_insn_ptr;
69f034231aSEd Maste }
70f034231aSEd Maste }
71f3fbd1c0SDimitry Andric return nullptr;
72f034231aSEd Maste }
73f034231aSEd Maste
EmulateInstruction(const ArchSpec & arch)745f29bb8aSDimitry Andric EmulateInstruction::EmulateInstruction(const ArchSpec &arch) : m_arch(arch) {}
75f034231aSEd Maste
76e3b55780SDimitry Andric std::optional<RegisterValue>
ReadRegister(const RegisterInfo & reg_info)77e3b55780SDimitry Andric EmulateInstruction::ReadRegister(const RegisterInfo ®_info) {
78e3b55780SDimitry Andric if (m_read_reg_callback == nullptr)
79e3b55780SDimitry Andric return {};
80e3b55780SDimitry Andric
81e3b55780SDimitry Andric RegisterValue reg_value;
82e3b55780SDimitry Andric bool success = m_read_reg_callback(this, m_baton, ®_info, reg_value);
83e3b55780SDimitry Andric if (success)
84e3b55780SDimitry Andric return reg_value;
85e3b55780SDimitry Andric return {};
86f034231aSEd Maste }
87f034231aSEd Maste
ReadRegister(lldb::RegisterKind reg_kind,uint32_t reg_num,RegisterValue & reg_value)8814f1b3e8SDimitry Andric bool EmulateInstruction::ReadRegister(lldb::RegisterKind reg_kind,
8914f1b3e8SDimitry Andric uint32_t reg_num,
9014f1b3e8SDimitry Andric RegisterValue ®_value) {
91e3b55780SDimitry Andric std::optional<RegisterInfo> reg_info = GetRegisterInfo(reg_kind, reg_num);
92e3b55780SDimitry Andric if (!reg_info)
93f034231aSEd Maste return false;
94e3b55780SDimitry Andric
95e3b55780SDimitry Andric std::optional<RegisterValue> value = ReadRegister(*reg_info);
96e3b55780SDimitry Andric if (value)
97e3b55780SDimitry Andric reg_value = *value;
98e3b55780SDimitry Andric return value.has_value();
99f034231aSEd Maste }
100f034231aSEd Maste
ReadRegisterUnsigned(lldb::RegisterKind reg_kind,uint32_t reg_num,uint64_t fail_value,bool * success_ptr)10114f1b3e8SDimitry Andric uint64_t EmulateInstruction::ReadRegisterUnsigned(lldb::RegisterKind reg_kind,
102f034231aSEd Maste uint32_t reg_num,
103f034231aSEd Maste uint64_t fail_value,
10414f1b3e8SDimitry Andric bool *success_ptr) {
105f034231aSEd Maste RegisterValue reg_value;
106f034231aSEd Maste if (ReadRegister(reg_kind, reg_num, reg_value))
107f034231aSEd Maste return reg_value.GetAsUInt64(fail_value, success_ptr);
108f034231aSEd Maste if (success_ptr)
109f034231aSEd Maste *success_ptr = false;
110f034231aSEd Maste return fail_value;
111f034231aSEd Maste }
112f034231aSEd Maste
ReadRegisterUnsigned(const RegisterInfo & reg_info,uint64_t fail_value,bool * success_ptr)113e3b55780SDimitry Andric uint64_t EmulateInstruction::ReadRegisterUnsigned(const RegisterInfo ®_info,
114f034231aSEd Maste uint64_t fail_value,
11514f1b3e8SDimitry Andric bool *success_ptr) {
116e3b55780SDimitry Andric std::optional<RegisterValue> reg_value = ReadRegister(reg_info);
117e3b55780SDimitry Andric if (!reg_value) {
118f034231aSEd Maste if (success_ptr)
119f034231aSEd Maste *success_ptr = false;
120f034231aSEd Maste return fail_value;
121f034231aSEd Maste }
122f034231aSEd Maste
123e3b55780SDimitry Andric return reg_value->GetAsUInt64(fail_value, success_ptr);
124e3b55780SDimitry Andric }
125e3b55780SDimitry Andric
WriteRegister(const Context & context,const RegisterInfo & reg_info,const RegisterValue & reg_value)12614f1b3e8SDimitry Andric bool EmulateInstruction::WriteRegister(const Context &context,
127e3b55780SDimitry Andric const RegisterInfo ®_info,
12814f1b3e8SDimitry Andric const RegisterValue ®_value) {
129f3fbd1c0SDimitry Andric if (m_write_reg_callback != nullptr)
130e3b55780SDimitry Andric return m_write_reg_callback(this, m_baton, context, ®_info, reg_value);
131f034231aSEd Maste return false;
132f034231aSEd Maste }
133f034231aSEd Maste
WriteRegister(const Context & context,lldb::RegisterKind reg_kind,uint32_t reg_num,const RegisterValue & reg_value)13414f1b3e8SDimitry Andric bool EmulateInstruction::WriteRegister(const Context &context,
1350cac4ca3SEd Maste lldb::RegisterKind reg_kind,
136f034231aSEd Maste uint32_t reg_num,
13714f1b3e8SDimitry Andric const RegisterValue ®_value) {
138e3b55780SDimitry Andric std::optional<RegisterInfo> reg_info = GetRegisterInfo(reg_kind, reg_num);
139e3b55780SDimitry Andric if (reg_info)
140e3b55780SDimitry Andric return WriteRegister(context, *reg_info, reg_value);
141f034231aSEd Maste return false;
142f034231aSEd Maste }
143f034231aSEd Maste
WriteRegisterUnsigned(const Context & context,lldb::RegisterKind reg_kind,uint32_t reg_num,uint64_t uint_value)14414f1b3e8SDimitry Andric bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
1450cac4ca3SEd Maste lldb::RegisterKind reg_kind,
146f034231aSEd Maste uint32_t reg_num,
14714f1b3e8SDimitry Andric uint64_t uint_value) {
148e3b55780SDimitry Andric std::optional<RegisterInfo> reg_info = GetRegisterInfo(reg_kind, reg_num);
149e3b55780SDimitry Andric if (reg_info) {
150f034231aSEd Maste RegisterValue reg_value;
151e3b55780SDimitry Andric if (reg_value.SetUInt(uint_value, reg_info->byte_size))
152e3b55780SDimitry Andric return WriteRegister(context, *reg_info, reg_value);
153f034231aSEd Maste }
154f034231aSEd Maste return false;
155f034231aSEd Maste }
156f034231aSEd Maste
WriteRegisterUnsigned(const Context & context,const RegisterInfo & reg_info,uint64_t uint_value)15714f1b3e8SDimitry Andric bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
158e3b55780SDimitry Andric const RegisterInfo ®_info,
15914f1b3e8SDimitry Andric uint64_t uint_value) {
160f034231aSEd Maste RegisterValue reg_value;
161e3b55780SDimitry Andric if (reg_value.SetUInt(uint_value, reg_info.byte_size))
162f034231aSEd Maste return WriteRegister(context, reg_info, reg_value);
163f034231aSEd Maste return false;
164f034231aSEd Maste }
165f034231aSEd Maste
ReadMemory(const Context & context,lldb::addr_t addr,void * dst,size_t dst_len)16614f1b3e8SDimitry Andric size_t EmulateInstruction::ReadMemory(const Context &context, lldb::addr_t addr,
16714f1b3e8SDimitry Andric void *dst, size_t dst_len) {
168f3fbd1c0SDimitry Andric if (m_read_mem_callback != nullptr)
16914f1b3e8SDimitry Andric return m_read_mem_callback(this, m_baton, context, addr, dst, dst_len) ==
17014f1b3e8SDimitry Andric dst_len;
171f034231aSEd Maste return false;
172f034231aSEd Maste }
173f034231aSEd Maste
ReadMemoryUnsigned(const Context & context,lldb::addr_t addr,size_t byte_size,uint64_t fail_value,bool * success_ptr)17414f1b3e8SDimitry Andric uint64_t EmulateInstruction::ReadMemoryUnsigned(const Context &context,
17514f1b3e8SDimitry Andric lldb::addr_t addr,
17614f1b3e8SDimitry Andric size_t byte_size,
17714f1b3e8SDimitry Andric uint64_t fail_value,
17814f1b3e8SDimitry Andric bool *success_ptr) {
179f034231aSEd Maste uint64_t uval64 = 0;
180f034231aSEd Maste bool success = false;
18114f1b3e8SDimitry Andric if (byte_size <= 8) {
182f034231aSEd Maste uint8_t buf[sizeof(uint64_t)];
18314f1b3e8SDimitry Andric size_t bytes_read =
18414f1b3e8SDimitry Andric m_read_mem_callback(this, m_baton, context, addr, buf, byte_size);
18514f1b3e8SDimitry Andric if (bytes_read == byte_size) {
186f034231aSEd Maste lldb::offset_t offset = 0;
187f034231aSEd Maste DataExtractor data(buf, byte_size, GetByteOrder(), GetAddressByteSize());
188f034231aSEd Maste uval64 = data.GetMaxU64(&offset, byte_size);
189f034231aSEd Maste success = true;
190f034231aSEd Maste }
191f034231aSEd Maste }
192f034231aSEd Maste
193f034231aSEd Maste if (success_ptr)
194f034231aSEd Maste *success_ptr = success;
195f034231aSEd Maste
196f034231aSEd Maste if (!success)
197f034231aSEd Maste uval64 = fail_value;
198f034231aSEd Maste return uval64;
199f034231aSEd Maste }
200f034231aSEd Maste
WriteMemoryUnsigned(const Context & context,lldb::addr_t addr,uint64_t uval,size_t uval_byte_size)20114f1b3e8SDimitry Andric bool EmulateInstruction::WriteMemoryUnsigned(const Context &context,
20214f1b3e8SDimitry Andric lldb::addr_t addr, uint64_t uval,
20314f1b3e8SDimitry Andric size_t uval_byte_size) {
204f034231aSEd Maste StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
205f034231aSEd Maste strm.PutMaxHex64(uval, uval_byte_size);
206f034231aSEd Maste
20714f1b3e8SDimitry Andric size_t bytes_written = m_write_mem_callback(
20814f1b3e8SDimitry Andric this, m_baton, context, addr, strm.GetString().data(), uval_byte_size);
209f3fbd1c0SDimitry Andric return (bytes_written == uval_byte_size);
210f034231aSEd Maste }
211f034231aSEd Maste
WriteMemory(const Context & context,lldb::addr_t addr,const void * src,size_t src_len)21214f1b3e8SDimitry Andric bool EmulateInstruction::WriteMemory(const Context &context, lldb::addr_t addr,
21314f1b3e8SDimitry Andric const void *src, size_t src_len) {
214f3fbd1c0SDimitry Andric if (m_write_mem_callback != nullptr)
21514f1b3e8SDimitry Andric return m_write_mem_callback(this, m_baton, context, addr, src, src_len) ==
21614f1b3e8SDimitry Andric src_len;
217f034231aSEd Maste return false;
218f034231aSEd Maste }
219f034231aSEd Maste
SetBaton(void * baton)22014f1b3e8SDimitry Andric void EmulateInstruction::SetBaton(void *baton) { m_baton = baton; }
221f034231aSEd Maste
SetCallbacks(ReadMemoryCallback read_mem_callback,WriteMemoryCallback write_mem_callback,ReadRegisterCallback read_reg_callback,WriteRegisterCallback write_reg_callback)22214f1b3e8SDimitry Andric void EmulateInstruction::SetCallbacks(
22314f1b3e8SDimitry Andric ReadMemoryCallback read_mem_callback,
224f034231aSEd Maste WriteMemoryCallback write_mem_callback,
225f034231aSEd Maste ReadRegisterCallback read_reg_callback,
22614f1b3e8SDimitry Andric WriteRegisterCallback write_reg_callback) {
227f034231aSEd Maste m_read_mem_callback = read_mem_callback;
228f034231aSEd Maste m_write_mem_callback = write_mem_callback;
229f034231aSEd Maste m_read_reg_callback = read_reg_callback;
230f034231aSEd Maste m_write_reg_callback = write_reg_callback;
231f034231aSEd Maste }
232f034231aSEd Maste
SetReadMemCallback(ReadMemoryCallback read_mem_callback)23314f1b3e8SDimitry Andric void EmulateInstruction::SetReadMemCallback(
23414f1b3e8SDimitry Andric ReadMemoryCallback read_mem_callback) {
235f034231aSEd Maste m_read_mem_callback = read_mem_callback;
236f034231aSEd Maste }
237f034231aSEd Maste
SetWriteMemCallback(WriteMemoryCallback write_mem_callback)23814f1b3e8SDimitry Andric void EmulateInstruction::SetWriteMemCallback(
23914f1b3e8SDimitry Andric WriteMemoryCallback write_mem_callback) {
240f034231aSEd Maste m_write_mem_callback = write_mem_callback;
241f034231aSEd Maste }
242f034231aSEd Maste
SetReadRegCallback(ReadRegisterCallback read_reg_callback)24314f1b3e8SDimitry Andric void EmulateInstruction::SetReadRegCallback(
24414f1b3e8SDimitry Andric ReadRegisterCallback read_reg_callback) {
245f034231aSEd Maste m_read_reg_callback = read_reg_callback;
246f034231aSEd Maste }
247f034231aSEd Maste
SetWriteRegCallback(WriteRegisterCallback write_reg_callback)24814f1b3e8SDimitry Andric void EmulateInstruction::SetWriteRegCallback(
24914f1b3e8SDimitry Andric WriteRegisterCallback write_reg_callback) {
250f034231aSEd Maste m_write_reg_callback = write_reg_callback;
251f034231aSEd Maste }
252f034231aSEd Maste
253f034231aSEd Maste //
254f034231aSEd Maste // Read & Write Memory and Registers callback functions.
255f034231aSEd Maste //
256f034231aSEd Maste
ReadMemoryFrame(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,void * dst,size_t dst_len)25714f1b3e8SDimitry Andric size_t EmulateInstruction::ReadMemoryFrame(EmulateInstruction *instruction,
25814f1b3e8SDimitry Andric void *baton, const Context &context,
25914f1b3e8SDimitry Andric lldb::addr_t addr, void *dst,
26014f1b3e8SDimitry Andric size_t dst_len) {
261f3fbd1c0SDimitry Andric if (baton == nullptr || dst == nullptr || dst_len == 0)
262f034231aSEd Maste return 0;
263f034231aSEd Maste
264f034231aSEd Maste StackFrame *frame = (StackFrame *)baton;
265f034231aSEd Maste
266f034231aSEd Maste ProcessSP process_sp(frame->CalculateProcess());
26714f1b3e8SDimitry Andric if (process_sp) {
268b76161e4SDimitry Andric Status error;
269f034231aSEd Maste return process_sp->ReadMemory(addr, dst, dst_len, error);
270f034231aSEd Maste }
271f034231aSEd Maste return 0;
272f034231aSEd Maste }
273f034231aSEd Maste
WriteMemoryFrame(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,const void * src,size_t src_len)27414f1b3e8SDimitry Andric size_t EmulateInstruction::WriteMemoryFrame(EmulateInstruction *instruction,
27514f1b3e8SDimitry Andric void *baton, const Context &context,
27614f1b3e8SDimitry Andric lldb::addr_t addr, const void *src,
27714f1b3e8SDimitry Andric size_t src_len) {
278f3fbd1c0SDimitry Andric if (baton == nullptr || src == nullptr || src_len == 0)
279f034231aSEd Maste return 0;
280f034231aSEd Maste
281f034231aSEd Maste StackFrame *frame = (StackFrame *)baton;
282f034231aSEd Maste
283f034231aSEd Maste ProcessSP process_sp(frame->CalculateProcess());
28414f1b3e8SDimitry Andric if (process_sp) {
285b76161e4SDimitry Andric Status error;
286f034231aSEd Maste return process_sp->WriteMemory(addr, src, src_len, error);
287f034231aSEd Maste }
288f034231aSEd Maste
289f034231aSEd Maste return 0;
290f034231aSEd Maste }
291f034231aSEd Maste
ReadRegisterFrame(EmulateInstruction * instruction,void * baton,const RegisterInfo * reg_info,RegisterValue & reg_value)29214f1b3e8SDimitry Andric bool EmulateInstruction::ReadRegisterFrame(EmulateInstruction *instruction,
293f034231aSEd Maste void *baton,
294f034231aSEd Maste const RegisterInfo *reg_info,
29514f1b3e8SDimitry Andric RegisterValue ®_value) {
296f3fbd1c0SDimitry Andric if (baton == nullptr)
297f034231aSEd Maste return false;
298f034231aSEd Maste
299f034231aSEd Maste StackFrame *frame = (StackFrame *)baton;
300f034231aSEd Maste return frame->GetRegisterContext()->ReadRegister(reg_info, reg_value);
301f034231aSEd Maste }
302f034231aSEd Maste
WriteRegisterFrame(EmulateInstruction * instruction,void * baton,const Context & context,const RegisterInfo * reg_info,const RegisterValue & reg_value)30314f1b3e8SDimitry Andric bool EmulateInstruction::WriteRegisterFrame(EmulateInstruction *instruction,
30414f1b3e8SDimitry Andric void *baton, const Context &context,
305f034231aSEd Maste const RegisterInfo *reg_info,
30614f1b3e8SDimitry Andric const RegisterValue ®_value) {
307f3fbd1c0SDimitry Andric if (baton == nullptr)
308f034231aSEd Maste return false;
309f034231aSEd Maste
310f034231aSEd Maste StackFrame *frame = (StackFrame *)baton;
311f034231aSEd Maste return frame->GetRegisterContext()->WriteRegister(reg_info, reg_value);
312f034231aSEd Maste }
313f034231aSEd Maste
ReadMemoryDefault(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,void * dst,size_t length)31414f1b3e8SDimitry Andric size_t EmulateInstruction::ReadMemoryDefault(EmulateInstruction *instruction,
315f034231aSEd Maste void *baton,
316f034231aSEd Maste const Context &context,
31714f1b3e8SDimitry Andric lldb::addr_t addr, void *dst,
31814f1b3e8SDimitry Andric size_t length) {
319f034231aSEd Maste StreamFile strm(stdout, false);
32014f1b3e8SDimitry Andric strm.Printf(" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64
32114f1b3e8SDimitry Andric ", context = ",
32214f1b3e8SDimitry Andric addr, (uint64_t)length);
323f034231aSEd Maste context.Dump(strm, instruction);
324f034231aSEd Maste strm.EOL();
325f034231aSEd Maste *((uint64_t *)dst) = 0xdeadbeef;
326f034231aSEd Maste return length;
327f034231aSEd Maste }
328f034231aSEd Maste
WriteMemoryDefault(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,const void * dst,size_t length)32914f1b3e8SDimitry Andric size_t EmulateInstruction::WriteMemoryDefault(EmulateInstruction *instruction,
330f034231aSEd Maste void *baton,
331f034231aSEd Maste const Context &context,
332f034231aSEd Maste lldb::addr_t addr,
33314f1b3e8SDimitry Andric const void *dst, size_t length) {
334f034231aSEd Maste StreamFile strm(stdout, false);
33514f1b3e8SDimitry Andric strm.Printf(" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64
33614f1b3e8SDimitry Andric ", context = ",
33714f1b3e8SDimitry Andric addr, (uint64_t)length);
338f034231aSEd Maste context.Dump(strm, instruction);
339f034231aSEd Maste strm.EOL();
340f034231aSEd Maste return length;
341f034231aSEd Maste }
342f034231aSEd Maste
ReadRegisterDefault(EmulateInstruction * instruction,void * baton,const RegisterInfo * reg_info,RegisterValue & reg_value)34314f1b3e8SDimitry Andric bool EmulateInstruction::ReadRegisterDefault(EmulateInstruction *instruction,
344f034231aSEd Maste void *baton,
345f034231aSEd Maste const RegisterInfo *reg_info,
34614f1b3e8SDimitry Andric RegisterValue ®_value) {
347f034231aSEd Maste StreamFile strm(stdout, false);
348f034231aSEd Maste strm.Printf(" Read Register (%s)\n", reg_info->name);
3490cac4ca3SEd Maste lldb::RegisterKind reg_kind;
3500cac4ca3SEd Maste uint32_t reg_num;
351f034231aSEd Maste if (GetBestRegisterKindAndNumber(reg_info, reg_kind, reg_num))
352f034231aSEd Maste reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
353f034231aSEd Maste else
354f034231aSEd Maste reg_value.SetUInt64(0);
355f034231aSEd Maste
356f034231aSEd Maste return true;
357f034231aSEd Maste }
358f034231aSEd Maste
WriteRegisterDefault(EmulateInstruction * instruction,void * baton,const Context & context,const RegisterInfo * reg_info,const RegisterValue & reg_value)35914f1b3e8SDimitry Andric bool EmulateInstruction::WriteRegisterDefault(EmulateInstruction *instruction,
360f034231aSEd Maste void *baton,
361f034231aSEd Maste const Context &context,
362f034231aSEd Maste const RegisterInfo *reg_info,
36314f1b3e8SDimitry Andric const RegisterValue ®_value) {
364f034231aSEd Maste StreamFile strm(stdout, false);
365f034231aSEd Maste strm.Printf(" Write to Register (name = %s, value = ", reg_info->name);
3667fa27ce4SDimitry Andric DumpRegisterValue(reg_value, strm, *reg_info, false, false, eFormatDefault);
367f034231aSEd Maste strm.PutCString(", context = ");
368f034231aSEd Maste context.Dump(strm, instruction);
369f034231aSEd Maste strm.EOL();
370f034231aSEd Maste return true;
371f034231aSEd Maste }
372f034231aSEd Maste
Dump(Stream & strm,EmulateInstruction * instruction) const37314f1b3e8SDimitry Andric void EmulateInstruction::Context::Dump(Stream &strm,
37414f1b3e8SDimitry Andric EmulateInstruction *instruction) const {
37514f1b3e8SDimitry Andric switch (type) {
376f034231aSEd Maste case eContextReadOpcode:
377f034231aSEd Maste strm.PutCString("reading opcode");
378f034231aSEd Maste break;
379f034231aSEd Maste
380f034231aSEd Maste case eContextImmediate:
381f034231aSEd Maste strm.PutCString("immediate");
382f034231aSEd Maste break;
383f034231aSEd Maste
384f034231aSEd Maste case eContextPushRegisterOnStack:
385f034231aSEd Maste strm.PutCString("push register");
386f034231aSEd Maste break;
387f034231aSEd Maste
388f034231aSEd Maste case eContextPopRegisterOffStack:
389f034231aSEd Maste strm.PutCString("pop register");
390f034231aSEd Maste break;
391f034231aSEd Maste
392f034231aSEd Maste case eContextAdjustStackPointer:
393f034231aSEd Maste strm.PutCString("adjust sp");
394f034231aSEd Maste break;
395f034231aSEd Maste
396f034231aSEd Maste case eContextSetFramePointer:
397f034231aSEd Maste strm.PutCString("set frame pointer");
398f034231aSEd Maste break;
399f034231aSEd Maste
400f034231aSEd Maste case eContextAdjustBaseRegister:
401f034231aSEd Maste strm.PutCString("adjusting (writing value back to) a base register");
402f034231aSEd Maste break;
403f034231aSEd Maste
404f034231aSEd Maste case eContextRegisterPlusOffset:
405f034231aSEd Maste strm.PutCString("register + offset");
406f034231aSEd Maste break;
407f034231aSEd Maste
408f034231aSEd Maste case eContextRegisterStore:
409f034231aSEd Maste strm.PutCString("store register");
410f034231aSEd Maste break;
411f034231aSEd Maste
412f034231aSEd Maste case eContextRegisterLoad:
413f034231aSEd Maste strm.PutCString("load register");
414f034231aSEd Maste break;
415f034231aSEd Maste
416f034231aSEd Maste case eContextRelativeBranchImmediate:
417f034231aSEd Maste strm.PutCString("relative branch immediate");
418f034231aSEd Maste break;
419f034231aSEd Maste
420f034231aSEd Maste case eContextAbsoluteBranchRegister:
421f034231aSEd Maste strm.PutCString("absolute branch register");
422f034231aSEd Maste break;
423f034231aSEd Maste
424f034231aSEd Maste case eContextSupervisorCall:
425f034231aSEd Maste strm.PutCString("supervisor call");
426f034231aSEd Maste break;
427f034231aSEd Maste
428f034231aSEd Maste case eContextTableBranchReadMemory:
429f034231aSEd Maste strm.PutCString("table branch read memory");
430f034231aSEd Maste break;
431f034231aSEd Maste
432f034231aSEd Maste case eContextWriteRegisterRandomBits:
433f034231aSEd Maste strm.PutCString("write random bits to a register");
434f034231aSEd Maste break;
435f034231aSEd Maste
436f034231aSEd Maste case eContextWriteMemoryRandomBits:
437f034231aSEd Maste strm.PutCString("write random bits to a memory address");
438f034231aSEd Maste break;
439f034231aSEd Maste
440f034231aSEd Maste case eContextArithmetic:
441f034231aSEd Maste strm.PutCString("arithmetic");
442f034231aSEd Maste break;
443f034231aSEd Maste
444f034231aSEd Maste case eContextReturnFromException:
445f034231aSEd Maste strm.PutCString("return from exception");
446f034231aSEd Maste break;
447f034231aSEd Maste
448f034231aSEd Maste default:
449f034231aSEd Maste strm.PutCString("unrecognized context.");
450f034231aSEd Maste break;
451f034231aSEd Maste }
452f034231aSEd Maste
453e3b55780SDimitry Andric switch (GetInfoType()) {
454f034231aSEd Maste case eInfoTypeRegisterPlusOffset:
455f034231aSEd Maste strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
456f034231aSEd Maste info.RegisterPlusOffset.reg.name,
457f034231aSEd Maste info.RegisterPlusOffset.signed_offset);
458f034231aSEd Maste break;
459f034231aSEd Maste
460f034231aSEd Maste case eInfoTypeRegisterPlusIndirectOffset:
461f034231aSEd Maste strm.Printf(" (reg_plus_reg = %s + %s)",
462f034231aSEd Maste info.RegisterPlusIndirectOffset.base_reg.name,
463f034231aSEd Maste info.RegisterPlusIndirectOffset.offset_reg.name);
464f034231aSEd Maste break;
465f034231aSEd Maste
466f034231aSEd Maste case eInfoTypeRegisterToRegisterPlusOffset:
467f034231aSEd Maste strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
468f034231aSEd Maste info.RegisterToRegisterPlusOffset.base_reg.name,
469f034231aSEd Maste info.RegisterToRegisterPlusOffset.offset,
470f034231aSEd Maste info.RegisterToRegisterPlusOffset.data_reg.name);
471f034231aSEd Maste break;
472f034231aSEd Maste
473f034231aSEd Maste case eInfoTypeRegisterToRegisterPlusIndirectOffset:
474f034231aSEd Maste strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
475f034231aSEd Maste info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
476f034231aSEd Maste info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
477f034231aSEd Maste info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
478f034231aSEd Maste break;
479f034231aSEd Maste
480f034231aSEd Maste case eInfoTypeRegisterRegisterOperands:
481f034231aSEd Maste strm.Printf(" (register to register binary op: %s and %s)",
482f034231aSEd Maste info.RegisterRegisterOperands.operand1.name,
483f034231aSEd Maste info.RegisterRegisterOperands.operand2.name);
484f034231aSEd Maste break;
485f034231aSEd Maste
486f034231aSEd Maste case eInfoTypeOffset:
487f034231aSEd Maste strm.Printf(" (signed_offset = %+" PRId64 ")", info.signed_offset);
488f034231aSEd Maste break;
489f034231aSEd Maste
490f034231aSEd Maste case eInfoTypeRegister:
491f034231aSEd Maste strm.Printf(" (reg = %s)", info.reg.name);
492f034231aSEd Maste break;
493f034231aSEd Maste
494f034231aSEd Maste case eInfoTypeImmediate:
495f034231aSEd Maste strm.Printf(" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
49614f1b3e8SDimitry Andric info.unsigned_immediate, info.unsigned_immediate);
497f034231aSEd Maste break;
498f034231aSEd Maste
499f034231aSEd Maste case eInfoTypeImmediateSigned:
500f034231aSEd Maste strm.Printf(" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
50114f1b3e8SDimitry Andric info.signed_immediate, info.signed_immediate);
502f034231aSEd Maste break;
503f034231aSEd Maste
504f034231aSEd Maste case eInfoTypeAddress:
505f034231aSEd Maste strm.Printf(" (address = 0x%" PRIx64 ")", info.address);
506f034231aSEd Maste break;
507f034231aSEd Maste
508f034231aSEd Maste case eInfoTypeISAAndImmediate:
509f034231aSEd Maste strm.Printf(" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
51014f1b3e8SDimitry Andric info.ISAAndImmediate.isa, info.ISAAndImmediate.unsigned_data32,
511f034231aSEd Maste info.ISAAndImmediate.unsigned_data32);
512f034231aSEd Maste break;
513f034231aSEd Maste
514f034231aSEd Maste case eInfoTypeISAAndImmediateSigned:
515f034231aSEd Maste strm.Printf(" (isa = %u, signed_immediate = %i (0x%8.8x))",
516f034231aSEd Maste info.ISAAndImmediateSigned.isa,
517f034231aSEd Maste info.ISAAndImmediateSigned.signed_data32,
518f034231aSEd Maste info.ISAAndImmediateSigned.signed_data32);
519f034231aSEd Maste break;
520f034231aSEd Maste
521f034231aSEd Maste case eInfoTypeISA:
522f034231aSEd Maste strm.Printf(" (isa = %u)", info.isa);
523f034231aSEd Maste break;
524f034231aSEd Maste
525f034231aSEd Maste case eInfoTypeNoArgs:
526f034231aSEd Maste break;
527f034231aSEd Maste }
528f034231aSEd Maste }
529f034231aSEd Maste
SetInstruction(const Opcode & opcode,const Address & inst_addr,Target * target)53014f1b3e8SDimitry Andric bool EmulateInstruction::SetInstruction(const Opcode &opcode,
53114f1b3e8SDimitry Andric const Address &inst_addr,
53214f1b3e8SDimitry Andric Target *target) {
533f034231aSEd Maste m_opcode = opcode;
534f034231aSEd Maste m_addr = LLDB_INVALID_ADDRESS;
53514f1b3e8SDimitry Andric if (inst_addr.IsValid()) {
536f3fbd1c0SDimitry Andric if (target != nullptr)
537f034231aSEd Maste m_addr = inst_addr.GetLoadAddress(target);
538f034231aSEd Maste if (m_addr == LLDB_INVALID_ADDRESS)
539f034231aSEd Maste m_addr = inst_addr.GetFileAddress();
540f034231aSEd Maste }
541f034231aSEd Maste return true;
542f034231aSEd Maste }
543f034231aSEd Maste
GetBestRegisterKindAndNumber(const RegisterInfo * reg_info,lldb::RegisterKind & reg_kind,uint32_t & reg_num)54414f1b3e8SDimitry Andric bool EmulateInstruction::GetBestRegisterKindAndNumber(
54514f1b3e8SDimitry Andric const RegisterInfo *reg_info, lldb::RegisterKind ®_kind,
54614f1b3e8SDimitry Andric uint32_t ®_num) {
547f034231aSEd Maste // Generic and DWARF should be the two most popular register kinds when
548f034231aSEd Maste // emulating instructions since they are the most platform agnostic...
549f034231aSEd Maste reg_num = reg_info->kinds[eRegisterKindGeneric];
55014f1b3e8SDimitry Andric if (reg_num != LLDB_INVALID_REGNUM) {
551f034231aSEd Maste reg_kind = eRegisterKindGeneric;
552f034231aSEd Maste return true;
553f034231aSEd Maste }
554f034231aSEd Maste
555f034231aSEd Maste reg_num = reg_info->kinds[eRegisterKindDWARF];
55614f1b3e8SDimitry Andric if (reg_num != LLDB_INVALID_REGNUM) {
557f034231aSEd Maste reg_kind = eRegisterKindDWARF;
558f034231aSEd Maste return true;
559f034231aSEd Maste }
560f034231aSEd Maste
561f034231aSEd Maste reg_num = reg_info->kinds[eRegisterKindLLDB];
56214f1b3e8SDimitry Andric if (reg_num != LLDB_INVALID_REGNUM) {
563f034231aSEd Maste reg_kind = eRegisterKindLLDB;
564f034231aSEd Maste return true;
565f034231aSEd Maste }
566f034231aSEd Maste
567e81d9d49SDimitry Andric reg_num = reg_info->kinds[eRegisterKindEHFrame];
56814f1b3e8SDimitry Andric if (reg_num != LLDB_INVALID_REGNUM) {
569e81d9d49SDimitry Andric reg_kind = eRegisterKindEHFrame;
570f034231aSEd Maste return true;
571f034231aSEd Maste }
572f034231aSEd Maste
573e81d9d49SDimitry Andric reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
57414f1b3e8SDimitry Andric if (reg_num != LLDB_INVALID_REGNUM) {
575e81d9d49SDimitry Andric reg_kind = eRegisterKindProcessPlugin;
576f034231aSEd Maste return true;
577f034231aSEd Maste }
578f034231aSEd Maste return false;
579f034231aSEd Maste }
580f034231aSEd Maste
581f034231aSEd Maste uint32_t
GetInternalRegisterNumber(RegisterContext * reg_ctx,const RegisterInfo & reg_info)58214f1b3e8SDimitry Andric EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx,
58314f1b3e8SDimitry Andric const RegisterInfo ®_info) {
5840cac4ca3SEd Maste lldb::RegisterKind reg_kind;
5850cac4ca3SEd Maste uint32_t reg_num;
586f034231aSEd Maste if (reg_ctx && GetBestRegisterKindAndNumber(®_info, reg_kind, reg_num))
587f034231aSEd Maste return reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
588f034231aSEd Maste return LLDB_INVALID_REGNUM;
589f034231aSEd Maste }
590f034231aSEd Maste
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)59114f1b3e8SDimitry Andric bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
592f034231aSEd Maste unwind_plan.Clear();
593f034231aSEd Maste return false;
594f034231aSEd Maste }
595