blob: 63342749918d8e0407a257b735b1bc43590e23f1 [file] [log] [blame]
Eugene Zelenko8456b162017-06-29 00:05:44 +00001//===- DebugStringTableSubsection.cpp - CodeView String Table -------------===//
Zachary Turnerc504ae32017-05-03 15:58:37 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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-exception
Zachary Turnerc504ae32017-05-03 15:58:37 +00006//
7//===----------------------------------------------------------------------===//
8
Zachary Turner591312c2017-05-30 17:13:33 +00009#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
Eugene Zelenko8456b162017-06-29 00:05:44 +000010#include "llvm/ADT/StringRef.h"
11#include "llvm/DebugInfo/CodeView/CodeView.h"
Zachary Turnerc504ae32017-05-03 15:58:37 +000012#include "llvm/Support/BinaryStreamReader.h"
13#include "llvm/Support/BinaryStreamWriter.h"
Eugene Zelenko8456b162017-06-29 00:05:44 +000014#include "llvm/Support/Error.h"
15#include <algorithm>
16#include <cassert>
17#include <cstdint>
Zachary Turnerc504ae32017-05-03 15:58:37 +000018
19using namespace llvm;
20using namespace llvm::codeview;
21
Zachary Turner591312c2017-05-30 17:13:33 +000022DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
23 : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
Zachary Turnerc504ae32017-05-03 15:58:37 +000024
Zachary Turner591312c2017-05-30 17:13:33 +000025Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
Zachary Turner2d5c2cd2017-05-03 17:11:11 +000026 Stream = Contents;
27 return Error::success();
Zachary Turnerc504ae32017-05-03 15:58:37 +000028}
Eugene Zelenko8456b162017-06-29 00:05:44 +000029
Zachary Turner1bf77622017-06-08 23:49:01 +000030Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {
Zachary Turnerdeb39132017-06-09 00:28:08 +000031 return Reader.readStreamRef(Stream);
Zachary Turner1bf77622017-06-08 23:49:01 +000032}
Zachary Turnerc504ae32017-05-03 15:58:37 +000033
Zachary Turner591312c2017-05-30 17:13:33 +000034Expected<StringRef>
35DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
Zachary Turnerc504ae32017-05-03 15:58:37 +000036 BinaryStreamReader Reader(Stream);
37 Reader.setOffset(Offset);
38 StringRef Result;
Zachary Turner2d5c2cd2017-05-03 17:11:11 +000039 if (auto EC = Reader.readCString(Result))
40 return std::move(EC);
Zachary Turnerc504ae32017-05-03 15:58:37 +000041 return Result;
42}
43
Zachary Turner591312c2017-05-30 17:13:33 +000044DebugStringTableSubsection::DebugStringTableSubsection()
45 : DebugSubsection(DebugSubsectionKind::StringTable) {}
46
47uint32_t DebugStringTableSubsection::insert(StringRef S) {
Zachary Turner71d36ad2018-03-22 17:37:28 +000048 auto P = StringToId.insert({S, StringSize});
Zachary Turnerc504ae32017-05-03 15:58:37 +000049
50 // If a given string didn't exist in the string table, we want to increment
Zachary Turner71d36ad2018-03-22 17:37:28 +000051 // the string table size and insert it into the reverse lookup.
52 if (P.second) {
53 IdToString.insert({P.first->getValue(), P.first->getKey()});
Zachary Turnerc504ae32017-05-03 15:58:37 +000054 StringSize += S.size() + 1; // +1 for '\0'
Zachary Turner71d36ad2018-03-22 17:37:28 +000055 }
56
Zachary Turnerc504ae32017-05-03 15:58:37 +000057 return P.first->second;
58}
59
Zachary Turner591312c2017-05-30 17:13:33 +000060uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
61 return StringSize;
62}
Zachary Turnerc504ae32017-05-03 15:58:37 +000063
Zachary Turner591312c2017-05-30 17:13:33 +000064Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
Zachary Turnerdeb39132017-06-09 00:28:08 +000065 uint32_t Begin = Writer.getOffset();
66 uint32_t End = Begin + StringSize;
Zachary Turnerc504ae32017-05-03 15:58:37 +000067
Zachary Turnera8cfc292017-06-14 15:59:27 +000068 // Write a null string at the beginning.
69 if (auto EC = Writer.writeCString(StringRef()))
70 return EC;
71
Zachary Turner71d36ad2018-03-22 17:37:28 +000072 for (auto &Pair : StringToId) {
Zachary Turnerc504ae32017-05-03 15:58:37 +000073 StringRef S = Pair.getKey();
Zachary Turnerdeb39132017-06-09 00:28:08 +000074 uint32_t Offset = Begin + Pair.getValue();
Zachary Turnerc504ae32017-05-03 15:58:37 +000075 Writer.setOffset(Offset);
76 if (auto EC = Writer.writeCString(S))
77 return EC;
Zachary Turnerdeb39132017-06-09 00:28:08 +000078 assert(Writer.getOffset() <= End);
Zachary Turnerc504ae32017-05-03 15:58:37 +000079 }
80
Zachary Turnerdeb39132017-06-09 00:28:08 +000081 Writer.setOffset(End);
Zachary Turnera8cfc292017-06-14 15:59:27 +000082 assert((End - Begin) == StringSize);
Zachary Turnerc504ae32017-05-03 15:58:37 +000083 return Error::success();
84}
85
Zachary Turner71d36ad2018-03-22 17:37:28 +000086uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }
Zachary Turnercf468d82017-05-03 17:11:40 +000087
Zachary Turnera6fb5362018-03-23 18:43:39 +000088std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const {
89 std::vector<uint32_t> Result;
90 Result.reserve(IdToString.size());
91 for (const auto &Entry : IdToString)
92 Result.push_back(Entry.first);
Fangrui Song0cac7262018-09-27 02:13:45 +000093 llvm::sort(Result);
Zachary Turnera6fb5362018-03-23 18:43:39 +000094 return Result;
95}
96
Zachary Turner71d36ad2018-03-22 17:37:28 +000097uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {
98 auto Iter = StringToId.find(S);
99 assert(Iter != StringToId.end());
100 return Iter->second;
101}
102
103StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const {
104 auto Iter = IdToString.find(Id);
105 assert(Iter != IdToString.end());
Zachary Turner92dcdda2017-06-02 19:49:14 +0000106 return Iter->second;
Zachary Turnercf468d82017-05-03 17:11:40 +0000107}