diff options
Diffstat (limited to 'contrib/llvm/lib/DebugInfo/PDB/Native/StringTable.cpp')
| -rw-r--r-- | contrib/llvm/lib/DebugInfo/PDB/Native/StringTable.cpp | 109 | 
1 files changed, 109 insertions, 0 deletions
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Native/StringTable.cpp b/contrib/llvm/lib/DebugInfo/PDB/Native/StringTable.cpp new file mode 100644 index 000000000000..7e28389b8383 --- /dev/null +++ b/contrib/llvm/lib/DebugInfo/PDB/Native/StringTable.cpp @@ -0,0 +1,109 @@ +//===- StringTable.cpp - PDB String Table -----------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Native/StringTable.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/PDB/Native/Hash.h" +#include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" + +using namespace llvm; +using namespace llvm::support; +using namespace llvm::pdb; + +StringTable::StringTable() {} + +Error StringTable::load(BinaryStreamReader &Stream) { +  ByteSize = Stream.getLength(); + +  const StringTableHeader *H; +  if (auto EC = Stream.readObject(H)) +    return EC; + +  if (H->Signature != StringTableSignature) +    return make_error<RawError>(raw_error_code::corrupt_file, +                                "Invalid hash table signature"); +  if (H->HashVersion != 1 && H->HashVersion != 2) +    return make_error<RawError>(raw_error_code::corrupt_file, +                                "Unsupported hash version"); + +  Signature = H->Signature; +  HashVersion = H->HashVersion; +  if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize)) +    return joinErrors(std::move(EC), +                      make_error<RawError>(raw_error_code::corrupt_file, +                                           "Invalid hash table byte length")); + +  const support::ulittle32_t *HashCount; +  if (auto EC = Stream.readObject(HashCount)) +    return EC; + +  if (auto EC = Stream.readArray(IDs, *HashCount)) +    return joinErrors(std::move(EC), +                      make_error<RawError>(raw_error_code::corrupt_file, +                                           "Could not read bucket array")); + +  if (Stream.bytesRemaining() < sizeof(support::ulittle32_t)) +    return make_error<RawError>(raw_error_code::corrupt_file, +                                "Missing name count"); + +  if (auto EC = Stream.readInteger(NameCount)) +    return EC; + +  if (Stream.bytesRemaining() > 0) +    return make_error<RawError>(raw_error_code::stream_too_long, +      "Unexpected bytes found in string table"); + +  return Error::success(); +} + +uint32_t StringTable::getByteSize() const { +  return ByteSize; +} + +StringRef StringTable::getStringForID(uint32_t ID) const { +  if (ID == IDs[0]) +    return StringRef(); + +  // NamesBuffer is a buffer of null terminated strings back to back.  ID is +  // the starting offset of the string we're looking for.  So just seek into +  // the desired offset and a read a null terminated stream from that offset. +  StringRef Result; +  BinaryStreamReader NameReader(NamesBuffer); +  NameReader.setOffset(ID); +  if (auto EC = NameReader.readCString(Result)) +    consumeError(std::move(EC)); +  return Result; +} + +uint32_t StringTable::getIDForString(StringRef Str) const { +  uint32_t Hash = (HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str); +  size_t Count = IDs.size(); +  uint32_t Start = Hash % Count; +  for (size_t I = 0; I < Count; ++I) { +    // The hash is just a starting point for the search, but if it +    // doesn't work we should find the string no matter what, because +    // we iterate the entire array. +    uint32_t Index = (Start + I) % Count; + +    uint32_t ID = IDs[Index]; +    StringRef S = getStringForID(ID); +    if (S == Str) +      return ID; +  } +  // IDs[0] contains the ID of the "invalid" entry. +  return IDs[0]; +} + +FixedStreamArray<support::ulittle32_t> StringTable::name_ids() const { +  return IDs; +}  | 
