From: Chris Lattner Date: Tue, 22 Dec 2009 22:50:29 +0000 (+0000) Subject: rename HexDisassembler -> Disassembler, it works on any input X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a3dcfb130044f306632a5fab43854eda4095a09c;p=oota-llvm.git rename HexDisassembler -> Disassembler, it works on any input integer encoding (0123, 0b10101, 42, etc). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91934 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/llvm-mc/CMakeLists.txt b/tools/llvm-mc/CMakeLists.txt index ffb7bc94017..46c5c6bfd64 100644 --- a/tools/llvm-mc/CMakeLists.txt +++ b/tools/llvm-mc/CMakeLists.txt @@ -4,5 +4,5 @@ add_llvm_tool(llvm-mc llvm-mc.cpp AsmLexer.cpp AsmParser.cpp - HexDisassembler.cpp + Disassembler.cpp ) diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp new file mode 100644 index 00000000000..5fde71238dc --- /dev/null +++ b/tools/llvm-mc/Disassembler.cpp @@ -0,0 +1,165 @@ +//===- Disassembler.cpp - Disassembler for hex strings --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class implements the disassembler of strings of bytes written in +// hexadecimal, from standard input or from a file. +// +//===----------------------------------------------------------------------===// + +#include "Disassembler.h" + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/MemoryObject.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SourceMgr.h" +using namespace llvm; + +typedef std::vector > ByteArrayTy; + +namespace { +class VectorMemoryObject : public MemoryObject { +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()) + return -1; + *Byte = Bytes[Addr].first; + return 0; + } +}; +} + +static bool PrintInst(const llvm::MCDisassembler &DisAsm, + llvm::MCInstPrinter &Printer, const ByteArrayTy &Bytes, + SourceMgr &SM) { + // Wrap the vector in a MemoryObject. + VectorMemoryObject memoryObject(Bytes); + + // Disassemble it to a string and get the size of the instruction. + MCInst Inst; + 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; + } + + 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(); + 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 (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') + Str = Str.substr(1); + 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; + Str = Str.substr(Str.find('\n')); + ByteArray.clear(); + continue; + } + + ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); + Str = Str.substr(Next); + } + + if (!ByteArray.empty()) + ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); + + return ErrorOccurred; +} diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h new file mode 100644 index 00000000000..78c2f854946 --- /dev/null +++ b/tools/llvm-mc/Disassembler.h @@ -0,0 +1,34 @@ +//===- Disassembler.h - Text File Disassembler ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class implements the disassembler of strings of bytes written in +// hexadecimal, from standard input or from a file. +// +//===----------------------------------------------------------------------===// + +#ifndef DISASSEMBLER_H +#define DISASSEMBLER_H + +#include + +namespace llvm { + +class Target; +class MemoryBuffer; + +class Disassembler { +public: + static int disassemble(const Target &target, + const std::string &tripleString, + MemoryBuffer &buffer); +}; + +} // namespace llvm + +#endif diff --git a/tools/llvm-mc/HexDisassembler.cpp b/tools/llvm-mc/HexDisassembler.cpp deleted file mode 100644 index 530520bde8f..00000000000 --- a/tools/llvm-mc/HexDisassembler.cpp +++ /dev/null @@ -1,165 +0,0 @@ -//===- HexDisassembler.cpp - Disassembler for hex strings -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class implements the disassembler of strings of bytes written in -// hexadecimal, from standard input or from a file. -// -//===----------------------------------------------------------------------===// - -#include "HexDisassembler.h" - -#include "llvm/ADT/OwningPtr.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCDisassembler.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstPrinter.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/MemoryObject.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/SourceMgr.h" -using namespace llvm; - -typedef std::vector > ByteArrayTy; - -namespace { -class VectorMemoryObject : public MemoryObject { -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()) - return -1; - *Byte = Bytes[Addr].first; - return 0; - } -}; -} - -static bool PrintInst(const llvm::MCDisassembler &DisAsm, - llvm::MCInstPrinter &Printer, const ByteArrayTy &Bytes, - SourceMgr &SM) { - // Wrap the vector in a MemoryObject. - VectorMemoryObject memoryObject(Bytes); - - // Disassemble it to a string and get the size of the instruction. - MCInst Inst; - 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; - } - - return false; -} - -int HexDisassembler::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(); - 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 (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') - Str = Str.substr(1); - 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; - Str = Str.substr(Str.find('\n')); - ByteArray.clear(); - continue; - } - - ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); - Str = Str.substr(Next); - } - - if (!ByteArray.empty()) - ErrorOccurred |= PrintInst(*DisAsm, *InstPrinter, ByteArray, SM); - - return ErrorOccurred; -} diff --git a/tools/llvm-mc/HexDisassembler.h b/tools/llvm-mc/HexDisassembler.h deleted file mode 100644 index d197aea9bc8..00000000000 --- a/tools/llvm-mc/HexDisassembler.h +++ /dev/null @@ -1,34 +0,0 @@ -//===- HexDisassembler.h - Disassembler for hex strings -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class implements the disassembler of strings of bytes written in -// hexadecimal, from standard input or from a file. -// -//===----------------------------------------------------------------------===// - -#ifndef HEXDISASSEMBLER_H -#define HEXDISASSEMBLER_H - -#include - -namespace llvm { - -class Target; -class MemoryBuffer; - -class HexDisassembler { -public: - static int disassemble(const Target &target, - const std::string &tripleString, - MemoryBuffer &buffer); -}; - -} // namespace llvm - -#endif diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 75cb2b83508..30cdfba57b5 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -32,7 +32,7 @@ #include "llvm/Target/TargetMachine.h" // FIXME. #include "llvm/Target/TargetSelect.h" #include "AsmParser.h" -#include "HexDisassembler.h" +#include "Disassembler.h" using namespace llvm; static cl::opt @@ -310,7 +310,7 @@ static int DisassembleInput(const char *ProgName) { return 1; } - return HexDisassembler::disassemble(*TheTarget, TripleName, *Buffer); + return Disassembler::disassemble(*TheTarget, TripleName, *Buffer); }