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