diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp | 94 |
1 files changed, 37 insertions, 57 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp index ee32f61..fd3e69d 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp @@ -1,4 +1,5 @@ -//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===// +//===- PDBStringTable.cpp - PDB String Table -----------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -10,7 +11,6 @@ #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/Hash.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" @@ -21,91 +21,71 @@ using namespace llvm; using namespace llvm::support; using namespace llvm::pdb; -uint32_t PDBStringTable::getByteSize() const { return ByteSize; } -uint32_t PDBStringTable::getNameCount() const { return NameCount; } -uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; } -uint32_t PDBStringTable::getSignature() const { return Header->Signature; } +PDBStringTable::PDBStringTable() {} + +Error PDBStringTable::load(BinaryStreamReader &Stream) { + ByteSize = Stream.getLength(); -Error PDBStringTable::readHeader(BinaryStreamReader &Reader) { - if (auto EC = Reader.readObject(Header)) + const PDBStringTableHeader *H; + if (auto EC = Stream.readObject(H)) return EC; - if (Header->Signature != PDBStringTableSignature) + if (H->Signature != PDBStringTableSignature) return make_error<RawError>(raw_error_code::corrupt_file, "Invalid hash table signature"); - if (Header->HashVersion != 1 && Header->HashVersion != 2) + if (H->HashVersion != 1 && H->HashVersion != 2) return make_error<RawError>(raw_error_code::corrupt_file, "Unsupported hash version"); - assert(Reader.bytesRemaining() == 0); - return Error::success(); -} - -Error PDBStringTable::readStrings(BinaryStreamReader &Reader) { - if (auto EC = Strings.initialize(Reader)) { + 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")); - } - - assert(Reader.bytesRemaining() == 0); - return Error::success(); -} -Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) { const support::ulittle32_t *HashCount; - if (auto EC = Reader.readObject(HashCount)) + if (auto EC = Stream.readObject(HashCount)) return EC; - if (auto EC = Reader.readArray(IDs, *HashCount)) { + 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")); - } - return Error::success(); -} - -Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) { - if (auto EC = Reader.readInteger(NameCount)) - return EC; - - assert(Reader.bytesRemaining() == 0); - return Error::success(); -} - -Error PDBStringTable::reload(BinaryStreamReader &Reader) { - - BinaryStreamReader SectionReader; - - std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader)); - if (auto EC = readHeader(SectionReader)) - return EC; - - std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize); - if (auto EC = readStrings(SectionReader)) - return EC; + if (Stream.bytesRemaining() < sizeof(support::ulittle32_t)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Missing name count"); - // We don't know how long the hash table is until we parse it, so let the - // function responsible for doing that figure it out. - if (auto EC = readHashTable(Reader)) + if (auto EC = Stream.readInteger(NameCount)) return EC; - std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t)); - if (auto EC = readEpilogue(SectionReader)) - return EC; + if (Stream.bytesRemaining() > 0) + return make_error<RawError>(raw_error_code::stream_too_long, + "Unexpected bytes found in string table"); - assert(Reader.bytesRemaining() == 0); return Error::success(); } +uint32_t PDBStringTable::getByteSize() const { return ByteSize; } + StringRef PDBStringTable::getStringForID(uint32_t ID) const { - return Strings.getString(ID); + 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 PDBStringTable::getIDForString(StringRef Str) const { - uint32_t Hash = - (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str); + 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) { |