1 : // Copyright 2011 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 some utilities for dealing with PDB files via the DIA interface.
16 : #ifndef SYZYGY_PE_DIA_UTIL_H_
17 : #define SYZYGY_PE_DIA_UTIL_H_
18 :
19 : #include <windows.h> // NOLINT
20 : #include <dia2.h>
21 : #include <vector>
22 :
23 : #include "base/callback.h"
24 : #include "base/files/file_path.h"
25 : #include "base/win/scoped_comptr.h"
26 :
27 m : namespace pe {
28 :
29 : // The name of the DIA SDK DLL.
30 m : extern const wchar_t kDiaDllName[];
31 :
32 : // The names of various debug streams.
33 m : extern const wchar_t kFixupDiaDebugStreamName[];
34 m : extern const wchar_t kOmapToDiaDebugStreamName[];
35 m : extern const wchar_t kOmapFromDiaDebugStreamName[];
36 :
37 : // A trinary value that is returned by search routines.
38 m : enum SearchResult {
39 : // The search completed and the object was found.
40 m : kSearchSucceeded,
41 : // The search completed, but the object was not found.
42 m : kSearchFailed,
43 : // The search did not complete due to an error.
44 m : kSearchErrored,
45 m : };
46 :
47 : // Creates a DiaDataSource object. Logs any errors.
48 : //
49 : // @param created_source pointer that will receive the created object.
50 : // @returns true on success, false otherwise.
51 m : bool CreateDiaSource(IDiaDataSource** created_source);
52 :
53 : // Creates a dia session for the provided object. Logs any errors.
54 : //
55 : // @param file the file to open.
56 : // @param dia_source the DIA source to use.
57 : // @param dia_session pointer that will receive the created DIA session.
58 : // @return true on success, false otherwise.
59 m : bool CreateDiaSession(const base::FilePath& file,
60 m : IDiaDataSource* dia_source,
61 m : IDiaSession** dia_session);
62 :
63 : // Find the table with the given IID. Logs any errors.
64 : //
65 : // @param iid the IID of the table to look for.
66 : // @param dia_session the DIA session whose tables are to be queried.
67 : // @param out_table a pointer to the object to receive the table. If the table
68 : // is not found this will be NULL on return.
69 : // @returns a SearchResult
70 m : SearchResult FindDiaTable(const IID& iid,
71 m : IDiaSession* dia_session,
72 m : void** out_table);
73 :
74 : // Find the table that can be cast to the given Dia interface. Logs any errors.
75 : //
76 : // @tparam T an IDia* intercace.
77 : // @param session the DIA session whose tables are to be queried.
78 : // @param out_table a pointer to the object to receive the table. If the table
79 : // is not found this will be NULL on return.
80 : // @returns a SearchResult
81 m : template <typename T>
82 m : SearchResult FindDiaTable(IDiaSession* dia_session, T** out_table);
83 :
84 : // Finds teh debug stream with the given name. Logs any errors.
85 : //
86 : // @param name the name of the stream to find.
87 : // @param dia_session the DIA session to search.
88 : // @param dia_debug_stream the pointer that will receive the debug stream, if
89 : // found.
90 : // @returns a SearchResult.
91 m : SearchResult FindDiaDebugStream(const wchar_t* name,
92 m : IDiaSession* dia_session,
93 m : IDiaEnumDebugStreamData** dia_debug_stream);
94 :
95 : // This reads a given debug stream into the provided vector. The type T
96 : // must be the same size as the debug stream record size. Logs any errors.
97 : //
98 : // @tparam T the type of object to read from the debug stream.
99 : // @param stream the debug stream from which to read objects.
100 : // @param list the list to be populated.
101 : // @returns true on success, false otherwise.
102 m : template <typename T>
103 m : bool LoadDiaDebugStream(IDiaEnumDebugStreamData* stream, std::vector<T>* list);
104 :
105 : // This loads the named debug stream into the provided vector. The type T must
106 : // be the same size as the debug stream record size. Logs any errors.
107 : //
108 : // @tparam T the type of object to read from the debug stream.
109 : // @param name the name of the stream to load.
110 : // @param dia_session the DIA session to search.
111 : // @param list the list to be populated.
112 : // @returns a SearchResults.
113 m : template <typename T>
114 m : SearchResult FindAndLoadDiaDebugStreamByName(const wchar_t* name,
115 m : IDiaSession* dia_session,
116 m : std::vector<T>* list);
117 :
118 : // Gets the symbol tab associated with the given symbol.
119 : // @param symbol the symbol to examine.
120 : // @param sym_tag on success, returns @p symbol's tag.
121 : // @returns true on success, false on failure.
122 m : bool GetSymTag(IDiaSymbol* symbol, enum SymTagEnum* sym_tag);
123 :
124 : // Checks to see if the given symbol is of the expected type.
125 : // @returns true if @p symbol is of type @p expected_sym_tag,
126 : // false on error or mismatch.
127 m : bool IsSymTag(IDiaSymbol* symbol, enum SymTagEnum expected_sym_tag);
128 :
129 : // A worker class that makes it easy to visit specific children of a given
130 : // DIA symbol.
131 m : class ChildVisitor {
132 m : public:
133 m : typedef base::Callback<bool(IDiaSymbol*)> VisitSymbolCallback;
134 :
135 : // Creates a visitor for the children of @p parent of type @p type.
136 m : ChildVisitor(IDiaSymbol* parent, enum SymTagEnum type);
137 :
138 : // Visits all children of type type, of parent symbol,
139 : // calling @p child_callback for each.
140 : // @returns true on success.
141 m : bool VisitChildren(const VisitSymbolCallback& child_callback);
142 :
143 m : private:
144 m : bool VisitChildrenImpl();
145 m : bool EnumerateChildren(IDiaEnumSymbols* children);
146 m : bool VisitChild(IDiaSymbol* child);
147 :
148 m : base::win::ScopedComPtr<IDiaSymbol> parent_;
149 m : enum SymTagEnum type_;
150 :
151 m : const VisitSymbolCallback* child_callback_;
152 :
153 m : DISALLOW_COPY_AND_ASSIGN(ChildVisitor);
154 m : };
155 :
156 : // A worker class that makes it easy to visit each compiland in
157 : // in a given DIA session.
158 m : class CompilandVisitor {
159 m : public:
160 m : typedef ChildVisitor::VisitSymbolCallback VisitCompilandCallback;
161 :
162 : // Creates a visitor for all compilands of @p session.
163 m : explicit CompilandVisitor(IDiaSession* session);
164 :
165 : // Visits all compilands, calling @p compiland_callback for each.
166 : // @returns true on success.
167 m : bool VisitAllCompilands(const VisitCompilandCallback& compiland_callback);
168 :
169 m : private:
170 m : base::win::ScopedComPtr<IDiaSession> session_;
171 :
172 m : DISALLOW_COPY_AND_ASSIGN(CompilandVisitor);
173 m : };
174 :
175 : // A worker class that makes it easy to visit each source line record
176 : // in a given DIA compiland.
177 m : class LineVisitor {
178 m : public:
179 m : typedef base::Callback<bool(IDiaLineNumber*)> VisitLineCallback;
180 :
181 : // Create a line visitor for the given @p session and @p compiland.
182 m : LineVisitor(IDiaSession* session, IDiaSymbol* compiland);
183 :
184 : // Visit all lines records in our compiland.
185 m : bool VisitLines(const VisitLineCallback& line_callback);
186 :
187 m : private:
188 m : bool VisitLinesImpl();
189 m : bool EnumerateCompilandSource(IDiaSymbol* compiland,
190 m : IDiaSourceFile* source_file);
191 m : bool EnumerateCompilandSources(IDiaSymbol* compiland,
192 m : IDiaEnumSourceFiles* source_files);
193 m : bool VisitSourceLine(IDiaLineNumber* line_number);
194 :
195 m : base::win::ScopedComPtr<IDiaSession> session_;
196 m : base::win::ScopedComPtr<IDiaSymbol> compiland_;
197 :
198 m : const VisitLineCallback* line_callback_;
199 :
200 m : DISALLOW_COPY_AND_ASSIGN(LineVisitor);
201 m : };
202 :
203 m : } // namespace pe
204 :
205 : // Bring in the templated implementation details.
206 : #include "syzygy/pe/dia_util_internal.h"
207 :
208 : #endif // SYZYGY_PE_DIA_UTIL_H_
|