• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- StreamReader.h - Reads bytes and objects from a stream ---*- C++ -*-===//
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 
10 #ifndef LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
11 #define LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
12 
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
15 #include "llvm/DebugInfo/CodeView/StreamArray.h"
16 #include "llvm/DebugInfo/CodeView/StreamInterface.h"
17 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/Error.h"
19 
20 #include <string>
21 
22 namespace llvm {
23 namespace codeview {
24 
25 class StreamRef;
26 
27 class StreamReader {
28 public:
29   StreamReader(StreamRef Stream);
30 
31   Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
32   Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
33   Error readInteger(uint16_t &Dest);
34   Error readInteger(uint32_t &Dest);
35   Error readZeroString(StringRef &Dest);
36   Error readFixedString(StringRef &Dest, uint32_t Length);
37   Error readStreamRef(StreamRef &Ref);
38   Error readStreamRef(StreamRef &Ref, uint32_t Length);
39 
readEnum(T & Dest)40   template <typename T> Error readEnum(T &Dest) {
41     typename std::underlying_type<T>::type N;
42     if (auto EC = readInteger(N))
43       return EC;
44     Dest = static_cast<T>(N);
45     return Error::success();
46   }
47 
readObject(const T * & Dest)48   template <typename T> Error readObject(const T *&Dest) {
49     ArrayRef<uint8_t> Buffer;
50     if (auto EC = readBytes(Buffer, sizeof(T)))
51       return EC;
52     Dest = reinterpret_cast<const T *>(Buffer.data());
53     return Error::success();
54   }
55 
56   template <typename T>
readArray(ArrayRef<T> & Array,uint32_t NumElements)57   Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
58     ArrayRef<uint8_t> Bytes;
59     if (NumElements == 0) {
60       Array = ArrayRef<T>();
61       return Error::success();
62     }
63 
64     if (NumElements > UINT32_MAX/sizeof(T))
65       return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
66 
67     if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
68       return EC;
69     Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
70     return Error::success();
71   }
72 
73   template <typename T, typename U>
readArray(VarStreamArray<T,U> & Array,uint32_t Size)74   Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
75     StreamRef S;
76     if (auto EC = readStreamRef(S, Size))
77       return EC;
78     Array = VarStreamArray<T, U>(S, Array.getExtractor());
79     return Error::success();
80   }
81 
82   template <typename T>
readArray(FixedStreamArray<T> & Array,uint32_t NumItems)83   Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) {
84     if (NumItems == 0) {
85       Array = FixedStreamArray<T>();
86       return Error::success();
87     }
88     uint32_t Length = NumItems * sizeof(T);
89     if (Length / sizeof(T) != NumItems)
90       return make_error<CodeViewError>(cv_error_code::corrupt_record);
91     if (Offset + Length > Stream.getLength())
92       return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
93     StreamRef View = Stream.slice(Offset, Length);
94     Array = FixedStreamArray<T>(View);
95     Offset += Length;
96     return Error::success();
97   }
98 
setOffset(uint32_t Off)99   void setOffset(uint32_t Off) { Offset = Off; }
getOffset()100   uint32_t getOffset() const { return Offset; }
getLength()101   uint32_t getLength() const { return Stream.getLength(); }
bytesRemaining()102   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
103 
104 private:
105   StreamRef Stream;
106   uint32_t Offset;
107 };
108 } // namespace codeview
109 } // namespace llvm
110 
111 #endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
112