19df3605dSDimitry Andric //===- SymbolSerializer.cpp -----------------------------------------------===//
271d5a254SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
671d5a254SDimitry Andric //
771d5a254SDimitry Andric //===----------------------------------------------------------------------===//
871d5a254SDimitry Andric
971d5a254SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
109df3605dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
119df3605dSDimitry Andric #include "llvm/Support/Error.h"
12145449b1SDimitry Andric #include "llvm/Support/ErrorHandling.h"
139df3605dSDimitry Andric #include <cassert>
149df3605dSDimitry Andric #include <cstdint>
159df3605dSDimitry Andric #include <cstring>
1671d5a254SDimitry Andric
1771d5a254SDimitry Andric using namespace llvm;
1871d5a254SDimitry Andric using namespace llvm::codeview;
1971d5a254SDimitry Andric
SymbolSerializer(BumpPtrAllocator & Allocator,CodeViewContainer Container)20d288ef4cSDimitry Andric SymbolSerializer::SymbolSerializer(BumpPtrAllocator &Allocator,
21d288ef4cSDimitry Andric CodeViewContainer Container)
22b1c73532SDimitry Andric : Storage(Allocator), Stream(RecordBuffer, llvm::endianness::little),
23b1c73532SDimitry Andric Writer(Stream), Mapping(Writer, Container) {}
2471d5a254SDimitry Andric
visitSymbolBegin(CVSymbol & Record)2571d5a254SDimitry Andric Error SymbolSerializer::visitSymbolBegin(CVSymbol &Record) {
26145449b1SDimitry Andric assert(!CurrentSymbol && "Already in a symbol mapping!");
2771d5a254SDimitry Andric
2871d5a254SDimitry Andric Writer.setOffset(0);
2971d5a254SDimitry Andric
3071d5a254SDimitry Andric if (auto EC = writeRecordPrefix(Record.kind()))
3171d5a254SDimitry Andric return EC;
3271d5a254SDimitry Andric
3371d5a254SDimitry Andric CurrentSymbol = Record.kind();
3471d5a254SDimitry Andric if (auto EC = Mapping.visitSymbolBegin(Record))
3571d5a254SDimitry Andric return EC;
3671d5a254SDimitry Andric
3771d5a254SDimitry Andric return Error::success();
3871d5a254SDimitry Andric }
3971d5a254SDimitry Andric
visitSymbolEnd(CVSymbol & Record)4071d5a254SDimitry Andric Error SymbolSerializer::visitSymbolEnd(CVSymbol &Record) {
41145449b1SDimitry Andric assert(CurrentSymbol && "Not in a symbol mapping!");
4271d5a254SDimitry Andric
4371d5a254SDimitry Andric if (auto EC = Mapping.visitSymbolEnd(Record))
4471d5a254SDimitry Andric return EC;
4571d5a254SDimitry Andric
4671d5a254SDimitry Andric uint32_t RecordEnd = Writer.getOffset();
4771d5a254SDimitry Andric uint16_t Length = RecordEnd - 2;
4871d5a254SDimitry Andric Writer.setOffset(0);
4971d5a254SDimitry Andric if (auto EC = Writer.writeInteger(Length))
5071d5a254SDimitry Andric return EC;
5171d5a254SDimitry Andric
5271d5a254SDimitry Andric uint8_t *StableStorage = Storage.Allocate<uint8_t>(RecordEnd);
5371d5a254SDimitry Andric ::memcpy(StableStorage, &RecordBuffer[0], RecordEnd);
5471d5a254SDimitry Andric Record.RecordData = ArrayRef<uint8_t>(StableStorage, RecordEnd);
5571d5a254SDimitry Andric CurrentSymbol.reset();
5671d5a254SDimitry Andric
5771d5a254SDimitry Andric return Error::success();
5871d5a254SDimitry Andric }
59