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