107 lines · cpp
1//===- DebugStringTableSubsection.cpp - CodeView String Table -------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/DebugInfo/CodeView/CodeView.h"12#include "llvm/Support/BinaryStreamReader.h"13#include "llvm/Support/BinaryStreamWriter.h"14#include "llvm/Support/Error.h"15#include <cassert>16#include <cstdint>17 18using namespace llvm;19using namespace llvm::codeview;20 21DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()22 : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}23 24Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {25 Stream = Contents;26 return Error::success();27}28 29Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {30 return Reader.readStreamRef(Stream);31}32 33Expected<StringRef>34DebugStringTableSubsectionRef::getString(uint32_t Offset) const {35 BinaryStreamReader Reader(Stream);36 Reader.setOffset(Offset);37 StringRef Result;38 if (auto EC = Reader.readCString(Result))39 return std::move(EC);40 return Result;41}42 43DebugStringTableSubsection::DebugStringTableSubsection()44 : DebugSubsection(DebugSubsectionKind::StringTable) {}45 46uint32_t DebugStringTableSubsection::insert(StringRef S) {47 auto P = StringToId.insert({S, StringSize});48 49 // If a given string didn't exist in the string table, we want to increment50 // the string table size and insert it into the reverse lookup.51 if (P.second) {52 IdToString.insert({P.first->getValue(), P.first->getKey()});53 StringSize += S.size() + 1; // +1 for '\0'54 }55 56 return P.first->second;57}58 59uint32_t DebugStringTableSubsection::calculateSerializedSize() const {60 return StringSize;61}62 63Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {64 uint32_t Begin = Writer.getOffset();65 uint32_t End = Begin + StringSize;66 67 // Write a null string at the beginning.68 if (auto EC = Writer.writeCString(StringRef()))69 return EC;70 71 for (auto &Pair : StringToId) {72 StringRef S = Pair.getKey();73 uint32_t Offset = Begin + Pair.getValue();74 Writer.setOffset(Offset);75 if (auto EC = Writer.writeCString(S))76 return EC;77 assert(Writer.getOffset() <= End);78 }79 80 Writer.setOffset(End);81 assert((End - Begin) == StringSize);82 return Error::success();83}84 85uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }86 87std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const {88 std::vector<uint32_t> Result;89 Result.reserve(IdToString.size());90 for (const auto &Entry : IdToString)91 Result.push_back(Entry.first);92 llvm::sort(Result);93 return Result;94}95 96uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {97 auto Iter = StringToId.find(S);98 assert(Iter != StringToId.end());99 return Iter->second;100}101 102StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const {103 auto Iter = IdToString.find(Id);104 assert(Iter != IdToString.end());105 return Iter->second;106}107