X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-mc%2FDisassembler.cpp;h=06c7721d7e8ca251b8821eaf62531c71767118a2;hb=1b0dc64919e947bb4f4677b138c734e33061f7c4;hp=5fde71238dc93bcd9a2647541aa2ae2e7e769c39;hpb=a3dcfb130044f306632a5fab43854eda4095a09c;p=oota-llvm.git diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp index 5fde71238dc..06c7721d7e8 100644 --- a/tools/llvm-mc/Disassembler.cpp +++ b/tools/llvm-mc/Disassembler.cpp @@ -13,17 +13,18 @@ //===----------------------------------------------------------------------===// #include "Disassembler.h" - #include "llvm/ADT/OwningPtr.h" -#include "llvm/MC/MCAsmInfo.h" +#include "llvm/ADT/Triple.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstPrinter.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryObject.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" + using namespace llvm; typedef std::vector > ByteArrayTy; @@ -34,12 +35,12 @@ private: const ByteArrayTy &Bytes; public: VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} - + uint64_t getBase() const { return 0; } uint64_t getExtent() const { return Bytes.size(); } int readByte(uint64_t Addr, uint8_t *Byte) const { - if (Addr > getExtent()) + if (Addr >= getExtent()) return -1; *Byte = Bytes[Addr].first; return 0; @@ -47,119 +48,120 @@ public: }; } -static bool PrintInst(const llvm::MCDisassembler &DisAsm, - llvm::MCInstPrinter &Printer, const ByteArrayTy &Bytes, - SourceMgr &SM) { +static bool PrintInsts(const MCDisassembler &DisAsm, + const ByteArrayTy &Bytes, + SourceMgr &SM, raw_ostream &Out, + MCStreamer &Streamer) { // Wrap the vector in a MemoryObject. VectorMemoryObject memoryObject(Bytes); - - // Disassemble it to a string and get the size of the instruction. - MCInst Inst; + + // Disassemble it to strings. uint64_t Size; - - if (!DisAsm.getInstruction(Inst, Size, memoryObject, 0, - /*REMOVE*/ nulls())) { - SM.PrintMessage(SMLoc::getFromPointer(Bytes[0].second), - "invalid instruction encoding", "error"); - return true; - } - - Printer.printInst(&Inst); - outs() << "\n"; - - // If the disassembled instruction was smaller than the number of bytes we - // read, reject the excess bytes. - if (Bytes.size() != Size) { - SM.PrintMessage(SMLoc::getFromPointer(Bytes[Size].second), - "excess data detected in input", "error"); - return true; + uint64_t Index; + + for (Index = 0; Index < Bytes.size(); Index += Size) { + MCInst Inst; + + MCDisassembler::DecodeStatus S; + S = DisAsm.getInstruction(Inst, Size, memoryObject, Index, + /*REMOVE*/ nulls(), nulls()); + switch (S) { + case MCDisassembler::Fail: + SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), + SourceMgr::DK_Warning, + "invalid instruction encoding"); + if (Size == 0) + Size = 1; // skip illegible bytes + break; + + case MCDisassembler::SoftFail: + SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), + SourceMgr::DK_Warning, + "potentially undefined instruction encoding"); + // Fall through + + case MCDisassembler::Success: + Streamer.EmitInstruction(Inst); + break; + } } - + return false; } -int Disassembler::disassemble(const Target &T, const std::string &Triple, - MemoryBuffer &Buffer) { - // Set up disassembler. - llvm::OwningPtr AsmInfo(T.createAsmInfo(Triple)); - - if (!AsmInfo) { - errs() << "error: no assembly info for target " << Triple << "\n"; - return -1; - } - - llvm::OwningPtr DisAsm(T.createMCDisassembler()); - if (!DisAsm) { - errs() << "error: no disassembler for target " << Triple << "\n"; - return -1; - } - - llvm::MCInstPrinter *InstPrinter = T.createMCInstPrinter(0, *AsmInfo, outs()); - - if (!InstPrinter) { - errs() << "error: no instruction printer for target " << Triple << '\n'; - return -1; - } - - bool ErrorOccurred = false; - - SourceMgr SM; - SM.AddNewSourceBuffer(&Buffer, SMLoc()); - - // Convert the input to a vector for disassembly. - ByteArrayTy ByteArray; - - StringRef Str = Buffer.getBuffer(); +static bool ByteArrayFromString(ByteArrayTy &ByteArray, + StringRef &Str, + SourceMgr &SM) { while (!Str.empty()) { // Strip horizontal whitespace. if (size_t Pos = Str.find_first_not_of(" \t\r")) { Str = Str.substr(Pos); continue; } - - // If this is the end of a line or start of a comment, process the - // instruction we have so far. + + // If this is the end of a line or start of a comment, remove the rest of + // the line. if (Str[0] == '\n' || Str[0] == '#') { - // If we have bytes to process, do so. - if (!ByteArray.empty()) { - ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); - ByteArray.clear(); - } - // Strip to the end of line if we already processed any bytes on this // line. This strips the comment and/or the \n. - if (Str[0] == '\n') + if (Str[0] == '\n') { Str = Str.substr(1); - else { + } else { Str = Str.substr(Str.find_first_of('\n')); if (!Str.empty()) Str = Str.substr(1); } continue; } - + // Get the current token. size_t Next = Str.find_first_of(" \t\n\r#"); StringRef Value = Str.substr(0, Next); - + // Convert to a byte and add to the byte vector. unsigned ByteVal; if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) { // If we have an error, print it and skip to the end of line. - SM.PrintMessage(SMLoc::getFromPointer(Value.data()), - "invalid input token", "error"); - ErrorOccurred = true; + SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error, + "invalid input token"); Str = Str.substr(Str.find('\n')); ByteArray.clear(); continue; } - + ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); Str = Str.substr(Next); } - + + return false; +} + +int Disassembler::disassemble(const Target &T, + const std::string &Triple, + MCSubtargetInfo &STI, + MCStreamer &Streamer, + MemoryBuffer &Buffer, + SourceMgr &SM, + raw_ostream &Out) { + OwningPtr DisAsm(T.createMCDisassembler(STI)); + if (!DisAsm) { + errs() << "error: no disassembler for target " << Triple << "\n"; + return -1; + } + + // Set up initial section manually here + Streamer.InitSections(); + + bool ErrorOccurred = false; + + // Convert the input to a vector for disassembly. + ByteArrayTy ByteArray; + StringRef Str = Buffer.getBuffer(); + + ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM); + if (!ByteArray.empty()) - ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); - + ErrorOccurred |= PrintInsts(*DisAsm, ByteArray, SM, Out, Streamer); + return ErrorOccurred; }