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