1 //===-- Disassembler.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 liblldb_Disassembler_h_ 11 #define liblldb_Disassembler_h_ 12 13 // C Includes 14 // C++ Includes 15 #include <vector> 16 #include <string> 17 18 // Other libraries and framework includes 19 // Project includes 20 #include "lldb/lldb-private.h" 21 #include "lldb/Core/Address.h" 22 #include "lldb/Core/ArchSpec.h" 23 #include "lldb/Core/EmulateInstruction.h" 24 #include "lldb/Core/Opcode.h" 25 #include "lldb/Core/PluginInterface.h" 26 #include "lldb/Interpreter/OptionValue.h" 27 28 namespace lldb_private { 29 30 class Instruction 31 { 32 public: 33 Instruction (const Address &address, 34 lldb::AddressClass addr_class = lldb::eAddressClassInvalid); 35 36 virtual 37 ~Instruction(); 38 39 const Address & GetAddress()40 GetAddress () const 41 { 42 return m_address; 43 } 44 45 const char * GetMnemonic(const ExecutionContext * exe_ctx)46 GetMnemonic (const ExecutionContext* exe_ctx) 47 { 48 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 49 return m_opcode_name.c_str(); 50 } 51 const char * GetOperands(const ExecutionContext * exe_ctx)52 GetOperands (const ExecutionContext* exe_ctx) 53 { 54 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 55 return m_mnemonics.c_str(); 56 } 57 58 const char * GetComment(const ExecutionContext * exe_ctx)59 GetComment (const ExecutionContext* exe_ctx) 60 { 61 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 62 return m_comment.c_str(); 63 } 64 65 virtual void 66 CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx) = 0; 67 68 lldb::AddressClass 69 GetAddressClass (); 70 71 void SetAddress(const Address & addr)72 SetAddress (const Address &addr) 73 { 74 // Invalidate the address class to lazily discover 75 // it if we need to. 76 m_address_class = lldb::eAddressClassInvalid; 77 m_address = addr; 78 } 79 80 virtual void 81 Dump (Stream *s, 82 uint32_t max_opcode_byte_size, 83 bool show_address, 84 bool show_bytes, 85 const ExecutionContext* exe_ctx); 86 87 virtual bool 88 DoesBranch () = 0; 89 90 virtual size_t 91 Decode (const Disassembler &disassembler, 92 const DataExtractor& data, 93 lldb::offset_t data_offset) = 0; 94 95 virtual void SetDescription(const char *)96 SetDescription (const char *) {} // May be overridden in sub-classes that have descriptions. 97 98 lldb::OptionValueSP 99 ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type); 100 101 lldb::OptionValueSP 102 ReadDictionary (FILE *in_file, Stream *out_stream); 103 104 bool 105 DumpEmulation (const ArchSpec &arch); 106 107 virtual bool 108 TestEmulation (Stream *stream, const char *test_file_name); 109 110 bool 111 Emulate (const ArchSpec &arch, 112 uint32_t evaluate_options, 113 void *baton, 114 EmulateInstruction::ReadMemoryCallback read_mem_callback, 115 EmulateInstruction::WriteMemoryCallback write_mem_calback, 116 EmulateInstruction::ReadRegisterCallback read_reg_callback, 117 EmulateInstruction::WriteRegisterCallback write_reg_callback); 118 119 const Opcode & GetOpcode()120 GetOpcode () const 121 { 122 return m_opcode; 123 } 124 125 uint32_t 126 GetData (DataExtractor &data); 127 128 protected: 129 Address m_address; // The section offset address of this instruction 130 // We include an address class in the Instruction class to 131 // allow the instruction specify the eAddressClassCodeAlternateISA 132 // (currently used for thumb), and also to specify data (eAddressClassData). 133 // The usual value will be eAddressClassCode, but often when 134 // disassembling memory, you might run into data. This can 135 // help us to disassemble appropriately. 136 private: 137 lldb::AddressClass m_address_class; // Use GetAddressClass () accessor function! 138 protected: 139 Opcode m_opcode; // The opcode for this instruction 140 std::string m_opcode_name; 141 std::string m_mnemonics; 142 std::string m_comment; 143 bool m_calculated_strings; 144 145 void CalculateMnemonicOperandsAndCommentIfNeeded(const ExecutionContext * exe_ctx)146 CalculateMnemonicOperandsAndCommentIfNeeded (const ExecutionContext* exe_ctx) 147 { 148 if (!m_calculated_strings) 149 { 150 m_calculated_strings = true; 151 CalculateMnemonicOperandsAndComment(exe_ctx); 152 } 153 } 154 }; 155 156 157 class InstructionList 158 { 159 public: 160 InstructionList(); 161 ~InstructionList(); 162 163 size_t 164 GetSize() const; 165 166 uint32_t 167 GetMaxOpcocdeByteSize () const; 168 169 lldb::InstructionSP 170 GetInstructionAtIndex (size_t idx) const; 171 172 uint32_t 173 GetIndexOfNextBranchInstruction(uint32_t start) const; 174 175 uint32_t 176 GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target); 177 178 void 179 Clear(); 180 181 void 182 Append (lldb::InstructionSP &inst_sp); 183 184 void 185 Dump (Stream *s, 186 bool show_address, 187 bool show_bytes, 188 const ExecutionContext* exe_ctx); 189 190 private: 191 typedef std::vector<lldb::InstructionSP> collection; 192 typedef collection::iterator iterator; 193 typedef collection::const_iterator const_iterator; 194 195 collection m_instructions; 196 }; 197 198 class PseudoInstruction : 199 public Instruction 200 { 201 public: 202 203 PseudoInstruction (); 204 205 virtual 206 ~PseudoInstruction (); 207 208 virtual bool 209 DoesBranch (); 210 211 virtual void CalculateMnemonicOperandsAndComment(const ExecutionContext * exe_ctx)212 CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx) 213 { 214 // TODO: fill this in and put opcode name into Instruction::m_opcode_name, 215 // mnemonic into Instruction::m_mnemonics, and any comment into 216 // Instruction::m_comment 217 } 218 219 virtual size_t 220 Decode (const Disassembler &disassembler, 221 const DataExtractor &data, 222 lldb::offset_t data_offset); 223 224 void 225 SetOpcode (size_t opcode_size, void *opcode_data); 226 227 virtual void 228 SetDescription (const char *description); 229 230 protected: 231 std::string m_description; 232 233 DISALLOW_COPY_AND_ASSIGN (PseudoInstruction); 234 }; 235 236 class Disassembler : 237 public std::enable_shared_from_this<Disassembler>, 238 public PluginInterface 239 { 240 public: 241 242 enum 243 { 244 eOptionNone = 0u, 245 eOptionShowBytes = (1u << 0), 246 eOptionRawOuput = (1u << 1), 247 eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only) 248 eOptionMarkPCAddress = (1u << 3) // Mark the disassembly line the contains the PC 249 }; 250 251 enum HexImmediateStyle 252 { 253 eHexStyleC, 254 eHexStyleAsm, 255 }; 256 257 // FindPlugin should be lax about the flavor string (it is too annoying to have various internal uses of the 258 // disassembler fail because the global flavor string gets set wrong. Instead, if you get a flavor string you 259 // don't understand, use the default. Folks who care to check can use the FlavorValidForArchSpec method on the 260 // disassembler they got back. 261 static lldb::DisassemblerSP 262 FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name); 263 264 // This version will use the value in the Target settings if flavor is NULL; 265 static lldb::DisassemblerSP 266 FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name); 267 268 static lldb::DisassemblerSP 269 DisassembleRange (const ArchSpec &arch, 270 const char *plugin_name, 271 const char *flavor, 272 const ExecutionContext &exe_ctx, 273 const AddressRange &disasm_range); 274 275 static lldb::DisassemblerSP 276 DisassembleBytes (const ArchSpec &arch, 277 const char *plugin_name, 278 const char *flavor, 279 const Address &start, 280 const void *bytes, 281 size_t length, 282 uint32_t max_num_instructions, 283 bool data_from_file); 284 285 static bool 286 Disassemble (Debugger &debugger, 287 const ArchSpec &arch, 288 const char *plugin_name, 289 const char *flavor, 290 const ExecutionContext &exe_ctx, 291 const AddressRange &range, 292 uint32_t num_instructions, 293 uint32_t num_mixed_context_lines, 294 uint32_t options, 295 Stream &strm); 296 297 static bool 298 Disassemble (Debugger &debugger, 299 const ArchSpec &arch, 300 const char *plugin_name, 301 const char *flavor, 302 const ExecutionContext &exe_ctx, 303 const Address &start, 304 uint32_t num_instructions, 305 uint32_t num_mixed_context_lines, 306 uint32_t options, 307 Stream &strm); 308 309 static size_t 310 Disassemble (Debugger &debugger, 311 const ArchSpec &arch, 312 const char *plugin_name, 313 const char *flavor, 314 const ExecutionContext &exe_ctx, 315 SymbolContextList &sc_list, 316 uint32_t num_instructions, 317 uint32_t num_mixed_context_lines, 318 uint32_t options, 319 Stream &strm); 320 321 static bool 322 Disassemble (Debugger &debugger, 323 const ArchSpec &arch, 324 const char *plugin_name, 325 const char *flavor, 326 const ExecutionContext &exe_ctx, 327 const ConstString &name, 328 Module *module, 329 uint32_t num_instructions, 330 uint32_t num_mixed_context_lines, 331 uint32_t options, 332 Stream &strm); 333 334 static bool 335 Disassemble (Debugger &debugger, 336 const ArchSpec &arch, 337 const char *plugin_name, 338 const char *flavor, 339 const ExecutionContext &exe_ctx, 340 uint32_t num_instructions, 341 uint32_t num_mixed_context_lines, 342 uint32_t options, 343 Stream &strm); 344 345 //------------------------------------------------------------------ 346 // Constructors and Destructors 347 //------------------------------------------------------------------ 348 Disassembler(const ArchSpec &arch, const char *flavor); 349 virtual ~Disassembler(); 350 351 typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data); 352 353 static bool 354 PrintInstructions (Disassembler *disasm_ptr, 355 Debugger &debugger, 356 const ArchSpec &arch, 357 const ExecutionContext &exe_ctx, 358 uint32_t num_instructions, 359 uint32_t num_mixed_context_lines, 360 uint32_t options, 361 Stream &strm); 362 363 size_t 364 ParseInstructions (const ExecutionContext *exe_ctx, 365 const AddressRange &range, 366 Stream *error_strm_ptr, 367 bool prefer_file_cache); 368 369 size_t 370 ParseInstructions (const ExecutionContext *exe_ctx, 371 const Address &range, 372 uint32_t num_instructions, 373 bool prefer_file_cache); 374 375 virtual size_t 376 DecodeInstructions (const Address &base_addr, 377 const DataExtractor& data, 378 lldb::offset_t data_offset, 379 size_t num_instructions, 380 bool append, 381 bool data_from_file) = 0; 382 383 InstructionList & 384 GetInstructionList (); 385 386 const InstructionList & 387 GetInstructionList () const; 388 389 const ArchSpec & GetArchitecture()390 GetArchitecture () const 391 { 392 return m_arch; 393 } 394 395 const char * GetFlavor()396 GetFlavor () const 397 { 398 return m_flavor.c_str(); 399 } 400 401 virtual bool 402 FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0; 403 404 protected: 405 //------------------------------------------------------------------ 406 // Classes that inherit from Disassembler can see and modify these 407 //------------------------------------------------------------------ 408 const ArchSpec m_arch; 409 InstructionList m_instruction_list; 410 lldb::addr_t m_base_addr; 411 std::string m_flavor; 412 413 private: 414 //------------------------------------------------------------------ 415 // For Disassembler only 416 //------------------------------------------------------------------ 417 DISALLOW_COPY_AND_ASSIGN (Disassembler); 418 }; 419 420 } // namespace lldb_private 421 422 #endif // liblldb_Disassembler_h_ 423