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 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