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

Generated by: LCOV version 1.13