summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
diff options
context:
space:
mode:
authorVlad Tsyrklevich <vlad@tsyrklevich.net>2017-10-11 20:35:01 +0000
committerVlad Tsyrklevich <vlad@tsyrklevich.net>2017-10-11 20:35:01 +0000
commit89c3c8c403e074755be8d853fda9266f7961b469 (patch)
tree6f6c7a9028dd001c459050928493c17ed469bd7e /llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
parent75480e3871179480ce5f012ae6b73122f34216f9 (diff)
downloadbcm5719-llvm-89c3c8c403e074755be8d853fda9266f7961b469.tar.gz
bcm5719-llvm-89c3c8c403e074755be8d853fda9266f7961b469.zip
Reland 'Classify llvm-cfi-verify.'
Summary: Move llvm-cfi-verify into a class in preparation for CFI analysis to come. Reviewers: vlad.tsyrklevich Reviewed By: vlad.tsyrklevich Subscribers: mgorny, llvm-commits, pcc, kcc Differential Revision: https://reviews.llvm.org/D38379 llvm-svn: 315504
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp')
-rw-r--r--llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp212
1 files changed, 16 insertions, 196 deletions
diff --git a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
index 63dc6f128e1..c363cb1a6cb 100644
--- a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
+++ b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
@@ -17,64 +17,31 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDisassembler/MCDisassembler.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/MC/MCInstrAnalysis.h"
-#include "llvm/MC/MCInstrDesc.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Casting.h"
+#include "lib/FileAnalysis.h"
+
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Error.h"
-#include <cassert>
#include <cstdlib>
using namespace llvm;
using namespace llvm::object;
+using namespace llvm::cfi_verify;
-cl::opt<bool> ArgDumpSymbols("sym", cl::desc("Dump the symbol table."));
cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
cl::Required);
-static void printSymbols(const ObjectFile *Object) {
- for (const SymbolRef &Symbol : Object->symbols()) {
- outs() << "Symbol [" << format_hex_no_prefix(Symbol.getValue(), 2)
- << "] = ";
-
- auto SymbolName = Symbol.getName();
- if (SymbolName)
- outs() << *SymbolName;
- else
- outs() << "UNKNOWN";
-
- if (Symbol.getFlags() & SymbolRef::SF_Hidden)
- outs() << " .hidden";
-
- outs() << " (Section = ";
-
- auto SymbolSection = Symbol.getSection();
- if (SymbolSection) {
- StringRef SymbolSectionName;
- if ((*SymbolSection)->getName(SymbolSectionName))
- outs() << "UNKNOWN)";
- else
- outs() << SymbolSectionName << ")";
- } else {
- outs() << "N/A)";
- }
+ExitOnError ExitOnErr;
+void printIndirectCFInstructions(const FileAnalysis &Verifier) {
+ for (uint64_t Address : Verifier.getIndirectInstructions()) {
+ const auto &InstrMeta = Verifier.getInstructionOrDie(Address);
+ outs() << format_hex(Address, 2) << " |"
+ << Verifier.getMCInstrInfo()->getName(
+ InstrMeta.Instruction.getOpcode())
+ << " ";
+ InstrMeta.Instruction.print(outs());
outs() << "\n";
}
}
@@ -87,155 +54,8 @@ int main(int argc, char **argv) {
InitializeAllAsmParsers();
InitializeAllDisassemblers();
- Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(InputFilename);
- if (!BinaryOrErr) {
- errs() << "Failed to open file.\n";
- return EXIT_FAILURE;
- }
-
- Binary &Binary = *BinaryOrErr.get().getBinary();
- ObjectFile *Object = dyn_cast<ObjectFile>(&Binary);
- if (!Object) {
- errs() << "Disassembling of non-objects not currently supported.\n";
- return EXIT_FAILURE;
- }
-
- Triple TheTriple = Object->makeTriple();
- std::string TripleName = TheTriple.getTriple();
- std::string ArchName = "";
- std::string ErrorString;
-
- const Target *TheTarget =
- TargetRegistry::lookupTarget(ArchName, TheTriple, ErrorString);
-
- if (!TheTarget) {
- errs() << "Couldn't find target \"" << TheTriple.getTriple()
- << "\", failed with error: " << ErrorString << ".\n";
- return EXIT_FAILURE;
- }
-
- SubtargetFeatures Features = Object->getFeatures();
-
- std::unique_ptr<const MCRegisterInfo> RegisterInfo(
- TheTarget->createMCRegInfo(TripleName));
- if (!RegisterInfo) {
- errs() << "Failed to initialise RegisterInfo.\n";
- return EXIT_FAILURE;
- }
-
- std::unique_ptr<const MCAsmInfo> AsmInfo(
- TheTarget->createMCAsmInfo(*RegisterInfo, TripleName));
- if (!AsmInfo) {
- errs() << "Failed to initialise AsmInfo.\n";
- return EXIT_FAILURE;
- }
-
- std::string MCPU = "";
- std::unique_ptr<MCSubtargetInfo> SubtargetInfo(
- TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
- if (!SubtargetInfo) {
- errs() << "Failed to initialise SubtargetInfo.\n";
- return EXIT_FAILURE;
- }
-
- std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
- if (!MII) {
- errs() << "Failed to initialise MII.\n";
- return EXIT_FAILURE;
- }
-
- MCObjectFileInfo MOFI;
- MCContext Context(AsmInfo.get(), RegisterInfo.get(), &MOFI);
-
- std::unique_ptr<const MCDisassembler> Disassembler(
- TheTarget->createMCDisassembler(*SubtargetInfo, Context));
-
- if (!Disassembler) {
- errs() << "No disassembler available for target.";
- return EXIT_FAILURE;
- }
-
- std::unique_ptr<const MCInstrAnalysis> MIA(
- TheTarget->createMCInstrAnalysis(MII.get()));
-
- std::unique_ptr<MCInstPrinter> Printer(
- TheTarget->createMCInstPrinter(TheTriple, AsmInfo->getAssemblerDialect(),
- *AsmInfo, *MII, *RegisterInfo));
-
- if (ArgDumpSymbols)
- printSymbols(Object);
-
- for (const SectionRef &Section : Object->sections()) {
- outs() << "Section [" << format_hex_no_prefix(Section.getAddress(), 2)
- << "] = ";
- StringRef SectionName;
-
- if (Section.getName(SectionName))
- outs() << "UNKNOWN.\n";
- else
- outs() << SectionName << "\n";
-
- StringRef SectionContents;
- if (Section.getContents(SectionContents)) {
- errs() << "Failed to retrieve section contents.\n";
- return EXIT_FAILURE;
- }
-
- MCInst Instruction;
- uint64_t InstructionSize;
-
- ArrayRef<uint8_t> SectionBytes((const uint8_t *)SectionContents.data(),
- Section.getSize());
-
- for (uint64_t Byte = 0; Byte < Section.getSize();) {
- bool BadInstruction = false;
-
- // Disassemble the instruction.
- if (Disassembler->getInstruction(
- Instruction, InstructionSize, SectionBytes.drop_front(Byte), 0,
- nulls(), outs()) != MCDisassembler::Success) {
- BadInstruction = true;
- }
-
- Byte += InstructionSize;
-
- if (BadInstruction)
- continue;
-
- // Skip instructions that do not affect the control flow.
- const auto &InstrDesc = MII->get(Instruction.getOpcode());
- if (!InstrDesc.mayAffectControlFlow(Instruction, *RegisterInfo))
- continue;
-
- // Skip instructions that do not operate on register operands.
- bool UsesRegisterOperand = false;
- for (const auto &Operand : Instruction) {
- if (Operand.isReg())
- UsesRegisterOperand = true;
- }
-
- if (!UsesRegisterOperand)
- continue;
-
- // Print the instruction address.
- outs() << " "
- << format_hex(Section.getAddress() + Byte - InstructionSize, 2)
- << ": ";
-
- // Print the instruction bytes.
- for (uint64_t i = 0; i < InstructionSize; ++i) {
- outs() << format_hex_no_prefix(SectionBytes[Byte - InstructionSize + i],
- 2)
- << " ";
- }
-
- // Print the instruction.
- outs() << " | " << MII->getName(Instruction.getOpcode()) << " ";
- Instruction.dump_pretty(outs(), Printer.get());
-
- outs() << "\n";
- }
- }
+ FileAnalysis Verifier = ExitOnErr(FileAnalysis::Create(InputFilename));
+ printIndirectCFInstructions(Verifier);
return EXIT_SUCCESS;
}
OpenPOWER on IntegriCloud