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 : // Declares structure and functions useful to grinders that process basic-
16 : // block frequency data.
17 :
18 : #ifndef SYZYGY_GRINDER_BASIC_BLOCK_UTIL_H_
19 : #define SYZYGY_GRINDER_BASIC_BLOCK_UTIL_H_
20 :
21 : #include <map>
22 : #include <vector>
23 :
24 : #include "base/files/file_path.h"
25 : #include "syzygy/common/indexed_frequency_data.h"
26 : #include "syzygy/grinder/line_info.h"
27 : #include "syzygy/pe/pe_file.h"
28 : #include "syzygy/trace/protocol/call_trace_defs.h"
29 :
30 : namespace grinder {
31 : namespace basic_block_util {
32 :
33 : // Address related types.
34 : typedef core::RelativeAddress RelativeAddress;
35 : typedef core::AddressRange<RelativeAddress, size_t> RelativeAddressRange;
36 : typedef std::vector<RelativeAddressRange> RelativeAddressRangeVector;
37 :
38 : // Module information.
39 : typedef pe::ModuleInformation ModuleInformation;
40 :
41 : // Compares module information on identity properties alone.
42 : struct ModuleIdentityComparator {
43 : bool operator()(const ModuleInformation& lhs,
44 : const ModuleInformation& rhs) const;
45 : };
46 :
47 : // Type definitions for the basic block entry count data.
48 : typedef int32_t EntryCountType;
49 : typedef int32_t BasicBlockOffset;
50 : // An entry count map maps from the relative virtual address of the first
51 : // instruction or data byte in the basic block, to its entry count.
52 : typedef std::map<BasicBlockOffset, EntryCountType> EntryCountMap;
53 :
54 : // Type definitions for the indexed frequency data.
55 : typedef std::pair<RelativeAddress, size_t> IndexedFrequencyOffset;
56 E : typedef std::map<IndexedFrequencyOffset, EntryCountType> IndexedFrequencyMap;
57 : // The information kept for each module.
58 : struct IndexedFrequencyInformation {
59 : uint32_t num_entries;
60 : uint32_t num_columns;
61 : common::IndexedFrequencyData::DataType data_type;
62 : uint8_t frequency_size;
63 : IndexedFrequencyMap frequency_map;
64 : };
65 :
66 : bool operator==(const IndexedFrequencyInformation& lhs,
67 : const IndexedFrequencyInformation& rhs);
68 :
69 : // An indexed frequency map maps from the relative virtual address of the first
70 : // instruction or data byte in the basic block, to its frequencies.
71 : typedef std::map<ModuleInformation,
72 : IndexedFrequencyInformation,
73 : ModuleIdentityComparator> ModuleIndexedFrequencyMap;
74 :
75 : // This structure holds the information extracted from a PDB file for a
76 : // given module.
77 : struct PdbInfo {
78 : // The path to this PDB file.
79 : base::FilePath pdb_path;
80 :
81 : // Line and coverage information for all the source files associated with
82 : // a particular PDB.
83 : LineInfo line_info;
84 :
85 : // Basic-block addresses for the module associated with a particular PDB.
86 : // Used to transform basic-block frequency data to line visits via line_info.
87 : RelativeAddressRangeVector bb_ranges;
88 : };
89 :
90 : typedef std::map<ModuleInformation,
91 : PdbInfo,
92 : ModuleIdentityComparator> PdbInfoMap;
93 :
94 : bool FindIndexedFrequencyInfo(
95 : const pe::PEFile::Signature& signature,
96 : const ModuleIndexedFrequencyMap& module_entry_map,
97 : const IndexedFrequencyInformation** information);
98 :
99 : // A helper function to populate @p frequencies from a branching file for a
100 : // given module signature.
101 : // @param file the file containing branching information.
102 : // @param signature the signature of the module to retrieve.
103 : // @param frequencies receives the module branch frequencies.
104 : // @returns true on success, false otherwise.
105 : bool LoadBranchStatisticsFromFile(const base::FilePath& file,
106 : const pe::PEFile::Signature& signature,
107 : IndexedFrequencyMap* frequencies);
108 :
109 : // A helper function to populate @p bb_ranges from the PDB file given by
110 : // @p pdb_path.
111 : // @returns true on success, false otherwise.
112 : bool LoadBasicBlockRanges(const base::FilePath& pdb_path,
113 : RelativeAddressRangeVector* bb_ranges);
114 :
115 : // Loads a new or retrieves the cached PDB info for the given module. This
116 : // also caches failures; it will not re-attempt to look up PDB information
117 : // if a previous attempt for the same module failed.
118 : // @param pdb_info_cache the cache of PDB info already seen.
119 : // @param module_info the info representing the module to find PDB info for.
120 : // @param pdb_info a pointer to the pdb info will be returned here.
121 : // @returns true on success, false otherwise.
122 : bool LoadPdbInfo(PdbInfoMap* pdb_info_cache,
123 : const ModuleInformation& module_info,
124 : PdbInfo** pdb_info);
125 :
126 : // @returns true if the given @p size is a valid frequency size.
127 : bool IsValidFrequencySize(size_t size);
128 :
129 : // @returns the frequency value contained in @p data for the basic_block given
130 : // by @p bb_id.
131 : uint32_t GetFrequency(const TraceIndexedFrequencyData* data,
132 : size_t bb_id,
133 : size_t column);
134 :
135 : } // namespace basic_block_util
136 : } // namespace grinder
137 :
138 : #endif // SYZYGY_GRINDER_BASIC_BLOCK_UTIL_H_
|