diff options
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView')
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/ByteStream.cpp | 72 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/CMakeLists.txt | 3 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/CodeViewError.cpp | 65 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/StreamReader.cpp | 51 |
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(); +} |