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