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