LLVM  4.0.0
ModStream.cpp
Go to the documentation of this file.
1 //===- ModStream.cpp - PDB Module Info Stream Access ----------------------===//
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 
19 #include "llvm/Support/Error.h"
20 #include <algorithm>
21 #include <cstdint>
22 
23 using namespace llvm;
24 using namespace llvm::msf;
25 using namespace llvm::pdb;
26 
27 ModStream::ModStream(const ModInfo &Module,
28  std::unique_ptr<MappedBlockStream> Stream)
29  : Mod(Module), Stream(std::move(Stream)) {}
30 
31 ModStream::~ModStream() = default;
32 
34  StreamReader Reader(*Stream);
35 
36  uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
37  uint32_t C11Size = Mod.getLineInfoByteSize();
38  uint32_t C13Size = Mod.getC13LineInfoByteSize();
39 
40  if (C11Size > 0 && C13Size > 0)
41  return make_error<RawError>(raw_error_code::corrupt_file,
42  "Module has both C11 and C13 line info");
43 
45 
46  if (auto EC = Reader.readInteger(Signature))
47  return EC;
48  if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
49  return EC;
50 
51  if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size))
52  return EC;
53  if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
54  return EC;
55 
56  StreamReader LineReader(C13LinesSubstream);
57  if (auto EC = LineReader.readArray(LineInfo, LineReader.bytesRemaining()))
58  return EC;
59 
60  uint32_t GlobalRefsSize;
61  if (auto EC = Reader.readInteger(GlobalRefsSize))
62  return EC;
63  if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))
64  return EC;
65  if (Reader.bytesRemaining() > 0)
66  return make_error<RawError>(raw_error_code::corrupt_file,
67  "Unexpected bytes in module stream.");
68 
69  return Error::success();
70 }
71 
73 ModStream::symbols(bool *HadError) const {
74  // It's OK if the stream is empty.
75  if (SymbolsSubstream.getUnderlyingStream().getLength() == 0)
76  return make_range(SymbolsSubstream.end(), SymbolsSubstream.end());
77  return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end());
78 }
79 
81 ModStream::lines(bool *HadError) const {
82  return make_range(LineInfo.begin(HadError), LineInfo.end());
83 }
84 
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
uint32_t getC13LineInfoByteSize() const
Definition: ModInfo.cpp:59
iterator_range< codeview::ModuleSubstreamArray::Iterator > lines(bool *HadError) const
Definition: ModStream.cpp:81
Iterator begin(bool *HadError=nullptr) const
Definition: StreamArray.h:96
ReadableStreamRef getUnderlyingStream() const
Definition: StreamArray.h:104
uint32_t getLength() const
Definition: StreamRef.h:29
Error readInteger(uint8_t &Dest)
Error readArray(ArrayRef< T > &Array, uint32_t NumElements)
Definition: StreamReader.h:62
uint32_t getLineInfoByteSize() const
Definition: ModInfo.cpp:57
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator end() const
Definition: StreamArray.h:100
static ErrorSuccess success()
Create a success value.
A range adaptor for a pair of iterators.
uint32_t getSymbolDebugInfoByteSize() const
Definition: ModInfo.cpp:53
Error readStreamRef(ReadableStreamRef &Ref)
uint32_t bytesRemaining() const
Definition: StreamReader.h:108
Lightweight error class with error context and mandatory checking.
iterator_range< codeview::CVSymbolArray::Iterator > symbols(bool *HadError) const
Definition: ModStream.cpp:73