1 //===- DebugStringTableSubsection.cpp - CodeView String Table ---*- C++ -*-===// 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/DebugStringTableSubsection.h" 11 12 #include "llvm/Support/BinaryStream.h" 13 #include "llvm/Support/BinaryStreamReader.h" 14 #include "llvm/Support/BinaryStreamWriter.h" 15 16 using namespace llvm; 17 using namespace llvm::codeview; 18 19 DebugStringTableSubsectionRef::DebugStringTableSubsectionRef() 20 : DebugSubsectionRef(DebugSubsectionKind::StringTable) {} 21 22 Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) { 23 Stream = Contents; 24 return Error::success(); 25 } 26 Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) { 27 return Reader.readStreamRef(Stream, Reader.bytesRemaining()); 28 } 29 30 Expected<StringRef> 31 DebugStringTableSubsectionRef::getString(uint32_t Offset) const { 32 BinaryStreamReader Reader(Stream); 33 Reader.setOffset(Offset); 34 StringRef Result; 35 if (auto EC = Reader.readCString(Result)) 36 return std::move(EC); 37 return Result; 38 } 39 40 DebugStringTableSubsection::DebugStringTableSubsection() 41 : DebugSubsection(DebugSubsectionKind::StringTable) {} 42 43 uint32_t DebugStringTableSubsection::insert(StringRef S) { 44 auto P = Strings.insert({S, StringSize}); 45 46 // If a given string didn't exist in the string table, we want to increment 47 // the string table size. 48 if (P.second) 49 StringSize += S.size() + 1; // +1 for '\0' 50 return P.first->second; 51 } 52 53 uint32_t DebugStringTableSubsection::calculateSerializedSize() const { 54 return StringSize; 55 } 56 57 Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const { 58 assert(Writer.bytesRemaining() == StringSize); 59 uint32_t MaxOffset = 1; 60 61 for (auto &Pair : Strings) { 62 StringRef S = Pair.getKey(); 63 uint32_t Offset = Pair.getValue(); 64 Writer.setOffset(Offset); 65 if (auto EC = Writer.writeCString(S)) 66 return EC; 67 MaxOffset = std::max<uint32_t>(MaxOffset, Offset + S.size() + 1); 68 } 69 70 Writer.setOffset(MaxOffset); 71 assert(Writer.bytesRemaining() == 0); 72 return Error::success(); 73 } 74 75 uint32_t DebugStringTableSubsection::size() const { return Strings.size(); } 76 77 uint32_t DebugStringTableSubsection::getStringId(StringRef S) const { 78 auto Iter = Strings.find(S); 79 assert(Iter != Strings.end()); 80 return Iter->second; 81 } 82