blob: ee32f61f16fa322fcab1e44042a6b01fb62a35ea [file] [log] [blame]
Zachary Turnerc504ae32017-05-03 15:58:37 +00001//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
Zachary Turner0eace0b2016-05-02 18:09:14 +00002//
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
Zachary Turnere204a6c2017-05-02 18:00:13 +000010#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
Zachary Turner0eace0b2016-05-02 18:09:14 +000011
12#include "llvm/ADT/ArrayRef.h"
Zachary Turnerc504ae32017-05-03 15:58:37 +000013#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000014#include "llvm/DebugInfo/PDB/Native/Hash.h"
15#include "llvm/DebugInfo/PDB/Native/RawError.h"
16#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
Zachary Turnerd9dc2822017-03-02 20:52:51 +000017#include "llvm/Support/BinaryStreamReader.h"
Zachary Turner0eace0b2016-05-02 18:09:14 +000018#include "llvm/Support/Endian.h"
19
20using namespace llvm;
21using namespace llvm::support;
22using namespace llvm::pdb;
23
Zachary Turnerc504ae32017-05-03 15:58:37 +000024uint32_t PDBStringTable::getByteSize() const { return ByteSize; }
25uint32_t PDBStringTable::getNameCount() const { return NameCount; }
26uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
27uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
Zachary Turner0eace0b2016-05-02 18:09:14 +000028
Zachary Turnerc504ae32017-05-03 15:58:37 +000029Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
30 if (auto EC = Reader.readObject(Header))
Zachary Turner819e77d2016-05-06 20:51:57 +000031 return EC;
32
Zachary Turnerc504ae32017-05-03 15:58:37 +000033 if (Header->Signature != PDBStringTableSignature)
Zachary Turner819e77d2016-05-06 20:51:57 +000034 return make_error<RawError>(raw_error_code::corrupt_file,
35 "Invalid hash table signature");
Zachary Turnerc504ae32017-05-03 15:58:37 +000036 if (Header->HashVersion != 1 && Header->HashVersion != 2)
Zachary Turner819e77d2016-05-06 20:51:57 +000037 return make_error<RawError>(raw_error_code::corrupt_file,
38 "Unsupported hash version");
Zachary Turner0eace0b2016-05-02 18:09:14 +000039
Zachary Turnerc504ae32017-05-03 15:58:37 +000040 assert(Reader.bytesRemaining() == 0);
41 return Error::success();
42}
43
44Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
45 if (auto EC = Strings.initialize(Reader)) {
David Majnemer836937e2016-05-27 16:16:56 +000046 return joinErrors(std::move(EC),
47 make_error<RawError>(raw_error_code::corrupt_file,
48 "Invalid hash table byte length"));
Zachary Turnerc504ae32017-05-03 15:58:37 +000049 }
Zachary Turner0eace0b2016-05-02 18:09:14 +000050
Zachary Turnerc504ae32017-05-03 15:58:37 +000051 assert(Reader.bytesRemaining() == 0);
52 return Error::success();
53}
54
55Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
Zachary Turner8dbe3622016-05-27 01:54:44 +000056 const support::ulittle32_t *HashCount;
Zachary Turnerc504ae32017-05-03 15:58:37 +000057 if (auto EC = Reader.readObject(HashCount))
Zachary Turner819e77d2016-05-06 20:51:57 +000058 return EC;
59
Zachary Turnerc504ae32017-05-03 15:58:37 +000060 if (auto EC = Reader.readArray(IDs, *HashCount)) {
David Majnemer836937e2016-05-27 16:16:56 +000061 return joinErrors(std::move(EC),
62 make_error<RawError>(raw_error_code::corrupt_file,
63 "Could not read bucket array"));
Zachary Turnerc504ae32017-05-03 15:58:37 +000064 }
Zachary Turnerf1220082017-03-15 22:19:30 +000065
Zachary Turner819e77d2016-05-06 20:51:57 +000066 return Error::success();
Zachary Turner0eace0b2016-05-02 18:09:14 +000067}
68
Zachary Turnerc504ae32017-05-03 15:58:37 +000069Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
70 if (auto EC = Reader.readInteger(NameCount))
71 return EC;
72
73 assert(Reader.bytesRemaining() == 0);
74 return Error::success();
75}
76
77Error PDBStringTable::reload(BinaryStreamReader &Reader) {
78
79 BinaryStreamReader SectionReader;
80
81 std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
82 if (auto EC = readHeader(SectionReader))
83 return EC;
84
85 std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
86 if (auto EC = readStrings(SectionReader))
87 return EC;
88
89 // We don't know how long the hash table is until we parse it, so let the
90 // function responsible for doing that figure it out.
91 if (auto EC = readHashTable(Reader))
92 return EC;
93
94 std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
95 if (auto EC = readEpilogue(SectionReader))
96 return EC;
97
98 assert(Reader.bytesRemaining() == 0);
99 return Error::success();
100}
Zachary Turnerf1220082017-03-15 22:19:30 +0000101
Zachary Turnere204a6c2017-05-02 18:00:13 +0000102StringRef PDBStringTable::getStringForID(uint32_t ID) const {
Zachary Turnerc504ae32017-05-03 15:58:37 +0000103 return Strings.getString(ID);
Zachary Turner0eace0b2016-05-02 18:09:14 +0000104}
105
Zachary Turnere204a6c2017-05-02 18:00:13 +0000106uint32_t PDBStringTable::getIDForString(StringRef Str) const {
Zachary Turnerc504ae32017-05-03 15:58:37 +0000107 uint32_t Hash =
108 (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
Zachary Turner0eace0b2016-05-02 18:09:14 +0000109 size_t Count = IDs.size();
110 uint32_t Start = Hash % Count;
111 for (size_t I = 0; I < Count; ++I) {
112 // The hash is just a starting point for the search, but if it
113 // doesn't work we should find the string no matter what, because
114 // we iterate the entire array.
115 uint32_t Index = (Start + I) % Count;
116
117 uint32_t ID = IDs[Index];
118 StringRef S = getStringForID(ID);
119 if (S == Str)
120 return ID;
121 }
122 // IDs[0] contains the ID of the "invalid" entry.
123 return IDs[0];
124}
125
Zachary Turnere204a6c2017-05-02 18:00:13 +0000126FixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {
Zachary Turnerb393d952016-05-27 03:51:53 +0000127 return IDs;
128}