18456b16eSEugene Zelenko //===- DebugStringTableSubsection.cpp - CodeView String Table -------------===// 2591312c5SZachary Turner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6591312c5SZachary Turner // 7591312c5SZachary Turner //===----------------------------------------------------------------------===// 8591312c5SZachary Turner 9591312c5SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 108456b16eSEugene Zelenko #include "llvm/ADT/StringRef.h" 118456b16eSEugene Zelenko #include "llvm/DebugInfo/CodeView/CodeView.h" 12591312c5SZachary Turner #include "llvm/Support/BinaryStreamReader.h" 13591312c5SZachary Turner #include "llvm/Support/BinaryStreamWriter.h" 148456b16eSEugene Zelenko #include "llvm/Support/Error.h" 158456b16eSEugene Zelenko #include <algorithm> 168456b16eSEugene Zelenko #include <cassert> 178456b16eSEugene Zelenko #include <cstdint> 18591312c5SZachary Turner 19591312c5SZachary Turner using namespace llvm; 20591312c5SZachary Turner using namespace llvm::codeview; 21591312c5SZachary Turner DebugStringTableSubsectionRef()22591312c5SZachary TurnerDebugStringTableSubsectionRef::DebugStringTableSubsectionRef() 23591312c5SZachary Turner : DebugSubsectionRef(DebugSubsectionKind::StringTable) {} 24591312c5SZachary Turner initialize(BinaryStreamRef Contents)25591312c5SZachary TurnerError DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) { 26591312c5SZachary Turner Stream = Contents; 27591312c5SZachary Turner return Error::success(); 28591312c5SZachary Turner } 298456b16eSEugene Zelenko initialize(BinaryStreamReader & Reader)301bf77620SZachary TurnerError DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) { 31deb39130SZachary Turner return Reader.readStreamRef(Stream); 321bf77620SZachary Turner } 33591312c5SZachary Turner 34591312c5SZachary Turner Expected<StringRef> getString(uint32_t Offset) const35591312c5SZachary TurnerDebugStringTableSubsectionRef::getString(uint32_t Offset) const { 36591312c5SZachary Turner BinaryStreamReader Reader(Stream); 37591312c5SZachary Turner Reader.setOffset(Offset); 38591312c5SZachary Turner StringRef Result; 39591312c5SZachary Turner if (auto EC = Reader.readCString(Result)) 40*c55cf4afSBill Wendling return std::move(EC); 41591312c5SZachary Turner return Result; 42591312c5SZachary Turner } 43591312c5SZachary Turner DebugStringTableSubsection()44591312c5SZachary TurnerDebugStringTableSubsection::DebugStringTableSubsection() 45591312c5SZachary Turner : DebugSubsection(DebugSubsectionKind::StringTable) {} 46591312c5SZachary Turner insert(StringRef S)47591312c5SZachary Turneruint32_t DebugStringTableSubsection::insert(StringRef S) { 4871d36ad9SZachary Turner auto P = StringToId.insert({S, StringSize}); 49591312c5SZachary Turner 50591312c5SZachary Turner // If a given string didn't exist in the string table, we want to increment 5171d36ad9SZachary Turner // the string table size and insert it into the reverse lookup. 5271d36ad9SZachary Turner if (P.second) { 5371d36ad9SZachary Turner IdToString.insert({P.first->getValue(), P.first->getKey()}); 54591312c5SZachary Turner StringSize += S.size() + 1; // +1 for '\0' 5571d36ad9SZachary Turner } 5671d36ad9SZachary Turner 57591312c5SZachary Turner return P.first->second; 58591312c5SZachary Turner } 59591312c5SZachary Turner calculateSerializedSize() const60591312c5SZachary Turneruint32_t DebugStringTableSubsection::calculateSerializedSize() const { 61591312c5SZachary Turner return StringSize; 62591312c5SZachary Turner } 63591312c5SZachary Turner commit(BinaryStreamWriter & Writer) const64591312c5SZachary TurnerError DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const { 65deb39130SZachary Turner uint32_t Begin = Writer.getOffset(); 66deb39130SZachary Turner uint32_t End = Begin + StringSize; 67591312c5SZachary Turner 68a8cfc29cSZachary Turner // Write a null string at the beginning. 69a8cfc29cSZachary Turner if (auto EC = Writer.writeCString(StringRef())) 70a8cfc29cSZachary Turner return EC; 71a8cfc29cSZachary Turner 7271d36ad9SZachary Turner for (auto &Pair : StringToId) { 73591312c5SZachary Turner StringRef S = Pair.getKey(); 74deb39130SZachary Turner uint32_t Offset = Begin + Pair.getValue(); 75591312c5SZachary Turner Writer.setOffset(Offset); 76591312c5SZachary Turner if (auto EC = Writer.writeCString(S)) 77591312c5SZachary Turner return EC; 78deb39130SZachary Turner assert(Writer.getOffset() <= End); 79591312c5SZachary Turner } 80591312c5SZachary Turner 81deb39130SZachary Turner Writer.setOffset(End); 82a8cfc29cSZachary Turner assert((End - Begin) == StringSize); 83591312c5SZachary Turner return Error::success(); 84591312c5SZachary Turner } 85591312c5SZachary Turner size() const8671d36ad9SZachary Turneruint32_t DebugStringTableSubsection::size() const { return StringToId.size(); } 87591312c5SZachary Turner sortedIds() const88a6fb536eSZachary Turnerstd::vector<uint32_t> DebugStringTableSubsection::sortedIds() const { 89a6fb536eSZachary Turner std::vector<uint32_t> Result; 90a6fb536eSZachary Turner Result.reserve(IdToString.size()); 91a6fb536eSZachary Turner for (const auto &Entry : IdToString) 92a6fb536eSZachary Turner Result.push_back(Entry.first); 930cac726aSFangrui Song llvm::sort(Result); 94a6fb536eSZachary Turner return Result; 95a6fb536eSZachary Turner } 96a6fb536eSZachary Turner getIdForString(StringRef S) const9771d36ad9SZachary Turneruint32_t DebugStringTableSubsection::getIdForString(StringRef S) const { 9871d36ad9SZachary Turner auto Iter = StringToId.find(S); 9971d36ad9SZachary Turner assert(Iter != StringToId.end()); 10071d36ad9SZachary Turner return Iter->second; 10171d36ad9SZachary Turner } 10271d36ad9SZachary Turner getStringForId(uint32_t Id) const10371d36ad9SZachary TurnerStringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const { 10471d36ad9SZachary Turner auto Iter = IdToString.find(Id); 10571d36ad9SZachary Turner assert(Iter != IdToString.end()); 10692dcdda6SZachary Turner return Iter->second; 107591312c5SZachary Turner } 108