1*c1dfd93eSGreg Clayton //===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
2*c1dfd93eSGreg Clayton //
3*c1dfd93eSGreg Clayton //                     The LLVM Compiler Infrastructure
4*c1dfd93eSGreg Clayton //
5*c1dfd93eSGreg Clayton // This file is distributed under the University of Illinois Open Source
6*c1dfd93eSGreg Clayton // License. See LICENSE.TXT for details.
7*c1dfd93eSGreg Clayton //
8*c1dfd93eSGreg Clayton //===----------------------------------------------------------------------===//
9*c1dfd93eSGreg Clayton 
10*c1dfd93eSGreg Clayton #include "EmulateInstruction.h"
11*c1dfd93eSGreg Clayton 
12*c1dfd93eSGreg Clayton #include "lldb/Core/DataExtractor.h"
13*c1dfd93eSGreg Clayton #include "lldb/Core/StreamString.h"
14*c1dfd93eSGreg Clayton using namespace lldb;
15*c1dfd93eSGreg Clayton using namespace lldb_private;
16*c1dfd93eSGreg Clayton 
17*c1dfd93eSGreg Clayton 
18*c1dfd93eSGreg Clayton EmulateInstruction::EmulateInstruction
19*c1dfd93eSGreg Clayton (
20*c1dfd93eSGreg Clayton     lldb::ByteOrder byte_order,
21*c1dfd93eSGreg Clayton     uint32_t addr_byte_size,
22*c1dfd93eSGreg Clayton     void *baton,
23*c1dfd93eSGreg Clayton     ReadMemory read_mem_callback,
24*c1dfd93eSGreg Clayton     WriteMemory write_mem_callback,
25*c1dfd93eSGreg Clayton     ReadRegister read_reg_callback,
26*c1dfd93eSGreg Clayton     WriteRegister write_reg_callback
27*c1dfd93eSGreg Clayton ) :
28*c1dfd93eSGreg Clayton     m_byte_order (lldb::eByteOrderHost),
29*c1dfd93eSGreg Clayton     m_addr_byte_size (sizeof (void *)),
30*c1dfd93eSGreg Clayton     m_baton (baton),
31*c1dfd93eSGreg Clayton     m_read_mem_callback (read_mem_callback),
32*c1dfd93eSGreg Clayton     m_write_mem_callback (write_mem_callback),
33*c1dfd93eSGreg Clayton     m_read_reg_callback (read_reg_callback),
34*c1dfd93eSGreg Clayton     m_write_reg_callback (write_reg_callback),
35*c1dfd93eSGreg Clayton     m_inst_pc (LLDB_INVALID_ADDRESS)
36*c1dfd93eSGreg Clayton {
37*c1dfd93eSGreg Clayton     ::bzero (&m_inst, sizeof (m_inst));
38*c1dfd93eSGreg Clayton }
39*c1dfd93eSGreg Clayton 
40*c1dfd93eSGreg Clayton uint64_t
41*c1dfd93eSGreg Clayton EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
42*c1dfd93eSGreg Clayton {
43*c1dfd93eSGreg Clayton     uint64_t uval64 = 0;
44*c1dfd93eSGreg Clayton     bool success = m_read_reg_callback (m_baton, reg_kind, reg_num, uval64);
45*c1dfd93eSGreg Clayton     if (success_ptr)
46*c1dfd93eSGreg Clayton         *success_ptr = success;
47*c1dfd93eSGreg Clayton     if (!success)
48*c1dfd93eSGreg Clayton         uval64 = fail_value;
49*c1dfd93eSGreg Clayton     return uval64;
50*c1dfd93eSGreg Clayton }
51*c1dfd93eSGreg Clayton 
52*c1dfd93eSGreg Clayton bool
53*c1dfd93eSGreg Clayton EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
54*c1dfd93eSGreg Clayton {
55*c1dfd93eSGreg Clayton     return m_write_reg_callback (m_baton, context, reg_kind, reg_num, reg_value);
56*c1dfd93eSGreg Clayton }
57*c1dfd93eSGreg Clayton 
58*c1dfd93eSGreg Clayton uint64_t
59*c1dfd93eSGreg Clayton EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
60*c1dfd93eSGreg Clayton {
61*c1dfd93eSGreg Clayton     uint64_t uval64 = 0;
62*c1dfd93eSGreg Clayton     bool success = false;
63*c1dfd93eSGreg Clayton     if (byte_size <= 8)
64*c1dfd93eSGreg Clayton     {
65*c1dfd93eSGreg Clayton         uint8_t buf[sizeof(uint64_t)];
66*c1dfd93eSGreg Clayton         size_t bytes_read = m_read_mem_callback (m_baton, context, addr, buf, byte_size);
67*c1dfd93eSGreg Clayton         if (bytes_read == byte_size)
68*c1dfd93eSGreg Clayton         {
69*c1dfd93eSGreg Clayton             uint32_t offset = 0;
70*c1dfd93eSGreg Clayton             DataExtractor data (buf, byte_size, m_byte_order, m_addr_byte_size);
71*c1dfd93eSGreg Clayton             uval64 = data.GetMaxU64 (&offset, byte_size);
72*c1dfd93eSGreg Clayton             success = true;
73*c1dfd93eSGreg Clayton         }
74*c1dfd93eSGreg Clayton     }
75*c1dfd93eSGreg Clayton 
76*c1dfd93eSGreg Clayton     if (success_ptr)
77*c1dfd93eSGreg Clayton         *success_ptr = success;
78*c1dfd93eSGreg Clayton 
79*c1dfd93eSGreg Clayton     if (!success)
80*c1dfd93eSGreg Clayton         uval64 = fail_value;
81*c1dfd93eSGreg Clayton     return uval64;
82*c1dfd93eSGreg Clayton }
83*c1dfd93eSGreg Clayton 
84*c1dfd93eSGreg Clayton 
85*c1dfd93eSGreg Clayton bool
86*c1dfd93eSGreg Clayton EmulateInstruction::WriteMemoryUnsigned (const Context &context,
87*c1dfd93eSGreg Clayton                                          lldb::addr_t addr,
88*c1dfd93eSGreg Clayton                                          uint64_t uval,
89*c1dfd93eSGreg Clayton                                          size_t uval_byte_size)
90*c1dfd93eSGreg Clayton {
91*c1dfd93eSGreg Clayton     StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
92*c1dfd93eSGreg Clayton     strm.PutMaxHex64 (uval, uval_byte_size);
93*c1dfd93eSGreg Clayton 
94*c1dfd93eSGreg Clayton     size_t bytes_written = m_write_mem_callback (m_baton, context, addr, strm.GetData(), uval_byte_size);
95*c1dfd93eSGreg Clayton     if (bytes_written == uval_byte_size)
96*c1dfd93eSGreg Clayton         return true;
97*c1dfd93eSGreg Clayton     return false;
98*c1dfd93eSGreg Clayton }
99