Coverage for /Syzygy/pdb/pdb_reader.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
75.4%49650.C++source

Line-by-line coverage:

   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    :  #include "syzygy/pdb/pdb_reader.h"
  16    :  
  17    :  #include "base/logging.h"
  18    :  #include "base/string_util.h"
  19    :  #include "syzygy/pdb/pdb_file_stream.h"
  20    :  
  21    :  namespace pdb {
  22    :  
  23    :  namespace {
  24    :  
  25  E :  bool GetFileSize(FILE* file, uint32* size) {
  26  E :    DCHECK(file != NULL);
  27  E :    DCHECK(size != NULL);
  28    :  
  29  E :    if (fseek(file, 0, SEEK_END) != 0) {
  30  i :      LOG(ERROR) << "Failed seeking to end of file.";
  31  i :      return false;
  32    :    }
  33    :  
  34  E :    long temp = ftell(file);
  35  E :    if (temp == -1L) {
  36  i :      LOG(ERROR) << "Failed to read stream position.";
  37  i :      return false;
  38    :    }
  39  E :    DCHECK_GT(temp, 0);
  40    :  
  41  E :    (*size) = static_cast<uint32>(temp);
  42  E :    return true;
  43  E :  }
  44    :  
  45  E :  uint32 GetNumPages(const PdbHeader& header, uint32 num_bytes) {
  46  E :    return (num_bytes + header.page_size - 1) / header.page_size;
  47  E :  }
  48    :  
  49    :  }  // namespace
  50    :  
  51  E :  bool PdbReader::Read(const base::FilePath& pdb_path, PdbFile* pdb_file) {
  52  E :    DCHECK(pdb_file != NULL);
  53    :  
  54  E :    pdb_file->Clear();
  55    :  
  56    :    scoped_refptr<RefCountedFILE> file(new RefCountedFILE(
  57  E :        file_util::OpenFile(pdb_path, "rb")));
  58  E :    if (!file->file()) {
  59  E :      LOG(ERROR) << "Unable to open '" << pdb_path.value() << "'.";
  60  E :      return false;
  61    :    }
  62    :  
  63    :    // Get the file size.
  64  E :    uint32 file_size = 0;
  65  E :    if (!GetFileSize(file->file(), &file_size)) {
  66  i :      LOG(ERROR) << "Unable to determine size of '" << pdb_path.value() << "'.";
  67  i :      return false;
  68    :    }
  69    :  
  70  E :    PdbHeader header = { 0 };
  71    :  
  72    :    // Read the header from the first page in the file.
  73  E :    uint32 header_page = 0;
  74    :    scoped_refptr<PdbFileStream> header_stream(new PdbFileStream(
  75  E :        file, sizeof(header), &header_page, kPdbPageSize));
  76  E :    if (!header_stream->Read(&header, 1)) {
  77  i :      LOG(ERROR) << "Failed to read PDB file header.";
  78  i :      return false;
  79    :    }
  80    :  
  81    :    // Sanity checks.
  82  E :    if (header.num_pages * header.page_size != file_size) {
  83  E :      LOG(ERROR) << "Invalid PDB file size.";
  84  E :      return false;
  85    :    }
  86    :  
  87    :    if (memcmp(header.magic_string, kPdbHeaderMagicString,
  88  E :               sizeof(kPdbHeaderMagicString)) != 0) {
  89  i :      LOG(ERROR) << "Invalid PDB magic string.";
  90  i :      return false;
  91    :    }
  92    :  
  93    :    // Load the directory page list (a sequence of uint32 page numbers that is
  94    :    // itself written across multiple root pages). To do this we need to know how
  95    :    // many pages are required to represent the directory, then we load a stream
  96    :    // containing that many page pointers from the root pages array.
  97    :    int num_dir_pages = static_cast<int>(GetNumPages(header,
  98  E :                                                     header.directory_size));
  99    :    scoped_refptr<PdbFileStream> dir_page_stream(new PdbFileStream(
 100    :        file, num_dir_pages * sizeof(uint32),
 101  E :        header.root_pages, header.page_size));
 102  E :    scoped_ptr<uint32[]> dir_pages(new uint32[num_dir_pages]);
 103  E :    if (dir_pages.get() == NULL) {
 104  i :      LOG(ERROR) << "Failed to allocate directory pages.";
 105  i :      return false;
 106    :    }
 107  E :    if (!dir_page_stream->Read(dir_pages.get(), num_dir_pages)) {
 108  i :      LOG(ERROR) << "Failed to read directory page stream.";
 109  i :      return false;
 110    :    }
 111    :  
 112    :    // Load the actual directory.
 113  E :    int dir_size = static_cast<int>(header.directory_size / sizeof(uint32));
 114    :    scoped_refptr<PdbFileStream> dir_stream(new PdbFileStream(
 115  E :        file, header.directory_size, dir_pages.get(), header.page_size));
 116  E :    std::vector<uint32> directory(dir_size);
 117  E :    if (!dir_stream->Read(&directory[0], dir_size)) {
 118  i :      LOG(ERROR) << "Failed to read directory stream.";
 119  i :      return false;
 120    :    }
 121    :  
 122    :    // Iterate through the streams and construct PdbStreams.
 123  E :    const uint32& num_streams = directory[0];
 124  E :    const uint32* stream_lengths = &(directory[1]);
 125  E :    const uint32* stream_pages = &(directory[1 + num_streams]);
 126    :  
 127  E :    uint32 page_index = 0;
 128  E :    for (uint32 stream_index = 0; stream_index < num_streams; ++stream_index) {
 129    :      pdb_file->AppendStream(new PdbFileStream(file,
 130    :                                               stream_lengths[stream_index],
 131    :                                               stream_pages + page_index,
 132  E :                                               header.page_size));
 133  E :      page_index += GetNumPages(header, stream_lengths[stream_index]);
 134  E :    }
 135    :  
 136  E :    return true;
 137  E :  }
 138    :  
 139    :  }  // namespace pdb

Coverage information generated Thu Jul 04 09:34:53 2013.