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 : // 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/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 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 : bool Visit(core::RelativeAddress address, size_t size);
56 :
57 : // @name Accessors.
58 : // @{
59 E : const SourceFileSet& source_files() const { return source_files_; }
60 E : const SourceLines& source_lines() const { return source_lines_; }
61 : // @}
62 :
63 : protected:
64 : // Used to store unique file names in a manner such that we can draw stable
65 : // pointers to them. The SourceLine objects will point to the strings in this
66 : // set.
67 : SourceFileSet source_files_;
68 :
69 : // Source line information is stored here sorted by order of address, which is
70 : // the order in which we retrieve it from the PDB. This lets us do efficient
71 : // binary search lookups in Visit.
72 : SourceLines source_lines_;
73 : };
74 :
75 : // Describes a single line of source code from some file.
76 : struct LineInfo::SourceLine {
77 : SourceLine(const std::string* source_file_name,
78 : size_t line_number,
79 : core::RelativeAddress address,
80 : size_t size)
81 : : source_file_name(source_file_name),
82 : line_number(line_number),
83 : address(address),
84 : size(size),
85 E : visited(false) {
86 E : }
87 :
88 : // Points to the source file in which this line is found.
89 : const std::string* source_file_name;
90 : size_t line_number;
91 :
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 :
98 : // Indicates whether or not this line has been visited.
99 : bool visited;
100 : };
101 :
102 : } // namespace grinder
103 :
104 : #endif // SYZYGY_GRINDER_LINE_INFO_H_
|