summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/CodeView
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-05-25 20:37:03 +0000
committerZachary Turner <zturner@google.com>2016-05-25 20:37:03 +0000
commitd5d37dcf8329b7c5774aadc60c4474c8e4a4e55f (patch)
treed6b8dde6b19a10110b013544b3288848120add80 /llvm/lib/DebugInfo/CodeView
parent1fe3f1ca50bfc7b1dcc356ee9785bfe3757a8aec (diff)
downloadbcm5719-llvm-d5d37dcf8329b7c5774aadc60c4474c8e4a4e55f.tar.gz
bcm5719-llvm-d5d37dcf8329b7c5774aadc60c4474c8e4a4e55f.zip
[codeview] Move StreamInterface and StreamReader to libcodeview.
We have need to reuse this functionality, including making additional generic stream types that are smarter about how and when they copy memory versus referencing the original memory. So all of these structures belong in the common library rather than being pdb specific. llvm-svn: 270751
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView')
-rw-r--r--llvm/lib/DebugInfo/CodeView/ByteStream.cpp72
-rw-r--r--llvm/lib/DebugInfo/CodeView/CMakeLists.txt3
-rw-r--r--llvm/lib/DebugInfo/CodeView/CodeViewError.cpp65
-rw-r--r--llvm/lib/DebugInfo/CodeView/StreamReader.cpp51
4 files changed, 191 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/ByteStream.cpp b/llvm/lib/DebugInfo/CodeView/ByteStream.cpp
new file mode 100644
index 00000000000..879343afbfd
--- /dev/null
+++ b/llvm/lib/DebugInfo/CodeView/ByteStream.cpp
@@ -0,0 +1,72 @@
+//===- ByteStream.cpp - Reads stream data from a byte sequence ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/ByteStream.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/StreamReader.h"
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+ByteStream::ByteStream() {}
+
+ByteStream::ByteStream(MutableArrayRef<uint8_t> Bytes) { initialize(Bytes); }
+
+ByteStream::ByteStream(uint32_t Length) { initialize(Length); }
+
+ByteStream::~ByteStream() { reset(); }
+
+void ByteStream::reset() {
+ Ownership.reset();
+ Data = MutableArrayRef<uint8_t>();
+}
+
+void ByteStream::initialize(MutableArrayRef<uint8_t> Bytes) {
+ reset();
+ Data = Bytes;
+}
+
+void ByteStream::initialize(uint32_t Length) {
+ reset();
+ if (Length > 0)
+ Data = MutableArrayRef<uint8_t>(new uint8_t[Length], Length);
+ Ownership.reset(Data.data());
+}
+
+Error ByteStream::initialize(StreamReader &Reader, uint32_t Length) {
+ initialize(Length);
+ auto EC = Reader.readBytes(Data);
+ if (EC)
+ reset();
+ return EC;
+}
+
+Error ByteStream::readBytes(uint32_t Offset,
+ MutableArrayRef<uint8_t> Buffer) const {
+ if (Data.size() < Buffer.size() + Offset)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ ::memcpy(Buffer.data(), Data.data() + Offset, Buffer.size());
+ return Error::success();
+}
+
+Error ByteStream::getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,
+ uint32_t Length) const {
+ if (Data.size() < Length + Offset)
+ return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
+ Buffer = Data.slice(Offset, Length);
+ return Error::success();
+}
+
+uint32_t ByteStream::getLength() const { return Data.size(); }
+
+StringRef ByteStream::str() const {
+ const char *CharData = reinterpret_cast<const char *>(Data.data());
+ return StringRef(CharData, Data.size());
+}
diff --git a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
index e0c7119dd91..8e7628dcf05 100644
--- a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -1,10 +1,13 @@
add_llvm_library(LLVMDebugInfoCodeView
+ ByteStream.cpp
+ CodeViewError.cpp
FieldListRecordBuilder.cpp
Line.cpp
ListRecordBuilder.cpp
MemoryTypeTableBuilder.cpp
MethodListRecordBuilder.cpp
RecordSerialization.cpp
+ StreamReader.cpp
SymbolDumper.cpp
TypeDumper.cpp
TypeRecord.cpp
diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
new file mode 100644
index 00000000000..4db6b2941a6
--- /dev/null
+++ b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
@@ -0,0 +1,65 @@
+//===- CodeViewError.cpp - Error extensions for CodeView --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+namespace {
+// FIXME: This class is only here to support the transition to llvm::Error. It
+// will be removed once this transition is complete. Clients should prefer to
+// deal with the Error value directly, rather than converting to error_code.
+class CodeViewErrorCategory : public std::error_category {
+public:
+ const char *name() const LLVM_NOEXCEPT override { return "llvm.codeview"; }
+
+ std::string message(int Condition) const override {
+ switch (static_cast<cv_error_code>(Condition)) {
+ case cv_error_code::unspecified:
+ return "An unknown error has occurred.";
+ case cv_error_code::insufficient_buffer:
+ return "The buffer is not large enough to read the requested number of "
+ "bytes.";
+ case cv_error_code::corrupt_record:
+ return "The CodeView record is corrupted.";
+ }
+ llvm_unreachable("Unrecognized cv_error_code");
+ }
+};
+} // end anonymous namespace
+
+static ManagedStatic<CodeViewErrorCategory> Category;
+
+char CodeViewError::ID = 0;
+
+CodeViewError::CodeViewError(cv_error_code C) : CodeViewError(C, "") {}
+
+CodeViewError::CodeViewError(const std::string &Context)
+ : CodeViewError(cv_error_code::unspecified, Context) {}
+
+CodeViewError::CodeViewError(cv_error_code C, const std::string &Context)
+ : Code(C) {
+ ErrMsg = "CodeView Error: ";
+ std::error_code EC = convertToErrorCode();
+ if (Code != cv_error_code::unspecified)
+ ErrMsg += EC.message() + " ";
+ if (!Context.empty())
+ ErrMsg += Context;
+}
+
+void CodeViewError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
+
+const std::string &CodeViewError::getErrorMessage() const { return ErrMsg; }
+
+std::error_code CodeViewError::convertToErrorCode() const {
+ return std::error_code(static_cast<int>(Code), *Category);
+}
diff --git a/llvm/lib/DebugInfo/CodeView/StreamReader.cpp b/llvm/lib/DebugInfo/CodeView/StreamReader.cpp
new file mode 100644
index 00000000000..8a2926bc883
--- /dev/null
+++ b/llvm/lib/DebugInfo/CodeView/StreamReader.cpp
@@ -0,0 +1,51 @@
+//===- StreamReader.cpp - Reads bytes and objects from a stream -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/StreamReader.h"
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+StreamReader::StreamReader(const StreamInterface &S) : Stream(S), Offset(0) {}
+
+Error StreamReader::readBytes(MutableArrayRef<uint8_t> Buffer) {
+ if (auto EC = Stream.readBytes(Offset, Buffer))
+ return EC;
+ Offset += Buffer.size();
+ return Error::success();
+}
+
+Error StreamReader::readInteger(uint32_t &Dest) {
+ support::ulittle32_t P;
+ if (auto EC = readObject(&P))
+ return EC;
+ Dest = P;
+ return Error::success();
+}
+
+Error StreamReader::readZeroString(std::string &Dest) {
+ Dest.clear();
+ char C;
+ do {
+ if (auto EC = readObject(&C))
+ return EC;
+ if (C != '\0')
+ Dest.push_back(C);
+ } while (C != '\0');
+ return Error::success();
+}
+
+Error StreamReader::getArrayRef(ArrayRef<uint8_t> &Array, uint32_t Length) {
+ if (auto EC = Stream.getArrayRef(Offset, Array, Length))
+ return EC;
+ Offset += Length;
+ return Error::success();
+}
OpenPOWER on IntegriCloud