180814287SRaphael Isemann //===-- EmulateInstruction.cpp --------------------------------------------===//
2c1dfd93eSGreg Clayton //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c1dfd93eSGreg Clayton //
7c1dfd93eSGreg Clayton //===----------------------------------------------------------------------===//
8c1dfd93eSGreg Clayton
995e31426SGreg Clayton #include "lldb/Core/EmulateInstruction.h"
10c1dfd93eSGreg Clayton
112ed751bdSGreg Clayton #include "lldb/Core/Address.h"
12e03334cfSPavel Labath #include "lldb/Core/DumpRegisterValue.h"
134272cc7dSGreg Clayton #include "lldb/Core/PluginManager.h"
147349bd90SGreg Clayton #include "lldb/Core/StreamFile.h"
1579ea878bSGreg Clayton #include "lldb/Symbol/UnwindPlan.h"
16ad379efcSCaroline Tice #include "lldb/Target/Process.h"
17ad379efcSCaroline Tice #include "lldb/Target/RegisterContext.h"
18672d2c12SJonas Devlieghere #include "lldb/Target/StackFrame.h"
19672d2c12SJonas Devlieghere #include "lldb/Utility/ConstString.h"
20666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
21d821c997SPavel Labath #include "lldb/Utility/RegisterValue.h"
2297206d57SZachary Turner #include "lldb/Utility/Status.h"
23672d2c12SJonas Devlieghere #include "lldb/Utility/Stream.h"
24bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
25672d2c12SJonas Devlieghere #include "lldb/lldb-forward.h"
26672d2c12SJonas Devlieghere #include "lldb/lldb-private-interfaces.h"
272f3df613SZachary Turner
28672d2c12SJonas Devlieghere #include "llvm/ADT/StringRef.h"
292f3df613SZachary Turner
302f3df613SZachary Turner #include <cstring>
31672d2c12SJonas Devlieghere #include <memory>
322f3df613SZachary Turner
3376e47d48SRaphael Isemann #include <cinttypes>
3476e47d48SRaphael Isemann #include <cstdio>
352f3df613SZachary Turner
362f3df613SZachary Turner namespace lldb_private {
372f3df613SZachary Turner class Target;
382f3df613SZachary Turner }
39ad379efcSCaroline Tice
40c1dfd93eSGreg Clayton using namespace lldb;
41c1dfd93eSGreg Clayton using namespace lldb_private;
42c1dfd93eSGreg Clayton
434272cc7dSGreg Clayton EmulateInstruction *
FindPlugin(const ArchSpec & arch,InstructionType supported_inst_type,const char * plugin_name)44b9c1b51eSKate Stone EmulateInstruction::FindPlugin(const ArchSpec &arch,
45b9c1b51eSKate Stone InstructionType supported_inst_type,
46b9c1b51eSKate Stone const char *plugin_name) {
4734ede34aSEugene Zelenko EmulateInstructionCreateInstance create_callback = nullptr;
48b9c1b51eSKate Stone if (plugin_name) {
49b9c1b51eSKate Stone create_callback =
50b9c1b51eSKate Stone PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
51*6fa1b4ffSPavel Labath plugin_name);
52b9c1b51eSKate Stone if (create_callback) {
53b9c1b51eSKate Stone EmulateInstruction *emulate_insn_ptr =
54b9c1b51eSKate Stone create_callback(arch, supported_inst_type);
55ad379efcSCaroline Tice if (emulate_insn_ptr)
56ad379efcSCaroline Tice return emulate_insn_ptr;
574272cc7dSGreg Clayton }
58b9c1b51eSKate Stone } else {
59b9c1b51eSKate Stone for (uint32_t idx = 0;
60b9c1b51eSKate Stone (create_callback =
61b9c1b51eSKate Stone PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) !=
62b9c1b51eSKate Stone nullptr;
63b9c1b51eSKate Stone ++idx) {
64b9c1b51eSKate Stone EmulateInstruction *emulate_insn_ptr =
65b9c1b51eSKate Stone create_callback(arch, supported_inst_type);
66ad379efcSCaroline Tice if (emulate_insn_ptr)
67ad379efcSCaroline Tice return emulate_insn_ptr;
684272cc7dSGreg Clayton }
694272cc7dSGreg Clayton }
7034ede34aSEugene Zelenko return nullptr;
714272cc7dSGreg Clayton }
72c1dfd93eSGreg Clayton
EmulateInstruction(const ArchSpec & arch)7306453b06SPavel Labath EmulateInstruction::EmulateInstruction(const ArchSpec &arch) : m_arch(arch) {}
74ad379efcSCaroline Tice
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)75b9c1b51eSKate Stone bool EmulateInstruction::ReadRegister(const RegisterInfo *reg_info,
76b9c1b51eSKate Stone RegisterValue ®_value) {
7734ede34aSEugene Zelenko if (m_read_reg_callback != nullptr)
787349bd90SGreg Clayton return m_read_reg_callback(this, m_baton, reg_info, reg_value);
797349bd90SGreg Clayton return false;
807349bd90SGreg Clayton }
817349bd90SGreg Clayton
ReadRegister(lldb::RegisterKind reg_kind,uint32_t reg_num,RegisterValue & reg_value)82b9c1b51eSKate Stone bool EmulateInstruction::ReadRegister(lldb::RegisterKind reg_kind,
83b9c1b51eSKate Stone uint32_t reg_num,
84b9c1b51eSKate Stone RegisterValue ®_value) {
8579ea878bSGreg Clayton RegisterInfo reg_info;
8679ea878bSGreg Clayton if (GetRegisterInfo(reg_kind, reg_num, reg_info))
877349bd90SGreg Clayton return ReadRegister(®_info, reg_value);
887349bd90SGreg Clayton return false;
897349bd90SGreg Clayton }
907349bd90SGreg Clayton
ReadRegisterUnsigned(lldb::RegisterKind reg_kind,uint32_t reg_num,uint64_t fail_value,bool * success_ptr)91b9c1b51eSKate Stone uint64_t EmulateInstruction::ReadRegisterUnsigned(lldb::RegisterKind reg_kind,
927349bd90SGreg Clayton uint32_t reg_num,
937349bd90SGreg Clayton uint64_t fail_value,
94b9c1b51eSKate Stone bool *success_ptr) {
957349bd90SGreg Clayton RegisterValue reg_value;
967349bd90SGreg Clayton if (ReadRegister(reg_kind, reg_num, reg_value))
977349bd90SGreg Clayton return reg_value.GetAsUInt64(fail_value, success_ptr);
9879ea878bSGreg Clayton if (success_ptr)
9979ea878bSGreg Clayton *success_ptr = false;
10079ea878bSGreg Clayton return fail_value;
10179ea878bSGreg Clayton }
10279ea878bSGreg Clayton
ReadRegisterUnsigned(const RegisterInfo * reg_info,uint64_t fail_value,bool * success_ptr)103b9c1b51eSKate Stone uint64_t EmulateInstruction::ReadRegisterUnsigned(const RegisterInfo *reg_info,
1047349bd90SGreg Clayton uint64_t fail_value,
105b9c1b51eSKate Stone bool *success_ptr) {
1067349bd90SGreg Clayton RegisterValue reg_value;
1077349bd90SGreg Clayton if (ReadRegister(reg_info, reg_value))
1087349bd90SGreg Clayton return reg_value.GetAsUInt64(fail_value, success_ptr);
109c1dfd93eSGreg Clayton if (success_ptr)
1107349bd90SGreg Clayton *success_ptr = false;
1117349bd90SGreg Clayton return fail_value;
112c1dfd93eSGreg Clayton }
113c1dfd93eSGreg Clayton
WriteRegister(const Context & context,const RegisterInfo * reg_info,const RegisterValue & reg_value)114b9c1b51eSKate Stone bool EmulateInstruction::WriteRegister(const Context &context,
1157349bd90SGreg Clayton const RegisterInfo *reg_info,
116b9c1b51eSKate Stone const RegisterValue ®_value) {
11734ede34aSEugene Zelenko if (m_write_reg_callback != nullptr)
1187349bd90SGreg Clayton return m_write_reg_callback(this, m_baton, context, reg_info, reg_value);
11979ea878bSGreg Clayton return false;
12079ea878bSGreg Clayton }
12179ea878bSGreg Clayton
WriteRegister(const Context & context,lldb::RegisterKind reg_kind,uint32_t reg_num,const RegisterValue & reg_value)122b9c1b51eSKate Stone bool EmulateInstruction::WriteRegister(const Context &context,
123e7c7c3deSJean-Daniel Dupas lldb::RegisterKind reg_kind,
1247349bd90SGreg Clayton uint32_t reg_num,
125b9c1b51eSKate Stone const RegisterValue ®_value) {
1267349bd90SGreg Clayton RegisterInfo reg_info;
1277349bd90SGreg Clayton if (GetRegisterInfo(reg_kind, reg_num, reg_info))
1287349bd90SGreg Clayton return WriteRegister(context, ®_info, reg_value);
1297349bd90SGreg Clayton return false;
1307349bd90SGreg Clayton }
1317349bd90SGreg Clayton
WriteRegisterUnsigned(const Context & context,lldb::RegisterKind reg_kind,uint32_t reg_num,uint64_t uint_value)132b9c1b51eSKate Stone bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
133e7c7c3deSJean-Daniel Dupas lldb::RegisterKind reg_kind,
1347349bd90SGreg Clayton uint32_t reg_num,
135b9c1b51eSKate Stone uint64_t uint_value) {
1367349bd90SGreg Clayton RegisterInfo reg_info;
137b9c1b51eSKate Stone if (GetRegisterInfo(reg_kind, reg_num, reg_info)) {
1387349bd90SGreg Clayton RegisterValue reg_value;
1397349bd90SGreg Clayton if (reg_value.SetUInt(uint_value, reg_info.byte_size))
1407349bd90SGreg Clayton return WriteRegister(context, ®_info, reg_value);
1417349bd90SGreg Clayton }
1427349bd90SGreg Clayton return false;
1437349bd90SGreg Clayton }
1447349bd90SGreg Clayton
WriteRegisterUnsigned(const Context & context,const RegisterInfo * reg_info,uint64_t uint_value)145b9c1b51eSKate Stone bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
1467349bd90SGreg Clayton const RegisterInfo *reg_info,
147b9c1b51eSKate Stone uint64_t uint_value) {
148b9c1b51eSKate Stone if (reg_info != nullptr) {
1497349bd90SGreg Clayton RegisterValue reg_value;
1507349bd90SGreg Clayton if (reg_value.SetUInt(uint_value, reg_info->byte_size))
1517349bd90SGreg Clayton return WriteRegister(context, reg_info, reg_value);
1527349bd90SGreg Clayton }
1537349bd90SGreg Clayton return false;
1547349bd90SGreg Clayton }
1557349bd90SGreg Clayton
ReadMemory(const Context & context,lldb::addr_t addr,void * dst,size_t dst_len)156b9c1b51eSKate Stone size_t EmulateInstruction::ReadMemory(const Context &context, lldb::addr_t addr,
157b9c1b51eSKate Stone void *dst, size_t dst_len) {
15834ede34aSEugene Zelenko if (m_read_mem_callback != nullptr)
159b9c1b51eSKate Stone return m_read_mem_callback(this, m_baton, context, addr, dst, dst_len) ==
160b9c1b51eSKate Stone dst_len;
1617349bd90SGreg Clayton return false;
162c1dfd93eSGreg Clayton }
163c1dfd93eSGreg Clayton
ReadMemoryUnsigned(const Context & context,lldb::addr_t addr,size_t byte_size,uint64_t fail_value,bool * success_ptr)164b9c1b51eSKate Stone uint64_t EmulateInstruction::ReadMemoryUnsigned(const Context &context,
165b9c1b51eSKate Stone lldb::addr_t addr,
166b9c1b51eSKate Stone size_t byte_size,
167b9c1b51eSKate Stone uint64_t fail_value,
168b9c1b51eSKate Stone bool *success_ptr) {
169c1dfd93eSGreg Clayton uint64_t uval64 = 0;
170c1dfd93eSGreg Clayton bool success = false;
171b9c1b51eSKate Stone if (byte_size <= 8) {
172c1dfd93eSGreg Clayton uint8_t buf[sizeof(uint64_t)];
173b9c1b51eSKate Stone size_t bytes_read =
174b9c1b51eSKate Stone m_read_mem_callback(this, m_baton, context, addr, buf, byte_size);
175b9c1b51eSKate Stone if (bytes_read == byte_size) {
176c7bece56SGreg Clayton lldb::offset_t offset = 0;
1772ed751bdSGreg Clayton DataExtractor data(buf, byte_size, GetByteOrder(), GetAddressByteSize());
178c1dfd93eSGreg Clayton uval64 = data.GetMaxU64(&offset, byte_size);
179c1dfd93eSGreg Clayton success = true;
180c1dfd93eSGreg Clayton }
181c1dfd93eSGreg Clayton }
182c1dfd93eSGreg Clayton
183c1dfd93eSGreg Clayton if (success_ptr)
184c1dfd93eSGreg Clayton *success_ptr = success;
185c1dfd93eSGreg Clayton
186c1dfd93eSGreg Clayton if (!success)
187c1dfd93eSGreg Clayton uval64 = fail_value;
188c1dfd93eSGreg Clayton return uval64;
189c1dfd93eSGreg Clayton }
190c1dfd93eSGreg Clayton
WriteMemoryUnsigned(const Context & context,lldb::addr_t addr,uint64_t uval,size_t uval_byte_size)191b9c1b51eSKate Stone bool EmulateInstruction::WriteMemoryUnsigned(const Context &context,
192b9c1b51eSKate Stone lldb::addr_t addr, uint64_t uval,
193b9c1b51eSKate Stone size_t uval_byte_size) {
194c1dfd93eSGreg Clayton StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
195c1dfd93eSGreg Clayton strm.PutMaxHex64(uval, uval_byte_size);
196c1dfd93eSGreg Clayton
197c156427dSZachary Turner size_t bytes_written = m_write_mem_callback(
198c156427dSZachary Turner this, m_baton, context, addr, strm.GetString().data(), uval_byte_size);
19934ede34aSEugene Zelenko return (bytes_written == uval_byte_size);
200c1dfd93eSGreg Clayton }
201ad379efcSCaroline Tice
WriteMemory(const Context & context,lldb::addr_t addr,const void * src,size_t src_len)202b9c1b51eSKate Stone bool EmulateInstruction::WriteMemory(const Context &context, lldb::addr_t addr,
203b9c1b51eSKate Stone const void *src, size_t src_len) {
20434ede34aSEugene Zelenko if (m_write_mem_callback != nullptr)
205b9c1b51eSKate Stone return m_write_mem_callback(this, m_baton, context, addr, src, src_len) ==
206b9c1b51eSKate Stone src_len;
2077349bd90SGreg Clayton return false;
2087349bd90SGreg Clayton }
2097349bd90SGreg Clayton
SetBaton(void * baton)210b9c1b51eSKate Stone void EmulateInstruction::SetBaton(void *baton) { m_baton = baton; }
211ad379efcSCaroline Tice
SetCallbacks(ReadMemoryCallback read_mem_callback,WriteMemoryCallback write_mem_callback,ReadRegisterCallback read_reg_callback,WriteRegisterCallback write_reg_callback)212b9c1b51eSKate Stone void EmulateInstruction::SetCallbacks(
213b9c1b51eSKate Stone ReadMemoryCallback read_mem_callback,
2147349bd90SGreg Clayton WriteMemoryCallback write_mem_callback,
2157349bd90SGreg Clayton ReadRegisterCallback read_reg_callback,
216b9c1b51eSKate Stone WriteRegisterCallback write_reg_callback) {
217ad379efcSCaroline Tice m_read_mem_callback = read_mem_callback;
218ad379efcSCaroline Tice m_write_mem_callback = write_mem_callback;
219ad379efcSCaroline Tice m_read_reg_callback = read_reg_callback;
220ad379efcSCaroline Tice m_write_reg_callback = write_reg_callback;
221ad379efcSCaroline Tice }
222ad379efcSCaroline Tice
SetReadMemCallback(ReadMemoryCallback read_mem_callback)223b9c1b51eSKate Stone void EmulateInstruction::SetReadMemCallback(
224b9c1b51eSKate Stone ReadMemoryCallback read_mem_callback) {
225ad379efcSCaroline Tice m_read_mem_callback = read_mem_callback;
226ad379efcSCaroline Tice }
227ad379efcSCaroline Tice
SetWriteMemCallback(WriteMemoryCallback write_mem_callback)228b9c1b51eSKate Stone void EmulateInstruction::SetWriteMemCallback(
229b9c1b51eSKate Stone WriteMemoryCallback write_mem_callback) {
230ad379efcSCaroline Tice m_write_mem_callback = write_mem_callback;
231ad379efcSCaroline Tice }
232ad379efcSCaroline Tice
SetReadRegCallback(ReadRegisterCallback read_reg_callback)233b9c1b51eSKate Stone void EmulateInstruction::SetReadRegCallback(
234b9c1b51eSKate Stone ReadRegisterCallback read_reg_callback) {
235ad379efcSCaroline Tice m_read_reg_callback = read_reg_callback;
236ad379efcSCaroline Tice }
237ad379efcSCaroline Tice
SetWriteRegCallback(WriteRegisterCallback write_reg_callback)238b9c1b51eSKate Stone void EmulateInstruction::SetWriteRegCallback(
239b9c1b51eSKate Stone WriteRegisterCallback write_reg_callback) {
240ad379efcSCaroline Tice m_write_reg_callback = write_reg_callback;
241ad379efcSCaroline Tice }
242ad379efcSCaroline Tice
243ad379efcSCaroline Tice //
244ad379efcSCaroline Tice // Read & Write Memory and Registers callback functions.
245ad379efcSCaroline Tice //
246ad379efcSCaroline Tice
ReadMemoryFrame(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,void * dst,size_t dst_len)247b9c1b51eSKate Stone size_t EmulateInstruction::ReadMemoryFrame(EmulateInstruction *instruction,
248b9c1b51eSKate Stone void *baton, const Context &context,
249b9c1b51eSKate Stone lldb::addr_t addr, void *dst,
250b9c1b51eSKate Stone size_t dst_len) {
25134ede34aSEugene Zelenko if (baton == nullptr || dst == nullptr || dst_len == 0)
252ad379efcSCaroline Tice return 0;
253ad379efcSCaroline Tice
254b57e4a1bSJason Molenda StackFrame *frame = (StackFrame *)baton;
2553d50b2f7SCaroline Tice
256d9e416c0SGreg Clayton ProcessSP process_sp(frame->CalculateProcess());
257b9c1b51eSKate Stone if (process_sp) {
25897206d57SZachary Turner Status error;
259d9e416c0SGreg Clayton return process_sp->ReadMemory(addr, dst, dst_len, error);
260d9e416c0SGreg Clayton }
261d9e416c0SGreg Clayton return 0;
262ad379efcSCaroline Tice }
263ad379efcSCaroline Tice
WriteMemoryFrame(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,const void * src,size_t src_len)264b9c1b51eSKate Stone size_t EmulateInstruction::WriteMemoryFrame(EmulateInstruction *instruction,
265b9c1b51eSKate Stone void *baton, const Context &context,
266b9c1b51eSKate Stone lldb::addr_t addr, const void *src,
267b9c1b51eSKate Stone size_t src_len) {
26834ede34aSEugene Zelenko if (baton == nullptr || src == nullptr || src_len == 0)
269ad379efcSCaroline Tice return 0;
270ad379efcSCaroline Tice
271b57e4a1bSJason Molenda StackFrame *frame = (StackFrame *)baton;
2723d50b2f7SCaroline Tice
273d9e416c0SGreg Clayton ProcessSP process_sp(frame->CalculateProcess());
274b9c1b51eSKate Stone if (process_sp) {
27597206d57SZachary Turner Status error;
276d9e416c0SGreg Clayton return process_sp->WriteMemory(addr, src, src_len, error);
277ad379efcSCaroline Tice }
278ad379efcSCaroline Tice
279ad379efcSCaroline Tice return 0;
280ad379efcSCaroline Tice }
281ad379efcSCaroline Tice
ReadRegisterFrame(EmulateInstruction * instruction,void * baton,const RegisterInfo * reg_info,RegisterValue & reg_value)282b9c1b51eSKate Stone bool EmulateInstruction::ReadRegisterFrame(EmulateInstruction *instruction,
2832ed751bdSGreg Clayton void *baton,
2847349bd90SGreg Clayton const RegisterInfo *reg_info,
285b9c1b51eSKate Stone RegisterValue ®_value) {
28634ede34aSEugene Zelenko if (baton == nullptr)
287ad379efcSCaroline Tice return false;
288ad379efcSCaroline Tice
289b57e4a1bSJason Molenda StackFrame *frame = (StackFrame *)baton;
2907349bd90SGreg Clayton return frame->GetRegisterContext()->ReadRegister(reg_info, reg_value);
291ad379efcSCaroline Tice }
292ad379efcSCaroline Tice
WriteRegisterFrame(EmulateInstruction * instruction,void * baton,const Context & context,const RegisterInfo * reg_info,const RegisterValue & reg_value)293b9c1b51eSKate Stone bool EmulateInstruction::WriteRegisterFrame(EmulateInstruction *instruction,
294b9c1b51eSKate Stone void *baton, const Context &context,
2957349bd90SGreg Clayton const RegisterInfo *reg_info,
296b9c1b51eSKate Stone const RegisterValue ®_value) {
29734ede34aSEugene Zelenko if (baton == nullptr)
2983d50b2f7SCaroline Tice return false;
2993d50b2f7SCaroline Tice
300b57e4a1bSJason Molenda StackFrame *frame = (StackFrame *)baton;
3017349bd90SGreg Clayton return frame->GetRegisterContext()->WriteRegister(reg_info, reg_value);
302ad379efcSCaroline Tice }
303ad379efcSCaroline Tice
ReadMemoryDefault(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,void * dst,size_t length)304b9c1b51eSKate Stone size_t EmulateInstruction::ReadMemoryDefault(EmulateInstruction *instruction,
3052ed751bdSGreg Clayton void *baton,
306ad379efcSCaroline Tice const Context &context,
307b9c1b51eSKate Stone lldb::addr_t addr, void *dst,
308b9c1b51eSKate Stone size_t length) {
30931f1d2f5SGreg Clayton StreamFile strm(stdout, false);
310b9c1b51eSKate Stone strm.Printf(" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64
311b9c1b51eSKate Stone ", context = ",
312b9c1b51eSKate Stone addr, (uint64_t)length);
31331f1d2f5SGreg Clayton context.Dump(strm, instruction);
31431f1d2f5SGreg Clayton strm.EOL();
315ad379efcSCaroline Tice *((uint64_t *)dst) = 0xdeadbeef;
316ad379efcSCaroline Tice return length;
317ad379efcSCaroline Tice }
318ad379efcSCaroline Tice
WriteMemoryDefault(EmulateInstruction * instruction,void * baton,const Context & context,lldb::addr_t addr,const void * dst,size_t length)319b9c1b51eSKate Stone size_t EmulateInstruction::WriteMemoryDefault(EmulateInstruction *instruction,
3202ed751bdSGreg Clayton void *baton,
321ad379efcSCaroline Tice const Context &context,
322ad379efcSCaroline Tice lldb::addr_t addr,
323b9c1b51eSKate Stone const void *dst, size_t length) {
32431f1d2f5SGreg Clayton StreamFile strm(stdout, false);
325b9c1b51eSKate Stone strm.Printf(" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64
326b9c1b51eSKate Stone ", context = ",
327b9c1b51eSKate Stone addr, (uint64_t)length);
32831f1d2f5SGreg Clayton context.Dump(strm, instruction);
32931f1d2f5SGreg Clayton strm.EOL();
330ad379efcSCaroline Tice return length;
331ad379efcSCaroline Tice }
332ad379efcSCaroline Tice
ReadRegisterDefault(EmulateInstruction * instruction,void * baton,const RegisterInfo * reg_info,RegisterValue & reg_value)333b9c1b51eSKate Stone bool EmulateInstruction::ReadRegisterDefault(EmulateInstruction *instruction,
3342ed751bdSGreg Clayton void *baton,
3357349bd90SGreg Clayton const RegisterInfo *reg_info,
336b9c1b51eSKate Stone RegisterValue ®_value) {
33731f1d2f5SGreg Clayton StreamFile strm(stdout, false);
33831f1d2f5SGreg Clayton strm.Printf(" Read Register (%s)\n", reg_info->name);
339e7c7c3deSJean-Daniel Dupas lldb::RegisterKind reg_kind;
340e7c7c3deSJean-Daniel Dupas uint32_t reg_num;
34179ea878bSGreg Clayton if (GetBestRegisterKindAndNumber(reg_info, reg_kind, reg_num))
3427349bd90SGreg Clayton reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
34379ea878bSGreg Clayton else
3447349bd90SGreg Clayton reg_value.SetUInt64(0);
345ad379efcSCaroline Tice
346ad379efcSCaroline Tice return true;
347ad379efcSCaroline Tice }
348ad379efcSCaroline Tice
WriteRegisterDefault(EmulateInstruction * instruction,void * baton,const Context & context,const RegisterInfo * reg_info,const RegisterValue & reg_value)349b9c1b51eSKate Stone bool EmulateInstruction::WriteRegisterDefault(EmulateInstruction *instruction,
3502ed751bdSGreg Clayton void *baton,
351ad379efcSCaroline Tice const Context &context,
3527349bd90SGreg Clayton const RegisterInfo *reg_info,
353b9c1b51eSKate Stone const RegisterValue ®_value) {
3547349bd90SGreg Clayton StreamFile strm(stdout, false);
3557349bd90SGreg Clayton strm.Printf(" Write to Register (name = %s, value = ", reg_info->name);
356e03334cfSPavel Labath DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault);
3577349bd90SGreg Clayton strm.PutCString(", context = ");
35831f1d2f5SGreg Clayton context.Dump(strm, instruction);
35931f1d2f5SGreg Clayton strm.EOL();
360ad379efcSCaroline Tice return true;
361ad379efcSCaroline Tice }
362ad379efcSCaroline Tice
Dump(Stream & strm,EmulateInstruction * instruction) const363b9c1b51eSKate Stone void EmulateInstruction::Context::Dump(Stream &strm,
364b9c1b51eSKate Stone EmulateInstruction *instruction) const {
365b9c1b51eSKate Stone switch (type) {
366ad379efcSCaroline Tice case eContextReadOpcode:
36731f1d2f5SGreg Clayton strm.PutCString("reading opcode");
368ad379efcSCaroline Tice break;
369ad379efcSCaroline Tice
370ad379efcSCaroline Tice case eContextImmediate:
37131f1d2f5SGreg Clayton strm.PutCString("immediate");
372ad379efcSCaroline Tice break;
373ad379efcSCaroline Tice
374ad379efcSCaroline Tice case eContextPushRegisterOnStack:
37531f1d2f5SGreg Clayton strm.PutCString("push register");
376ad379efcSCaroline Tice break;
377ad379efcSCaroline Tice
378ad379efcSCaroline Tice case eContextPopRegisterOffStack:
37931f1d2f5SGreg Clayton strm.PutCString("pop register");
380ad379efcSCaroline Tice break;
381ad379efcSCaroline Tice
382ad379efcSCaroline Tice case eContextAdjustStackPointer:
38331f1d2f5SGreg Clayton strm.PutCString("adjust sp");
384ad379efcSCaroline Tice break;
385ad379efcSCaroline Tice
386a658fd26SGreg Clayton case eContextSetFramePointer:
387a658fd26SGreg Clayton strm.PutCString("set frame pointer");
388a658fd26SGreg Clayton break;
389a658fd26SGreg Clayton
390ad379efcSCaroline Tice case eContextAdjustBaseRegister:
39131f1d2f5SGreg Clayton strm.PutCString("adjusting (writing value back to) a base register");
392ad379efcSCaroline Tice break;
393ad379efcSCaroline Tice
394ad379efcSCaroline Tice case eContextRegisterPlusOffset:
39531f1d2f5SGreg Clayton strm.PutCString("register + offset");
396ad379efcSCaroline Tice break;
397ad379efcSCaroline Tice
398ad379efcSCaroline Tice case eContextRegisterStore:
39931f1d2f5SGreg Clayton strm.PutCString("store register");
400ad379efcSCaroline Tice break;
401ad379efcSCaroline Tice
402ad379efcSCaroline Tice case eContextRegisterLoad:
40331f1d2f5SGreg Clayton strm.PutCString("load register");
404ad379efcSCaroline Tice break;
405ad379efcSCaroline Tice
406ad379efcSCaroline Tice case eContextRelativeBranchImmediate:
40731f1d2f5SGreg Clayton strm.PutCString("relative branch immediate");
408ad379efcSCaroline Tice break;
409ad379efcSCaroline Tice
410ad379efcSCaroline Tice case eContextAbsoluteBranchRegister:
41131f1d2f5SGreg Clayton strm.PutCString("absolute branch register");
412ad379efcSCaroline Tice break;
413ad379efcSCaroline Tice
414ad379efcSCaroline Tice case eContextSupervisorCall:
41531f1d2f5SGreg Clayton strm.PutCString("supervisor call");
416ad379efcSCaroline Tice break;
417ad379efcSCaroline Tice
418ad379efcSCaroline Tice case eContextTableBranchReadMemory:
41931f1d2f5SGreg Clayton strm.PutCString("table branch read memory");
420ad379efcSCaroline Tice break;
421ad379efcSCaroline Tice
422ad379efcSCaroline Tice case eContextWriteRegisterRandomBits:
42331f1d2f5SGreg Clayton strm.PutCString("write random bits to a register");
424ad379efcSCaroline Tice break;
425ad379efcSCaroline Tice
426ad379efcSCaroline Tice case eContextWriteMemoryRandomBits:
42731f1d2f5SGreg Clayton strm.PutCString("write random bits to a memory address");
428ad379efcSCaroline Tice break;
429ad379efcSCaroline Tice
43079ea878bSGreg Clayton case eContextArithmetic:
43131f1d2f5SGreg Clayton strm.PutCString("arithmetic");
432ad379efcSCaroline Tice break;
433ad379efcSCaroline Tice
434ad379efcSCaroline Tice case eContextReturnFromException:
43531f1d2f5SGreg Clayton strm.PutCString("return from exception");
436ad379efcSCaroline Tice break;
437ad379efcSCaroline Tice
438ad379efcSCaroline Tice default:
43931f1d2f5SGreg Clayton strm.PutCString("unrecognized context.");
440ad379efcSCaroline Tice break;
441ad379efcSCaroline Tice }
442ad379efcSCaroline Tice
443b9c1b51eSKate Stone switch (info_type) {
444ad379efcSCaroline Tice case eInfoTypeRegisterPlusOffset:
445d01b2953SDaniel Malea strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
44679ea878bSGreg Clayton info.RegisterPlusOffset.reg.name,
44779ea878bSGreg Clayton info.RegisterPlusOffset.signed_offset);
448ad379efcSCaroline Tice break;
44979ea878bSGreg Clayton
450ad379efcSCaroline Tice case eInfoTypeRegisterPlusIndirectOffset:
45131f1d2f5SGreg Clayton strm.Printf(" (reg_plus_reg = %s + %s)",
45279ea878bSGreg Clayton info.RegisterPlusIndirectOffset.base_reg.name,
45379ea878bSGreg Clayton info.RegisterPlusIndirectOffset.offset_reg.name);
454ad379efcSCaroline Tice break;
45579ea878bSGreg Clayton
456ad379efcSCaroline Tice case eInfoTypeRegisterToRegisterPlusOffset:
457d01b2953SDaniel Malea strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
45879ea878bSGreg Clayton info.RegisterToRegisterPlusOffset.base_reg.name,
45979ea878bSGreg Clayton info.RegisterToRegisterPlusOffset.offset,
46079ea878bSGreg Clayton info.RegisterToRegisterPlusOffset.data_reg.name);
461ad379efcSCaroline Tice break;
46279ea878bSGreg Clayton
463ad379efcSCaroline Tice case eInfoTypeRegisterToRegisterPlusIndirectOffset:
46431f1d2f5SGreg Clayton strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
46579ea878bSGreg Clayton info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
46679ea878bSGreg Clayton info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
46779ea878bSGreg Clayton info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
468ad379efcSCaroline Tice break;
469ad379efcSCaroline Tice
470ad379efcSCaroline Tice case eInfoTypeRegisterRegisterOperands:
47131f1d2f5SGreg Clayton strm.Printf(" (register to register binary op: %s and %s)",
47279ea878bSGreg Clayton info.RegisterRegisterOperands.operand1.name,
47379ea878bSGreg Clayton info.RegisterRegisterOperands.operand2.name);
474ad379efcSCaroline Tice break;
47579ea878bSGreg Clayton
476ad379efcSCaroline Tice case eInfoTypeOffset:
477d01b2953SDaniel Malea strm.Printf(" (signed_offset = %+" PRId64 ")", info.signed_offset);
478ad379efcSCaroline Tice break;
479ad379efcSCaroline Tice
480ad379efcSCaroline Tice case eInfoTypeRegister:
48131f1d2f5SGreg Clayton strm.Printf(" (reg = %s)", info.reg.name);
482ad379efcSCaroline Tice break;
483ad379efcSCaroline Tice
484ad379efcSCaroline Tice case eInfoTypeImmediate:
485d01b2953SDaniel Malea strm.Printf(" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
486b9c1b51eSKate Stone info.unsigned_immediate, info.unsigned_immediate);
487ad379efcSCaroline Tice break;
488ad379efcSCaroline Tice
489ad379efcSCaroline Tice case eInfoTypeImmediateSigned:
490d01b2953SDaniel Malea strm.Printf(" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
491b9c1b51eSKate Stone info.signed_immediate, info.signed_immediate);
492ad379efcSCaroline Tice break;
493ad379efcSCaroline Tice
494ad379efcSCaroline Tice case eInfoTypeAddress:
495d01b2953SDaniel Malea strm.Printf(" (address = 0x%" PRIx64 ")", info.address);
496ad379efcSCaroline Tice break;
497ad379efcSCaroline Tice
49879ea878bSGreg Clayton case eInfoTypeISAAndImmediate:
49931f1d2f5SGreg Clayton strm.Printf(" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
500b9c1b51eSKate Stone info.ISAAndImmediate.isa, info.ISAAndImmediate.unsigned_data32,
50179ea878bSGreg Clayton info.ISAAndImmediate.unsigned_data32);
502ad379efcSCaroline Tice break;
503ad379efcSCaroline Tice
50479ea878bSGreg Clayton case eInfoTypeISAAndImmediateSigned:
50531f1d2f5SGreg Clayton strm.Printf(" (isa = %u, signed_immediate = %i (0x%8.8x))",
50679ea878bSGreg Clayton info.ISAAndImmediateSigned.isa,
50779ea878bSGreg Clayton info.ISAAndImmediateSigned.signed_data32,
50879ea878bSGreg Clayton info.ISAAndImmediateSigned.signed_data32);
509ad379efcSCaroline Tice break;
510ad379efcSCaroline Tice
51179ea878bSGreg Clayton case eInfoTypeISA:
51231f1d2f5SGreg Clayton strm.Printf(" (isa = %u)", info.isa);
513ad379efcSCaroline Tice break;
514ad379efcSCaroline Tice
515ad379efcSCaroline Tice case eInfoTypeNoArgs:
516ad379efcSCaroline Tice break;
517ad379efcSCaroline Tice }
518ad379efcSCaroline Tice }
519ad379efcSCaroline Tice
SetInstruction(const Opcode & opcode,const Address & inst_addr,Target * target)520b9c1b51eSKate Stone bool EmulateInstruction::SetInstruction(const Opcode &opcode,
521b9c1b51eSKate Stone const Address &inst_addr,
522b9c1b51eSKate Stone Target *target) {
5232ed751bdSGreg Clayton m_opcode = opcode;
524e5b3498eSGreg Clayton m_addr = LLDB_INVALID_ADDRESS;
525b9c1b51eSKate Stone if (inst_addr.IsValid()) {
52634ede34aSEugene Zelenko if (target != nullptr)
527e5b3498eSGreg Clayton m_addr = inst_addr.GetLoadAddress(target);
528e5b3498eSGreg Clayton if (m_addr == LLDB_INVALID_ADDRESS)
529e5b3498eSGreg Clayton m_addr = inst_addr.GetFileAddress();
5302ed751bdSGreg Clayton }
5312ed751bdSGreg Clayton return true;
5322ed751bdSGreg Clayton }
5332ed751bdSGreg Clayton
GetBestRegisterKindAndNumber(const RegisterInfo * reg_info,lldb::RegisterKind & reg_kind,uint32_t & reg_num)534b9c1b51eSKate Stone bool EmulateInstruction::GetBestRegisterKindAndNumber(
535b9c1b51eSKate Stone const RegisterInfo *reg_info, lldb::RegisterKind ®_kind,
536b9c1b51eSKate Stone uint32_t ®_num) {
53779ea878bSGreg Clayton // Generic and DWARF should be the two most popular register kinds when
53879ea878bSGreg Clayton // emulating instructions since they are the most platform agnostic...
5397349bd90SGreg Clayton reg_num = reg_info->kinds[eRegisterKindGeneric];
540b9c1b51eSKate Stone if (reg_num != LLDB_INVALID_REGNUM) {
54179ea878bSGreg Clayton reg_kind = eRegisterKindGeneric;
54279ea878bSGreg Clayton return true;
5432ed751bdSGreg Clayton }
5442ed751bdSGreg Clayton
5457349bd90SGreg Clayton reg_num = reg_info->kinds[eRegisterKindDWARF];
546b9c1b51eSKate Stone if (reg_num != LLDB_INVALID_REGNUM) {
54779ea878bSGreg Clayton reg_kind = eRegisterKindDWARF;
54879ea878bSGreg Clayton return true;
54979ea878bSGreg Clayton }
5502ed751bdSGreg Clayton
5517349bd90SGreg Clayton reg_num = reg_info->kinds[eRegisterKindLLDB];
552b9c1b51eSKate Stone if (reg_num != LLDB_INVALID_REGNUM) {
55379ea878bSGreg Clayton reg_kind = eRegisterKindLLDB;
55479ea878bSGreg Clayton return true;
55579ea878bSGreg Clayton }
5562ed751bdSGreg Clayton
557a18f7071SJason Molenda reg_num = reg_info->kinds[eRegisterKindEHFrame];
558b9c1b51eSKate Stone if (reg_num != LLDB_INVALID_REGNUM) {
559a18f7071SJason Molenda reg_kind = eRegisterKindEHFrame;
56079ea878bSGreg Clayton return true;
56179ea878bSGreg Clayton }
5622ed751bdSGreg Clayton
56363bd0db0SJason Molenda reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
564b9c1b51eSKate Stone if (reg_num != LLDB_INVALID_REGNUM) {
56563bd0db0SJason Molenda reg_kind = eRegisterKindProcessPlugin;
56679ea878bSGreg Clayton return true;
56779ea878bSGreg Clayton }
56879ea878bSGreg Clayton return false;
56979ea878bSGreg Clayton }
5702ed751bdSGreg Clayton
57179ea878bSGreg Clayton uint32_t
GetInternalRegisterNumber(RegisterContext * reg_ctx,const RegisterInfo & reg_info)572b9c1b51eSKate Stone EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx,
573b9c1b51eSKate Stone const RegisterInfo ®_info) {
574e7c7c3deSJean-Daniel Dupas lldb::RegisterKind reg_kind;
575e7c7c3deSJean-Daniel Dupas uint32_t reg_num;
5767349bd90SGreg Clayton if (reg_ctx && GetBestRegisterKindAndNumber(®_info, reg_kind, reg_num))
57779ea878bSGreg Clayton return reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
57879ea878bSGreg Clayton return LLDB_INVALID_REGNUM;
5792ed751bdSGreg Clayton }
5802ed751bdSGreg Clayton
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)581b9c1b51eSKate Stone bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
58279ea878bSGreg Clayton unwind_plan.Clear();
58379ea878bSGreg Clayton return false;
584ad379efcSCaroline Tice }
585