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