1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #ifndef SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_TEST_UTIL_H_
16 : #define SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_TEST_UTIL_H_
17 :
18 : #include "gtest/gtest.h"
19 : #include "syzygy/block_graph/basic_block_decomposer.h"
20 : #include "syzygy/block_graph/basic_block_subgraph.h"
21 : #include "syzygy/block_graph/unittest_util.h"
22 :
23 m : extern "C" {
24 :
25 : // Functions and labels exposed from our .asm test stub.
26 m : extern int assembly_func();
27 m : extern int unreachable_label();
28 m : extern int interrupt_label();
29 m : extern int assembly_func_end();
30 :
31 m : extern int case_0();
32 m : extern int case_1();
33 m : extern int case_default();
34 m : extern int jump_table();
35 m : extern int case_table();
36 :
37 : // Functions invoked or referred by the .asm test stub. These are defined in
38 : // basic_block_test_util.cc.
39 m : extern int func1();
40 m : extern int func2();
41 :
42 m : } // extern "C"
43 :
44 m : namespace testing {
45 :
46 : // A utility class for generating test data built around the function in
47 : // basic_block_assembly_func.asm. When assembly_func_ is decomposed as a basic
48 : // block subgraph the layout is as follows:
49 : //
50 : // BB0: offset 0, code, assembly_func, 4 instructions, 0 successors
51 : // BB1: offset 23, code/padding (unreachable code)
52 : // BB2: offset 24, code, case_0, 2 instructions, 1 successor
53 : // BB3: offset 31, code, sub eax to jnz, 1 instruction, 2 successors
54 : // BB4: offset 36, code, ret, 1 instruction, 0 successors
55 : // BB5: offset 37, code, case_1, 1 instruction, 1 successor
56 : // BB6: offset 42, code, case_default, 2 instructions, 0 successors
57 : // BB7: offset 49, code/padding, interrupt_label, 3 instruction, 0 successors
58 : // BB8: offset 50, data, jump_table, 12 bytes
59 : // BB9: offset 62, data, case_table, 256 bytes
60 m : class BasicBlockTest : public ::testing::Test {
61 m : public:
62 m : typedef core::RelativeAddress RelativeAddress;
63 m : typedef block_graph::BlockGraph BlockGraph;
64 m : typedef block_graph::BasicBlockDecomposer BasicBlockDecomposer;
65 m : typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
66 m : typedef BasicBlockSubGraph::BasicBlock BasicBlock;
67 m : typedef BasicBlockSubGraph::BlockDescription BlockDescription;
68 m : typedef BlockGraph::Block Block;
69 m : typedef BlockGraph::Reference Reference;
70 m : typedef BlockGraph::Section Section;
71 :
72 : // The number and type of basic blocks.
73 m : static const size_t kNumCodeBasicBlocks = 8;
74 m : static const size_t kNumDataBasicBlocks = 2;
75 m : static const size_t kNumEndBasicBlocks = 1;
76 m : static const size_t kNumCodePaddingBasicBlocks = 2;
77 m : static const size_t kNumDataPaddingBasicBlocks = 0;
78 m : static const size_t kNumBasicBlocks =
79 m : kNumCodeBasicBlocks + kNumDataBasicBlocks + kNumEndBasicBlocks;
80 :
81 m : BasicBlockTest();
82 :
83 : // Initializes block_graph, assembly_func, func1, func2 and data. Meant to be
84 : // wrapped in ASSERT_NO_FATAL_FAILURE.
85 m : void InitBlockGraph();
86 :
87 : // Initializes subgraph, bbs and bds. Meant to be wrapped in
88 : // ASSERT_NO_FATAL_FAILURE.
89 : // @pre InitBlockGraph must have been called successfully.
90 m : void InitBasicBlockSubGraph();
91 :
92 : // Initializes block_graph_, text_section_, func1_, and func2_. Leaves
93 : // data_section_, assembly_func_ and data_ NULL. func2_ contains a function
94 : // with a debug-end label past the end of the block, and internally it calls
95 : // func1_.
96 m : void InitBasicBlockSubGraphWithLabelPastEnd();
97 :
98 : // Initialized by InitBlockGraph.
99 : // @{
100 : // Start address of the assembly function.
101 m : RelativeAddress start_addr_;
102 :
103 m : testing::DummyTransformPolicy policy_;
104 m : BlockGraph block_graph_;
105 m : Section* text_section_;
106 m : Section* data_section_;
107 m : Block* assembly_func_;
108 m : Block* func1_;
109 m : Block* func2_;
110 m : Block* data_;
111 : // @}
112 :
113 : // Initialized by InitBasicBlockSubGraph and
114 : // InitBasicBlockSubGraphWithLabelPastEnd.
115 : // @{
116 m : BasicBlockSubGraph subgraph_;
117 m : std::vector<BasicBlock*> bbs_;
118 m : std::vector<BlockDescription*> bds_;
119 : // @}
120 m : };
121 :
122 m : } // namespace testing
123 :
124 : #endif // SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_TEST_UTIL_H_
|