RuntimeDyldChecker.h revision 274955
1//===---- RuntimeDyldChecker.h - RuntimeDyld tester framework -----*- C++ -*-=//
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#ifndef LLVM_RUNTIMEDYLDCHECKER_H
11#define LLVM_RUNTIMEDYLDCHECKER_H
12
13#include "RuntimeDyld.h"
14#include "llvm/Support/Debug.h"
15#include "llvm/Support/raw_ostream.h"
16#include <map>
17
18namespace llvm {
19
20class MCDisassembler;
21class MCInstPrinter;
22
23/// \brief RuntimeDyld invariant checker for verifying that RuntimeDyld has
24///        correctly applied relocations.
25///
26/// The RuntimeDyldChecker class evaluates expressions against an attached
27/// RuntimeDyld instance to verify that relocations have been applied
28/// correctly.
29///
30/// The expression language supports basic pointer arithmetic and bit-masking,
31/// and has limited disassembler integration for accessing instruction
32/// operands and the next PC (program counter) address for each instruction.
33///
34/// The language syntax is:
35///
36/// check = expr '=' expr
37///
38/// expr = binary_expr
39///      | sliceable_expr
40///
41/// sliceable_expr = '*{' number '}' load_addr_expr [slice]
42///                | '(' expr ')' [slice]
43///                | ident_expr [slice]
44///                | number [slice]
45///
46/// slice = '[' high-bit-index ':' low-bit-index ']'
47///
48/// load_addr_expr = symbol
49///                | '(' symbol '+' number ')'
50///                | '(' symbol '-' number ')'
51///
52/// ident_expr = 'decode_operand' '(' symbol ',' operand-index ')'
53///            | 'next_pc'        '(' symbol ')'
54///            | symbol
55///
56/// binary_expr = expr '+' expr
57///             | expr '-' expr
58///             | expr '&' expr
59///             | expr '|' expr
60///             | expr '<<' expr
61///             | expr '>>' expr
62///
63class RuntimeDyldChecker {
64  friend class RuntimeDyldCheckerExprEval;
65public:
66  RuntimeDyldChecker(RuntimeDyld &RTDyld,
67                     MCDisassembler *Disassembler,
68                     MCInstPrinter *InstPrinter,
69                     llvm::raw_ostream &ErrStream)
70    : RTDyld(*RTDyld.Dyld), Disassembler(Disassembler),
71      InstPrinter(InstPrinter), ErrStream(ErrStream) {}
72
73  /// \brief Check a single expression against the attached RuntimeDyld
74  ///        instance.
75  bool check(StringRef CheckExpr) const;
76
77  /// \brief Scan the given memory buffer for lines beginning with the string
78  ///        in RulePrefix. The remainder of the line is passed to the check
79  ///        method to be evaluated as an expression.
80  bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
81
82private:
83
84  bool isSymbolValid(StringRef Symbol) const;
85  uint64_t getSymbolAddress(StringRef Symbol) const;
86  uint64_t readMemoryAtSymbol(StringRef Symbol, int64_t Offset,
87                              unsigned Size) const;
88  StringRef getSubsectionStartingAt(StringRef Name) const;
89
90  RuntimeDyldImpl &RTDyld;
91  MCDisassembler *Disassembler;
92  MCInstPrinter *InstPrinter;
93  llvm::raw_ostream &ErrStream;
94};
95
96} // end namespace llvm
97
98#endif // LLVM_RUNTIMEDYLDCHECKER_H
99