Disassembler.cpp revision adef06a71458ded0716935a61b3d43d164d4df12
1a3dcfb130044f306632a5fab43854eda4095a09cChris Lattner//===- Disassembler.cpp - Disassembler for hex strings --------------------===// 2ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// 3ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// The LLVM Compiler Infrastructure 4ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// 5ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// This file is distributed under the University of Illinois Open Source 6ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// License. See LICENSE.TXT for details. 7ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// 8ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan//===----------------------------------------------------------------------===// 9ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// 10ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// This class implements the disassembler of strings of bytes written in 11ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// hexadecimal, from standard input or from a file. 12ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan// 13ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan//===----------------------------------------------------------------------===// 14ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 15a3dcfb130044f306632a5fab43854eda4095a09cChris Lattner#include "Disassembler.h" 16847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner#include "../../lib/MC/MCDisassembler/EDDisassembler.h" 17847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner#include "../../lib/MC/MCDisassembler/EDInst.h" 18847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner#include "../../lib/MC/MCDisassembler/EDOperand.h" 19847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner#include "../../lib/MC/MCDisassembler/EDToken.h" 20ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCAsmInfo.h" 21ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCDisassembler.h" 22ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCInst.h" 23ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCInstPrinter.h" 24b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy#include "llvm/MC/MCSubtargetInfo.h" 25847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner#include "llvm/ADT/OwningPtr.h" 26847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner#include "llvm/ADT/Triple.h" 27d1e1703c39742f3c9fc3d27a442ff59bbdbfb5aaBenjamin Kramer#include "llvm/ADT/Twine.h" 28ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/Support/MemoryBuffer.h" 29ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/Support/MemoryObject.h" 30c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner#include "llvm/Support/SourceMgr.h" 313e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 323e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/raw_ostream.h" 33ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananusing namespace llvm; 34ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 35665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattnertypedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy; 36665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner 37665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattnernamespace { 38ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananclass VectorMemoryObject : public MemoryObject { 39ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananprivate: 40665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner const ByteArrayTy &Bytes; 41ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananpublic: 42665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} 43f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 44665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner uint64_t getBase() const { return 0; } 45adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff uint64_t getExtent() const { return Bytes.size(); } 46ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 47adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff int readByte(uint64_t Addr, uint8_t *Byte) const { 482f867a63daf99dc27830d4442a574a790e02f27eRafael Espindola if (Addr >= getExtent()) 49ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan return -1; 50665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner *Byte = Bytes[Addr].first; 51ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan return 0; 52ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 53ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan}; 54665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner} 55ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 56c6ab1901f922c854c84e9e055cbc83601df80addDaniel Dunbarstatic bool PrintInsts(const MCDisassembler &DisAsm, 57d374087be5360a353a4239a155b1227057145f48Chris Lattner MCInstPrinter &Printer, const ByteArrayTy &Bytes, 58d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman SourceMgr &SM, raw_ostream &Out) { 59ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan // Wrap the vector in a MemoryObject. 60665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner VectorMemoryObject memoryObject(Bytes); 61f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 622e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan // Disassemble it to strings. 63665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner uint64_t Size; 642e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan uint64_t Index; 65f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 662e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan for (Index = 0; Index < Bytes.size(); Index += Size) { 672e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan MCInst Inst; 68f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 6983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson MCDisassembler::DecodeStatus S; 7083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson S = DisAsm.getInstruction(Inst, Size, memoryObject, Index, 7198c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson /*REMOVE*/ nulls(), nulls()); 7283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson switch (S) { 7383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson case MCDisassembler::Fail: 742e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), 753f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Warning, 763f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid instruction encoding"); 772e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan if (Size == 0) 782e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan Size = 1; // skip illegible bytes 7983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson break; 8083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 8183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson case MCDisassembler::SoftFail: 8283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), 833f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SourceMgr::DK_Warning, 843f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "potentially undefined instruction encoding"); 8583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson // Fall through 8683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 8783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson case MCDisassembler::Success: 8898c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson Printer.printInst(&Inst, Out, ""); 8983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Out << "\n"; 9083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson break; 912e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan } 92ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 93f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 94665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner return false; 95ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan} 96ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 97f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbachstatic bool ByteArrayFromString(ByteArrayTy &ByteArray, 98f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach StringRef &Str, 99668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan SourceMgr &SM) { 100222af464822c9c47b2859e813912ed6ba5339217Chris Lattner while (!Str.empty()) { 1012adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner // Strip horizontal whitespace. 1022adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner if (size_t Pos = Str.find_first_not_of(" \t\r")) { 1032adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(Pos); 1042adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner continue; 1052adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner } 106f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 1072e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan // If this is the end of a line or start of a comment, remove the rest of 1082e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan // the line. 1092adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner if (Str[0] == '\n' || Str[0] == '#') { 1102adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner // Strip to the end of line if we already processed any bytes on this 1112adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner // line. This strips the comment and/or the \n. 112668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan if (Str[0] == '\n') { 1132adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(1); 114668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } else { 1152adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(Str.find_first_of('\n')); 1162adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner if (!Str.empty()) 1172adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(1); 1182adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner } 1192adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner continue; 120ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 121f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 122ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan // Get the current token. 1232adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner size_t Next = Str.find_first_of(" \t\n\r#"); 1242adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner StringRef Value = Str.substr(0, Next); 125f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 126ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan // Convert to a byte and add to the byte vector. 127222af464822c9c47b2859e813912ed6ba5339217Chris Lattner unsigned ByteVal; 128222af464822c9c47b2859e813912ed6ba5339217Chris Lattner if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) { 129c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner // If we have an error, print it and skip to the end of line. 1303f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error, 1313f2d5f60b31fd057c10f77b2e607b23a8c94f6d3Chris Lattner "invalid input token"); 132c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner Str = Str.substr(Str.find('\n')); 133c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner ByteArray.clear(); 134c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner continue; 135ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 136f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 137665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); 138222af464822c9c47b2859e813912ed6ba5339217Chris Lattner Str = Str.substr(Next); 139ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 140f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 141668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return false; 142668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan} 143668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan 144b262799d49891b036daa00eddf51947487346c98Evan Chengint Disassembler::disassemble(const Target &T, 145a5c177e70a42f48e4885075c4c48aad0816a2817Bill Wendling const std::string &Triple, 146b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy const std::string &Cpu, 147b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy const std::string &FeaturesStr, 148d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman MemoryBuffer &Buffer, 149d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman raw_ostream &Out) { 150668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan // Set up disassembler. 1511abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng OwningPtr<const MCAsmInfo> AsmInfo(T.createMCAsmInfo(Triple)); 152f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 153668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan if (!AsmInfo) { 154668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan errs() << "error: no assembly info for target " << Triple << "\n"; 155668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 156668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 157f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 158b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu, FeaturesStr)); 159b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy if (!STI) { 160b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy errs() << "error: no subtarget info for target " << Triple << "\n"; 161b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy return -1; 162b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy } 163b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy 164b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI)); 165668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan if (!DisAsm) { 166668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan errs() << "error: no disassembler for target " << Triple << "\n"; 167668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 168668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 169f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 170f23c7692947cfa69934476979941e91e5d945daaChris Lattner int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 171b262799d49891b036daa00eddf51947487346c98Evan Cheng OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, 172b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy *AsmInfo, *STI)); 173668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan if (!IP) { 174668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan errs() << "error: no instruction printer for target " << Triple << '\n'; 175668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 176668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 177f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 178668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan bool ErrorOccurred = false; 179f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 180668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan SourceMgr SM; 181668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan SM.AddNewSourceBuffer(&Buffer, SMLoc()); 182f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 183668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan // Convert the input to a vector for disassembly. 184668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan ByteArrayTy ByteArray; 185668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan StringRef Str = Buffer.getBuffer(); 186f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 187668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM); 188f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 189222af464822c9c47b2859e813912ed6ba5339217Chris Lattner if (!ByteArray.empty()) 190d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM, Out); 191f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 192665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner return ErrorOccurred; 193ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan} 194668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan 195668b15467be158a5f0e0c4a5e1ec232da021892cSean Callananstatic int byteArrayReader(uint8_t *B, uint64_t A, void *Arg) { 196668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan ByteArrayTy &ByteArray = *((ByteArrayTy*)Arg); 197f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 198668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan if (A >= ByteArray.size()) 199668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 200f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 201668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan *B = ByteArray[A].first; 202f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 203668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return 0; 204668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan} 205668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan 206668b15467be158a5f0e0c4a5e1ec232da021892cSean Callananstatic int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) { 207d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman EDDisassembler &disassembler = *(EDDisassembler *)((void **)Arg)[0]; 208d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman raw_ostream &Out = *(raw_ostream *)((void **)Arg)[1]; 209f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 210847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner if (const char *regName = disassembler.nameWithRegisterID(R)) 211d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman Out << "[" << regName << "/" << R << "]"; 212f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 213847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner if (disassembler.registerIsStackPointer(R)) 214d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman Out << "(sp)"; 215847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner if (disassembler.registerIsProgramCounter(R)) 216d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman Out << "(pc)"; 217f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 218668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan *V = 0; 219668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return 0; 220668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan} 221668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan 222f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbachint Disassembler::disassembleEnhanced(const std::string &TS, 223d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman MemoryBuffer &Buffer, 224d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman raw_ostream &Out) { 225668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan ByteArrayTy ByteArray; 226668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan StringRef Str = Buffer.getBuffer(); 227668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan SourceMgr SM; 228f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 229668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan SM.AddNewSourceBuffer(&Buffer, SMLoc()); 230f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 231668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan if (ByteArrayFromString(ByteArray, Str, SM)) { 232668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 233668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 234f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 235668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan Triple T(TS); 236847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner EDDisassembler::AssemblySyntax AS; 237f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 238668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan switch (T.getArch()) { 239668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan default: 240668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan errs() << "error: no default assembly syntax for " << TS.c_str() << "\n"; 241668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 242668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan case Triple::arm: 243668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan case Triple::thumb: 244847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner AS = EDDisassembler::kEDAssemblySyntaxARMUAL; 245668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan break; 246668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan case Triple::x86: 247668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan case Triple::x86_64: 248847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner AS = EDDisassembler::kEDAssemblySyntaxX86ATT; 249668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan break; 250668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 251f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 252f26be1e9652dd6a05797986aaaaef041a82545f4Benjamin Kramer OwningPtr<EDDisassembler> 253f26be1e9652dd6a05797986aaaaef041a82545f4Benjamin Kramer disassembler(EDDisassembler::getDisassembler(TS.c_str(), AS)); 254f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 255847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner if (disassembler == 0) { 256847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner errs() << "error: couldn't get disassembler for " << TS << '\n'; 257668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 258668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 259f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2603894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan while (ByteArray.size()) { 261f26be1e9652dd6a05797986aaaaef041a82545f4Benjamin Kramer OwningPtr<EDInst> 262f26be1e9652dd6a05797986aaaaef041a82545f4Benjamin Kramer inst(disassembler->createInst(byteArrayReader, 0, &ByteArray)); 263f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2643894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (inst == 0) { 2653894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: Didn't get an instruction\n"; 266668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 267668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 268052aa2c256acebab662b6099b155057d4092c3cfSean Callanan 269052aa2c256acebab662b6099b155057d4092c3cfSean Callanan ByteArray.erase (ByteArray.begin(), ByteArray.begin() + inst->byteSize()); 270f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2713894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan unsigned numTokens = inst->numTokens(); 2723894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if ((int)numTokens < 0) { 2733894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: couldn't count the instruction's tokens\n"; 274668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 275668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 276f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2773894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) { 2783894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan EDToken *token; 279f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2803894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (inst->getToken(token, tokenIndex)) { 2813894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: Couldn't get token\n"; 282668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 283668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 284f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2853894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan const char *buf; 2863894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (token->getString(buf)) { 2873894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: Couldn't get string for token\n"; 288668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 289668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 290f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2913894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << '['; 2923894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan int operandIndex = token->operandID(); 293f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2943894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (operandIndex >= 0) 2953894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << operandIndex << "-"; 296f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 2973894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan switch (token->type()) { 2983894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan case EDToken::kTokenWhitespace: Out << "w"; break; 2993894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan case EDToken::kTokenPunctuation: Out << "p"; break; 3003894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan case EDToken::kTokenOpcode: Out << "o"; break; 3013894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan case EDToken::kTokenLiteral: Out << "l"; break; 3023894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan case EDToken::kTokenRegister: Out << "r"; break; 3033894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan } 304f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3053894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << ":" << buf; 306f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3073894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (token->type() == EDToken::kTokenLiteral) { 3083894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "="; 3093894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (token->literalSign()) 3103894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "-"; 3113894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan uint64_t absoluteValue; 3123894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (token->literalAbsoluteValue(absoluteValue)) { 3133894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: Couldn't get the value of a literal token\n"; 3143894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan return -1; 3153894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan } 3163894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << absoluteValue; 3173894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan } else if (token->type() == EDToken::kTokenRegister) { 3183894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "="; 3193894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan unsigned regID; 3203894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (token->registerID(regID)) { 3213894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: Couldn't get the ID of a register token\n"; 3223894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan return -1; 3233894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan } 3243894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "r" << regID; 3253894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan } 326f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3273894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "]"; 328668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 329f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3303894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << " "; 331f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3323894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (inst->isBranch()) 3333894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "<br> "; 3343894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (inst->isMove()) 3353894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "<mov> "; 336f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3373894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan unsigned numOperands = inst->numOperands(); 338f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3393894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if ((int)numOperands < 0) { 3403894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: Couldn't count operands\n"; 341668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return -1; 342668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 343f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 344f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach for (unsigned operandIndex = 0; operandIndex != numOperands; 345f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach ++operandIndex) { 3463894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << operandIndex << ":"; 347f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3483894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan EDOperand *operand; 3493894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (inst->getOperand(operand, operandIndex)) { 3503894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: couldn't get operand\n"; 3513894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan return -1; 3523894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan } 353f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3543894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan uint64_t evaluatedResult; 355f26be1e9652dd6a05797986aaaaef041a82545f4Benjamin Kramer void *Arg[] = { disassembler.get(), &Out }; 3563894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan if (operand->evaluate(evaluatedResult, verboseEvaluator, Arg)) { 3573894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan errs() << "error: Couldn't evaluate an operand\n"; 3583894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan return -1; 3593894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan } 3603894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << "=" << evaluatedResult << " "; 361b21e49c8fe241965716511013e0aed35970ecdb1Sean Callanan } 362f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 3633894a795e6283b4b62ccf7b20d69eebd49e8532fSean Callanan Out << '\n'; 364668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan } 365f5bf3cf7e2a0ff1ca884a83a8b56b5a57f8a5c80Jim Grosbach 366668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan return 0; 367668b15467be158a5f0e0c4a5e1ec232da021892cSean Callanan} 368