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 a class for holding file and line information as extracted from a
16 : // PDB.
17 :
18 : #ifndef SYZYGY_GRINDER_LINE_INFO_H_
19 : #define SYZYGY_GRINDER_LINE_INFO_H_
20 :
21 : #include "base/files/file_path.h"
22 : #include "syzygy/core/address.h"
23 : #include "syzygy/core/address_space.h"
24 :
25 : namespace grinder {
26 :
27 : // Holds line information extracted from a PDB. This object holds information
28 : // on multiple files, and each file holds information in an address space for
29 : // efficient lookup by code address.
30 : //
31 : // NOTE: This does not handle 'partial' line coverage right now. It is possible
32 : // for only some of the code bytes associated with a line to have been
33 : // visited. We need finer grained bookkeeping to accomodate this (the
34 : // LCOV file format can handle it just fine). The MSVC tools do not seem to
35 : // make a distinction between partially and fully covered lines.
36 : //
37 : // TODO(chrisha): Make a more efficient sorted-collection-based version of
38 : // Visit. This can be O(N) rather than O(N log N) and would be useful with
39 : // the coverage grinder.
40 : class LineInfo {
41 : public:
42 : struct SourceLine; // Forward declaration.
43 : typedef std::set<std::string> SourceFileSet;
44 : typedef std::vector<SourceLine> SourceLines;
45 :
46 : // Initializes this LineInfo object with data read from the provided PDB.
47 : // @param pdb_path the PDB whose line information is to be read.
48 : // @returns true on success, false otherwise.
49 : bool Init(const base::FilePath& pdb_path);
50 :
51 : // Visits the given address range. A partial visit of the code associated
52 : // with a line is considered as a visit of that line.
53 : // @param address the starting address of the address range.
54 : // @param size the size of the address range to visit.
55 : // @param the number of times to visit this line.
56 : bool Visit(core::RelativeAddress address, size_t size, size_t count);
57 :
58 : // @name Accessors.
59 : // @{
60 E : const SourceFileSet& source_files() const { return source_files_; }
61 E : const SourceLines& source_lines() const { return source_lines_; }
62 : // @}
63 :
64 : protected:
65 : // Used to store unique file names in a manner such that we can draw stable
66 : // pointers to them. The SourceLine objects will point to the strings in this
67 : // set.
68 : SourceFileSet source_files_;
69 :
70 : // Source line information is stored here sorted by order of address, which is
71 : // the order in which we retrieve it from the PDB. This lets us do efficient
72 : // binary search lookups in Visit.
73 : SourceLines source_lines_;
74 : };
75 :
76 : // Describes a single line of source code from some file.
77 : struct LineInfo::SourceLine {
78 : SourceLine(const std::string* source_file_name,
79 : size_t line_number,
80 : core::RelativeAddress address,
81 : size_t size)
82 : : source_file_name(source_file_name),
83 : line_number(line_number),
84 : address(address),
85 : size(size),
86 E : visit_count(0) {
87 E : }
88 :
89 : // Points to the source file in which this line is found.
90 : const std::string* source_file_name;
91 : size_t line_number;
92 : // The address in the image corresponding to the line.
93 : core::RelativeAddress address;
94 : // The size may be zero if there are multiple lines mapping to a single
95 : // basic-block. This can happen during optimizations, etc.
96 : size_t size;
97 : // Indicates the number of visits to this line. A value of zero indicates
98 : // that the line is instrumented, but has not been visited.
99 : uint32 visit_count;
100 : };
101 :
102 : } // namespace grinder
103 :
104 : #endif // SYZYGY_GRINDER_LINE_INFO_H_
|