|
@@ -168,6 +168,8 @@ Stream::~Stream() = default;
|
|
|
|
|
|
Stream::StreamKind Stream::getKind(StreamType Type) {
|
|
Stream::StreamKind Stream::getKind(StreamType Type) {
|
|
switch (Type) {
|
|
switch (Type) {
|
|
|
|
+ case StreamType::MemoryList:
|
|
|
|
+ return StreamKind::MemoryList;
|
|
case StreamType::ModuleList:
|
|
case StreamType::ModuleList:
|
|
return StreamKind::ModuleList;
|
|
return StreamKind::ModuleList;
|
|
case StreamType::SystemInfo:
|
|
case StreamType::SystemInfo:
|
|
@@ -190,6 +192,8 @@ Stream::StreamKind Stream::getKind(StreamType Type) {
|
|
std::unique_ptr<Stream> Stream::create(StreamType Type) {
|
|
std::unique_ptr<Stream> Stream::create(StreamType Type) {
|
|
StreamKind Kind = getKind(Type);
|
|
StreamKind Kind = getKind(Type);
|
|
switch (Kind) {
|
|
switch (Kind) {
|
|
|
|
+ case StreamKind::MemoryList:
|
|
|
|
+ return llvm::make_unique<MemoryListStream>();
|
|
case StreamKind::ModuleList:
|
|
case StreamKind::ModuleList:
|
|
return llvm::make_unique<ModuleListStream>();
|
|
return llvm::make_unique<ModuleListStream>();
|
|
case StreamKind::RawContent:
|
|
case StreamKind::RawContent:
|
|
@@ -353,6 +357,16 @@ static StringRef streamValidate(RawContentStream &Stream) {
|
|
return "";
|
|
return "";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void yaml::MappingTraits<MemoryListStream::entry_type>::mapping(
|
|
|
|
+ IO &IO, MemoryListStream::entry_type &Range) {
|
|
|
|
+ MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
|
|
|
|
+ IO, Range.Entry, Range.Content);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void streamMapping(yaml::IO &IO, MemoryListStream &Stream) {
|
|
|
|
+ IO.mapRequired("Memory Ranges", Stream.Entries);
|
|
|
|
+}
|
|
|
|
+
|
|
static void streamMapping(yaml::IO &IO, ModuleListStream &Stream) {
|
|
static void streamMapping(yaml::IO &IO, ModuleListStream &Stream) {
|
|
IO.mapRequired("Modules", Stream.Entries);
|
|
IO.mapRequired("Modules", Stream.Entries);
|
|
}
|
|
}
|
|
@@ -421,6 +435,9 @@ void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
|
|
if (!IO.outputting())
|
|
if (!IO.outputting())
|
|
S = MinidumpYAML::Stream::create(Type);
|
|
S = MinidumpYAML::Stream::create(Type);
|
|
switch (S->Kind) {
|
|
switch (S->Kind) {
|
|
|
|
+ case MinidumpYAML::Stream::StreamKind::MemoryList:
|
|
|
|
+ streamMapping(IO, llvm::cast<MemoryListStream>(*S));
|
|
|
|
+ break;
|
|
case MinidumpYAML::Stream::StreamKind::ModuleList:
|
|
case MinidumpYAML::Stream::StreamKind::ModuleList:
|
|
streamMapping(IO, llvm::cast<ModuleListStream>(*S));
|
|
streamMapping(IO, llvm::cast<ModuleListStream>(*S));
|
|
break;
|
|
break;
|
|
@@ -444,6 +461,7 @@ StringRef yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
|
|
switch (S->Kind) {
|
|
switch (S->Kind) {
|
|
case MinidumpYAML::Stream::StreamKind::RawContent:
|
|
case MinidumpYAML::Stream::StreamKind::RawContent:
|
|
return streamValidate(cast<RawContentStream>(*S));
|
|
return streamValidate(cast<RawContentStream>(*S));
|
|
|
|
+ case MinidumpYAML::Stream::StreamKind::MemoryList:
|
|
case MinidumpYAML::Stream::StreamKind::ModuleList:
|
|
case MinidumpYAML::Stream::StreamKind::ModuleList:
|
|
case MinidumpYAML::Stream::StreamKind::SystemInfo:
|
|
case MinidumpYAML::Stream::StreamKind::SystemInfo:
|
|
case MinidumpYAML::Stream::StreamKind::TextContent:
|
|
case MinidumpYAML::Stream::StreamKind::TextContent:
|
|
@@ -466,6 +484,10 @@ static LocationDescriptor layout(BlobAllocator &File, yaml::BinaryRef Data) {
|
|
support::ulittle32_t(File.allocateBytes(Data))};
|
|
support::ulittle32_t(File.allocateBytes(Data))};
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void layout(BlobAllocator &File, MemoryListStream::entry_type &Range) {
|
|
|
|
+ Range.Entry.Memory = layout(File, Range.Content);
|
|
|
|
+}
|
|
|
|
+
|
|
static void layout(BlobAllocator &File, ModuleListStream::entry_type &M) {
|
|
static void layout(BlobAllocator &File, ModuleListStream::entry_type &M) {
|
|
M.Entry.ModuleNameRVA = File.allocateString(M.Name);
|
|
M.Entry.ModuleNameRVA = File.allocateString(M.Name);
|
|
|
|
|
|
@@ -502,6 +524,9 @@ static Directory layout(BlobAllocator &File, Stream &S) {
|
|
Result.Location.RVA = File.tell();
|
|
Result.Location.RVA = File.tell();
|
|
Optional<size_t> DataEnd;
|
|
Optional<size_t> DataEnd;
|
|
switch (S.Kind) {
|
|
switch (S.Kind) {
|
|
|
|
+ case Stream::StreamKind::MemoryList:
|
|
|
|
+ DataEnd = layout(File, cast<MemoryListStream>(S));
|
|
|
|
+ break;
|
|
case Stream::StreamKind::ModuleList:
|
|
case Stream::StreamKind::ModuleList:
|
|
DataEnd = layout(File, cast<ModuleListStream>(S));
|
|
DataEnd = layout(File, cast<ModuleListStream>(S));
|
|
break;
|
|
break;
|
|
@@ -566,6 +591,19 @@ Expected<std::unique_ptr<Stream>>
|
|
Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
|
|
Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
|
|
StreamKind Kind = getKind(StreamDesc.Type);
|
|
StreamKind Kind = getKind(StreamDesc.Type);
|
|
switch (Kind) {
|
|
switch (Kind) {
|
|
|
|
+ case StreamKind::MemoryList: {
|
|
|
|
+ auto ExpectedList = File.getMemoryList();
|
|
|
|
+ if (!ExpectedList)
|
|
|
|
+ return ExpectedList.takeError();
|
|
|
|
+ std::vector<MemoryListStream::entry_type> Ranges;
|
|
|
|
+ for (const MemoryDescriptor &MD : *ExpectedList) {
|
|
|
|
+ auto ExpectedContent = File.getRawData(MD.Memory);
|
|
|
|
+ if (!ExpectedContent)
|
|
|
|
+ return ExpectedContent.takeError();
|
|
|
|
+ Ranges.push_back({MD, *ExpectedContent});
|
|
|
|
+ }
|
|
|
|
+ return llvm::make_unique<MemoryListStream>(std::move(Ranges));
|
|
|
|
+ }
|
|
case StreamKind::ModuleList: {
|
|
case StreamKind::ModuleList: {
|
|
auto ExpectedList = File.getModuleList();
|
|
auto ExpectedList = File.getModuleList();
|
|
if (!ExpectedList)
|
|
if (!ExpectedList)
|