blob: d723282eb7158e3b90889c0c56b8c4b573236198 [file] [log] [blame]
Eugene Zelenko8456b162017-06-29 00:05:44 +00001//===- DebugStringTableSubsection.cpp - CodeView String Table -------------===//
Zachary Turnerc504ae32017-05-03 15:58:37 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Zachary Turner591312c2017-05-30 17:13:33 +000010#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
Eugene Zelenko8456b162017-06-29 00:05:44 +000011#include "llvm/ADT/StringRef.h"
12#include "llvm/DebugInfo/CodeView/CodeView.h"
Zachary Turnerc504ae32017-05-03 15:58:37 +000013#include "llvm/Support/BinaryStreamReader.h"
14#include "llvm/Support/BinaryStreamWriter.h"
Eugene Zelenko8456b162017-06-29 00:05:44 +000015#include "llvm/Support/Error.h"
16#include <algorithm>
17#include <cassert>
18#include <cstdint>
Zachary Turnerc504ae32017-05-03 15:58:37 +000019
20using namespace llvm;
21using namespace llvm::codeview;
22
Zachary Turner591312c2017-05-30 17:13:33 +000023DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
24 : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
Zachary Turnerc504ae32017-05-03 15:58:37 +000025
Zachary Turner591312c2017-05-30 17:13:33 +000026Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
Zachary Turner2d5c2cd2017-05-03 17:11:11 +000027 Stream = Contents;
28 return Error::success();
Zachary Turnerc504ae32017-05-03 15:58:37 +000029}
Eugene Zelenko8456b162017-06-29 00:05:44 +000030
Zachary Turner1bf77622017-06-08 23:49:01 +000031Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {
Zachary Turnerdeb39132017-06-09 00:28:08 +000032 return Reader.readStreamRef(Stream);
Zachary Turner1bf77622017-06-08 23:49:01 +000033}
Zachary Turnerc504ae32017-05-03 15:58:37 +000034
Zachary Turner591312c2017-05-30 17:13:33 +000035Expected<StringRef>
36DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
Zachary Turnerc504ae32017-05-03 15:58:37 +000037 BinaryStreamReader Reader(Stream);
38 Reader.setOffset(Offset);
39 StringRef Result;
Zachary Turner2d5c2cd2017-05-03 17:11:11 +000040 if (auto EC = Reader.readCString(Result))
41 return std::move(EC);
Zachary Turnerc504ae32017-05-03 15:58:37 +000042 return Result;
43}
44
Zachary Turner591312c2017-05-30 17:13:33 +000045DebugStringTableSubsection::DebugStringTableSubsection()
46 : DebugSubsection(DebugSubsectionKind::StringTable) {}
47
48uint32_t DebugStringTableSubsection::insert(StringRef S) {
Zachary Turnerfced5302018-03-20 18:37:03 +000049 auto P = Strings.insert({S, StringSize});
Zachary Turnerc504ae32017-05-03 15:58:37 +000050
51 // If a given string didn't exist in the string table, we want to increment
Zachary Turnerfced5302018-03-20 18:37:03 +000052 // the string table size.
53 if (P.second)
Zachary Turnerc504ae32017-05-03 15:58:37 +000054 StringSize += S.size() + 1; // +1 for '\0'
55 return P.first->second;
56}
57
Zachary Turner591312c2017-05-30 17:13:33 +000058uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
59 return StringSize;
60}
Zachary Turnerc504ae32017-05-03 15:58:37 +000061
Zachary Turner591312c2017-05-30 17:13:33 +000062Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
Zachary Turnerdeb39132017-06-09 00:28:08 +000063 uint32_t Begin = Writer.getOffset();
64 uint32_t End = Begin + StringSize;
Zachary Turnerc504ae32017-05-03 15:58:37 +000065
Zachary Turnera8cfc292017-06-14 15:59:27 +000066 // Write a null string at the beginning.
67 if (auto EC = Writer.writeCString(StringRef()))
68 return EC;
69
Zachary Turnerfced5302018-03-20 18:37:03 +000070 for (auto &Pair : Strings) {
Zachary Turnerc504ae32017-05-03 15:58:37 +000071 StringRef S = Pair.getKey();
Zachary Turnerdeb39132017-06-09 00:28:08 +000072 uint32_t Offset = Begin + Pair.getValue();
Zachary Turnerc504ae32017-05-03 15:58:37 +000073 Writer.setOffset(Offset);
74 if (auto EC = Writer.writeCString(S))
75 return EC;
Zachary Turnerdeb39132017-06-09 00:28:08 +000076 assert(Writer.getOffset() <= End);
Zachary Turnerc504ae32017-05-03 15:58:37 +000077 }
78
Zachary Turnerdeb39132017-06-09 00:28:08 +000079 Writer.setOffset(End);
Zachary Turnera8cfc292017-06-14 15:59:27 +000080 assert((End - Begin) == StringSize);
Zachary Turnerc504ae32017-05-03 15:58:37 +000081 return Error::success();
82}
83
Zachary Turnerfced5302018-03-20 18:37:03 +000084uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
Zachary Turnercf468d82017-05-03 17:11:40 +000085
Zachary Turnerfced5302018-03-20 18:37:03 +000086uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
87 auto Iter = Strings.find(S);
88 assert(Iter != Strings.end());
Zachary Turner92dcdda2017-06-02 19:49:14 +000089 return Iter->second;
Zachary Turnercf468d82017-05-03 17:11:40 +000090}