EDDisassembler.cpp revision 3e74d6fdd248e20a280f1dff3da9a6c689c2c4c3
1ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===-EDDisassembler.cpp - LLVM Enhanced Disassembler ---------------------===// 2ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// 3ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// The LLVM Compiler Infrastructure 4ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// 5ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// This file is distributed under the University of Illinois Open Source 6ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// License. See LICENSE.TXT for details. 7ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// 8ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===----------------------------------------------------------------------===// 9ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// 10ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// This file implements the Enhanced Disassembly library's disassembler class. 11ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// The disassembler is responsible for vending individual instructions according 12ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// to a given architecture and disassembly syntax. 13ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// 14ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===----------------------------------------------------------------------===// 15ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 168f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan#include "EDDisassembler.h" 178f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan#include "EDInst.h" 189899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan#include "llvm/MC/EDInstInfo.h" 19ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCAsmInfo.h" 20ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCContext.h" 21ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCDisassembler.h" 22ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCExpr.h" 23ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCInst.h" 24ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCInstPrinter.h" 250e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 26ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCStreamer.h" 27ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng#include "llvm/MC/MCSubtargetInfo.h" 28ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/AsmLexer.h" 29ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCAsmParser.h" 30ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmLexer.h" 3294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 33ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryBuffer.h" 34ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryObject.h" 35ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/SourceMgr.h" 363e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 373e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h" 38ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananusing namespace llvm; 39ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 40ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::sInitialized = false; 41ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers; 42ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 439899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstruct TripleMap { 44ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan Triple::ArchType Arch; 45ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan const char *String; 46ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}; 47ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 489899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstatic struct TripleMap triplemap[] = { 499899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::x86, "i386-unknown-unknown" }, 509899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::x86_64, "x86_64-unknown-unknown" }, 519899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::arm, "arm-unknown-unknown" }, 529899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::thumb, "thumb-unknown-unknown" }, 539899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::InvalidArch, NULL, } 54ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}; 55ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 569899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan/// infoFromArch - Returns the TripleMap corresponding to a given architecture, 57ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// or NULL if there is an error 58ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// 59ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch - The Triple::ArchType for the desired architecture 609899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstatic const char *tripleFromArch(Triple::ArchType arch) { 61ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan unsigned int infoIndex; 62ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 639899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan for (infoIndex = 0; triplemap[infoIndex].String != NULL; ++infoIndex) { 649899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan if (arch == triplemap[infoIndex].Arch) 659899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan return triplemap[infoIndex].String; 66ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 67ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 68ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 69ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 70ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 71ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer 72ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// for the desired assembly syntax, suitable for passing to 73ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// Target::createMCInstPrinter() 74ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// 75ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch - The target architecture 76ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg syntax - The assembly syntax in sd form 77ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananstatic int getLLVMSyntaxVariant(Triple::ArchType arch, 78847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner EDDisassembler::AssemblySyntax syntax) { 79ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan switch (syntax) { 80ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan default: 81ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return -1; 82ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan // Mappings below from X86AsmPrinter.cpp 83847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner case EDDisassembler::kEDAssemblySyntaxX86ATT: 84ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (arch == Triple::x86 || arch == Triple::x86_64) 85ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 86ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan else 87ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return -1; 88847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner case EDDisassembler::kEDAssemblySyntaxX86Intel: 89ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (arch == Triple::x86 || arch == Triple::x86_64) 90ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 1; 91ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan else 92ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return -1; 93847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner case EDDisassembler::kEDAssemblySyntaxARMUAL: 948f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (arch == Triple::arm || arch == Triple::thumb) 958f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan return 0; 968f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan else 978f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan return -1; 98ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 99ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 100ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 101ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananvoid EDDisassembler::initialize() { 102ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (sInitialized) 103ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 104ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 105ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan sInitialized = true; 106ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1079899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan InitializeAllTargetInfos(); 108e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng InitializeAllTargetMCs(); 1099899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan InitializeAllAsmParsers(); 1109899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan InitializeAllDisassemblers(); 111ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 112ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 113ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#undef BRINGUP_TARGET 114ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 115ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch, 116847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner AssemblySyntax syntax) { 117ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan CPUKey key; 118ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan key.Arch = arch; 119ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan key.Syntax = syntax; 120ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 121ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key); 122ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 123ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (i != sDisassemblers.end()) { 124ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return i->second; 1258f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan } else { 126ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDDisassembler* sdd = new EDDisassembler(key); 1278f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (!sdd->valid()) { 128ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan delete sdd; 129ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 130ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 131ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 132ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan sDisassemblers[key] = sdd; 133ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 134ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return sdd; 135ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 136ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 137ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 138ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 139ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 140ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler *EDDisassembler::getDisassembler(StringRef str, 141847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner AssemblySyntax syntax) { 142847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner return getDisassembler(Triple(str).getArch(), syntax); 143ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 144ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 145ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::EDDisassembler(CPUKey &key) : 1468f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan Valid(false), 1478f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan HasSemantics(false), 1488f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan ErrorStream(nulls()), 1498f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan Key(key) { 1509899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan const char *triple = tripleFromArch(key.Arch); 1518f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan 1529899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan if (!triple) 1539899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan return; 154ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1554285b294a86f507822b8c00d85888e78f69672e5Sean Callanan LLVMSyntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax); 156ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1574285b294a86f507822b8c00d85888e78f69672e5Sean Callanan if (LLVMSyntaxVariant < 0) 158ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 159ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 160ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan std::string tripleString(triple); 161ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan std::string errorString; 162ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 163ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan Tgt = TargetRegistry::lookupTarget(tripleString, 164ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan errorString); 165ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 166ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!Tgt) 167ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 168ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1691b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng MRI.reset(Tgt->createMCRegInfo(tripleString)); 170ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1711b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng if (!MRI) 172ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 1731b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng 1741b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng initMaps(*MRI); 175ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1761abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng AsmInfo.reset(Tgt->createMCAsmInfo(tripleString)); 177ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 178ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!AsmInfo) 179ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 180ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 181ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan Disassembler.reset(Tgt->createMCDisassembler()); 182ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 183ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!Disassembler) 184ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 1859899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan 1869899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan InstInfos = Disassembler->getEDInfo(); 187ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 188ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstString.reset(new std::string); 189ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstStream.reset(new raw_string_ostream(*InstString)); 190b262799d49891b036daa00eddf51947487346c98Evan Cheng InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo)); 191ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 192ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!InstPrinter) 193ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 194ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 195ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan GenericAsmLexer.reset(new AsmLexer(*AsmInfo)); 19694b9550a32d189704a8eae55505edf62662c0534Evan Cheng SpecificAsmLexer.reset(Tgt->createMCAsmLexer(*MRI, *AsmInfo)); 197ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SpecificAsmLexer->InstallLexer(*GenericAsmLexer); 198d74667e226c3053128f34c6f2c6c9ebfe5b98e50Sean Callanan 1991b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng initMaps(*MRI); 200ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 201ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan Valid = true; 202ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 203ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 204ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::~EDDisassembler() { 2058f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (!valid()) 206ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 207ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 208ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 209ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanannamespace { 210ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback 211ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan /// as provided by the sd interface. See MemoryObject. 212ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan class EDMemoryObject : public llvm::MemoryObject { 213ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan private: 214ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDByteReaderCallback Callback; 215ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan void *Arg; 216ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan public: 217ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDMemoryObject(EDByteReaderCallback callback, 218ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan void *arg) : Callback(callback), Arg(arg) { } 219ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ~EDMemoryObject() { } 220ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan uint64_t getBase() const { return 0x0; } 221ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan uint64_t getExtent() const { return (uint64_t)-1; } 222ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan int readByte(uint64_t address, uint8_t *ptr) const { 2238f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (!Callback) 224ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return -1; 225ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 2268f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (Callback(ptr, address, Arg)) 227ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return -1; 228ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 229ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 230ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 231ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan }; 232ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 233ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 234ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader, 235ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan uint64_t address, 236ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan void *arg) { 237ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDMemoryObject memoryObject(byteReader, arg); 238ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 239ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan MCInst* inst = new MCInst; 240ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan uint64_t byteSize; 241ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 242ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!Disassembler->getInstruction(*inst, 243ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan byteSize, 244ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan memoryObject, 245ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan address, 246ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ErrorStream)) { 247ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan delete inst; 248ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 2498f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan } else { 2500da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen const llvm::EDInstInfo *thisInstInfo = NULL; 2518f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan 2520da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen if (InstInfos) { 2530da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen thisInstInfo = &InstInfos[inst->getOpcode()]; 2540da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen } 255ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 256ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo); 257ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return sdInst; 258ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 259ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 260ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 2611b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Chengvoid EDDisassembler::initMaps(const MCRegisterInfo ®isterInfo) { 262ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan unsigned numRegisters = registerInfo.getNumRegs(); 263ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan unsigned registerIndex; 264ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 265ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) { 266ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan const char* registerName = registerInfo.get(registerIndex).Name; 267ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 268ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan RegVec.push_back(registerName); 269ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan RegRMap[registerName] = registerIndex; 270ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 271ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 2728f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan switch (Key.Arch) { 2738f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan default: 2748f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 2758f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86: 2768f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86_64: 277ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan stackPointers.insert(registerIDWithName("SP")); 278ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan stackPointers.insert(registerIDWithName("ESP")); 279ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan stackPointers.insert(registerIDWithName("RSP")); 280ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 281ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan programCounters.insert(registerIDWithName("IP")); 282ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan programCounters.insert(registerIDWithName("EIP")); 283ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan programCounters.insert(registerIDWithName("RIP")); 2848f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 2858f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::arm: 2868f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::thumb: 2878f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan stackPointers.insert(registerIDWithName("SP")); 2888f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan 2898f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan programCounters.insert(registerIDWithName("PC")); 2908f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 291ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 292ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 293ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 294ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananconst char *EDDisassembler::nameWithRegisterID(unsigned registerID) const { 295ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (registerID >= RegVec.size()) 296ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 297ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan else 298ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return RegVec[registerID].c_str(); 299ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 300ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 301ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananunsigned EDDisassembler::registerIDWithName(const char *name) const { 302ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan regrmap_t::const_iterator iter = RegRMap.find(std::string(name)); 303ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (iter == RegRMap.end()) 304ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 305ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan else 306ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return (*iter).second; 307ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 308ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 309ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsStackPointer(unsigned registerID) { 310ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return (stackPointers.find(registerID) != stackPointers.end()); 311ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 312ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 313ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsProgramCounter(unsigned registerID) { 314ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return (programCounters.find(registerID) != programCounters.end()); 315ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 316ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 317d374087be5360a353a4239a155b1227057145f48Chris Lattnerint EDDisassembler::printInst(std::string &str, MCInst &inst) { 318ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan PrinterMutex.acquire(); 319ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 320d374087be5360a353a4239a155b1227057145f48Chris Lattner InstPrinter->printInst(&inst, *InstStream); 321ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstStream->flush(); 322ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan str = *InstString; 323ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstString->clear(); 324ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 325ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan PrinterMutex.release(); 326ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 327ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 328ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 329ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 330457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callananstatic void diag_handler(const SMDiagnostic &diag, 331457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan void *context) 332457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan{ 333457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan if (context) { 334457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan EDDisassembler *disassembler = static_cast<EDDisassembler*>(context); 335457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan diag.Print("", disassembler->ErrorStream); 336457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan } 337457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan} 338457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan 339ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands, 340ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SmallVectorImpl<AsmToken> &tokens, 341ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan const std::string &str) { 342ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan int ret = 0; 343ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 3448f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan switch (Key.Arch) { 3458f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan default: 3468f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan return -1; 3478f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86: 3488f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86_64: 3498f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::arm: 3508f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::thumb: 3518f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 3528f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan } 3538f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan 354ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan const char *cStr = str.c_str(); 355ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr)); 356ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 357ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan StringRef instName; 358ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SMLoc instLoc; 359ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 360ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SourceMgr sourceMgr; 361457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this)); 362ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over 363203576aa0cb9d8bf2d2e4d910ebab4b7a63262aeEvan Cheng MCContext context(*AsmInfo, *MRI, NULL); 364c18409aed80ba1c6c5998befd3c3c8edc865c423Chris Lattner OwningPtr<MCStreamer> streamer(createNullStreamer(context)); 3651b84cce77f8bccc905b4800927ce9016f76c1c40Jim Grosbach OwningPtr<MCAsmParser> genericParser(createMCAsmParser(sourceMgr, 3669fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar context, *streamer, 3679fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar *AsmInfo)); 368ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 369ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng StringRef triple = tripleFromArch(Key.Arch); 370ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(triple, "", "")); 37194b9550a32d189704a8eae55505edf62662c0534Evan Cheng OwningPtr<MCTargetAsmParser> 37294b9550a32d189704a8eae55505edf62662c0534Evan Cheng TargetParser(Tgt->createMCAsmParser(*STI, *genericParser)); 373ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 3749fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar AsmToken OpcodeToken = genericParser->Lex(); 3759fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar AsmToken NextToken = genericParser->Lex(); // consume next token, because specificParser expects us to 376a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan 3778f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (OpcodeToken.is(AsmToken::Identifier)) { 378ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan instName = OpcodeToken.getString(); 379ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan instLoc = OpcodeToken.getLoc(); 380a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan 381a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan if (NextToken.isNot(AsmToken::Eof) && 382a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan TargetParser->ParseInstruction(instName, instLoc, operands)) 383ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ret = -1; 3848f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan } else { 385ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ret = -1; 386ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 387ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 388ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ParserMutex.acquire(); 389ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 390ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!ret) { 391ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan GenericAsmLexer->setBuffer(buf); 392ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 393ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan while (SpecificAsmLexer->Lex(), 394ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SpecificAsmLexer->isNot(AsmToken::Eof) && 395ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) { 396ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (SpecificAsmLexer->is(AsmToken::Error)) { 397ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ret = -1; 398ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan break; 399ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 400ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan tokens.push_back(SpecificAsmLexer->getTok()); 401ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 402ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 403ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 404ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ParserMutex.release(); 405ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 406ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return ret; 407ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 408ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 409ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::llvmSyntaxVariant() const { 410ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return LLVMSyntaxVariant; 411ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 412