1*8456b16eSEugene Zelenko //===- DebugStringTableSubsection.cpp - CodeView String Table -------------===// 2591312c5SZachary Turner // 3591312c5SZachary Turner // The LLVM Compiler Infrastructure 4591312c5SZachary Turner // 5591312c5SZachary Turner // This file is distributed under the University of Illinois Open Source 6591312c5SZachary Turner // License. See LICENSE.TXT for details. 7591312c5SZachary Turner // 8591312c5SZachary Turner //===----------------------------------------------------------------------===// 9591312c5SZachary Turner 10591312c5SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 11*8456b16eSEugene Zelenko #include "llvm/ADT/StringRef.h" 12*8456b16eSEugene Zelenko #include "llvm/DebugInfo/CodeView/CodeView.h" 13591312c5SZachary Turner #include "llvm/Support/BinaryStreamReader.h" 14591312c5SZachary Turner #include "llvm/Support/BinaryStreamWriter.h" 15*8456b16eSEugene Zelenko #include "llvm/Support/Error.h" 16*8456b16eSEugene Zelenko #include <algorithm> 17*8456b16eSEugene Zelenko #include <cassert> 18*8456b16eSEugene Zelenko #include <cstdint> 19591312c5SZachary Turner 20591312c5SZachary Turner using namespace llvm; 21591312c5SZachary Turner using namespace llvm::codeview; 22591312c5SZachary Turner 23591312c5SZachary Turner DebugStringTableSubsectionRef::DebugStringTableSubsectionRef() 24591312c5SZachary Turner : DebugSubsectionRef(DebugSubsectionKind::StringTable) {} 25591312c5SZachary Turner 26591312c5SZachary Turner Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) { 27591312c5SZachary Turner Stream = Contents; 28591312c5SZachary Turner return Error::success(); 29591312c5SZachary Turner } 30*8456b16eSEugene Zelenko 311bf77620SZachary Turner Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) { 32deb39130SZachary Turner return Reader.readStreamRef(Stream); 331bf77620SZachary Turner } 34591312c5SZachary Turner 35591312c5SZachary Turner Expected<StringRef> 36591312c5SZachary Turner DebugStringTableSubsectionRef::getString(uint32_t Offset) const { 37591312c5SZachary Turner BinaryStreamReader Reader(Stream); 38591312c5SZachary Turner Reader.setOffset(Offset); 39591312c5SZachary Turner StringRef Result; 40591312c5SZachary Turner if (auto EC = Reader.readCString(Result)) 41591312c5SZachary Turner return std::move(EC); 42591312c5SZachary Turner return Result; 43591312c5SZachary Turner } 44591312c5SZachary Turner 45591312c5SZachary Turner DebugStringTableSubsection::DebugStringTableSubsection() 46591312c5SZachary Turner : DebugSubsection(DebugSubsectionKind::StringTable) {} 47591312c5SZachary Turner 48591312c5SZachary Turner uint32_t DebugStringTableSubsection::insert(StringRef S) { 49591312c5SZachary Turner auto P = Strings.insert({S, StringSize}); 50591312c5SZachary Turner 51591312c5SZachary Turner // If a given string didn't exist in the string table, we want to increment 52591312c5SZachary Turner // the string table size. 53591312c5SZachary Turner if (P.second) 54591312c5SZachary Turner StringSize += S.size() + 1; // +1 for '\0' 55591312c5SZachary Turner return P.first->second; 56591312c5SZachary Turner } 57591312c5SZachary Turner 58591312c5SZachary Turner uint32_t DebugStringTableSubsection::calculateSerializedSize() const { 59591312c5SZachary Turner return StringSize; 60591312c5SZachary Turner } 61591312c5SZachary Turner 62591312c5SZachary Turner Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const { 63deb39130SZachary Turner uint32_t Begin = Writer.getOffset(); 64deb39130SZachary Turner uint32_t End = Begin + StringSize; 65591312c5SZachary Turner 66a8cfc29cSZachary Turner // Write a null string at the beginning. 67a8cfc29cSZachary Turner if (auto EC = Writer.writeCString(StringRef())) 68a8cfc29cSZachary Turner return EC; 69a8cfc29cSZachary Turner 70591312c5SZachary Turner for (auto &Pair : Strings) { 71591312c5SZachary Turner StringRef S = Pair.getKey(); 72deb39130SZachary Turner uint32_t Offset = Begin + Pair.getValue(); 73591312c5SZachary Turner Writer.setOffset(Offset); 74591312c5SZachary Turner if (auto EC = Writer.writeCString(S)) 75591312c5SZachary Turner return EC; 76deb39130SZachary Turner assert(Writer.getOffset() <= End); 77591312c5SZachary Turner } 78591312c5SZachary Turner 79deb39130SZachary Turner Writer.setOffset(End); 80a8cfc29cSZachary Turner assert((End - Begin) == StringSize); 81591312c5SZachary Turner return Error::success(); 82591312c5SZachary Turner } 83591312c5SZachary Turner 84591312c5SZachary Turner uint32_t DebugStringTableSubsection::size() const { return Strings.size(); } 85591312c5SZachary Turner 86591312c5SZachary Turner uint32_t DebugStringTableSubsection::getStringId(StringRef S) const { 8792dcdda6SZachary Turner auto Iter = Strings.find(S); 8892dcdda6SZachary Turner assert(Iter != Strings.end()); 8992dcdda6SZachary Turner return Iter->second; 90591312c5SZachary Turner } 91