1 : // Copyright 2012 Google Inc.
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 : // Coverage instrumentation transform unittests.
16 :
17 : #include "syzygy/instrument/transforms/coverage_transform.h"
18 :
19 : #include "gtest/gtest.h"
20 : #include "syzygy/block_graph/transform.h"
21 : #include "syzygy/block_graph/typed_block.h"
22 : #include "syzygy/common/basic_block_frequency_data.h"
23 : #include "syzygy/core/unittest_util.h"
24 : #include "syzygy/pe/decomposer.h"
25 : #include "syzygy/pe/unittest_util.h"
26 :
27 : namespace instrument {
28 : namespace transforms {
29 :
30 : using common::BasicBlockFrequencyData;
31 : using block_graph::BlockGraph;
32 :
33 : class CoverageInstrumentationTransformTest : public testing::PELibUnitTest {
34 : public:
35 E : CoverageInstrumentationTransformTest() : dos_header_block_(NULL) { }
36 :
37 E : virtual void SetUp() OVERRIDE {
38 E : }
39 :
40 E : void DecomposeTestDll() {
41 E : FilePath test_dll_path = ::testing::GetOutputRelativePath(kDllName);
42 :
43 E : ASSERT_TRUE(pe_file_.Init(test_dll_path));
44 :
45 E : pe::ImageLayout layout(&block_graph_);
46 E : pe::Decomposer decomposer(pe_file_);
47 E : ASSERT_TRUE(decomposer.Decompose(&layout));
48 :
49 : dos_header_block_ = layout.blocks.GetBlockByAddress(
50 E : core::RelativeAddress(0));
51 E : ASSERT_TRUE(dos_header_block_ != NULL);
52 E : }
53 :
54 : pe::PEFile pe_file_;
55 : BlockGraph block_graph_;
56 : BlockGraph::Block* dos_header_block_;
57 : };
58 :
59 E : TEST_F(CoverageInstrumentationTransformTest, FailsWhenCoverageSectionExists) {
60 E : ASSERT_NO_FATAL_FAILURE(DecomposeTestDll());
61 :
62 : BlockGraph::Section* coverage_section = block_graph_.AddSection(
63 : common::kBasicBlockFrequencySectionName,
64 E : common::kBasicBlockFrequencySectionCharacteristics);
65 E : ASSERT_TRUE(coverage_section != NULL);
66 :
67 E : CoverageInstrumentationTransform tx;
68 : ASSERT_FALSE(block_graph::ApplyBlockGraphTransform(
69 E : &tx, &block_graph_, dos_header_block_));
70 E : }
71 :
72 E : TEST_F(CoverageInstrumentationTransformTest, Apply) {
73 E : ASSERT_NO_FATAL_FAILURE(DecomposeTestDll());
74 :
75 E : CoverageInstrumentationTransform tx;
76 : ASSERT_TRUE(block_graph::ApplyBlockGraphTransform(
77 E : &tx, &block_graph_, dos_header_block_));
78 :
79 : // There should be a coverage section, and it should contain 1 block.
80 : BlockGraph::Section* coverage_section = block_graph_.FindSection(
81 E : common::kBasicBlockFrequencySectionName);
82 E : ASSERT_TRUE(coverage_section != NULL);
83 :
84 E : const BlockGraph::Block* coverage_block = NULL;
85 E : BlockGraph::BlockMap::const_iterator it = block_graph_.blocks().begin();
86 E : for (; it != block_graph_.blocks().end(); ++it) {
87 E : if (it->second.section() == coverage_section->id()) {
88 E : ASSERT_TRUE(coverage_block == NULL);
89 E : coverage_block = &it->second;
90 : }
91 E : }
92 E : ASSERT_TRUE(coverage_block != NULL);
93 :
94 : // The coverage block should have the appropriate size, etc.
95 E : ASSERT_EQ(sizeof(BasicBlockFrequencyData), coverage_block->size());
96 E : ASSERT_EQ(sizeof(BasicBlockFrequencyData), coverage_block->data_size());
97 :
98 E : block_graph::ConstTypedBlock<BasicBlockFrequencyData> coverage_data;
99 E : ASSERT_TRUE(coverage_data.Init(0, coverage_block));
100 E : ASSERT_EQ(common::kBasicBlockCoverageAgentId, coverage_data->agent_id);
101 E : ASSERT_EQ(common::kBasicBlockFrequencyDataVersion, coverage_data->version);
102 E : ASSERT_EQ(tx.bb_ranges().size(), coverage_data->num_basic_blocks);
103 : ASSERT_TRUE(coverage_data.HasReferenceAt(
104 E : coverage_data.OffsetOf(coverage_data->frequency_data)));
105 E : }
106 :
107 : } // namespace transforms
108 : } // namespace instrument
|