1320572Sdim//===- DebugStringTableSubsection.cpp - CodeView String Table -------------===// 2319230Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6319230Sdim// 7319230Sdim//===----------------------------------------------------------------------===// 8319230Sdim 9319230Sdim#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 10320572Sdim#include "llvm/ADT/StringRef.h" 11320572Sdim#include "llvm/DebugInfo/CodeView/CodeView.h" 12319230Sdim#include "llvm/Support/BinaryStreamReader.h" 13319230Sdim#include "llvm/Support/BinaryStreamWriter.h" 14320572Sdim#include "llvm/Support/Error.h" 15320572Sdim#include <algorithm> 16320572Sdim#include <cassert> 17320572Sdim#include <cstdint> 18319230Sdim 19319230Sdimusing namespace llvm; 20319230Sdimusing namespace llvm::codeview; 21319230Sdim 22319230SdimDebugStringTableSubsectionRef::DebugStringTableSubsectionRef() 23319230Sdim : DebugSubsectionRef(DebugSubsectionKind::StringTable) {} 24319230Sdim 25319230SdimError DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) { 26319230Sdim Stream = Contents; 27319230Sdim return Error::success(); 28319230Sdim} 29320572Sdim 30319799SdimError DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) { 31319799Sdim return Reader.readStreamRef(Stream); 32319799Sdim} 33319230Sdim 34319230SdimExpected<StringRef> 35319230SdimDebugStringTableSubsectionRef::getString(uint32_t Offset) const { 36319230Sdim BinaryStreamReader Reader(Stream); 37319230Sdim Reader.setOffset(Offset); 38319230Sdim StringRef Result; 39319230Sdim if (auto EC = Reader.readCString(Result)) 40319230Sdim return std::move(EC); 41319230Sdim return Result; 42319230Sdim} 43319230Sdim 44319230SdimDebugStringTableSubsection::DebugStringTableSubsection() 45319230Sdim : DebugSubsection(DebugSubsectionKind::StringTable) {} 46319230Sdim 47319230Sdimuint32_t DebugStringTableSubsection::insert(StringRef S) { 48341825Sdim auto P = StringToId.insert({S, StringSize}); 49319230Sdim 50319230Sdim // If a given string didn't exist in the string table, we want to increment 51341825Sdim // the string table size and insert it into the reverse lookup. 52341825Sdim if (P.second) { 53341825Sdim IdToString.insert({P.first->getValue(), P.first->getKey()}); 54319230Sdim StringSize += S.size() + 1; // +1 for '\0' 55341825Sdim } 56341825Sdim 57319230Sdim return P.first->second; 58319230Sdim} 59319230Sdim 60319230Sdimuint32_t DebugStringTableSubsection::calculateSerializedSize() const { 61319230Sdim return StringSize; 62319230Sdim} 63319230Sdim 64319230SdimError DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const { 65319799Sdim uint32_t Begin = Writer.getOffset(); 66319799Sdim uint32_t End = Begin + StringSize; 67319230Sdim 68320041Sdim // Write a null string at the beginning. 69320041Sdim if (auto EC = Writer.writeCString(StringRef())) 70320041Sdim return EC; 71320041Sdim 72341825Sdim for (auto &Pair : StringToId) { 73319230Sdim StringRef S = Pair.getKey(); 74319799Sdim uint32_t Offset = Begin + Pair.getValue(); 75319230Sdim Writer.setOffset(Offset); 76319230Sdim if (auto EC = Writer.writeCString(S)) 77319230Sdim return EC; 78319799Sdim assert(Writer.getOffset() <= End); 79319230Sdim } 80319230Sdim 81319799Sdim Writer.setOffset(End); 82320041Sdim assert((End - Begin) == StringSize); 83319230Sdim return Error::success(); 84319230Sdim} 85319230Sdim 86341825Sdimuint32_t DebugStringTableSubsection::size() const { return StringToId.size(); } 87319230Sdim 88341825Sdimstd::vector<uint32_t> DebugStringTableSubsection::sortedIds() const { 89341825Sdim std::vector<uint32_t> Result; 90341825Sdim Result.reserve(IdToString.size()); 91341825Sdim for (const auto &Entry : IdToString) 92341825Sdim Result.push_back(Entry.first); 93344779Sdim llvm::sort(Result); 94341825Sdim return Result; 95341825Sdim} 96341825Sdim 97341825Sdimuint32_t DebugStringTableSubsection::getIdForString(StringRef S) const { 98341825Sdim auto Iter = StringToId.find(S); 99341825Sdim assert(Iter != StringToId.end()); 100319547Sdim return Iter->second; 101319230Sdim} 102341825Sdim 103341825SdimStringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const { 104341825Sdim auto Iter = IdToString.find(Id); 105341825Sdim assert(Iter != IdToString.end()); 106341825Sdim return Iter->second; 107341825Sdim} 108