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 : #ifndef SYZYGY_PDB_PDB_UTIL_H_
16 : #define SYZYGY_PDB_PDB_UTIL_H_
17 :
18 : #include <windows.h> // NOLINT
19 : #include <dbghelp.h>
20 : #include <map>
21 : #include <vector>
22 :
23 : #include "base/files/file_path.h"
24 : #include "syzygy/pdb/pdb_data.h"
25 : #include "syzygy/pdb/pdb_stream.h"
26 :
27 : namespace pdb {
28 :
29 : // Forward declare.
30 : class PdbFile;
31 : class PdbStream;
32 : class WritablePdbStream;
33 :
34 : // A map of names to stream IDs, stored in the header stream.
35 : typedef std::map<std::string, uint32> NameStreamMap;
36 :
37 : // A map of position offset to strings, stored in some streams of the Pdb.
38 : typedef std::map<size_t, std::string> OffsetStringMap;
39 :
40 : // Used for parsing a variable sized bitset as found in PDB streams.
41 : class PdbBitSet {
42 : public:
43 : // Reads a bit set from the given stream at its current cursor position.
44 : // @param stream the stream to be read.
45 : // @returns true on success, false otherwise.
46 : bool Read(PdbStream* stream);
47 :
48 : // Writes a bit set to the given stream at its current cursor position.
49 : // @param with_size if true, the bit set is preceded by its size.
50 : // @returns true on success, false otherwise.
51 : bool Write(WritablePdbStream* stream, bool with_size);
52 :
53 : // Resizes the given bit set. Will be the next multiple of 32 in size.
54 : // @param bits the minimum number of bits to hold.
55 : void Resize(size_t bits);
56 :
57 : // Sets the given bit.
58 : void Set(size_t bit);
59 :
60 : // Clears the given bit.
61 : void Clear(size_t bit);
62 :
63 : // Toggles the given bit.
64 : void Toggle(size_t bit);
65 :
66 : // Determines if a given bit is set.
67 : // @param bit the position of the bit to inspect.
68 : // @returns true if the bit at position @p bit is set.
69 : bool IsSet(size_t bit) const;
70 :
71 : // @returns true if the bit set contains no data.
72 : bool IsEmpty() const;
73 :
74 : // @returns the number of bits in the bit set.
75 E : size_t size() const { return bits_.size() * 32; }
76 :
77 : private:
78 : std::vector<uint32> bits_;
79 : };
80 :
81 : // Calculates the hash value associated with a string, as used by hash tables
82 : // found in PDB files. This is required for interoperability with dbghelp and
83 : // srcsrv tools.
84 : // @param string the string to hash.
85 : // @returns the hashed string.
86 : uint16 HashString(const base::StringPiece& string);
87 :
88 : // Get the DbiDbgHeader offset within the Dbi info stream. For some reason,
89 : // the EC info data comes before the Dbi debug header despite that the Dbi
90 : // debug header size comes before the EC info size in the Dbi header struct.
91 : // @param dbi_header the DBI header.
92 : // @returns the offset in the DBI stream of the DbiDbgHeader, in bytes.
93 : uint32 GetDbiDbgHeaderOffset(const DbiHeader& dbi_header);
94 :
95 : // Ensures that the given stream in a PdbFile is writable.
96 : // @param index the index of the stream to make writable.
97 : // @param pdb_file the PdbFile containing the stream.
98 : // @returns true on success, false otherwise.
99 : bool EnsureStreamWritable(uint32 index, PdbFile* pdb_file);
100 :
101 : // Sets the OMAP_TO stream in the in-memory representation of a PDB file,
102 : // creating one if none exists.
103 : // @param omap_to_list the list of OMAP_TO entries.
104 : // @param pdb_file the PdbFile to be modified.
105 : // @returns true on success, false otherwise.
106 : bool SetOmapToStream(const std::vector<OMAP>& omap_to_list,
107 : PdbFile* pdb_file);
108 :
109 : // Sets the OMAP_FROM stream in the in-memory representation of a PDB file,
110 : // creating one if none exists.
111 : // @param omap_from_list the list of OMAP_FROM entries.
112 : // @param pdb_file the PdbFile to be modified.
113 : // @returns true on success, false otherwise.
114 : bool SetOmapFromStream(const std::vector<OMAP>& omap_from_list,
115 : PdbFile* pdb_file);
116 :
117 : // Sets the GUID in a PDB file, resetting its age and timestamp as well.
118 : // @param guid the new GUID for the PDB.
119 : // @param pdb_file the PdbFile to be modified.
120 : // @returns true on success, false otherwise.
121 : bool SetGuid(const GUID& guid, PdbFile* pdb_file);
122 :
123 : // Reads the header from the given PDB file @p pdb_path.
124 : // @param pdb_path the path to the PDB whose header is to be read.
125 : // @param pdb_header the header to be filled in.
126 : // @returns true on success, false otherwise.
127 : bool ReadPdbHeader(const base::FilePath& pdb_path, PdbInfoHeader70* pdb_header);
128 :
129 : // Reads the header info from the given PDB file.
130 : // @param pdb_file the file to read from.
131 : // @param pdb_header the header to be filled in.
132 : // @param name_stream_map the name-stream map to be filled in.
133 : // @returns true on success, false on error.
134 : bool ReadHeaderInfoStream(const PdbFile& pdb_file,
135 : PdbInfoHeader70* pdb_header,
136 : NameStreamMap* name_stream_map);
137 :
138 : // Reads the header info from the given PDB stream.
139 : // @param pdb_stream the stream containing the header.
140 : // @param pdb_header the header to be filled in.
141 : // @param name_stream_map the name-stream map to be filled in.
142 : // @returns true on success, false on error.
143 : bool ReadHeaderInfoStream(PdbStream* pdb_stream,
144 : PdbInfoHeader70* pdb_header,
145 : NameStreamMap* name_stream_map);
146 :
147 : // Writes the header info the given PDB file. Will look up the header stream
148 : // and convert it to a writable stream type if necessary.
149 : // @param pdb_header the header to write.
150 : // @param name_stream_map the name-stream map to write.
151 : // @param pdb_file the file to be written to.
152 : // @returns true on success, false on error.
153 : bool WriteHeaderInfoStream(const PdbInfoHeader70& pdb_header,
154 : const NameStreamMap& name_stream_map,
155 : PdbFile* pdb_file);
156 :
157 : // Writes the header info to the given PDB stream.
158 : // @param pdb_header the header to write.
159 : // @param name_stream_map the name-stream map to write.
160 : // @param pdb_stream the stream to be written to.
161 : // @returns true on success, false on error.
162 : bool WriteHeaderInfoStream(const PdbInfoHeader70& pdb_header,
163 : const NameStreamMap& name_stream_map,
164 : WritablePdbStream* pdb_stream);
165 :
166 : // Reads a string from the given PDB stream.
167 : // @param pdb_stream the stream containing the string.
168 : // @param out the string to be read.
169 : // @returns true on success, false on error.
170 : bool ReadString(PdbStream* stream, std::string* out);
171 :
172 : // Reads a string from the given PDB stream at a given position.
173 : // @param pdb_stream the stream containing the string.
174 : // @param pos the position where to read the string.
175 : // @param out the string to be read.
176 : // @returns true on success, false on error.
177 : bool ReadStringAt(PdbStream* stream, size_t pos, std::string* out);
178 :
179 : // Reads a string table from a given PDB stream at a given position.
180 : // @param stream the stream containing the string table.
181 : // @param table_name the name of the table to be read (used in the error
182 : // messages).
183 : // @param string_table_start start position of the name table.
184 : // @param string_table_end end position of the name table.
185 : // @param string_map the string map to be filled.
186 : // @returns true on success, false on error.
187 : bool ReadStringTable(PdbStream* stream,
188 : const char* table_name,
189 : size_t string_table_start,
190 : size_t string_table_end,
191 : OffsetStringMap* string_map);
192 :
193 : // Loads a named stream from the given PDB file.
194 : // @param stream_name the name of the stream to load.
195 : // @param pdb_file the PDB file from which to read the stream.
196 : // @param stream if the stream is found it will be returned via this pointer.
197 : // This should be an empty pointer (not referring to any stream currently).
198 : // @returns true if no errors were encountered, false otherwise. If the named
199 : // stream exists it is returned via @p stream.
200 : // @note It is possible for this function to return true (no errors were
201 : // encountered), but for @p stream to remain NULL.
202 : bool LoadNamedStreamFromPdbFile(
203 : const base::StringPiece& stream_name,
204 : PdbFile* pdb_file,
205 : scoped_refptr<PdbStream>* stream);
206 :
207 : } // namespace pdb
208 :
209 : #endif // SYZYGY_PDB_PDB_UTIL_H_
|