Zachary Turner | 67c5601 | 2017-04-27 16:11:19 +0000 | [diff] [blame] | 1 | //===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===// |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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-exception |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
Zachary Turner | 67c5601 | 2017-04-27 16:11:19 +0000 | [diff] [blame] | 9 | #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" |
Eugene Zelenko | 570e39a | 2016-11-23 23:16:32 +0000 | [diff] [blame] | 10 | #include "llvm/ADT/iterator_range.h" |
Eugene Zelenko | 4fcfc19 | 2017-06-30 23:06:03 +0000 | [diff] [blame] | 11 | #include "llvm/DebugInfo/CodeView/CodeView.h" |
| 12 | #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" |
Zachary Turner | bb3d7e5 | 2018-12-17 16:15:36 +0000 | [diff] [blame] | 13 | #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" |
Eugene Zelenko | 570e39a | 2016-11-23 23:16:32 +0000 | [diff] [blame] | 14 | #include "llvm/DebugInfo/CodeView/SymbolRecord.h" |
Zachary Turner | bb3d7e5 | 2018-12-17 16:15:36 +0000 | [diff] [blame] | 15 | #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" |
Zachary Turner | 67c5601 | 2017-04-27 16:11:19 +0000 | [diff] [blame] | 16 | #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" |
Alexandre Ganea | 4aeea4c | 2019-03-18 19:13:23 +0000 | [diff] [blame] | 17 | #include "llvm/DebugInfo/PDB/Native/RawConstants.h" |
Adrian McCarthy | 6b6b8c4 | 2017-01-25 22:38:55 +0000 | [diff] [blame] | 18 | #include "llvm/DebugInfo/PDB/Native/RawError.h" |
Zachary Turner | d9dc282 | 2017-03-02 20:52:51 +0000 | [diff] [blame] | 19 | #include "llvm/Support/BinaryStreamReader.h" |
| 20 | #include "llvm/Support/BinaryStreamRef.h" |
Eugene Zelenko | 570e39a | 2016-11-23 23:16:32 +0000 | [diff] [blame] | 21 | #include "llvm/Support/Error.h" |
| 22 | #include <algorithm> |
| 23 | #include <cstdint> |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 24 | |
| 25 | using namespace llvm; |
Zachary Turner | c37cb0c | 2017-04-27 16:12:16 +0000 | [diff] [blame] | 26 | using namespace llvm::codeview; |
Zachary Turner | bac69d3 | 2016-07-22 19:56:05 +0000 | [diff] [blame] | 27 | using namespace llvm::msf; |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 28 | using namespace llvm::pdb; |
| 29 | |
Zachary Turner | 7cc13e5 | 2017-05-01 16:46:39 +0000 | [diff] [blame] | 30 | ModuleDebugStreamRef::ModuleDebugStreamRef( |
| 31 | const DbiModuleDescriptor &Module, |
| 32 | std::unique_ptr<MappedBlockStream> Stream) |
Zachary Turner | a1657a9 | 2016-06-08 17:26:39 +0000 | [diff] [blame] | 33 | : Mod(Module), Stream(std::move(Stream)) {} |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 34 | |
Zachary Turner | 7cc13e5 | 2017-05-01 16:46:39 +0000 | [diff] [blame] | 35 | ModuleDebugStreamRef::~ModuleDebugStreamRef() = default; |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 36 | |
Zachary Turner | 7cc13e5 | 2017-05-01 16:46:39 +0000 | [diff] [blame] | 37 | Error ModuleDebugStreamRef::reload() { |
Zachary Turner | 120faca | 2017-02-27 22:11:43 +0000 | [diff] [blame] | 38 | BinaryStreamReader Reader(*Stream); |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 39 | |
Alexandre Ganea | 4aeea4c | 2019-03-18 19:13:23 +0000 | [diff] [blame] | 40 | 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 | |
| 50 | Error ModuleDebugStreamRef::reloadSerialize(BinaryStreamReader &Reader) { |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 51 | uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize(); |
Zachary Turner | 5b6e4e0 | 2017-04-29 01:13:21 +0000 | [diff] [blame] | 52 | uint32_t C11Size = Mod.getC11LineInfoByteSize(); |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 53 | uint32_t C13Size = Mod.getC13LineInfoByteSize(); |
| 54 | |
| 55 | if (C11Size > 0 && C13Size > 0) |
Eugene Zelenko | 570e39a | 2016-11-23 23:16:32 +0000 | [diff] [blame] | 56 | return make_error<RawError>(raw_error_code::corrupt_file, |
| 57 | "Module has both C11 and C13 line info"); |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 58 | |
Zachary Turner | 120faca | 2017-02-27 22:11:43 +0000 | [diff] [blame] | 59 | BinaryStreamRef S; |
Zachary Turner | 1de49c9 | 2016-05-27 18:47:20 +0000 | [diff] [blame] | 60 | |
Zachary Turner | 695ed56 | 2017-02-28 00:04:07 +0000 | [diff] [blame] | 61 | if (auto EC = Reader.readInteger(Signature)) |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 62 | return EC; |
Zachary Turner | 579264b | 2018-12-06 16:55:00 +0000 | [diff] [blame] | 63 | Reader.setOffset(0); |
| 64 | if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize)) |
Zachary Turner | fa33282 | 2017-06-23 23:08:57 +0000 | [diff] [blame] | 65 | return EC; |
| 66 | if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size)) |
| 67 | return EC; |
| 68 | if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size)) |
Zachary Turner | 1de49c9 | 2016-05-27 18:47:20 +0000 | [diff] [blame] | 69 | return EC; |
| 70 | |
Zachary Turner | fa33282 | 2017-06-23 23:08:57 +0000 | [diff] [blame] | 71 | BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData); |
Zachary Turner | 579264b | 2018-12-06 16:55:00 +0000 | [diff] [blame] | 72 | if (auto EC = SymbolReader.readArray( |
| 73 | SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t))) |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 74 | return EC; |
Zachary Turner | 7eb6d35 | 2016-06-02 20:11:22 +0000 | [diff] [blame] | 75 | |
Zachary Turner | fa33282 | 2017-06-23 23:08:57 +0000 | [diff] [blame] | 76 | BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData); |
Zachary Turner | 92dcdda | 2017-06-02 19:49:14 +0000 | [diff] [blame] | 77 | if (auto EC = SubsectionsReader.readArray(Subsections, |
| 78 | SubsectionsReader.bytesRemaining())) |
Zachary Turner | 93839cb | 2016-06-02 05:07:49 +0000 | [diff] [blame] | 79 | return EC; |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 80 | |
| 81 | uint32_t GlobalRefsSize; |
Zachary Turner | 695ed56 | 2017-02-28 00:04:07 +0000 | [diff] [blame] | 82 | if (auto EC = Reader.readInteger(GlobalRefsSize)) |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 83 | return EC; |
Zachary Turner | fa33282 | 2017-06-23 23:08:57 +0000 | [diff] [blame] | 84 | if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize)) |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 85 | return EC; |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 86 | return Error::success(); |
| 87 | } |
| 88 | |
Zachary Turner | bb3d7e5 | 2018-12-17 16:15:36 +0000 | [diff] [blame] | 89 | const codeview::CVSymbolArray |
| 90 | ModuleDebugStreamRef::getSymbolArrayForScope(uint32_t ScopeBegin) const { |
| 91 | return limitSymbolArrayToScope(SymbolArray, ScopeBegin); |
| 92 | } |
| 93 | |
Zachary Turner | fa33282 | 2017-06-23 23:08:57 +0000 | [diff] [blame] | 94 | BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const { |
| 95 | return SymbolsSubstream; |
| 96 | } |
| 97 | |
| 98 | BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const { |
| 99 | return C11LinesSubstream; |
| 100 | } |
| 101 | |
| 102 | BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const { |
| 103 | return C13LinesSubstream; |
| 104 | } |
| 105 | |
| 106 | BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const { |
| 107 | return GlobalRefsSubstream; |
| 108 | } |
| 109 | |
Zachary Turner | 0d43c1c | 2016-05-28 05:21:57 +0000 | [diff] [blame] | 110 | iterator_range<codeview::CVSymbolArray::Iterator> |
Zachary Turner | 7cc13e5 | 2017-05-01 16:46:39 +0000 | [diff] [blame] | 111 | ModuleDebugStreamRef::symbols(bool *HadError) const { |
Zachary Turner | fa33282 | 2017-06-23 23:08:57 +0000 | [diff] [blame] | 112 | return make_range(SymbolArray.begin(HadError), SymbolArray.end()); |
Zachary Turner | 06c2b4b | 2016-05-09 17:45:21 +0000 | [diff] [blame] | 113 | } |
Zachary Turner | 7eb6d35 | 2016-06-02 20:11:22 +0000 | [diff] [blame] | 114 | |
Zachary Turner | 94926a6 | 2018-10-08 04:19:16 +0000 | [diff] [blame] | 115 | CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const { |
Zachary Turner | 579264b | 2018-12-06 16:55:00 +0000 | [diff] [blame] | 116 | auto Iter = SymbolArray.at(Offset); |
Zachary Turner | 94926a6 | 2018-10-08 04:19:16 +0000 | [diff] [blame] | 117 | assert(Iter != SymbolArray.end()); |
| 118 | return *Iter; |
| 119 | } |
| 120 | |
Eugene Zelenko | 4fcfc19 | 2017-06-30 23:06:03 +0000 | [diff] [blame] | 121 | iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator> |
Zachary Turner | 92dcdda | 2017-06-02 19:49:14 +0000 | [diff] [blame] | 122 | ModuleDebugStreamRef::subsections() const { |
| 123 | return make_range(Subsections.begin(), Subsections.end()); |
Zachary Turner | 7eb6d35 | 2016-06-02 20:11:22 +0000 | [diff] [blame] | 124 | } |
Zachary Turner | 8848a7a | 2016-07-06 18:05:57 +0000 | [diff] [blame] | 125 | |
Zachary Turner | 92dcdda | 2017-06-02 19:49:14 +0000 | [diff] [blame] | 126 | bool ModuleDebugStreamRef::hasDebugSubsections() const { |
Zachary Turner | fa33282 | 2017-06-23 23:08:57 +0000 | [diff] [blame] | 127 | return !C13LinesSubstream.empty(); |
Zachary Turner | ee3b9c2 | 2017-04-25 20:22:02 +0000 | [diff] [blame] | 128 | } |
| 129 | |
Zachary Turner | 7cc13e5 | 2017-05-01 16:46:39 +0000 | [diff] [blame] | 130 | Error ModuleDebugStreamRef::commit() { return Error::success(); } |
Zachary Turner | 92dcdda | 2017-06-02 19:49:14 +0000 | [diff] [blame] | 131 | |
| 132 | Expected<codeview::DebugChecksumsSubsectionRef> |
| 133 | ModuleDebugStreamRef::findChecksumsSubsection() const { |
Zachary Turner | 349c18f | 2017-06-05 21:40:33 +0000 | [diff] [blame] | 134 | codeview::DebugChecksumsSubsectionRef Result; |
Zachary Turner | 92dcdda | 2017-06-02 19:49:14 +0000 | [diff] [blame] | 135 | for (const auto &SS : subsections()) { |
| 136 | if (SS.kind() != DebugSubsectionKind::FileChecksums) |
| 137 | continue; |
| 138 | |
Zachary Turner | 92dcdda | 2017-06-02 19:49:14 +0000 | [diff] [blame] | 139 | if (auto EC = Result.initialize(SS.getRecordData())) |
| 140 | return std::move(EC); |
| 141 | return Result; |
| 142 | } |
Zachary Turner | 349c18f | 2017-06-05 21:40:33 +0000 | [diff] [blame] | 143 | return Result; |
Zachary Turner | 92dcdda | 2017-06-02 19:49:14 +0000 | [diff] [blame] | 144 | } |