18456b16eSEugene 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" 118456b16eSEugene Zelenko #include "llvm/ADT/StringRef.h" 128456b16eSEugene Zelenko #include "llvm/DebugInfo/CodeView/CodeView.h" 13591312c5SZachary Turner #include "llvm/Support/BinaryStreamReader.h" 14591312c5SZachary Turner #include "llvm/Support/BinaryStreamWriter.h" 158456b16eSEugene Zelenko #include "llvm/Support/Error.h" 168456b16eSEugene Zelenko #include <algorithm> 178456b16eSEugene Zelenko #include <cassert> 188456b16eSEugene 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 } 308456b16eSEugene 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) { 4971d36ad9SZachary Turner auto P = StringToId.insert({S, StringSize}); 50591312c5SZachary Turner 51591312c5SZachary Turner // If a given string didn't exist in the string table, we want to increment 5271d36ad9SZachary Turner // the string table size and insert it into the reverse lookup. 5371d36ad9SZachary Turner if (P.second) { 5471d36ad9SZachary Turner IdToString.insert({P.first->getValue(), P.first->getKey()}); 55591312c5SZachary Turner StringSize += S.size() + 1; // +1 for '\0' 5671d36ad9SZachary Turner } 5771d36ad9SZachary Turner 58591312c5SZachary Turner return P.first->second; 59591312c5SZachary Turner } 60591312c5SZachary Turner 61591312c5SZachary Turner uint32_t DebugStringTableSubsection::calculateSerializedSize() const { 62591312c5SZachary Turner return StringSize; 63591312c5SZachary Turner } 64591312c5SZachary Turner 65591312c5SZachary Turner Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const { 66deb39130SZachary Turner uint32_t Begin = Writer.getOffset(); 67deb39130SZachary Turner uint32_t End = Begin + StringSize; 68591312c5SZachary Turner 69a8cfc29cSZachary Turner // Write a null string at the beginning. 70a8cfc29cSZachary Turner if (auto EC = Writer.writeCString(StringRef())) 71a8cfc29cSZachary Turner return EC; 72a8cfc29cSZachary Turner 7371d36ad9SZachary Turner for (auto &Pair : StringToId) { 74591312c5SZachary Turner StringRef S = Pair.getKey(); 75deb39130SZachary Turner uint32_t Offset = Begin + Pair.getValue(); 76591312c5SZachary Turner Writer.setOffset(Offset); 77591312c5SZachary Turner if (auto EC = Writer.writeCString(S)) 78591312c5SZachary Turner return EC; 79deb39130SZachary Turner assert(Writer.getOffset() <= End); 80591312c5SZachary Turner } 81591312c5SZachary Turner 82deb39130SZachary Turner Writer.setOffset(End); 83a8cfc29cSZachary Turner assert((End - Begin) == StringSize); 84591312c5SZachary Turner return Error::success(); 85591312c5SZachary Turner } 86591312c5SZachary Turner 8771d36ad9SZachary Turner uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); } 88591312c5SZachary Turner 89a6fb536eSZachary Turner std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const { 90a6fb536eSZachary Turner std::vector<uint32_t> Result; 91a6fb536eSZachary Turner Result.reserve(IdToString.size()); 92a6fb536eSZachary Turner for (const auto &Entry : IdToString) 93a6fb536eSZachary Turner Result.push_back(Entry.first); 94*0cac726aSFangrui Song llvm::sort(Result); 95a6fb536eSZachary Turner return Result; 96a6fb536eSZachary Turner } 97a6fb536eSZachary Turner 9871d36ad9SZachary Turner uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const { 9971d36ad9SZachary Turner auto Iter = StringToId.find(S); 10071d36ad9SZachary Turner assert(Iter != StringToId.end()); 10171d36ad9SZachary Turner return Iter->second; 10271d36ad9SZachary Turner } 10371d36ad9SZachary Turner 10471d36ad9SZachary Turner StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const { 10571d36ad9SZachary Turner auto Iter = IdToString.find(Id); 10671d36ad9SZachary Turner assert(Iter != IdToString.end()); 10792dcdda6SZachary Turner return Iter->second; 108591312c5SZachary Turner } 109