summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/ByteStream.h21
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h1
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamArray.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h13
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamReader.h1
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamRef.h28
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h82
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h3
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h6
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h2
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h4
-rw-r--r--llvm/include/llvm/Support/MathExtras.h8
12 files changed, 163 insertions, 8 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h b/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h
index 44fcbaabd6d..ec841d9f45e 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/ByteStream.h
@@ -16,19 +16,27 @@
#include "llvm/Support/Error.h"
#include <cstdint>
#include <memory>
+#include <type_traits>
namespace llvm {
namespace codeview {
class StreamReader;
-class ByteStream : public StreamInterface {
+template <bool Writable = false> class ByteStream : public StreamInterface {
+ typedef typename std::conditional<Writable, MutableArrayRef<uint8_t>,
+ ArrayRef<uint8_t>>::type ArrayType;
+
public:
- ByteStream();
- explicit ByteStream(ArrayRef<uint8_t> Data);
- ~ByteStream() override;
+ ByteStream() {}
+ explicit ByteStream(ArrayType Data) : Data(Data) {}
+ ~ByteStream() override {}
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const override;
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const override;
+
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
uint32_t getLength() const override;
@@ -36,9 +44,12 @@ public:
StringRef str() const;
private:
- ArrayRef<uint8_t> Data;
+ ArrayType Data;
};
+extern template class ByteStream<true>;
+extern template class ByteStream<false>;
+
} // end namespace pdb
} // end namespace llvm
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h b/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
index a3d4171f693..69ff29aab6f 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewError.h
@@ -19,6 +19,7 @@ namespace codeview {
enum class cv_error_code {
unspecified = 1,
insufficient_buffer,
+ operation_unsupported,
corrupt_record,
};
diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h b/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
index 0241bb82be2..b6ecc75e439 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/StreamArray.h
@@ -97,6 +97,8 @@ public:
const Extractor &getExtractor() const { return E; }
+ StreamRef getUnderlyingStream() const { return Stream; }
+
private:
StreamRef Stream;
Extractor E;
diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h b/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h
index f875f1896a4..a8b9dbfc2b6 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/StreamInterface.h
@@ -28,9 +28,22 @@ class StreamInterface {
public:
virtual ~StreamInterface() {}
+ // Given an offset into the stream and a number of bytes, attempt to read
+ // the bytes and set the output ArrayRef to point to a reference into the
+ // stream, without copying any data.
virtual Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const = 0;
+ // Given an offset into the stream, read as much as possible without copying
+ // any data.
+ virtual Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const = 0;
+
+ // Attempt to write the given bytes into the stream at the desired offset.
+ // This will always necessitate a copy. Cannot shrink or grow the stream,
+ // only writes into existing allocated space.
+ virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const = 0;
+
virtual uint32_t getLength() const = 0;
};
diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h b/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
index a42cc8bc7b8..2f497c2c43f 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/StreamReader.h
@@ -28,6 +28,7 @@ class StreamReader {
public:
StreamReader(StreamRef Stream);
+ Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer);
Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size);
Error readInteger(uint16_t &Dest);
Error readInteger(uint32_t &Dest);
diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h b/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h
index 036802d2499..93b116b78c8 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/StreamRef.h
@@ -24,7 +24,8 @@ public:
StreamRef(const StreamInterface &Stream, uint32_t Offset, uint32_t Length)
: Stream(&Stream), ViewOffset(Offset), Length(Length) {}
- StreamRef(const StreamRef &Stream, uint32_t Offset, uint32_t Length) = delete;
+ // Use StreamRef.slice() instead.
+ StreamRef(const StreamRef &S, uint32_t Offset, uint32_t Length) = delete;
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const override {
@@ -33,7 +34,32 @@ public:
return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
}
+ // Given an offset into the stream, read as much as possible without copying
+ // any data.
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const override {
+ if (Offset >= Length)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+
+ if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer))
+ return EC;
+ // This StreamRef might refer to a smaller window over a larger stream. In
+ // that case we will have read out more bytes than we should return, because
+ // we should not read past the end of the current view.
+ uint32_t MaxLength = Length - Offset;
+ if (Buffer.size() > MaxLength)
+ Buffer = Buffer.slice(0, MaxLength);
+ return Error::success();
+ }
+
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override {
+ if (Data.size() + Offset > Length)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ return Stream->writeBytes(ViewOffset + Offset, Data);
+ }
+
uint32_t getLength() const override { return Length; }
+
StreamRef drop_front(uint32_t N) const {
if (!Stream)
return StreamRef();
diff --git a/llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h b/llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h
new file mode 100644
index 00000000000..ad9277b8e22
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/CodeView/StreamWriter.h
@@ -0,0 +1,82 @@
+//===- StreamWriter.h - Writes bytes and objects to a stream ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_STREAMWRITER_H
+#define LLVM_DEBUGINFO_CODEVIEW_STREAMWRITER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/StreamArray.h"
+#include "llvm/DebugInfo/CodeView/StreamInterface.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+#include <string>
+
+namespace llvm {
+namespace codeview {
+
+class StreamRef;
+
+class StreamWriter {
+public:
+ StreamWriter(StreamRef Stream);
+
+ Error writeBytes(ArrayRef<uint8_t> Buffer);
+ Error writeInteger(uint16_t Dest);
+ Error writeInteger(uint32_t Dest);
+ Error writeZeroString(StringRef Str);
+ Error writeFixedString(StringRef Str);
+ Error writeStreamRef(StreamRef Ref);
+ Error writeStreamRef(StreamRef Ref, uint32_t Size);
+
+ template <typename T> Error writeEnum(T Num) {
+ return writeInteger(
+ static_cast<typename std::underlying_type<T>::type>(Num));
+ }
+
+ template <typename T> Error writeObject(const T &Obj) {
+ return writeBytes(
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
+ }
+
+ template <typename T> Error writeArray(ArrayRef<T> Array) {
+ if (Array.size() == 0)
+ return Error::success();
+
+ if (Array.size() > UINT32_MAX / sizeof(T))
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+
+ return writeBytes(
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
+ Array.size() * sizeof(T)));
+ }
+
+ template <typename T, typename U>
+ Error writeArray(VarStreamArray<T, U> Array) {
+ return writeStreamRef(Array.getUnderlyingStream());
+ }
+
+ template <typename T> Error writeArray(FixedStreamArray<T> Array) {
+ return writeStreamRef(Array.getUnderlyingStream());
+ }
+
+ void setOffset(uint32_t Off) { Offset = Off; }
+ uint32_t getOffset() const { return Offset; }
+ uint32_t getLength() const { return Stream.getLength(); }
+ uint32_t bytesRemaining() const { return getLength() - getOffset(); }
+
+private:
+ StreamRef Stream;
+ uint32_t Offset;
+};
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
index 0f8736d55c4..717a7880f3c 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h
@@ -14,6 +14,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/StreamArray.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include <stdint.h>
@@ -34,6 +35,8 @@ public:
virtual ArrayRef<uint8_t> getBlockData(uint32_t BlockIndex,
uint32_t NumBytes) const = 0;
+ virtual Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
+ ArrayRef<uint8_t> Data) const = 0;
};
}
}
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
index 0148ed6086b..8ee0ab66446 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
@@ -31,6 +31,9 @@ class MappedBlockStream : public codeview::StreamInterface {
public:
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const override;
+ Error readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) const override;
+ Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override;
uint32_t getLength() const override;
@@ -51,8 +54,9 @@ protected:
const IPDBFile &Pdb;
std::unique_ptr<IPDBStreamData> Data;
+ typedef MutableArrayRef<uint8_t> CacheEntry;
mutable llvm::BumpPtrAllocator Pool;
- mutable DenseMap<uint32_t, uint8_t *> CacheMap;
+ mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap;
};
} // end namespace pdb
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
index f6ee987adcd..20e22e318c6 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
@@ -54,6 +54,8 @@ public:
ArrayRef<uint8_t> getBlockData(uint32_t BlockIndex,
uint32_t NumBytes) const override;
+ Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
+ ArrayRef<uint8_t> Data) const override;
ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h b/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h
index 5a1614fc82e..076f75ba031 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h
@@ -22,7 +22,9 @@ enum class raw_error_code {
corrupt_file,
insufficient_buffer,
no_stream,
- index_out_of_bounds
+ index_out_of_bounds,
+ invalid_block_address,
+ not_writable,
};
/// Base class for errors originating when parsing raw PDB files
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index e9639450a70..94ca40d5789 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -681,6 +681,14 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) {
return int64_t(X << (64 - B)) >> (64 - B);
}
+/// \brief Subtract two unsigned integers, X and Y, of type T and return their
+/// absolute value.
+template <typename T>
+typename std::enable_if<std::is_unsigned<T>::value, T>::type
+AbsoluteDifference(T X, T Y) {
+ return std::max(X, Y) - std::min(X, Y);
+}
+
/// \brief Add two unsigned integers, X and Y, of type T.
/// Clamp the result to the maximum representable value of T on overflow.
/// ResultOverflowed indicates if the result is larger than the maximum
OpenPOWER on IntegriCloud