PDBStringTable.cpp revision 317760
1294838Szbb//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===// 2294838Szbb// 3294838Szbb// The LLVM Compiler Infrastructure 4294838Szbb// 5294838Szbb// This file is distributed under the University of Illinois Open Source 6294838Szbb// License. See LICENSE.TXT for details. 7294838Szbb// 8294838Szbb//===----------------------------------------------------------------------===// 9294838Szbb 10294838Szbb#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" 11294838Szbb 12294838Szbb#include "llvm/ADT/ArrayRef.h" 13294838Szbb#include "llvm/DebugInfo/MSF/MappedBlockStream.h" 14294838Szbb#include "llvm/DebugInfo/PDB/Native/Hash.h" 15294838Szbb#include "llvm/DebugInfo/PDB/Native/RawError.h" 16294838Szbb#include "llvm/DebugInfo/PDB/Native/RawTypes.h" 17294838Szbb#include "llvm/Support/BinaryStreamReader.h" 18294838Szbb#include "llvm/Support/Endian.h" 19294838Szbb 20294838Szbbusing namespace llvm; 21294838Szbbusing namespace llvm::support; 22294838Szbbusing namespace llvm::pdb; 23294838Szbb 24294838Szbbuint32_t PDBStringTable::getByteSize() const { return ByteSize; } 25294838Szbbuint32_t PDBStringTable::getNameCount() const { return NameCount; } 26294838Szbbuint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; } 27294838Szbbuint32_t PDBStringTable::getSignature() const { return Header->Signature; } 28294838Szbb 29294838SzbbError PDBStringTable::readHeader(BinaryStreamReader &Reader) { 30294838Szbb if (auto EC = Reader.readObject(Header)) 31294838Szbb return EC; 32294838Szbb 33294838Szbb if (Header->Signature != PDBStringTableSignature) 34294838Szbb return make_error<RawError>(raw_error_code::corrupt_file, 35294838Szbb "Invalid hash table signature"); 36294838Szbb if (Header->HashVersion != 1 && Header->HashVersion != 2) 37294838Szbb return make_error<RawError>(raw_error_code::corrupt_file, 38294838Szbb "Unsupported hash version"); 39294838Szbb 40294838Szbb assert(Reader.bytesRemaining() == 0); 41294838Szbb return Error::success(); 42294838Szbb} 43294838Szbb 44294838SzbbError PDBStringTable::readStrings(BinaryStreamReader &Reader) { 45294838Szbb BinaryStreamRef Stream; 46294838Szbb if (auto EC = Reader.readStreamRef(Stream)) 47294838Szbb return EC; 48294838Szbb 49294838Szbb if (auto EC = Strings.initialize(Stream)) { 50294838Szbb return joinErrors(std::move(EC), 51294838Szbb make_error<RawError>(raw_error_code::corrupt_file, 52294838Szbb "Invalid hash table byte length")); 53294838Szbb } 54294838Szbb 55294838Szbb assert(Reader.bytesRemaining() == 0); 56294838Szbb return Error::success(); 57294838Szbb} 58294838Szbb 59294838SzbbError PDBStringTable::readHashTable(BinaryStreamReader &Reader) { 60294838Szbb const support::ulittle32_t *HashCount; 61294838Szbb if (auto EC = Reader.readObject(HashCount)) 62294838Szbb return EC; 63294838Szbb 64294838Szbb if (auto EC = Reader.readArray(IDs, *HashCount)) { 65294838Szbb return joinErrors(std::move(EC), 66294838Szbb make_error<RawError>(raw_error_code::corrupt_file, 67294838Szbb "Could not read bucket array")); 68294838Szbb } 69294838Szbb 70294838Szbb return Error::success(); 71294838Szbb} 72294838Szbb 73294838SzbbError PDBStringTable::readEpilogue(BinaryStreamReader &Reader) { 74294838Szbb if (auto EC = Reader.readInteger(NameCount)) 75294838Szbb return EC; 76294838Szbb 77294838Szbb assert(Reader.bytesRemaining() == 0); 78294838Szbb return Error::success(); 79294838Szbb} 80294838Szbb 81294838SzbbError PDBStringTable::reload(BinaryStreamReader &Reader) { 82294838Szbb 83294838Szbb BinaryStreamReader SectionReader; 84294838Szbb 85294838Szbb std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader)); 86294838Szbb if (auto EC = readHeader(SectionReader)) 87294838Szbb return EC; 88294838Szbb 89294838Szbb std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize); 90294838Szbb if (auto EC = readStrings(SectionReader)) 91294838Szbb return EC; 92294838Szbb 93294838Szbb // We don't know how long the hash table is until we parse it, so let the 94294838Szbb // function responsible for doing that figure it out. 95294838Szbb if (auto EC = readHashTable(Reader)) 96294838Szbb return EC; 97294838Szbb 98294838Szbb std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t)); 99294838Szbb if (auto EC = readEpilogue(SectionReader)) 100294838Szbb return EC; 101294838Szbb 102294838Szbb assert(Reader.bytesRemaining() == 0); 103294838Szbb return Error::success(); 104294838Szbb} 105294838Szbb 106294838SzbbExpected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const { 107294838Szbb return Strings.getString(ID); 108294838Szbb} 109294838Szbb 110294838SzbbExpected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const { 111294838Szbb uint32_t Hash = 112294838Szbb (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str); 113294838Szbb size_t Count = IDs.size(); 114294838Szbb uint32_t Start = Hash % Count; 115294838Szbb for (size_t I = 0; I < Count; ++I) { 116294838Szbb // The hash is just a starting point for the search, but if it 117294838Szbb // doesn't work we should find the string no matter what, because 118294838Szbb // we iterate the entire array. 119294838Szbb uint32_t Index = (Start + I) % Count; 120294838Szbb 121294838Szbb uint32_t ID = IDs[Index]; 122294838Szbb auto ExpectedStr = getStringForID(ID); 123294838Szbb if (!ExpectedStr) 124294838Szbb return ExpectedStr.takeError(); 125294838Szbb 126294838Szbb if (*ExpectedStr == Str) 127294838Szbb return ID; 128294838Szbb } 129294838Szbb return make_error<RawError>(raw_error_code::no_entry); 130294838Szbb} 131294838Szbb 132294838SzbbFixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const { 133294838Szbb return IDs; 134294838Szbb} 135294838Szbb