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