blob: 458b631a91908da333bb800a877feff5cf3ecc47 [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SYZYGY_PDB_PDB_UTIL_H_
#define SYZYGY_PDB_PDB_UTIL_H_
#include <windows.h> // NOLINT
#include <dbghelp.h>
#include <map>
#include <vector>
#include "base/files/file_path.h"
#include "syzygy/common/binary_stream.h"
#include "syzygy/pdb/pdb_data.h"
#include "syzygy/pdb/pdb_file.h"
#include "syzygy/pdb/pdb_stream.h"
namespace pdb {
// A map of names to stream IDs, stored in the header stream.
typedef std::map<std::string, uint32_t> NameStreamMap;
// A map of position offset to strings, stored in some streams of the Pdb.
typedef std::map<size_t, std::string> OffsetStringMap;
// Used for parsing a variable sized bitset as found in PDB streams.
class PdbBitSet {
public:
// Reads a bit set from the given stream reader at its current cursor
// position.
// @param reader a reader for the bitset to be read.
// @returns true on success, false otherwise.
bool Read(common::BinaryStreamReader* reader);
// Writes a bit set to the given stream at its current cursor position.
// @param with_size if true, the bit set is preceded by its size.
// @returns true on success, false otherwise.
bool Write(WritablePdbStream* stream, bool with_size);
// Resizes the given bit set. Will be the next multiple of 32 in size.
// @param bits the minimum number of bits to hold.
void Resize(size_t bits);
// Sets the given bit.
void Set(size_t bit);
// Clears the given bit.
void Clear(size_t bit);
// Toggles the given bit.
void Toggle(size_t bit);
// Determines if a given bit is set.
// @param bit the position of the bit to inspect.
// @returns true if the bit at position @p bit is set.
bool IsSet(size_t bit) const;
// @returns true if the bit set contains no data.
bool IsEmpty() const;
// @returns the number of bits in the bit set.
size_t size() const { return bits_.size() * 32; }
private:
std::vector<uint32_t> bits_;
};
// Calculates the hash value associated with a string, as used by hash tables
// found in PDB files. This is required for interoperability with dbghelp and
// srcsrv tools.
// @param string the string to hash.
// @returns the hashed string.
uint16_t HashString(const base::StringPiece& string);
// Get the DbiDbgHeader offset within the Dbi info stream. For some reason,
// the EC info data comes before the Dbi debug header despite that the Dbi
// debug header size comes before the EC info size in the Dbi header struct.
// @param dbi_header the DBI header.
// @returns the offset in the DBI stream of the DbiDbgHeader, in bytes.
uint32_t GetDbiDbgHeaderOffset(const DbiHeader& dbi_header);
// Ensures that the given stream in a PdbFile is writable.
// @param index the index of the stream to make writable.
// @param pdb_file the PdbFile containing the stream.
// @returns true on success, false otherwise.
bool EnsureStreamWritable(uint32_t index, PdbFile* pdb_file);
// Sets the OMAP_TO stream in the in-memory representation of a PDB file,
// creating one if none exists.
// @param omap_to_list the list of OMAP_TO entries.
// @param pdb_file the PdbFile to be modified.
// @returns true on success, false otherwise.
bool SetOmapToStream(const std::vector<OMAP>& omap_to_list,
PdbFile* pdb_file);
// Sets the OMAP_FROM stream in the in-memory representation of a PDB file,
// creating one if none exists.
// @param omap_from_list the list of OMAP_FROM entries.
// @param pdb_file the PdbFile to be modified.
// @returns true on success, false otherwise.
bool SetOmapFromStream(const std::vector<OMAP>& omap_from_list,
PdbFile* pdb_file);
// Sets the GUID in a PDB file, resetting its age and timestamp as well.
// @param guid the new GUID for the PDB.
// @param pdb_file the PdbFile to be modified.
// @returns true on success, false otherwise.
bool SetGuid(const GUID& guid, PdbFile* pdb_file);
// Reads the header from the given PDB file @p pdb_path.
// @param pdb_path the path to the PDB whose header is to be read.
// @param pdb_header the header to be filled in.
// @returns true on success, false otherwise.
bool ReadPdbHeader(const base::FilePath& pdb_path, PdbInfoHeader70* pdb_header);
// Reads the header info from the given PDB file.
// @param pdb_file the file to read from.
// @param pdb_header the header to be filled in.
// @param name_stream_map the name-stream map to be filled in.
// @returns true on success, false on error.
bool ReadHeaderInfoStream(const PdbFile& pdb_file,
PdbInfoHeader70* pdb_header,
NameStreamMap* name_stream_map);
// Reads the header info from the given PDB stream.
// @param pdb_stream the stream containing the header.
// @param pdb_header the header to be filled in.
// @param name_stream_map the name-stream map to be filled in.
// @returns true on success, false on error.
bool ReadHeaderInfoStream(PdbStream* pdb_stream,
PdbInfoHeader70* pdb_header,
NameStreamMap* name_stream_map);
// Writes the header info the given PDB file. Will look up the header stream
// and convert it to a writable stream type if necessary.
// @param pdb_header the header to write.
// @param name_stream_map the name-stream map to write.
// @param pdb_file the file to be written to.
// @returns true on success, false on error.
bool WriteHeaderInfoStream(const PdbInfoHeader70& pdb_header,
const NameStreamMap& name_stream_map,
PdbFile* pdb_file);
// Writes the header info to the given PDB stream.
// @param pdb_header the header to write.
// @param name_stream_map the name-stream map to write.
// @param pdb_stream the stream to be written to.
// @returns true on success, false on error.
bool WriteHeaderInfoStream(const PdbInfoHeader70& pdb_header,
const NameStreamMap& name_stream_map,
WritablePdbStream* pdb_stream);
// Reads a string table from a given PDB stream at a given position.
// @param stream the stream containing the string table.
// @param table_name the name of the table to be read (used in the error
// messages).
// @param string_table_start start position of the name table.
// @param string_table_end end position of the name table.
// @param string_map the string map to be filled.
// @returns true on success, false on error.
bool ReadStringTable(PdbStream* stream,
const char* table_name,
size_t string_table_start,
size_t string_table_end,
OffsetStringMap* string_map);
// Loads a named stream from the given PDB file.
// @param stream_name the name of the stream to load.
// @param pdb_file the PDB file from which to read the stream.
// @param stream if the stream is found it will be returned via this pointer.
// This should be an empty pointer (not referring to any stream currently).
// @returns true if no errors were encountered, false otherwise. If the named
// stream exists it is returned via @p stream.
// @note It is possible for this function to return true (no errors were
// encountered), but for @p stream to remain NULL.
bool LoadNamedStreamFromPdbFile(
const base::StringPiece& stream_name,
PdbFile* pdb_file,
scoped_refptr<PdbStream>* stream);
} // namespace pdb
#endif // SYZYGY_PDB_PDB_UTIL_H_