blob: 28dc67a9d2ad46ec2896e8a39240fd7a7a89b202 [file] [log] [blame]
Zachary Turner2f09b502016-04-29 17:28:47 +00001//===- NameMap.cpp - PDB Name Map -------------------------------*- C++ -*-===//
Zachary Turnerf34e0162016-04-26 16:20:00 +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 Turner2f09b502016-04-29 17:28:47 +000010#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
Zachary Turnerf34e0162016-04-26 16:20:00 +000011#include "llvm/ADT/BitVector.h"
Zachary Turner6ba65de2016-04-29 17:22:58 +000012#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
Zachary Turnerf34e0162016-04-26 16:20:00 +000013
14using namespace llvm;
Zachary Turner2f09b502016-04-29 17:28:47 +000015using namespace llvm::pdb;
Zachary Turnerf34e0162016-04-26 16:20:00 +000016
Zachary Turner2f09b502016-04-29 17:28:47 +000017NameMap::NameMap() {}
Zachary Turnerf34e0162016-04-26 16:20:00 +000018
Zachary Turner2f09b502016-04-29 17:28:47 +000019std::error_code NameMap::load(StreamReader &Stream) {
Zachary Turner6ba65de2016-04-29 17:22:58 +000020
Zachary Turnerf34e0162016-04-26 16:20:00 +000021 // This is some sort of weird string-set/hash table encoded in the stream.
22 // It starts with the number of bytes in the table.
23 uint32_t NumberOfBytes;
24 Stream.readInteger(NumberOfBytes);
25
26 // Following that field is the starting offset of strings in the name table.
27 uint32_t StringsOffset = Stream.getOffset();
28 Stream.setOffset(StringsOffset + NumberOfBytes);
29
30 // This appears to be equivalent to the total number of strings *actually*
31 // in the name table.
32 uint32_t HashSize;
33 Stream.readInteger(HashSize);
34
35 // This appears to be an upper bound on the number of strings in the name
36 // table.
37 uint32_t MaxNumberOfStrings;
38 Stream.readInteger(MaxNumberOfStrings);
39
40 // This appears to be a hash table which uses bitfields to determine whether
41 // or not a bucket is 'present'.
42 uint32_t NumPresentWords;
43 Stream.readInteger(NumPresentWords);
44
45 // Store all the 'present' bits in a vector for later processing.
46 SmallVector<uint32_t, 1> PresentWords;
47 for (uint32_t I = 0; I != NumPresentWords; ++I) {
48 uint32_t Word;
49 Stream.readInteger(Word);
50 PresentWords.push_back(Word);
51 }
52
53 // This appears to be a hash table which uses bitfields to determine whether
54 // or not a bucket is 'deleted'.
55 uint32_t NumDeletedWords;
56 Stream.readInteger(NumDeletedWords);
57
58 // Store all the 'deleted' bits in a vector for later processing.
59 SmallVector<uint32_t, 1> DeletedWords;
60 for (uint32_t I = 0; I != NumDeletedWords; ++I) {
61 uint32_t Word;
62 Stream.readInteger(Word);
63 DeletedWords.push_back(Word);
64 }
65
66 BitVector Present(MaxNumberOfStrings, false);
67 if (!PresentWords.empty())
68 Present.setBitsInMask(PresentWords.data(), PresentWords.size());
69 BitVector Deleted(MaxNumberOfStrings, false);
70 if (!DeletedWords.empty())
71 Deleted.setBitsInMask(DeletedWords.data(), DeletedWords.size());
72
73 for (uint32_t I = 0; I < MaxNumberOfStrings; ++I) {
74 if (!Present.test(I))
75 continue;
76
77 // For all present entries, dump out their mapping.
78
79 // This appears to be an offset relative to the start of the strings.
80 // It tells us where the null-terminated string begins.
81 uint32_t NameOffset;
82 Stream.readInteger(NameOffset);
83
84 // This appears to be a stream number into the stream directory.
85 uint32_t NameIndex;
86 Stream.readInteger(NameIndex);
87
88 // Compute the offset of the start of the string relative to the stream.
89 uint32_t StringOffset = StringsOffset + NameOffset;
90 uint32_t OldOffset = Stream.getOffset();
91 // Pump out our c-string from the stream.
92 std::string Str;
93 Stream.setOffset(StringOffset);
94 Stream.readZeroString(Str);
95
96 Stream.setOffset(OldOffset);
97 // Add this to a string-map from name to stream number.
98 Mapping.insert({Str, NameIndex});
99 }
100
101 return std::error_code();
102}
103
Zachary Turner2f09b502016-04-29 17:28:47 +0000104bool NameMap::tryGetValue(StringRef Name, uint32_t &Value) const {
Zachary Turnerf34e0162016-04-26 16:20:00 +0000105 auto Iter = Mapping.find(Name);
106 if (Iter == Mapping.end())
107 return false;
108 Value = Iter->second;
109 return true;
110}