Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 1 | //===-- 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 Clayton | 95e3142 | 2011-02-05 02:56:16 +0000 | [diff] [blame] | 10 | #include "lldb/Core/EmulateInstruction.h" |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 11 | |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 12 | // C Includes |
| 13 | // C++ Includes |
| 14 | #include <cstring> |
| 15 | |
| 16 | // Other libraries and framework includes |
| 17 | // Project includes |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 18 | #include "lldb/Core/Address.h" |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 19 | #include "lldb/Core/DataExtractor.h" |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 20 | #include "lldb/Core/Error.h" |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 21 | #include "lldb/Core/PluginManager.h" |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 22 | #include "lldb/Core/RegisterValue.h" |
| 23 | #include "lldb/Core/StreamFile.h" |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 24 | #include "lldb/Core/StreamString.h" |
Greg Clayton | 7fb56d0 | 2011-02-01 01:31:41 +0000 | [diff] [blame] | 25 | #include "lldb/Host/Endian.h" |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 26 | #include "lldb/Symbol/UnwindPlan.h" |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 27 | #include "lldb/Target/Process.h" |
| 28 | #include "lldb/Target/RegisterContext.h" |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 29 | #include "lldb/Target/Target.h" |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 30 | #include "lldb/Target/Thread.h" |
| 31 | |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 32 | using namespace lldb; |
| 33 | using namespace lldb_private; |
| 34 | |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 35 | EmulateInstruction* |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 36 | EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name) |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 37 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 38 | EmulateInstructionCreateInstance create_callback = nullptr; |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 39 | if (plugin_name) |
| 40 | { |
Greg Clayton | 57abc5d | 2013-05-10 21:47:16 +0000 | [diff] [blame] | 41 | ConstString const_plugin_name (plugin_name); |
| 42 | create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name); |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 43 | if (create_callback) |
| 44 | { |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 45 | EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 46 | if (emulate_insn_ptr) |
| 47 | return emulate_insn_ptr; |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 48 | } |
| 49 | } |
| 50 | else |
| 51 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 52 | for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != nullptr; ++idx) |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 53 | { |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 54 | EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 55 | if (emulate_insn_ptr) |
| 56 | return emulate_insn_ptr; |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 57 | } |
| 58 | } |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 59 | return nullptr; |
Greg Clayton | 4272cc7 | 2011-02-02 02:24:04 +0000 | [diff] [blame] | 60 | } |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 61 | |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 62 | EmulateInstruction::EmulateInstruction (const ArchSpec &arch) : |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 63 | m_arch(arch), |
| 64 | m_baton(nullptr), |
| 65 | m_read_mem_callback(&ReadMemoryDefault), |
| 66 | m_write_mem_callback(&WriteMemoryDefault), |
| 67 | m_read_reg_callback(&ReadRegisterDefault), |
| 68 | m_write_reg_callback(&WriteRegisterDefault), |
| 69 | m_addr(LLDB_INVALID_ADDRESS) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 70 | { |
| 71 | ::memset (&m_opcode, 0, sizeof (m_opcode)); |
| 72 | } |
| 73 | |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 74 | bool |
| 75 | EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value) |
| 76 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 77 | if (m_read_reg_callback != nullptr) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 78 | return m_read_reg_callback (this, m_baton, reg_info, reg_value); |
| 79 | return false; |
| 80 | } |
| 81 | |
| 82 | bool |
Jean-Daniel Dupas | e7c7c3d | 2014-07-02 09:51:28 +0000 | [diff] [blame] | 83 | EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value) |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 84 | { |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 85 | RegisterInfo reg_info; |
| 86 | if (GetRegisterInfo(reg_kind, reg_num, reg_info)) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 87 | return ReadRegister (®_info, reg_value); |
| 88 | return false; |
| 89 | } |
| 90 | |
| 91 | uint64_t |
Jean-Daniel Dupas | e7c7c3d | 2014-07-02 09:51:28 +0000 | [diff] [blame] | 92 | EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind, |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 93 | uint32_t reg_num, |
| 94 | uint64_t fail_value, |
| 95 | bool *success_ptr) |
| 96 | { |
| 97 | RegisterValue reg_value; |
| 98 | if (ReadRegister (reg_kind, reg_num, reg_value)) |
| 99 | return reg_value.GetAsUInt64(fail_value, success_ptr); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 100 | if (success_ptr) |
| 101 | *success_ptr = false; |
| 102 | return fail_value; |
| 103 | } |
| 104 | |
| 105 | uint64_t |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 106 | EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info, |
| 107 | uint64_t fail_value, |
| 108 | bool *success_ptr) |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 109 | { |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 110 | RegisterValue reg_value; |
| 111 | if (ReadRegister (reg_info, reg_value)) |
| 112 | return reg_value.GetAsUInt64(fail_value, success_ptr); |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 113 | if (success_ptr) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 114 | *success_ptr = false; |
| 115 | return fail_value; |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 116 | } |
| 117 | |
| 118 | bool |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 119 | EmulateInstruction::WriteRegister (const Context &context, |
| 120 | const RegisterInfo *reg_info, |
| 121 | const RegisterValue& reg_value) |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 122 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 123 | if (m_write_reg_callback != nullptr) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 124 | return m_write_reg_callback (this, m_baton, context, reg_info, reg_value); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 125 | return false; |
| 126 | } |
| 127 | |
| 128 | bool |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 129 | EmulateInstruction::WriteRegister (const Context &context, |
Jean-Daniel Dupas | e7c7c3d | 2014-07-02 09:51:28 +0000 | [diff] [blame] | 130 | lldb::RegisterKind reg_kind, |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 131 | uint32_t reg_num, |
| 132 | const RegisterValue& reg_value) |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 133 | { |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 134 | RegisterInfo reg_info; |
| 135 | if (GetRegisterInfo(reg_kind, reg_num, reg_info)) |
| 136 | return WriteRegister (context, ®_info, reg_value); |
| 137 | return false; |
| 138 | } |
| 139 | |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 140 | bool |
| 141 | EmulateInstruction::WriteRegisterUnsigned (const Context &context, |
Jean-Daniel Dupas | e7c7c3d | 2014-07-02 09:51:28 +0000 | [diff] [blame] | 142 | lldb::RegisterKind reg_kind, |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 143 | uint32_t reg_num, |
| 144 | uint64_t uint_value) |
| 145 | { |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 146 | RegisterInfo reg_info; |
| 147 | if (GetRegisterInfo(reg_kind, reg_num, reg_info)) |
| 148 | { |
| 149 | RegisterValue reg_value; |
| 150 | if (reg_value.SetUInt(uint_value, reg_info.byte_size)) |
| 151 | return WriteRegister (context, ®_info, reg_value); |
| 152 | } |
| 153 | return false; |
| 154 | } |
| 155 | |
| 156 | bool |
| 157 | EmulateInstruction::WriteRegisterUnsigned (const Context &context, |
| 158 | const RegisterInfo *reg_info, |
| 159 | uint64_t uint_value) |
| 160 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 161 | if (reg_info != nullptr) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 162 | { |
| 163 | RegisterValue reg_value; |
| 164 | if (reg_value.SetUInt(uint_value, reg_info->byte_size)) |
| 165 | return WriteRegister (context, reg_info, reg_value); |
| 166 | } |
| 167 | return false; |
| 168 | } |
| 169 | |
| 170 | size_t |
| 171 | EmulateInstruction::ReadMemory (const Context &context, |
| 172 | lldb::addr_t addr, |
| 173 | void *dst, |
| 174 | size_t dst_len) |
| 175 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 176 | if (m_read_mem_callback != nullptr) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 177 | return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len; |
| 178 | return false; |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | uint64_t |
| 182 | EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr) |
| 183 | { |
| 184 | uint64_t uval64 = 0; |
| 185 | bool success = false; |
| 186 | if (byte_size <= 8) |
| 187 | { |
| 188 | uint8_t buf[sizeof(uint64_t)]; |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 189 | size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size); |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 190 | if (bytes_read == byte_size) |
| 191 | { |
Greg Clayton | c7bece56 | 2013-01-25 18:06:21 +0000 | [diff] [blame] | 192 | lldb::offset_t offset = 0; |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 193 | DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize()); |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 194 | uval64 = data.GetMaxU64 (&offset, byte_size); |
| 195 | success = true; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | if (success_ptr) |
| 200 | *success_ptr = success; |
| 201 | |
| 202 | if (!success) |
| 203 | uval64 = fail_value; |
| 204 | return uval64; |
| 205 | } |
| 206 | |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 207 | bool |
| 208 | EmulateInstruction::WriteMemoryUnsigned (const Context &context, |
| 209 | lldb::addr_t addr, |
| 210 | uint64_t uval, |
| 211 | size_t uval_byte_size) |
| 212 | { |
| 213 | StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder()); |
| 214 | strm.PutMaxHex64 (uval, uval_byte_size); |
| 215 | |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 216 | size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size); |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 217 | return (bytes_written == uval_byte_size); |
Greg Clayton | 6da4ca8 | 2011-01-21 22:02:52 +0000 | [diff] [blame] | 218 | } |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 219 | |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 220 | bool |
| 221 | EmulateInstruction::WriteMemory (const Context &context, |
| 222 | lldb::addr_t addr, |
| 223 | const void *src, |
| 224 | size_t src_len) |
| 225 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 226 | if (m_write_mem_callback != nullptr) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 227 | return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len; |
| 228 | return false; |
| 229 | } |
| 230 | |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 231 | void |
| 232 | EmulateInstruction::SetBaton (void *baton) |
| 233 | { |
| 234 | m_baton = baton; |
| 235 | } |
| 236 | |
| 237 | void |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 238 | EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback, |
| 239 | WriteMemoryCallback write_mem_callback, |
| 240 | ReadRegisterCallback read_reg_callback, |
| 241 | WriteRegisterCallback write_reg_callback) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 242 | { |
| 243 | m_read_mem_callback = read_mem_callback; |
| 244 | m_write_mem_callback = write_mem_callback; |
| 245 | m_read_reg_callback = read_reg_callback; |
| 246 | m_write_reg_callback = write_reg_callback; |
| 247 | } |
| 248 | |
| 249 | void |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 250 | EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 251 | { |
| 252 | m_read_mem_callback = read_mem_callback; |
| 253 | } |
| 254 | |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 255 | void |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 256 | EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 257 | { |
| 258 | m_write_mem_callback = write_mem_callback; |
| 259 | } |
| 260 | |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 261 | void |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 262 | EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 263 | { |
| 264 | m_read_reg_callback = read_reg_callback; |
| 265 | } |
| 266 | |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 267 | void |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 268 | EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 269 | { |
| 270 | m_write_reg_callback = write_reg_callback; |
| 271 | } |
| 272 | |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 273 | // |
| 274 | // Read & Write Memory and Registers callback functions. |
| 275 | // |
| 276 | |
| 277 | size_t |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 278 | EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction, |
| 279 | void *baton, |
Caroline Tice | 3d50b2f | 2011-04-05 20:18:48 +0000 | [diff] [blame] | 280 | const Context &context, |
| 281 | lldb::addr_t addr, |
| 282 | void *dst, |
Greg Clayton | d9e416c | 2012-02-18 05:35:26 +0000 | [diff] [blame] | 283 | size_t dst_len) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 284 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 285 | if (baton == nullptr || dst == nullptr || dst_len == 0) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 286 | return 0; |
Greg Clayton | d9e416c | 2012-02-18 05:35:26 +0000 | [diff] [blame] | 287 | |
Jason Molenda | b57e4a1 | 2013-11-04 09:33:30 +0000 | [diff] [blame] | 288 | StackFrame *frame = (StackFrame *) baton; |
Caroline Tice | 3d50b2f | 2011-04-05 20:18:48 +0000 | [diff] [blame] | 289 | |
Greg Clayton | d9e416c | 2012-02-18 05:35:26 +0000 | [diff] [blame] | 290 | ProcessSP process_sp (frame->CalculateProcess()); |
| 291 | if (process_sp) |
| 292 | { |
| 293 | Error error; |
| 294 | return process_sp->ReadMemory (addr, dst, dst_len, error); |
| 295 | } |
| 296 | return 0; |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 297 | } |
| 298 | |
| 299 | size_t |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 300 | EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction, |
| 301 | void *baton, |
Caroline Tice | 3d50b2f | 2011-04-05 20:18:48 +0000 | [diff] [blame] | 302 | const Context &context, |
| 303 | lldb::addr_t addr, |
Greg Clayton | d9e416c | 2012-02-18 05:35:26 +0000 | [diff] [blame] | 304 | const void *src, |
| 305 | size_t src_len) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 306 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 307 | if (baton == nullptr || src == nullptr || src_len == 0) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 308 | return 0; |
| 309 | |
Jason Molenda | b57e4a1 | 2013-11-04 09:33:30 +0000 | [diff] [blame] | 310 | StackFrame *frame = (StackFrame *) baton; |
Caroline Tice | 3d50b2f | 2011-04-05 20:18:48 +0000 | [diff] [blame] | 311 | |
Greg Clayton | d9e416c | 2012-02-18 05:35:26 +0000 | [diff] [blame] | 312 | ProcessSP process_sp (frame->CalculateProcess()); |
| 313 | if (process_sp) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 314 | { |
Greg Clayton | d9e416c | 2012-02-18 05:35:26 +0000 | [diff] [blame] | 315 | Error error; |
| 316 | return process_sp->WriteMemory (addr, src, src_len, error); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 317 | } |
| 318 | |
| 319 | return 0; |
| 320 | } |
| 321 | |
| 322 | bool |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 323 | EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction, |
| 324 | void *baton, |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 325 | const RegisterInfo *reg_info, |
| 326 | RegisterValue ®_value) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 327 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 328 | if (baton == nullptr) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 329 | return false; |
| 330 | |
Jason Molenda | b57e4a1 | 2013-11-04 09:33:30 +0000 | [diff] [blame] | 331 | StackFrame *frame = (StackFrame *) baton; |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 332 | return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 333 | } |
| 334 | |
| 335 | bool |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 336 | EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction, |
| 337 | void *baton, |
Caroline Tice | 3d50b2f | 2011-04-05 20:18:48 +0000 | [diff] [blame] | 338 | const Context &context, |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 339 | const RegisterInfo *reg_info, |
| 340 | const RegisterValue ®_value) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 341 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 342 | if (baton == nullptr) |
Caroline Tice | 3d50b2f | 2011-04-05 20:18:48 +0000 | [diff] [blame] | 343 | return false; |
| 344 | |
Jason Molenda | b57e4a1 | 2013-11-04 09:33:30 +0000 | [diff] [blame] | 345 | StackFrame *frame = (StackFrame *) baton; |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 346 | return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 347 | } |
| 348 | |
| 349 | size_t |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 350 | EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction, |
| 351 | void *baton, |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 352 | const Context &context, |
| 353 | lldb::addr_t addr, |
| 354 | void *dst, |
| 355 | size_t length) |
| 356 | { |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 357 | StreamFile strm (stdout, false); |
Daniel Malea | d01b295 | 2012-11-29 21:49:15 +0000 | [diff] [blame] | 358 | strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length); |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 359 | context.Dump (strm, instruction); |
| 360 | strm.EOL(); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 361 | *((uint64_t *) dst) = 0xdeadbeef; |
| 362 | return length; |
| 363 | } |
| 364 | |
| 365 | size_t |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 366 | EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction, |
| 367 | void *baton, |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 368 | const Context &context, |
| 369 | lldb::addr_t addr, |
| 370 | const void *dst, |
| 371 | size_t length) |
| 372 | { |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 373 | StreamFile strm (stdout, false); |
Daniel Malea | d01b295 | 2012-11-29 21:49:15 +0000 | [diff] [blame] | 374 | strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length); |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 375 | context.Dump (strm, instruction); |
| 376 | strm.EOL(); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 377 | return length; |
| 378 | } |
| 379 | |
| 380 | bool |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 381 | EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction, |
| 382 | void *baton, |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 383 | const RegisterInfo *reg_info, |
| 384 | RegisterValue ®_value) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 385 | { |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 386 | StreamFile strm (stdout, false); |
| 387 | strm.Printf (" Read Register (%s)\n", reg_info->name); |
Jean-Daniel Dupas | e7c7c3d | 2014-07-02 09:51:28 +0000 | [diff] [blame] | 388 | lldb::RegisterKind reg_kind; |
| 389 | uint32_t reg_num; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 390 | if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num)) |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 391 | reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 392 | else |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 393 | reg_value.SetUInt64(0); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 394 | |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 395 | return true; |
| 396 | } |
| 397 | |
| 398 | bool |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 399 | EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction, |
| 400 | void *baton, |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 401 | const Context &context, |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 402 | const RegisterInfo *reg_info, |
| 403 | const RegisterValue ®_value) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 404 | { |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 405 | StreamFile strm (stdout, false); |
| 406 | strm.Printf (" Write to Register (name = %s, value = " , reg_info->name); |
Greg Clayton | 9a8fa91 | 2011-05-15 04:12:07 +0000 | [diff] [blame] | 407 | reg_value.Dump(&strm, reg_info, false, false, eFormatDefault); |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 408 | strm.PutCString (", context = "); |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 409 | context.Dump (strm, instruction); |
| 410 | strm.EOL(); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 411 | return true; |
| 412 | } |
| 413 | |
| 414 | void |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 415 | EmulateInstruction::Context::Dump (Stream &strm, |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 416 | EmulateInstruction *instruction) const |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 417 | { |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 418 | switch (type) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 419 | { |
| 420 | case eContextReadOpcode: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 421 | strm.PutCString ("reading opcode"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 422 | break; |
| 423 | |
| 424 | case eContextImmediate: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 425 | strm.PutCString ("immediate"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 426 | break; |
| 427 | |
| 428 | case eContextPushRegisterOnStack: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 429 | strm.PutCString ("push register"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 430 | break; |
| 431 | |
| 432 | case eContextPopRegisterOffStack: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 433 | strm.PutCString ("pop register"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 434 | break; |
| 435 | |
| 436 | case eContextAdjustStackPointer: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 437 | strm.PutCString ("adjust sp"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 438 | break; |
| 439 | |
Greg Clayton | a658fd2 | 2011-06-04 01:26:29 +0000 | [diff] [blame] | 440 | case eContextSetFramePointer: |
| 441 | strm.PutCString ("set frame pointer"); |
| 442 | break; |
| 443 | |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 444 | case eContextAdjustBaseRegister: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 445 | strm.PutCString ("adjusting (writing value back to) a base register"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 446 | break; |
| 447 | |
| 448 | case eContextRegisterPlusOffset: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 449 | strm.PutCString ("register + offset"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 450 | break; |
| 451 | |
| 452 | case eContextRegisterStore: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 453 | strm.PutCString ("store register"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 454 | break; |
| 455 | |
| 456 | case eContextRegisterLoad: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 457 | strm.PutCString ("load register"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 458 | break; |
| 459 | |
| 460 | case eContextRelativeBranchImmediate: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 461 | strm.PutCString ("relative branch immediate"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 462 | break; |
| 463 | |
| 464 | case eContextAbsoluteBranchRegister: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 465 | strm.PutCString ("absolute branch register"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 466 | break; |
| 467 | |
| 468 | case eContextSupervisorCall: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 469 | strm.PutCString ("supervisor call"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 470 | break; |
| 471 | |
| 472 | case eContextTableBranchReadMemory: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 473 | strm.PutCString ("table branch read memory"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 474 | break; |
| 475 | |
| 476 | case eContextWriteRegisterRandomBits: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 477 | strm.PutCString ("write random bits to a register"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 478 | break; |
| 479 | |
| 480 | case eContextWriteMemoryRandomBits: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 481 | strm.PutCString ("write random bits to a memory address"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 482 | break; |
| 483 | |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 484 | case eContextArithmetic: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 485 | strm.PutCString ("arithmetic"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 486 | break; |
| 487 | |
| 488 | case eContextReturnFromException: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 489 | strm.PutCString ("return from exception"); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 490 | break; |
| 491 | |
| 492 | default: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 493 | strm.PutCString ("unrecognized context."); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 494 | break; |
| 495 | } |
| 496 | |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 497 | switch (info_type) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 498 | { |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 499 | case eInfoTypeRegisterPlusOffset: |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 500 | strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")", |
| 501 | info.RegisterPlusOffset.reg.name, |
| 502 | info.RegisterPlusOffset.signed_offset); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 503 | break; |
| 504 | |
| 505 | case eInfoTypeRegisterPlusIndirectOffset: |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 506 | strm.Printf(" (reg_plus_reg = %s + %s)", |
| 507 | info.RegisterPlusIndirectOffset.base_reg.name, |
| 508 | info.RegisterPlusIndirectOffset.offset_reg.name); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 509 | break; |
| 510 | |
| 511 | case eInfoTypeRegisterToRegisterPlusOffset: |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 512 | strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)", |
| 513 | info.RegisterToRegisterPlusOffset.base_reg.name, |
| 514 | info.RegisterToRegisterPlusOffset.offset, |
| 515 | info.RegisterToRegisterPlusOffset.data_reg.name); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 516 | break; |
| 517 | |
| 518 | case eInfoTypeRegisterToRegisterPlusIndirectOffset: |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 519 | strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)", |
| 520 | info.RegisterToRegisterPlusIndirectOffset.base_reg.name, |
| 521 | info.RegisterToRegisterPlusIndirectOffset.offset_reg.name, |
| 522 | info.RegisterToRegisterPlusIndirectOffset.data_reg.name); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 523 | break; |
| 524 | |
| 525 | case eInfoTypeRegisterRegisterOperands: |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 526 | strm.Printf(" (register to register binary op: %s and %s)", |
| 527 | info.RegisterRegisterOperands.operand1.name, |
| 528 | info.RegisterRegisterOperands.operand2.name); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 529 | break; |
| 530 | |
| 531 | case eInfoTypeOffset: |
Daniel Malea | d01b295 | 2012-11-29 21:49:15 +0000 | [diff] [blame] | 532 | strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 533 | break; |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 534 | |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 535 | case eInfoTypeRegister: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 536 | strm.Printf (" (reg = %s)", info.reg.name); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 537 | break; |
| 538 | |
| 539 | case eInfoTypeImmediate: |
Daniel Malea | d01b295 | 2012-11-29 21:49:15 +0000 | [diff] [blame] | 540 | strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))", |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 541 | info.unsigned_immediate, |
| 542 | info.unsigned_immediate); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 543 | break; |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 544 | |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 545 | case eInfoTypeImmediateSigned: |
Daniel Malea | d01b295 | 2012-11-29 21:49:15 +0000 | [diff] [blame] | 546 | strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))", |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 547 | info.signed_immediate, |
| 548 | info.signed_immediate); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 549 | break; |
| 550 | |
| 551 | case eInfoTypeAddress: |
Daniel Malea | d01b295 | 2012-11-29 21:49:15 +0000 | [diff] [blame] | 552 | strm.Printf (" (address = 0x%" PRIx64 ")", info.address); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 553 | break; |
| 554 | |
| 555 | case eInfoTypeISAAndImmediate: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 556 | strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))", |
| 557 | info.ISAAndImmediate.isa, |
| 558 | info.ISAAndImmediate.unsigned_data32, |
| 559 | info.ISAAndImmediate.unsigned_data32); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 560 | break; |
| 561 | |
| 562 | case eInfoTypeISAAndImmediateSigned: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 563 | strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))", |
| 564 | info.ISAAndImmediateSigned.isa, |
| 565 | info.ISAAndImmediateSigned.signed_data32, |
| 566 | info.ISAAndImmediateSigned.signed_data32); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 567 | break; |
| 568 | |
| 569 | case eInfoTypeISA: |
Greg Clayton | 31f1d2f | 2011-05-11 18:39:18 +0000 | [diff] [blame] | 570 | strm.Printf (" (isa = %u)", info.isa); |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 571 | break; |
| 572 | |
| 573 | case eInfoTypeNoArgs: |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 574 | break; |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 575 | } |
| 576 | } |
| 577 | |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 578 | bool |
| 579 | EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 580 | { |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 581 | m_opcode = opcode; |
Greg Clayton | e5b3498 | 2011-04-29 22:50:31 +0000 | [diff] [blame] | 582 | m_addr = LLDB_INVALID_ADDRESS; |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 583 | if (inst_addr.IsValid()) |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 584 | { |
Eugene Zelenko | 34ede34 | 2016-03-03 00:51:40 +0000 | [diff] [blame^] | 585 | if (target != nullptr) |
Greg Clayton | e5b3498 | 2011-04-29 22:50:31 +0000 | [diff] [blame] | 586 | m_addr = inst_addr.GetLoadAddress (target); |
| 587 | if (m_addr == LLDB_INVALID_ADDRESS) |
| 588 | m_addr = inst_addr.GetFileAddress (); |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 589 | } |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 590 | return true; |
Caroline Tice | ad379efc | 2011-04-05 18:46:00 +0000 | [diff] [blame] | 591 | } |
| 592 | |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 593 | bool |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 594 | EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, |
Jean-Daniel Dupas | e7c7c3d | 2014-07-02 09:51:28 +0000 | [diff] [blame] | 595 | lldb::RegisterKind ®_kind, |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 596 | uint32_t ®_num) |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 597 | { |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 598 | // Generic and DWARF should be the two most popular register kinds when |
| 599 | // emulating instructions since they are the most platform agnostic... |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 600 | reg_num = reg_info->kinds[eRegisterKindGeneric]; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 601 | if (reg_num != LLDB_INVALID_REGNUM) |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 602 | { |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 603 | reg_kind = eRegisterKindGeneric; |
| 604 | return true; |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 605 | } |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 606 | |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 607 | reg_num = reg_info->kinds[eRegisterKindDWARF]; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 608 | if (reg_num != LLDB_INVALID_REGNUM) |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 609 | { |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 610 | reg_kind = eRegisterKindDWARF; |
| 611 | return true; |
| 612 | } |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 613 | |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 614 | reg_num = reg_info->kinds[eRegisterKindLLDB]; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 615 | if (reg_num != LLDB_INVALID_REGNUM) |
| 616 | { |
| 617 | reg_kind = eRegisterKindLLDB; |
| 618 | return true; |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 619 | } |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 620 | |
Jason Molenda | a18f707 | 2015-08-15 01:21:01 +0000 | [diff] [blame] | 621 | reg_num = reg_info->kinds[eRegisterKindEHFrame]; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 622 | if (reg_num != LLDB_INVALID_REGNUM) |
| 623 | { |
Jason Molenda | a18f707 | 2015-08-15 01:21:01 +0000 | [diff] [blame] | 624 | reg_kind = eRegisterKindEHFrame; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 625 | return true; |
| 626 | } |
| 627 | |
Jason Molenda | 63bd0db | 2015-09-15 23:20:34 +0000 | [diff] [blame] | 628 | reg_num = reg_info->kinds[eRegisterKindProcessPlugin]; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 629 | if (reg_num != LLDB_INVALID_REGNUM) |
| 630 | { |
Jason Molenda | 63bd0db | 2015-09-15 23:20:34 +0000 | [diff] [blame] | 631 | reg_kind = eRegisterKindProcessPlugin; |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 632 | return true; |
| 633 | } |
| 634 | return false; |
| 635 | } |
| 636 | |
| 637 | uint32_t |
| 638 | EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo ®_info) |
| 639 | { |
Jean-Daniel Dupas | e7c7c3d | 2014-07-02 09:51:28 +0000 | [diff] [blame] | 640 | lldb::RegisterKind reg_kind; |
| 641 | uint32_t reg_num; |
Greg Clayton | 7349bd9 | 2011-05-09 20:18:18 +0000 | [diff] [blame] | 642 | if (reg_ctx && GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num)) |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 643 | return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num); |
| 644 | return LLDB_INVALID_REGNUM; |
| 645 | } |
| 646 | |
Greg Clayton | 79ea878 | 2011-04-26 23:48:45 +0000 | [diff] [blame] | 647 | bool |
| 648 | EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) |
| 649 | { |
| 650 | unwind_plan.Clear(); |
| 651 | return false; |
Greg Clayton | 2ed751b | 2011-04-26 04:39:08 +0000 | [diff] [blame] | 652 | } |