1 : // Copyright 2013 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 : #include "syzygy/optimize/transforms/block_alignment_transform.h"
16 :
17 : #include "gmock/gmock.h"
18 : #include "gtest/gtest.h"
19 : #include "syzygy/block_graph/basic_block_decomposer.h"
20 : #include "syzygy/block_graph/block_builder.h"
21 : #include "syzygy/block_graph/block_graph.h"
22 : #include "syzygy/pe/pe_transform_policy.h"
23 :
24 : namespace optimize {
25 : namespace transforms {
26 :
27 : namespace {
28 :
29 : using block_graph::BasicBlockDecomposer;
30 : using block_graph::BlockBuilder;
31 : using block_graph::BlockGraph;
32 : using block_graph::BasicBlockSubGraph;
33 : using optimize::ApplicationProfile;
34 : using optimize::SubGraphProfile;
35 : using pe::ImageLayout;
36 :
37 : // Dummy code body.
38 : const uint8 kCodeBody1[] = { 0x74, 0x02, 0x33, 0xC0, 0xC3 };
39 : const uint8 kCodeBody2[] = { 0x0B, 0xC0, 0x75, 0xFC, 0xC3 };
40 :
41 : class BlockAlignmentTransformTest : public testing::Test {
42 : public:
43 E : BlockAlignmentTransformTest()
44 : : code1_(NULL), code2_(NULL), image_(&block_graph_), profile_(&image_) {
45 E : }
46 :
47 E : virtual void SetUp() {
48 : code1_ = block_graph_.AddBlock(BlockGraph::CODE_BLOCK,
49 : sizeof(kCodeBody1),
50 E : "code1");
51 E : DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code1_);
52 E : code1_->SetData(kCodeBody1, code1_->size());
53 :
54 : code2_ = block_graph_.AddBlock(BlockGraph::CODE_BLOCK,
55 : sizeof(kCodeBody2),
56 E : "code2");
57 E : DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code2_);
58 E : code2_->SetData(kCodeBody2, code2_->size());
59 E : }
60 :
61 : void ApplyTransform(BlockGraph::Block** block);
62 :
63 : protected:
64 : pe::PETransformPolicy policy_;
65 : BlockGraph block_graph_;
66 : BlockGraph::Block* code1_;
67 : BlockGraph::Block* code2_;
68 : BlockAlignmentTransform tx_;
69 : ImageLayout image_;
70 : ApplicationProfile profile_;
71 : SubGraphProfile subgraph_profile_;
72 : };
73 :
74 E : void BlockAlignmentTransformTest::ApplyTransform(BlockGraph::Block** block) {
75 : // Decompose to subgraph.
76 E : BasicBlockSubGraph subgraph;
77 E : BasicBlockDecomposer decomposer(*block, &subgraph);
78 E : ASSERT_TRUE(decomposer.Decompose());
79 :
80 : // Apply block alignment transform.
81 : ASSERT_TRUE(
82 : tx_.TransformBasicBlockSubGraph(&policy_, &block_graph_, &subgraph,
83 E : &profile_, &subgraph_profile_));
84 :
85 : // Rebuild block.
86 E : BlockBuilder builder(&block_graph_);
87 E : ASSERT_TRUE(builder.Merge(&subgraph));
88 E : CHECK_EQ(1u, builder.new_blocks().size());
89 E : *block = *builder.new_blocks().begin();
90 E : }
91 :
92 : } // namespace
93 :
94 E : TEST_F(BlockAlignmentTransformTest, AlignmentTest) {
95 E : DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code1_);
96 E : DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code2_);
97 :
98 E : ApplyTransform(&code1_);
99 E : EXPECT_EQ(32U, code1_->alignment());
100 :
101 E : code2_->set_alignment(2);
102 E : ApplyTransform(&code2_);
103 E : EXPECT_EQ(2U, code2_->alignment());
104 E : }
105 :
106 : } // namespace transforms
107 : } // namespace optimize
|