Disassembler.cpp revision d374087be5360a353a4239a155b1227057145f48
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" 16ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 17ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/ADT/OwningPtr.h" 18ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCAsmInfo.h" 19ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCDisassembler.h" 20ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCInst.h" 21ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/MC/MCInstPrinter.h" 22ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/Target/TargetRegistry.h" 23ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/Support/MemoryBuffer.h" 24ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/Support/MemoryObject.h" 25ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan#include "llvm/Support/raw_ostream.h" 26c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner#include "llvm/Support/SourceMgr.h" 27ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananusing namespace llvm; 28ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 29665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattnertypedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy; 30665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner 31665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattnernamespace { 32ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananclass VectorMemoryObject : public MemoryObject { 33ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananprivate: 34665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner const ByteArrayTy &Bytes; 35ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callananpublic: 36665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} 37ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 38665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner uint64_t getBase() const { return 0; } 39665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner uint64_t getExtent() const { return Bytes.size(); } 40ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 41665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner int readByte(uint64_t Addr, uint8_t *Byte) const { 42665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner if (Addr > getExtent()) 43ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan return -1; 44665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner *Byte = Bytes[Addr].first; 45ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan return 0; 46ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 47ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan}; 48665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner} 49ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 50c6ab1901f922c854c84e9e055cbc83601df80addDaniel Dunbarstatic bool PrintInsts(const MCDisassembler &DisAsm, 51d374087be5360a353a4239a155b1227057145f48Chris Lattner MCInstPrinter &Printer, const ByteArrayTy &Bytes, 52d374087be5360a353a4239a155b1227057145f48Chris Lattner SourceMgr &SM) { 53ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan // Wrap the vector in a MemoryObject. 54665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner VectorMemoryObject memoryObject(Bytes); 55ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 562e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan // Disassemble it to strings. 57665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner uint64_t Size; 582e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan uint64_t Index; 59ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 602e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan for (Index = 0; Index < Bytes.size(); Index += Size) { 612e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan MCInst Inst; 622e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan 632e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan if (DisAsm.getInstruction(Inst, Size, memoryObject, Index, 642e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan /*REMOVE*/ nulls())) { 65d374087be5360a353a4239a155b1227057145f48Chris Lattner Printer.printInst(&Inst, outs()); 662e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan outs() << "\n"; 672e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan } 682e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan else { 692e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), 702e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan "invalid instruction encoding", "warning"); 712e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan if (Size == 0) 722e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan Size = 1; // skip illegible bytes 732e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan } 74ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 75665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner 76665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner return false; 77ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan} 78ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 79a3dcfb130044f306632a5fab43854eda4095a09cChris Lattnerint Disassembler::disassemble(const Target &T, const std::string &Triple, 80c6ab1901f922c854c84e9e055cbc83601df80addDaniel Dunbar MemoryBuffer &Buffer) { 81222af464822c9c47b2859e813912ed6ba5339217Chris Lattner // Set up disassembler. 82c6ab1901f922c854c84e9e055cbc83601df80addDaniel Dunbar OwningPtr<const MCAsmInfo> AsmInfo(T.createAsmInfo(Triple)); 83ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 84222af464822c9c47b2859e813912ed6ba5339217Chris Lattner if (!AsmInfo) { 85222af464822c9c47b2859e813912ed6ba5339217Chris Lattner errs() << "error: no assembly info for target " << Triple << "\n"; 86ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan return -1; 87ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 88ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 89c6ab1901f922c854c84e9e055cbc83601df80addDaniel Dunbar OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler()); 90222af464822c9c47b2859e813912ed6ba5339217Chris Lattner if (!DisAsm) { 91222af464822c9c47b2859e813912ed6ba5339217Chris Lattner errs() << "error: no disassembler for target " << Triple << "\n"; 92ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan return -1; 93ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 94ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 95d374087be5360a353a4239a155b1227057145f48Chris Lattner OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(0, *AsmInfo)); 96c6ab1901f922c854c84e9e055cbc83601df80addDaniel Dunbar if (!IP) { 97665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner errs() << "error: no instruction printer for target " << Triple << '\n'; 98ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan return -1; 99ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 100ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 101665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner bool ErrorOccurred = false; 102665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner 103665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner SourceMgr SM; 104665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner SM.AddNewSourceBuffer(&Buffer, SMLoc()); 105c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner 106ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan // Convert the input to a vector for disassembly. 107665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner ByteArrayTy ByteArray; 108ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 109222af464822c9c47b2859e813912ed6ba5339217Chris Lattner StringRef Str = Buffer.getBuffer(); 110222af464822c9c47b2859e813912ed6ba5339217Chris Lattner while (!Str.empty()) { 1112adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner // Strip horizontal whitespace. 1122adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner if (size_t Pos = Str.find_first_not_of(" \t\r")) { 1132adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(Pos); 1142adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner continue; 1152adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner } 1162adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner 1172e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan // If this is the end of a line or start of a comment, remove the rest of 1182e235a826d2f65a064b2a39b27c775d0adf8b7c3Sean Callanan // the line. 1192adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner if (Str[0] == '\n' || Str[0] == '#') { 1202adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner // Strip to the end of line if we already processed any bytes on this 1212adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner // line. This strips the comment and/or the \n. 1222adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner if (Str[0] == '\n') 1232adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(1); 1242adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner else { 1252adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(Str.find_first_of('\n')); 1262adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner if (!Str.empty()) 1272adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner Str = Str.substr(1); 1282adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner } 1292adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner continue; 130ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 131ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 132ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan // Get the current token. 1332adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner size_t Next = Str.find_first_of(" \t\n\r#"); 1342adbef06a637b367f724d0a46f7fa78d5827ec64Chris Lattner StringRef Value = Str.substr(0, Next); 135ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 136ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan // Convert to a byte and add to the byte vector. 137222af464822c9c47b2859e813912ed6ba5339217Chris Lattner unsigned ByteVal; 138222af464822c9c47b2859e813912ed6ba5339217Chris Lattner if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) { 139c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner // If we have an error, print it and skip to the end of line. 140665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner SM.PrintMessage(SMLoc::getFromPointer(Value.data()), 141c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner "invalid input token", "error"); 142665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner ErrorOccurred = true; 143c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner Str = Str.substr(Str.find('\n')); 144c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner ByteArray.clear(); 145c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner continue; 146ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 147c3de94fabf3858ad57373171fa6bda407f2224c9Chris Lattner 148665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); 149222af464822c9c47b2859e813912ed6ba5339217Chris Lattner Str = Str.substr(Next); 150ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan } 151ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 152222af464822c9c47b2859e813912ed6ba5339217Chris Lattner if (!ByteArray.empty()) 153c6ab1901f922c854c84e9e055cbc83601df80addDaniel Dunbar ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM); 154ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan 155665e947740bb1909f9c3dc60927e8b9620d644e5Chris Lattner return ErrorOccurred; 156ba847da571354e13f1caa3699ee06b2d57df9fe9Sean Callanan} 157