LCOV - code coverage report
Current view: top level - lib/DebugInfo/PDB/Native - GlobalsStream.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 34 53 64.2 %
Date: 2017-09-14 15:23:50 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- GlobalsStream.cpp - PDB Index of Symbols by Name ---- ----*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // The on-disk structores used in this file are based on the reference
      11             : // implementation which is available at
      12             : // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
      13             : //
      14             : // When you are reading the reference source code, you'd find the
      15             : // information below useful.
      16             : //
      17             : //  - ppdb1->m_fMinimalDbgInfo seems to be always true.
      18             : //  - SMALLBUCKETS macro is defined.
      19             : //
      20             : //===----------------------------------------------------------------------===//
      21             : 
      22             : #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
      23             : #include "llvm/DebugInfo/PDB/Native/RawError.h"
      24             : #include "llvm/Support/BinaryStreamReader.h"
      25             : #include "llvm/Support/Error.h"
      26             : #include <algorithm>
      27             : 
      28             : using namespace llvm;
      29             : using namespace llvm::msf;
      30             : using namespace llvm::pdb;
      31             : 
      32          10 : GlobalsStream::GlobalsStream(std::unique_ptr<MappedBlockStream> Stream)
      33          30 :     : Stream(std::move(Stream)) {}
      34             : 
      35             : GlobalsStream::~GlobalsStream() = default;
      36             : 
      37          10 : Error GlobalsStream::reload() {
      38          30 :   BinaryStreamReader Reader(*Stream);
      39          30 :   if (auto E = GlobalsTable.read(Reader))
      40           0 :     return E;
      41          30 :   return Error::success();
      42             : }
      43             : 
      44          26 : static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
      45          52 :   if (HashHdr->VerHdr != GSIHashHeader::HdrVersion)
      46             :     return make_error<RawError>(
      47             :         raw_error_code::feature_unsupported,
      48           0 :         "Encountered unsupported globals stream version.");
      49             : 
      50          78 :   return Error::success();
      51             : }
      52             : 
      53          13 : static Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
      54             :                                BinaryStreamReader &Reader) {
      55          39 :   if (Reader.readObject(HashHdr))
      56             :     return make_error<RawError>(raw_error_code::corrupt_file,
      57           0 :                                 "Stream does not contain a GSIHashHeader.");
      58             : 
      59          26 :   if (HashHdr->VerSignature != GSIHashHeader::HdrSignature)
      60             :     return make_error<RawError>(
      61             :         raw_error_code::feature_unsupported,
      62           0 :         "GSIHashHeader signature (0xffffffff) not found.");
      63             : 
      64          39 :   return Error::success();
      65             : }
      66             : 
      67          13 : static Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
      68             :                                 const GSIHashHeader *HashHdr,
      69             :                                 BinaryStreamReader &Reader) {
      70          39 :   if (auto EC = checkHashHdrVersion(HashHdr))
      71           0 :     return EC;
      72             : 
      73             :   // HashHdr->HrSize specifies the number of bytes of PSHashRecords we have.
      74             :   // Verify that we can read them all.
      75          26 :   if (HashHdr->HrSize % sizeof(PSHashRecord))
      76             :     return make_error<RawError>(raw_error_code::corrupt_file,
      77           0 :                                 "Invalid HR array size.");
      78          26 :   uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord);
      79          39 :   if (auto EC = Reader.readArray(HashRecords, NumHashRecords))
      80           0 :     return joinErrors(std::move(EC),
      81           0 :                       make_error<RawError>(raw_error_code::corrupt_file,
      82           0 :                                            "Error reading hash records."));
      83             : 
      84          39 :   return Error::success();
      85             : }
      86             : 
      87             : static Error
      88          13 : readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
      89             :                    ArrayRef<uint8_t> &HashBitmap, const GSIHashHeader *HashHdr,
      90             :                    BinaryStreamReader &Reader) {
      91          39 :   if (auto EC = checkHashHdrVersion(HashHdr))
      92           0 :     return EC;
      93             : 
      94             :   // Before the actual hash buckets, there is a bitmap of length determined by
      95             :   // IPHR_HASH.
      96          13 :   size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
      97          13 :   uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
      98          39 :   if (auto EC = Reader.readBytes(HashBitmap, NumBitmapEntries))
      99           0 :     return joinErrors(std::move(EC),
     100           0 :                       make_error<RawError>(raw_error_code::corrupt_file,
     101           0 :                                            "Could not read a bitmap."));
     102          13 :   uint32_t NumBuckets = 0;
     103        6734 :   for (uint8_t B : HashBitmap)
     104        6708 :     NumBuckets += countPopulation(B);
     105             : 
     106             :   // Hash buckets follow.
     107          39 :   if (auto EC = Reader.readArray(HashBuckets, NumBuckets))
     108           0 :     return joinErrors(std::move(EC),
     109           0 :                       make_error<RawError>(raw_error_code::corrupt_file,
     110           0 :                                            "Hash buckets corrupted."));
     111             : 
     112          39 :   return Error::success();
     113             : }
     114             : 
     115          13 : Error GSIHashTable::read(BinaryStreamReader &Reader) {
     116          39 :   if (auto EC = readGSIHashHeader(HashHdr, Reader))
     117           0 :     return EC;
     118          39 :   if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader))
     119           0 :     return EC;
     120          39 :   if (auto EC = readGSIHashBuckets(HashBuckets, HashBitmap, HashHdr, Reader))
     121           0 :     return EC;
     122          39 :   return Error::success();
     123             : }

Generated by: LCOV version 1.13