[RuntimeDyld] Add a framework for testing relocation logic in RuntimeDyld.
[oota-llvm.git] / include / llvm / ExecutionEngine / RuntimeDyldChecker.h
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
18 namespace llvm {
19
20 class MCDisassembler;
21 class 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 ///
63 class RuntimeDyldChecker {
64   friend class RuntimeDyldCheckerExprEval;
65 public:
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
82 private:
83
84   bool checkSymbolIsValidForLoad(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