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" 2517463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper#include "llvm/MC/MCInstrInfo.h" 260e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 27ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCStreamer.h" 28ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng#include "llvm/MC/MCSubtargetInfo.h" 29ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/AsmLexer.h" 30ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCAsmParser.h" 31ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 3294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmLexer.h" 3394b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 34ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryBuffer.h" 35ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryObject.h" 36ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/SourceMgr.h" 373e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 38ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananusing namespace llvm; 39ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 40ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers; 41ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 429899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstruct TripleMap { 43ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan Triple::ArchType Arch; 44ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan const char *String; 45ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}; 46ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 47e32981048244ecfa67d0bdc211af1bac2020a555Craig Topperstatic const struct TripleMap triplemap[] = { 489899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::x86, "i386-unknown-unknown" }, 499899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::x86_64, "x86_64-unknown-unknown" }, 509899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan { Triple::arm, "arm-unknown-unknown" }, 51124e51c0d2b521b0fb3aaaf2443403cd451b7857Chandler Carruth { Triple::thumb, "thumb-unknown-unknown" } 52ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}; 53ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 549899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan/// infoFromArch - Returns the TripleMap corresponding to a given architecture, 55ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// or NULL if there is an error 56ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// 57ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch - The Triple::ArchType for the desired architecture 589899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstatic const char *tripleFromArch(Triple::ArchType arch) { 59ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan unsigned int infoIndex; 60ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 619899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan for (infoIndex = 0; triplemap[infoIndex].String != NULL; ++infoIndex) { 629899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan if (arch == triplemap[infoIndex].Arch) 639899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan return triplemap[infoIndex].String; 64ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 65ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 66ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 67ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 68ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 69ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer 70ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// for the desired assembly syntax, suitable for passing to 71ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// Target::createMCInstPrinter() 72ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// 73ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch - The target architecture 74ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg syntax - The assembly syntax in sd form 75ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananstatic int getLLVMSyntaxVariant(Triple::ArchType arch, 76847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner EDDisassembler::AssemblySyntax syntax) { 77ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan switch (syntax) { 78ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan // Mappings below from X86AsmPrinter.cpp 79847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner case EDDisassembler::kEDAssemblySyntaxX86ATT: 80ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (arch == Triple::x86 || arch == Triple::x86_64) 81ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 82e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer break; 83847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner case EDDisassembler::kEDAssemblySyntaxX86Intel: 84ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (arch == Triple::x86 || arch == Triple::x86_64) 85ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 1; 86e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer break; 87847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner case EDDisassembler::kEDAssemblySyntaxARMUAL: 888f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (arch == Triple::arm || arch == Triple::thumb) 898f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan return 0; 90e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer break; 91ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 92e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer 93e4ad58272970ecd850d233862f40a72d15649639Benjamin Kramer return -1; 94ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 95ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 96ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch, 97847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner AssemblySyntax syntax) { 983f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan const char *triple = tripleFromArch(arch); 993f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan return getDisassembler(StringRef(triple), syntax); 1003f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan} 1013f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan 1023f4f34c7ba24c3703a0cddf778183f7d876ac83fSean CallananEDDisassembler *EDDisassembler::getDisassembler(StringRef str, 1033f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan AssemblySyntax syntax) { 104ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan CPUKey key; 1053f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan key.Triple = str.str(); 106ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan key.Syntax = syntax; 107b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles 108ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key); 109b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles 110ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (i != sDisassemblers.end()) { 1113f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan return i->second; 1123f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan } 113b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles 114b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles EDDisassembler *sdd = new EDDisassembler(key); 115b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles if (!sdd->valid()) { 116b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles delete sdd; 117b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles return NULL; 118ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 119b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles 120b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles sDisassemblers[key] = sdd; 121b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles 122b0934ab7d811e23bf530371976b8b35f3242169cAhmed Charles return sdd; 123ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 124ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 125ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::EDDisassembler(CPUKey &key) : 1268f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan Valid(false), 1278f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan HasSemantics(false), 1288f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan ErrorStream(nulls()), 1293f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan Key(key), 1303f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan TgtTriple(key.Triple.c_str()) { 131ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1323f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan LLVMSyntaxVariant = getLLVMSyntaxVariant(TgtTriple.getArch(), key.Syntax); 133ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1344285b294a86f507822b8c00d85888e78f69672e5Sean Callanan if (LLVMSyntaxVariant < 0) 135ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 136ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1373f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan std::string tripleString(key.Triple); 138ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan std::string errorString; 139ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1403f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan Tgt = TargetRegistry::lookupTarget(key.Triple, 141ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan errorString); 142ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 143ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!Tgt) 144ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 145ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1461b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng MRI.reset(Tgt->createMCRegInfo(tripleString)); 147ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1481b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng if (!MRI) 149ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 1501b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng 1511b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng initMaps(*MRI); 152ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 1531abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng AsmInfo.reset(Tgt->createMCAsmInfo(tripleString)); 154ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 155ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!AsmInfo) 156ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 157ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 158b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy STI.reset(Tgt->createMCSubtargetInfo(tripleString, "", "")); 159b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy 160b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy if (!STI) 161b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy return; 162b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy 163b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy Disassembler.reset(Tgt->createMCDisassembler(*STI)); 164ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 165ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!Disassembler) 166ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 1679899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan 1689899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan InstInfos = Disassembler->getEDInfo(); 16917463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper 17017463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper MII.reset(Tgt->createMCInstrInfo()); 17117463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper 17217463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper if (!MII) 17317463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper return; 17417463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper 175ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstString.reset(new std::string); 176ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstStream.reset(new raw_string_ostream(*InstString)); 177c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo, 17817463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper *MII, *MRI, *STI)); 179ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 180ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!InstPrinter) 181ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 182ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 183ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan GenericAsmLexer.reset(new AsmLexer(*AsmInfo)); 18494b9550a32d189704a8eae55505edf62662c0534Evan Cheng SpecificAsmLexer.reset(Tgt->createMCAsmLexer(*MRI, *AsmInfo)); 185ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SpecificAsmLexer->InstallLexer(*GenericAsmLexer); 186d74667e226c3053128f34c6f2c6c9ebfe5b98e50Sean Callanan 1871b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng initMaps(*MRI); 188ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 189ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan Valid = true; 190ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 191ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 192ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::~EDDisassembler() { 1938f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (!valid()) 194ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return; 195ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 196ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 197ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanannamespace { 198ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback 199ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan /// as provided by the sd interface. See MemoryObject. 200ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan class EDMemoryObject : public llvm::MemoryObject { 201ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan private: 202ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDByteReaderCallback Callback; 203ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan void *Arg; 204ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan public: 205ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDMemoryObject(EDByteReaderCallback callback, 206ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan void *arg) : Callback(callback), Arg(arg) { } 207ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ~EDMemoryObject() { } 208ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan uint64_t getBase() const { return 0x0; } 209adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff uint64_t getExtent() const { return (uint64_t)-1; } 210adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff int readByte(uint64_t address, uint8_t *ptr) const { 2118f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (!Callback) 212ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return -1; 213ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 2148f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (Callback(ptr, address, Arg)) 215ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return -1; 216ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 217ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 218ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 219ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan }; 220ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 221ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 222ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader, 223ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan uint64_t address, 224ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan void *arg) { 225ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan EDMemoryObject memoryObject(byteReader, arg); 226ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 227ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan MCInst* inst = new MCInst; 228ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan uint64_t byteSize; 229ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 230ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy MCDisassembler::DecodeStatus S; 231ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy S = Disassembler->getInstruction(*inst, byteSize, memoryObject, address, 23298c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson ErrorStream, nulls()); 233ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy switch (S) { 234ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy case MCDisassembler::Fail: 235ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy case MCDisassembler::SoftFail: 236c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy // FIXME: Do something different on soft failure mode? 237ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan delete inst; 238ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 239ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy 240ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy case MCDisassembler::Success: { 241ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy const llvm::EDInstInfo *thisInstInfo = NULL; 242833a003da082ab0db343e0e640069dfc6813e7d6Nick Lewycky 243ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy if (InstInfos) { 244ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy thisInstInfo = &InstInfos[inst->getOpcode()]; 245ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy } 246833a003da082ab0db343e0e640069dfc6813e7d6Nick Lewycky 247ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo); 248ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy return sdInst; 249ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy } 250ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy } 251ee06443945b4c9f471c9b80c4325075dbc27746eJames Molloy return NULL; 252ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 253ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 2541b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Chengvoid EDDisassembler::initMaps(const MCRegisterInfo ®isterInfo) { 255ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan unsigned numRegisters = registerInfo.getNumRegs(); 256ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan unsigned registerIndex; 257ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 258ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) { 259d5ce3ffa67698b9d21f58011f370a210a214d301Jakob Stoklund Olesen const char* registerName = registerInfo.getName(registerIndex); 260ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 261ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan RegVec.push_back(registerName); 262ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan RegRMap[registerName] = registerIndex; 263ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 264ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 2653f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan switch (TgtTriple.getArch()) { 2668f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan default: 2678f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 2688f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86: 2698f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86_64: 270ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan stackPointers.insert(registerIDWithName("SP")); 271ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan stackPointers.insert(registerIDWithName("ESP")); 272ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan stackPointers.insert(registerIDWithName("RSP")); 273ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 274ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan programCounters.insert(registerIDWithName("IP")); 275ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan programCounters.insert(registerIDWithName("EIP")); 276ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan programCounters.insert(registerIDWithName("RIP")); 2778f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 2788f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::arm: 2798f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::thumb: 2808f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan stackPointers.insert(registerIDWithName("SP")); 2818f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan 2828f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan programCounters.insert(registerIDWithName("PC")); 2838f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 284ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 285ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 286ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 287ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananconst char *EDDisassembler::nameWithRegisterID(unsigned registerID) const { 288ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (registerID >= RegVec.size()) 289ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return NULL; 290ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan else 291ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return RegVec[registerID].c_str(); 292ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 293ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 294ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananunsigned EDDisassembler::registerIDWithName(const char *name) const { 295ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan regrmap_t::const_iterator iter = RegRMap.find(std::string(name)); 296ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (iter == RegRMap.end()) 297ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 298ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan else 299ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return (*iter).second; 300ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 301ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 302ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsStackPointer(unsigned registerID) { 303ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return (stackPointers.find(registerID) != stackPointers.end()); 304ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 305ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 306ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsProgramCounter(unsigned registerID) { 307ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return (programCounters.find(registerID) != programCounters.end()); 308ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 309ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 310d374087be5360a353a4239a155b1227057145f48Chris Lattnerint EDDisassembler::printInst(std::string &str, MCInst &inst) { 311ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan PrinterMutex.acquire(); 312ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 31398c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson InstPrinter->printInst(&inst, *InstStream, ""); 314ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstStream->flush(); 315ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan str = *InstString; 316ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan InstString->clear(); 317ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 318ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan PrinterMutex.release(); 319ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 320ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return 0; 321ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 322ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 323d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattnerstatic void diag_handler(const SMDiagnostic &diag, void *context) { 324d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner if (context) 325d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner diag.print("", static_cast<EDDisassembler*>(context)->ErrorStream); 326457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan} 327457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan 328ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands, 329ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SmallVectorImpl<AsmToken> &tokens, 330ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan const std::string &str) { 331ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan int ret = 0; 332ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 3333f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan switch (TgtTriple.getArch()) { 3348f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan default: 3358f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan return -1; 3368f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86: 3378f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::x86_64: 3388f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::arm: 3398f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan case Triple::thumb: 3408f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan break; 3418f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan } 3428f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan 343ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan const char *cStr = str.c_str(); 344ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr)); 345ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 346ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan StringRef instName; 347ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SMLoc instLoc; 348ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 349ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SourceMgr sourceMgr; 350457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this)); 351ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over 352203576aa0cb9d8bf2d2e4d910ebab4b7a63262aeEvan Cheng MCContext context(*AsmInfo, *MRI, NULL); 353c18409aed80ba1c6c5998befd3c3c8edc865c423Chris Lattner OwningPtr<MCStreamer> streamer(createNullStreamer(context)); 3541b84cce77f8bccc905b4800927ce9016f76c1c40Jim Grosbach OwningPtr<MCAsmParser> genericParser(createMCAsmParser(sourceMgr, 3559fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar context, *streamer, 3569fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar *AsmInfo)); 357ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 3583f4f34c7ba24c3703a0cddf778183f7d876ac83fSean Callanan OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(Key.Triple.c_str(), "", "")); 35994b9550a32d189704a8eae55505edf62662c0534Evan Cheng OwningPtr<MCTargetAsmParser> 36094b9550a32d189704a8eae55505edf62662c0534Evan Cheng TargetParser(Tgt->createMCAsmParser(*STI, *genericParser)); 361ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 3629fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar AsmToken OpcodeToken = genericParser->Lex(); 3639fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar AsmToken NextToken = genericParser->Lex(); // consume next token, because specificParser expects us to 364a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan 3658f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan if (OpcodeToken.is(AsmToken::Identifier)) { 366ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan instName = OpcodeToken.getString(); 367ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan instLoc = OpcodeToken.getLoc(); 368a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan 369a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan if (NextToken.isNot(AsmToken::Eof) && 370a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan TargetParser->ParseInstruction(instName, instLoc, operands)) 371ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ret = -1; 3728f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan } else { 373ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ret = -1; 374ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 375ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 376ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ParserMutex.acquire(); 377ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 378ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (!ret) { 379ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan GenericAsmLexer->setBuffer(buf); 380ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 381ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan while (SpecificAsmLexer->Lex(), 382ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SpecificAsmLexer->isNot(AsmToken::Eof) && 383ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) { 384ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan if (SpecificAsmLexer->is(AsmToken::Error)) { 385ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ret = -1; 386ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan break; 387ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 388ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan tokens.push_back(SpecificAsmLexer->getTok()); 389ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 390ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan } 391ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 392ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan ParserMutex.release(); 393ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 394ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return ret; 395ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 396ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan 397ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::llvmSyntaxVariant() const { 398ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan return LLVMSyntaxVariant; 399ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan} 400