EmulateInstructionARM.h revision 668b45124a14cbd03e7b4965b3d86fdbf208d282
1//===-- lldb_EmulateInstructionARM.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 10#ifndef lldb_EmulateInstructionARM_h_ 11#define lldb_EmulateInstructionARM_h_ 12 13#include "lldb/Core/EmulateInstruction.h" 14#include "lldb/Core/Error.h" 15 16namespace lldb_private { 17 18// ITSession - Keep track of the IT Block progression. 19class ITSession 20{ 21public: 22 ITSession() : ITCounter(0), ITState(0) {} 23 ~ITSession() {} 24 25 // InitIT - Initializes ITCounter/ITState. 26 bool InitIT(unsigned short bits7_0); 27 28 // ITAdvance - Updates ITCounter/ITState as IT Block progresses. 29 void ITAdvance(); 30 31 // InITBlock - Returns true if we're inside an IT Block. 32 bool InITBlock(); 33 34 // LastInITBlock - Returns true if we're the last instruction inside an IT Block. 35 bool LastInITBlock(); 36 37 // GetCond - Gets condition bits for the current thumb instruction. 38 uint32_t GetCond(); 39 40private: 41 uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4. 42 uint32_t ITState; // A2.5.2 Consists of IT[7:5] and IT[4:0] initially. 43}; 44 45class EmulateInstructionARM : public EmulateInstruction 46{ 47public: 48 typedef enum 49 { 50 eEncodingA1, 51 eEncodingA2, 52 eEncodingA3, 53 eEncodingA4, 54 eEncodingA5, 55 eEncodingT1, 56 eEncodingT2, 57 eEncodingT3, 58 eEncodingT4, 59 eEncodingT5 60 } ARMEncoding; 61 62 63 static void 64 Initialize (); 65 66 static void 67 Terminate (); 68 69 virtual const char * 70 GetPluginName() 71 { 72 return "EmulateInstructionARM"; 73 } 74 75 virtual const char * 76 GetShortPluginName() 77 { 78 return "lldb.emulate-instruction.arm"; 79 } 80 81 virtual uint32_t 82 GetPluginVersion() 83 { 84 return 1; 85 } 86 87 virtual void 88 GetPluginCommandHelp (const char *command, Stream *strm) 89 { 90 } 91 92 virtual lldb_private::Error 93 ExecutePluginCommand (Args &command, Stream *strm) 94 { 95 Error error; 96 error.SetErrorString("no plug-in commands are supported"); 97 return error; 98 } 99 100 virtual Log * 101 EnablePluginLogging (Stream *strm, Args &command) 102 { 103 return NULL; 104 } 105 106 enum Mode 107 { 108 eModeInvalid, 109 eModeARM, 110 eModeThumb 111 }; 112 113 EmulateInstructionARM (void *baton, 114 ReadMemory read_mem_callback, 115 WriteMemory write_mem_callback, 116 ReadRegister read_reg_callback, 117 WriteRegister write_reg_callback) : 118 EmulateInstruction (lldb::eByteOrderLittle, // Byte order for ARM 119 4, // Address size in byte 120 baton, 121 read_mem_callback, 122 write_mem_callback, 123 read_reg_callback, 124 write_reg_callback), 125 m_arm_isa (0), 126 m_inst_mode (eModeInvalid), 127 m_inst_cpsr (0), 128 m_it_session () 129 { 130 } 131 132 133 virtual bool 134 SetTargetTriple (const ConstString &triple); 135 136 virtual bool 137 ReadInstruction (); 138 139 virtual bool 140 EvaluateInstruction (); 141 142 uint32_t 143 ArchVersion(); 144 145 bool 146 ConditionPassed (); 147 148 uint32_t 149 CurrentCond (); 150 151 // InITBlock - Returns true if we're in Thumb mode and inside an IT Block. 152 bool InITBlock(); 153 154 // LastInITBlock - Returns true if we're in Thumb mode and the last instruction inside an IT Block. 155 bool LastInITBlock(); 156 157 bool 158 BranchWritePC(const Context &context, uint32_t addr); 159 160 bool 161 BXWritePC(Context &context, uint32_t addr); 162 163 bool 164 LoadWritePC(Context &context, uint32_t addr); 165 166 bool 167 ALUWritePC(Context &context, uint32_t addr); 168 169 Mode 170 CurrentInstrSet(); 171 172 bool 173 SelectInstrSet(Mode arm_or_thumb); 174 175 bool 176 WriteBits32Unknown (int n); 177 178 bool 179 WriteBits32UnknownToMemory (lldb::addr_t address); 180 181 bool 182 UnalignedSupport(); 183 184 typedef struct 185 { 186 uint32_t result; 187 uint8_t carry_out; 188 uint8_t overflow; 189 } AddWithCarryResult; 190 191 AddWithCarryResult 192 AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in); 193 194protected: 195 196 // Typedef for the callback function used during the emulation. 197 // Pass along (ARMEncoding)encoding as the callback data. 198 typedef enum 199 { 200 eSize16, 201 eSize32 202 } ARMInstrSize; 203 204 typedef struct 205 { 206 uint32_t mask; 207 uint32_t value; 208 uint32_t variants; 209 EmulateInstructionARM::ARMEncoding encoding; 210 ARMInstrSize size; 211 bool (EmulateInstructionARM::*callback) (EmulateInstructionARM::ARMEncoding encoding); 212 const char *name; 213 } ARMOpcode; 214 215 216 static ARMOpcode* 217 GetARMOpcodeForInstruction (const uint32_t opcode); 218 219 static ARMOpcode* 220 GetThumbOpcodeForInstruction (const uint32_t opcode); 221 222 bool 223 EmulatePush (ARMEncoding encoding); 224 225 bool 226 EmulatePop (ARMEncoding encoding); 227 228 bool 229 EmulateAddRdSPImmediate (ARMEncoding encoding); 230 231 bool 232 EmulateMovRdSP (ARMEncoding encoding); 233 234 bool 235 EmulateMovLowHigh (ARMEncoding encoding); 236 237 bool 238 EmulateLDRRtPCRelative (ARMEncoding encoding); 239 240 bool 241 EmulateAddSPImmediate (ARMEncoding encoding); 242 243 bool 244 EmulateAddSPRm (ARMEncoding encoding); 245 246 bool 247 EmulateBLXImmediate (ARMEncoding encoding); 248 249 bool 250 EmulateBLXRm (ARMEncoding encoding); 251 252 bool 253 EmulateBXRm (ARMEncoding encoding); 254 255 bool 256 EmulateSubR7IPImmediate (ARMEncoding encoding); 257 258 bool 259 EmulateSubIPSPImmediate (ARMEncoding encoding); 260 261 bool 262 EmulateSubSPImmdiate (ARMEncoding encoding); 263 264 bool 265 EmulateSTRRtSP (ARMEncoding encoding); 266 267 bool 268 EmulateVPUSH (ARMEncoding encoding); 269 270 bool 271 EmulateVPOP (ARMEncoding encoding); 272 273 bool 274 EmulateSVC (ARMEncoding encoding); 275 276 bool 277 EmulateIT (ARMEncoding encoding); 278 279 bool 280 EmulateB (ARMEncoding encoding); 281 282 // CBNZ, CBZ 283 bool 284 EmulateCB (ARMEncoding encoding); 285 286 bool 287 EmulateAddRdnRm (ARMEncoding encoding); 288 289 // MOV (register) 290 bool 291 EmulateMovRdRm (ARMEncoding encoding); 292 293 // MOV (immediate) 294 bool 295 EmulateMovRdImm (ARMEncoding encoding); 296 297 // MVN (immediate) 298 bool 299 EmulateMvnRdImm (ARMEncoding encoding); 300 301 bool 302 EmulateCmpRnImm (ARMEncoding encoding); 303 304 bool 305 EmulateCmpRnRm (ARMEncoding encoding); 306 307 // A8.6.14 ASR (immediate) 308 bool 309 EmulateASRImm (ARMEncoding encoding); 310 311 bool 312 EmulateLDM (ARMEncoding encoding); 313 314 bool 315 EmulateLDMDA (ARMEncoding encoding); 316 317 bool 318 EmulateLDMDB (ARMEncoding encoding); 319 320 bool 321 EmulateLDMIB (ARMEncoding encoding); 322 323 bool 324 EmulateLDRRtRnImm (ARMEncoding encoding); 325 326 bool 327 EmulateSTM (ARMEncoding encoding); 328 329 bool 330 EmulateSTMDA (ARMEncoding encoding); 331 332 bool 333 EmulateSTMDB (ARMEncoding encoding); 334 335 bool 336 EmulateSTMIB (ARMEncoding encoding); 337 338 uint32_t m_arm_isa; 339 Mode m_inst_mode; 340 uint32_t m_inst_cpsr; 341 uint32_t m_new_inst_cpsr; // This can get updated by the opcode. 342 ITSession m_it_session; 343}; 344 345} // namespace lldb_private 346 347#endif // lldb_EmulateInstructionARM_h_ 348