blob: 1445f0bd9e1be0f54f7d3a869c3cc4a66834a1a0 [file] [log] [blame]
Zachary Turner67c56012017-04-27 16:11:19 +00001//===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===//
Zachary Turner06c2b4b2016-05-09 17:45:21 +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 Turner06c2b4b2016-05-09 17:45:21 +00006//
7//===----------------------------------------------------------------------===//
8
Zachary Turner67c56012017-04-27 16:11:19 +00009#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
Eugene Zelenko570e39a2016-11-23 23:16:32 +000010#include "llvm/ADT/iterator_range.h"
Eugene Zelenko4fcfc192017-06-30 23:06:03 +000011#include "llvm/DebugInfo/CodeView/CodeView.h"
12#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
Zachary Turnerbb3d7e52018-12-17 16:15:36 +000013#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
Eugene Zelenko570e39a2016-11-23 23:16:32 +000014#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
Zachary Turnerbb3d7e52018-12-17 16:15:36 +000015#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
Zachary Turner67c56012017-04-27 16:11:19 +000016#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
Alexandre Ganea4aeea4c2019-03-18 19:13:23 +000017#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000018#include "llvm/DebugInfo/PDB/Native/RawError.h"
Zachary Turnerd9dc2822017-03-02 20:52:51 +000019#include "llvm/Support/BinaryStreamReader.h"
20#include "llvm/Support/BinaryStreamRef.h"
Eugene Zelenko570e39a2016-11-23 23:16:32 +000021#include "llvm/Support/Error.h"
22#include <algorithm>
23#include <cstdint>
Zachary Turner06c2b4b2016-05-09 17:45:21 +000024
25using namespace llvm;
Zachary Turnerc37cb0c2017-04-27 16:12:16 +000026using namespace llvm::codeview;
Zachary Turnerbac69d32016-07-22 19:56:05 +000027using namespace llvm::msf;
Zachary Turner06c2b4b2016-05-09 17:45:21 +000028using namespace llvm::pdb;
29
Zachary Turner7cc13e52017-05-01 16:46:39 +000030ModuleDebugStreamRef::ModuleDebugStreamRef(
31 const DbiModuleDescriptor &Module,
32 std::unique_ptr<MappedBlockStream> Stream)
Zachary Turnera1657a92016-06-08 17:26:39 +000033 : Mod(Module), Stream(std::move(Stream)) {}
Zachary Turner06c2b4b2016-05-09 17:45:21 +000034
Zachary Turner7cc13e52017-05-01 16:46:39 +000035ModuleDebugStreamRef::~ModuleDebugStreamRef() = default;
Zachary Turner06c2b4b2016-05-09 17:45:21 +000036
Zachary Turner7cc13e52017-05-01 16:46:39 +000037Error ModuleDebugStreamRef::reload() {
Zachary Turner120faca2017-02-27 22:11:43 +000038 BinaryStreamReader Reader(*Stream);
Zachary Turner06c2b4b2016-05-09 17:45:21 +000039
Alexandre Ganea4aeea4c2019-03-18 19:13:23 +000040 if (Mod.getModuleStreamIndex() != llvm::pdb::kInvalidStreamIndex) {
41 if (Error E = reloadSerialize(Reader))
42 return E;
43 }
44 if (Reader.bytesRemaining() > 0)
45 return make_error<RawError>(raw_error_code::corrupt_file,
46 "Unexpected bytes in module stream.");
47 return Error::success();
48}
49
50Error ModuleDebugStreamRef::reloadSerialize(BinaryStreamReader &Reader) {
Zachary Turner06c2b4b2016-05-09 17:45:21 +000051 uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
Zachary Turner5b6e4e02017-04-29 01:13:21 +000052 uint32_t C11Size = Mod.getC11LineInfoByteSize();
Zachary Turner06c2b4b2016-05-09 17:45:21 +000053 uint32_t C13Size = Mod.getC13LineInfoByteSize();
54
55 if (C11Size > 0 && C13Size > 0)
Eugene Zelenko570e39a2016-11-23 23:16:32 +000056 return make_error<RawError>(raw_error_code::corrupt_file,
57 "Module has both C11 and C13 line info");
Zachary Turner06c2b4b2016-05-09 17:45:21 +000058
Zachary Turner120faca2017-02-27 22:11:43 +000059 BinaryStreamRef S;
Zachary Turner1de49c92016-05-27 18:47:20 +000060
Zachary Turner695ed562017-02-28 00:04:07 +000061 if (auto EC = Reader.readInteger(Signature))
Zachary Turner06c2b4b2016-05-09 17:45:21 +000062 return EC;
Zachary Turner579264b2018-12-06 16:55:00 +000063 Reader.setOffset(0);
64 if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize))
Zachary Turnerfa332822017-06-23 23:08:57 +000065 return EC;
66 if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
67 return EC;
68 if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size))
Zachary Turner1de49c92016-05-27 18:47:20 +000069 return EC;
70
Zachary Turnerfa332822017-06-23 23:08:57 +000071 BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
Zachary Turner579264b2018-12-06 16:55:00 +000072 if (auto EC = SymbolReader.readArray(
73 SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t)))
Zachary Turner06c2b4b2016-05-09 17:45:21 +000074 return EC;
Zachary Turner7eb6d352016-06-02 20:11:22 +000075
Zachary Turnerfa332822017-06-23 23:08:57 +000076 BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
Zachary Turner92dcdda2017-06-02 19:49:14 +000077 if (auto EC = SubsectionsReader.readArray(Subsections,
78 SubsectionsReader.bytesRemaining()))
Zachary Turner93839cb2016-06-02 05:07:49 +000079 return EC;
Zachary Turner06c2b4b2016-05-09 17:45:21 +000080
81 uint32_t GlobalRefsSize;
Zachary Turner695ed562017-02-28 00:04:07 +000082 if (auto EC = Reader.readInteger(GlobalRefsSize))
Zachary Turner06c2b4b2016-05-09 17:45:21 +000083 return EC;
Zachary Turnerfa332822017-06-23 23:08:57 +000084 if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize))
Zachary Turner06c2b4b2016-05-09 17:45:21 +000085 return EC;
Zachary Turner06c2b4b2016-05-09 17:45:21 +000086 return Error::success();
87}
88
Zachary Turnerbb3d7e52018-12-17 16:15:36 +000089const codeview::CVSymbolArray
90ModuleDebugStreamRef::getSymbolArrayForScope(uint32_t ScopeBegin) const {
91 return limitSymbolArrayToScope(SymbolArray, ScopeBegin);
92}
93
Zachary Turnerfa332822017-06-23 23:08:57 +000094BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const {
95 return SymbolsSubstream;
96}
97
98BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const {
99 return C11LinesSubstream;
100}
101
102BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const {
103 return C13LinesSubstream;
104}
105
106BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const {
107 return GlobalRefsSubstream;
108}
109
Zachary Turner0d43c1c2016-05-28 05:21:57 +0000110iterator_range<codeview::CVSymbolArray::Iterator>
Zachary Turner7cc13e52017-05-01 16:46:39 +0000111ModuleDebugStreamRef::symbols(bool *HadError) const {
Zachary Turnerfa332822017-06-23 23:08:57 +0000112 return make_range(SymbolArray.begin(HadError), SymbolArray.end());
Zachary Turner06c2b4b2016-05-09 17:45:21 +0000113}
Zachary Turner7eb6d352016-06-02 20:11:22 +0000114
Zachary Turner94926a62018-10-08 04:19:16 +0000115CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const {
Zachary Turner579264b2018-12-06 16:55:00 +0000116 auto Iter = SymbolArray.at(Offset);
Zachary Turner94926a62018-10-08 04:19:16 +0000117 assert(Iter != SymbolArray.end());
118 return *Iter;
119}
120
Eugene Zelenko4fcfc192017-06-30 23:06:03 +0000121iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
Zachary Turner92dcdda2017-06-02 19:49:14 +0000122ModuleDebugStreamRef::subsections() const {
123 return make_range(Subsections.begin(), Subsections.end());
Zachary Turner7eb6d352016-06-02 20:11:22 +0000124}
Zachary Turner8848a7a2016-07-06 18:05:57 +0000125
Zachary Turner92dcdda2017-06-02 19:49:14 +0000126bool ModuleDebugStreamRef::hasDebugSubsections() const {
Zachary Turnerfa332822017-06-23 23:08:57 +0000127 return !C13LinesSubstream.empty();
Zachary Turneree3b9c22017-04-25 20:22:02 +0000128}
129
Zachary Turner7cc13e52017-05-01 16:46:39 +0000130Error ModuleDebugStreamRef::commit() { return Error::success(); }
Zachary Turner92dcdda2017-06-02 19:49:14 +0000131
132Expected<codeview::DebugChecksumsSubsectionRef>
133ModuleDebugStreamRef::findChecksumsSubsection() const {
Zachary Turner349c18f2017-06-05 21:40:33 +0000134 codeview::DebugChecksumsSubsectionRef Result;
Zachary Turner92dcdda2017-06-02 19:49:14 +0000135 for (const auto &SS : subsections()) {
136 if (SS.kind() != DebugSubsectionKind::FileChecksums)
137 continue;
138
Zachary Turner92dcdda2017-06-02 19:49:14 +0000139 if (auto EC = Result.initialize(SS.getRecordData()))
140 return std::move(EC);
141 return Result;
142 }
Zachary Turner349c18f2017-06-05 21:40:33 +0000143 return Result;
Zachary Turner92dcdda2017-06-02 19:49:14 +0000144}