LCOV - code coverage report
Current view: top level - lib/DebugInfo/PDB/Raw - StringTable.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 33 47 70.2 %
Date: 2017-01-24 23:09:07 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- StringTable.cpp - PDB String Table -----------------------*- 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             : #include "llvm/DebugInfo/PDB/Raw/StringTable.h"
      11             : 
      12             : #include "llvm/ADT/ArrayRef.h"
      13             : #include "llvm/DebugInfo/MSF/StreamReader.h"
      14             : #include "llvm/DebugInfo/PDB/Raw/Hash.h"
      15             : #include "llvm/DebugInfo/PDB/Raw/RawError.h"
      16             : #include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
      17             : #include "llvm/Support/Endian.h"
      18             : 
      19             : using namespace llvm;
      20             : using namespace llvm::msf;
      21             : using namespace llvm::support;
      22             : using namespace llvm::pdb;
      23             : 
      24          51 : StringTable::StringTable() : Signature(0), HashVersion(0), NameCount(0) {}
      25             : 
      26          15 : Error StringTable::load(StreamReader &Stream) {
      27             :   const StringTableHeader *H;
      28          45 :   if (auto EC = Stream.readObject(H))
      29           0 :     return EC;
      30             : 
      31          30 :   if (H->Signature != StringTableSignature)
      32             :     return make_error<RawError>(raw_error_code::corrupt_file,
      33           0 :                                 "Invalid hash table signature");
      34          30 :   if (H->HashVersion != 1 && H->HashVersion != 2)
      35             :     return make_error<RawError>(raw_error_code::corrupt_file,
      36           0 :                                 "Unsupported hash version");
      37             : 
      38          30 :   Signature = H->Signature;
      39          30 :   HashVersion = H->HashVersion;
      40          60 :   if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize))
      41           0 :     return joinErrors(std::move(EC),
      42           0 :                       make_error<RawError>(raw_error_code::corrupt_file,
      43           0 :                                            "Invalid hash table byte length"));
      44             : 
      45             :   const support::ulittle32_t *HashCount;
      46          45 :   if (auto EC = Stream.readObject(HashCount))
      47           0 :     return EC;
      48             : 
      49          60 :   if (auto EC = Stream.readArray(IDs, *HashCount))
      50           0 :     return joinErrors(std::move(EC),
      51           0 :                       make_error<RawError>(raw_error_code::corrupt_file,
      52           0 :                                            "Could not read bucket array"));
      53             : 
      54          15 :   if (Stream.bytesRemaining() < sizeof(support::ulittle32_t))
      55             :     return make_error<RawError>(raw_error_code::corrupt_file,
      56           0 :                                 "Missing name count");
      57             : 
      58          45 :   if (auto EC = Stream.readInteger(NameCount))
      59           0 :     return EC;
      60          45 :   return Error::success();
      61             : }
      62             : 
      63          49 : StringRef StringTable::getStringForID(uint32_t ID) const {
      64          98 :   if (ID == IDs[0])
      65          17 :     return StringRef();
      66             : 
      67             :   // NamesBuffer is a buffer of null terminated strings back to back.  ID is
      68             :   // the starting offset of the string we're looking for.  So just seek into
      69             :   // the desired offset and a read a null terminated stream from that offset.
      70          32 :   StringRef Result;
      71          32 :   StreamReader NameReader(NamesBuffer);
      72          64 :   NameReader.setOffset(ID);
      73          96 :   if (auto EC = NameReader.readZeroString(Result))
      74           0 :     consumeError(std::move(EC));
      75          32 :   return Result;
      76             : }
      77             : 
      78           3 : uint32_t StringTable::getIDForString(StringRef Str) const {
      79           3 :   uint32_t Hash = (HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
      80           6 :   size_t Count = IDs.size();
      81           3 :   uint32_t Start = Hash % Count;
      82           4 :   for (size_t I = 0; I < Count; ++I) {
      83             :     // The hash is just a starting point for the search, but if it
      84             :     // doesn't work we should find the string no matter what, because
      85             :     // we iterate the entire array.
      86           4 :     uint32_t Index = (Start + I) % Count;
      87             : 
      88           8 :     uint32_t ID = IDs[Index];
      89           4 :     StringRef S = getStringForID(ID);
      90           4 :     if (S == Str)
      91           3 :       return ID;
      92             :   }
      93             :   // IDs[0] contains the ID of the "invalid" entry.
      94           0 :   return IDs[0];
      95             : }
      96             : 
      97           6 : FixedStreamArray<support::ulittle32_t> StringTable::name_ids() const {
      98           6 :   return IDs;
      99             : }

Generated by: LCOV version 1.13