summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ObjectYAML
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ObjectYAML')
-rw-r--r--llvm/lib/ObjectYAML/MinidumpEmitter.cpp20
-rw-r--r--llvm/lib/ObjectYAML/MinidumpYAML.cpp49
2 files changed, 67 insertions, 2 deletions
diff --git a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
index 9029be80ad7..bbfd2cd8cba 100644
--- a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
@@ -118,6 +118,23 @@ static LocationDescriptor layout(BlobAllocator &File, yaml::BinaryRef Data) {
support::ulittle32_t(File.allocateBytes(Data))};
}
+static size_t layout(BlobAllocator &File, MinidumpYAML::ExceptionStream &S) {
+ File.allocateObject(S.MDExceptionStream);
+
+ size_t DataEnd = File.tell();
+
+ // Lay out the thread context data, (which is not a part of the stream).
+ // TODO: This usually (always?) matches the thread context of the
+ // corresponding thread, and may overlap memory regions as well. We could
+ // add a level of indirection to the MinidumpYAML format (like an array of
+ // Blobs that the LocationDescriptors index into) to be able to distinguish
+ // the cases where location descriptions overlap vs happen to reference
+ // identical data.
+ S.MDExceptionStream.ThreadContext = layout(File, S.ThreadContext);
+
+ return DataEnd;
+}
+
static void layout(BlobAllocator &File, MemoryListStream::entry_type &Range) {
Range.Entry.Memory = layout(File, Range.Content);
}
@@ -158,6 +175,9 @@ static Directory layout(BlobAllocator &File, Stream &S) {
Result.Location.RVA = File.tell();
Optional<size_t> DataEnd;
switch (S.Kind) {
+ case Stream::StreamKind::Exception:
+ DataEnd = layout(File, cast<MinidumpYAML::ExceptionStream>(S));
+ break;
case Stream::StreamKind::MemoryInfoList: {
MemoryInfoListStream &InfoList = cast<MemoryInfoListStream>(S);
File.allocateNewObject<minidump::MemoryInfoListHeader>(
diff --git a/llvm/lib/ObjectYAML/MinidumpYAML.cpp b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
index b9d1ded1816..21b2a4d7862 100644
--- a/llvm/lib/ObjectYAML/MinidumpYAML.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
@@ -69,6 +69,8 @@ Stream::~Stream() = default;
Stream::StreamKind Stream::getKind(StreamType Type) {
switch (Type) {
+ case StreamType::Exception:
+ return StreamKind::Exception;
case StreamType::MemoryInfoList:
return StreamKind::MemoryInfoList;
case StreamType::MemoryList:
@@ -95,6 +97,8 @@ Stream::StreamKind Stream::getKind(StreamType Type) {
std::unique_ptr<Stream> Stream::create(StreamType Type) {
StreamKind Kind = getKind(Type);
switch (Kind) {
+ case StreamKind::Exception:
+ return std::make_unique<ExceptionStream>();
case StreamKind::MemoryInfoList:
return std::make_unique<MemoryInfoListStream>();
case StreamKind::MemoryList:
@@ -274,8 +278,7 @@ void yaml::MappingTraits<ModuleListStream::entry_type>::mapping(
mapRequiredHex(IO, "Base of Image", M.Entry.BaseOfImage);
mapRequiredHex(IO, "Size of Image", M.Entry.SizeOfImage);
mapOptionalHex(IO, "Checksum", M.Entry.Checksum, 0);
- IO.mapOptional("Time Date Stamp", M.Entry.TimeDateStamp,
- support::ulittle32_t(0));
+ mapOptional(IO, "Time Date Stamp", M.Entry.TimeDateStamp, 0);
IO.mapRequired("Module Name", M.Name);
IO.mapOptional("Version Info", M.Entry.VersionInfo, VSFixedFileInfo());
IO.mapRequired("CodeView Record", M.CvRecord);
@@ -367,6 +370,32 @@ static void streamMapping(yaml::IO &IO, ThreadListStream &Stream) {
IO.mapRequired("Threads", Stream.Entries);
}
+static void streamMapping(yaml::IO &IO, MinidumpYAML::ExceptionStream &Stream) {
+ mapRequiredHex(IO, "Thread ID", Stream.MDExceptionStream.ThreadId);
+ IO.mapRequired("Exception Record", Stream.MDExceptionStream.ExceptionRecord);
+ IO.mapRequired("Thread Context", Stream.ThreadContext);
+}
+
+void yaml::MappingTraits<minidump::Exception>::mapping(
+ yaml::IO &IO, minidump::Exception &Exception) {
+ mapRequiredHex(IO, "Exception Code", Exception.ExceptionCode);
+ mapOptionalHex(IO, "Exception Flags", Exception.ExceptionFlags, 0);
+ mapOptionalHex(IO, "Exception Record", Exception.ExceptionRecord, 0);
+ mapOptionalHex(IO, "Exception Address", Exception.ExceptionAddress, 0);
+ mapOptional(IO, "Number of Parameters", Exception.NumberParameters, 0);
+
+ for (size_t Index = 0; Index < Exception.MaxParameters; ++Index) {
+ SmallString<16> Name("Parameter ");
+ Twine(Index).toVector(Name);
+ support::ulittle64_t &Field = Exception.ExceptionInformation[Index];
+
+ if (Index < Exception.NumberParameters)
+ mapRequiredHex(IO, Name.c_str(), Field);
+ else
+ mapOptionalHex(IO, Name.c_str(), Field, 0);
+ }
+}
+
void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
StreamType Type;
@@ -377,6 +406,9 @@ void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
if (!IO.outputting())
S = MinidumpYAML::Stream::create(Type);
switch (S->Kind) {
+ case MinidumpYAML::Stream::StreamKind::Exception:
+ streamMapping(IO, llvm::cast<MinidumpYAML::ExceptionStream>(*S));
+ break;
case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
streamMapping(IO, llvm::cast<MemoryInfoListStream>(*S));
break;
@@ -406,6 +438,7 @@ StringRef yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
switch (S->Kind) {
case MinidumpYAML::Stream::StreamKind::RawContent:
return streamValidate(cast<RawContentStream>(*S));
+ case MinidumpYAML::Stream::StreamKind::Exception:
case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
case MinidumpYAML::Stream::StreamKind::MemoryList:
case MinidumpYAML::Stream::StreamKind::ModuleList:
@@ -429,6 +462,18 @@ Expected<std::unique_ptr<Stream>>
Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
StreamKind Kind = getKind(StreamDesc.Type);
switch (Kind) {
+ case StreamKind::Exception: {
+ Expected<const minidump::ExceptionStream &> ExpectedExceptionStream =
+ File.getExceptionStream();
+ if (!ExpectedExceptionStream)
+ return ExpectedExceptionStream.takeError();
+ Expected<ArrayRef<uint8_t>> ExpectedThreadContext =
+ File.getRawData(ExpectedExceptionStream->ThreadContext);
+ if (!ExpectedThreadContext)
+ return ExpectedThreadContext.takeError();
+ return std::make_unique<ExceptionStream>(*ExpectedExceptionStream,
+ *ExpectedThreadContext);
+ }
case StreamKind::MemoryInfoList: {
if (auto ExpectedList = File.getMemoryInfoList())
return std::make_unique<MemoryInfoListStream>(*ExpectedList);
OpenPOWER on IntegriCloud