blob: c363cb1a6cba1c122f36fa06d01a80496c7e7118 [file] [log] [blame]
Vlad Tsyrklevich31b45312017-09-20 20:38:14 +00001//===-- llvm-cfi-verify.cpp - CFI Verification tool for LLVM --------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This tool verifies Control Flow Integrity (CFI) instrumentation by static
11// binary anaylsis. See the design document in /docs/CFIVerify.rst for more
12// information.
13//
14// This tool is currently incomplete. It currently only does disassembly for
15// object files, and searches through the code for indirect control flow
16// instructions, printing them once found.
17//
18//===----------------------------------------------------------------------===//
19
Vlad Tsyrklevich89c3c8c2017-10-11 20:35:01 +000020#include "lib/FileAnalysis.h"
Vlad Tsyrklevichb5488a22017-10-10 20:59:08 +000021
Vlad Tsyrklevich89c3c8c2017-10-11 20:35:01 +000022#include "llvm/BinaryFormat/ELF.h"
23#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/Error.h"
25
Vlad Tsyrklevich31b45312017-09-20 20:38:14 +000026#include <cstdlib>
27
28using namespace llvm;
29using namespace llvm::object;
Vlad Tsyrklevich89c3c8c2017-10-11 20:35:01 +000030using namespace llvm::cfi_verify;
Vlad Tsyrklevich31b45312017-09-20 20:38:14 +000031
Vlad Tsyrklevich31b45312017-09-20 20:38:14 +000032cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
33 cl::Required);
34
Vlad Tsyrklevich89c3c8c2017-10-11 20:35:01 +000035ExitOnError ExitOnErr;
Vlad Tsyrklevich31b45312017-09-20 20:38:14 +000036
Vlad Tsyrklevich89c3c8c2017-10-11 20:35:01 +000037void printIndirectCFInstructions(const FileAnalysis &Verifier) {
38 for (uint64_t Address : Verifier.getIndirectInstructions()) {
39 const auto &InstrMeta = Verifier.getInstructionOrDie(Address);
40 outs() << format_hex(Address, 2) << " |"
41 << Verifier.getMCInstrInfo()->getName(
42 InstrMeta.Instruction.getOpcode())
43 << " ";
44 InstrMeta.Instruction.print(outs());
Vlad Tsyrklevich31b45312017-09-20 20:38:14 +000045 outs() << "\n";
46 }
47}
48
49int main(int argc, char **argv) {
50 cl::ParseCommandLineOptions(argc, argv);
51
52 InitializeAllTargetInfos();
53 InitializeAllTargetMCs();
54 InitializeAllAsmParsers();
55 InitializeAllDisassemblers();
56
Vlad Tsyrklevich89c3c8c2017-10-11 20:35:01 +000057 FileAnalysis Verifier = ExitOnErr(FileAnalysis::Create(InputFilename));
58 printIndirectCFInstructions(Verifier);
Vlad Tsyrklevich31b45312017-09-20 20:38:14 +000059
60 return EXIT_SUCCESS;
61}