1 //===-- MemoryTypeTableBuilder.cpp ----------------------------------------===//
2 //
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
10 #include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
11 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
12
13 using namespace llvm;
14 using namespace codeview;
15
writeRecord(StringRef Data)16 TypeIndex MemoryTypeTableBuilder::writeRecord(StringRef Data) {
17 assert(Data.size() <= UINT16_MAX);
18 auto I = HashedRecords.find(Data);
19 if (I != HashedRecords.end()) {
20 return I->second;
21 }
22
23 // The record provided by the user lacks the 2 byte size field prefix and is
24 // not padded to 4 bytes. Ultimately, that is what gets emitted in the object
25 // file, so pad it out now.
26 const int SizeOfRecLen = 2;
27 const int Align = 4;
28 int TotalSize = alignTo(Data.size() + SizeOfRecLen, Align);
29 assert(TotalSize - SizeOfRecLen <= UINT16_MAX);
30 char *Mem =
31 reinterpret_cast<char *>(RecordStorage.Allocate(TotalSize, Align));
32 *reinterpret_cast<ulittle16_t *>(Mem) = uint16_t(TotalSize - SizeOfRecLen);
33 memcpy(Mem + SizeOfRecLen, Data.data(), Data.size());
34 for (int I = Data.size() + SizeOfRecLen; I < TotalSize; ++I)
35 Mem[I] = LF_PAD0 + (TotalSize - I);
36
37 TypeIndex TI(static_cast<uint32_t>(Records.size()) +
38 TypeIndex::FirstNonSimpleIndex);
39
40 // Use only the data supplied by the user as a key to the hash table, so that
41 // future lookups will succeed.
42 HashedRecords.insert(std::make_pair(StringRef(Mem + SizeOfRecLen, Data.size()), TI));
43 Records.push_back(StringRef(Mem, TotalSize));
44
45 return TI;
46 }
47