[llvm] r374337 - MinidumpYAML: Add support for the memory info list stream

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 10 06:05:46 PDT 2019


Author: labath
Date: Thu Oct 10 06:05:46 2019
New Revision: 374337

URL: http://llvm.org/viewvc/llvm-project?rev=374337&view=rev
Log:
MinidumpYAML: Add support for the memory info list stream

Summary:
The implementation is fairly straight-forward and uses the same patterns
as the existing streams. The yaml form does not attempt to preserve the
data in the "gaps" that can be created by setting a larger-than-required
header or entry size in the stream header, because the existing consumer
(lldb) does not make use of the information in the gap in any way, and
attempting to preserve that would make the implementation more
complicated.

Reviewers: amccarth, jhenderson, clayborg

Subscribers: llvm-commits, lldb-commits, markmentovai, zturner, JosephTremoulet

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D68645

Modified:
    llvm/trunk/include/llvm/BinaryFormat/Minidump.h
    llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h
    llvm/trunk/lib/ObjectYAML/MinidumpEmitter.cpp
    llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp
    llvm/trunk/test/tools/obj2yaml/basic-minidump.yaml

Modified: llvm/trunk/include/llvm/BinaryFormat/Minidump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Minidump.h?rev=374337&r1=374336&r2=374337&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Minidump.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Minidump.h Thu Oct 10 06:05:46 2019
@@ -72,6 +72,12 @@ struct MemoryInfoListHeader {
   support::ulittle32_t SizeOfHeader;
   support::ulittle32_t SizeOfEntry;
   support::ulittle64_t NumberOfEntries;
+
+  MemoryInfoListHeader() = default;
+  MemoryInfoListHeader(uint32_t SizeOfHeader, uint32_t SizeOfEntry,
+                       uint64_t NumberOfEntries)
+      : SizeOfHeader(SizeOfHeader), SizeOfEntry(SizeOfEntry),
+        NumberOfEntries(NumberOfEntries) {}
 };
 static_assert(sizeof(MemoryInfoListHeader) == 16, "");
 
@@ -84,11 +90,13 @@ enum class MemoryProtection : uint32_t {
 enum class MemoryState : uint32_t {
 #define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME) NAME = CODE,
 #include "llvm/BinaryFormat/MinidumpConstants.def"
+  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/0xffffffffu),
 };
 
 enum class MemoryType : uint32_t {
 #define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME) NAME = CODE,
 #include "llvm/BinaryFormat/MinidumpConstants.def"
+  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/0xffffffffu),
 };
 
 struct MemoryInfo {

Modified: llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h?rev=374337&r1=374336&r2=374337&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/MinidumpYAML.h Thu Oct 10 06:05:46 2019
@@ -26,6 +26,7 @@ namespace MinidumpYAML {
 /// from Types to Kinds is fixed and given by the static getKind function.
 struct Stream {
   enum class StreamKind {
+    MemoryInfoList,
     MemoryList,
     ModuleList,
     RawContent,
@@ -102,6 +103,26 @@ using ModuleListStream = detail::ListStr
 using ThreadListStream = detail::ListStream<detail::ParsedThread>;
 using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
 
+/// A structure containing the list of MemoryInfo entries comprising a
+/// MemoryInfoList stream.
+struct MemoryInfoListStream : public Stream {
+  std::vector<minidump::MemoryInfo> Infos;
+
+  MemoryInfoListStream()
+      : Stream(StreamKind::MemoryInfoList,
+               minidump::StreamType::MemoryInfoList) {}
+
+  explicit MemoryInfoListStream(
+      iterator_range<object::MinidumpFile::MemoryInfoIterator> Range)
+      : Stream(StreamKind::MemoryInfoList,
+               minidump::StreamType::MemoryInfoList),
+        Infos(Range.begin(), Range.end()) {}
+
+  static bool classof(const Stream *S) {
+    return S->Kind == StreamKind::MemoryInfoList;
+  }
+};
+
 /// A minidump stream represented as a sequence of hex bytes. This is used as a
 /// fallback when no other stream kind is suitable.
 struct RawContentStream : public Stream {
@@ -122,16 +143,16 @@ struct SystemInfoStream : public Stream
   minidump::SystemInfo Info;
   std::string CSDVersion;
 
-  explicit SystemInfoStream(const minidump::SystemInfo &Info,
-                            std::string CSDVersion)
-      : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo),
-        Info(Info), CSDVersion(std::move(CSDVersion)) {}
-
   SystemInfoStream()
       : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo) {
     memset(&Info, 0, sizeof(Info));
   }
 
+  explicit SystemInfoStream(const minidump::SystemInfo &Info,
+                            std::string CSDVersion)
+      : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo),
+        Info(Info), CSDVersion(std::move(CSDVersion)) {}
+
   static bool classof(const Stream *S) {
     return S->Kind == StreamKind::SystemInfo;
   }
@@ -207,6 +228,10 @@ template <> struct MappingContextTraits<
 
 } // namespace llvm
 
+LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryProtection)
+LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryState)
+LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryType)
+
 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::ProcessorArchitecture)
 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::OSPlatform)
 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::StreamType)
@@ -214,6 +239,7 @@ LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::mini
 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::ArmInfo)
 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::OtherInfo)
 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::MemoryInfo)
 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::VSFixedFileInfo)
 
 LLVM_YAML_DECLARE_MAPPING_TRAITS(
@@ -227,6 +253,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ThreadListStream::entry_type)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::minidump::MemoryInfo)
 
 LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object)
 

Modified: llvm/trunk/lib/ObjectYAML/MinidumpEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MinidumpEmitter.cpp?rev=374337&r1=374336&r2=374337&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/MinidumpEmitter.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/MinidumpEmitter.cpp Thu Oct 10 06:05:46 2019
@@ -158,6 +158,14 @@ static Directory layout(BlobAllocator &F
   Result.Location.RVA = File.tell();
   Optional<size_t> DataEnd;
   switch (S.Kind) {
+  case Stream::StreamKind::MemoryInfoList: {
+    MemoryInfoListStream &InfoList = cast<MemoryInfoListStream>(S);
+    File.allocateNewObject<minidump::MemoryInfoListHeader>(
+        sizeof(minidump::MemoryInfoListHeader), sizeof(minidump::MemoryInfo),
+        InfoList.Infos.size());
+    File.allocateArray(makeArrayRef(InfoList.Infos));
+    break;
+  }
   case Stream::StreamKind::MemoryList:
     DataEnd = layout(File, cast<MemoryListStream>(S));
     break;

Modified: llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp?rev=374337&r1=374336&r2=374337&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/MinidumpYAML.cpp Thu Oct 10 06:05:46 2019
@@ -69,6 +69,8 @@ Stream::~Stream() = default;
 
 Stream::StreamKind Stream::getKind(StreamType Type) {
   switch (Type) {
+  case StreamType::MemoryInfoList:
+    return StreamKind::MemoryInfoList;
   case StreamType::MemoryList:
     return StreamKind::MemoryList;
   case StreamType::ModuleList:
@@ -93,6 +95,8 @@ Stream::StreamKind Stream::getKind(Strea
 std::unique_ptr<Stream> Stream::create(StreamType Type) {
   StreamKind Kind = getKind(Type);
   switch (Kind) {
+  case StreamKind::MemoryInfoList:
+    return std::make_unique<MemoryInfoListStream>();
   case StreamKind::MemoryList:
     return std::make_unique<MemoryListStream>();
   case StreamKind::ModuleList:
@@ -109,6 +113,25 @@ std::unique_ptr<Stream> Stream::create(S
   llvm_unreachable("Unhandled stream kind!");
 }
 
+void yaml::ScalarBitSetTraits<MemoryProtection>::bitset(
+    IO &IO, MemoryProtection &Protect) {
+#define HANDLE_MDMP_PROTECT(CODE, NAME, NATIVENAME)                            \
+  IO.bitSetCase(Protect, #NATIVENAME, MemoryProtection::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+}
+
+void yaml::ScalarBitSetTraits<MemoryState>::bitset(IO &IO, MemoryState &State) {
+#define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME)                           \
+  IO.bitSetCase(State, #NATIVENAME, MemoryState::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+}
+
+void yaml::ScalarBitSetTraits<MemoryType>::bitset(IO &IO, MemoryType &Type) {
+#define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME)                            \
+  IO.bitSetCase(Type, #NATIVENAME, MemoryType::NAME);
+#include "llvm/BinaryFormat/MinidumpConstants.def"
+}
+
 void yaml::ScalarEnumerationTraits<ProcessorArchitecture>::enumeration(
     IO &IO, ProcessorArchitecture &Arch) {
 #define HANDLE_MDMP_ARCH(CODE, NAME)                                           \
@@ -215,6 +238,20 @@ void yaml::MappingTraits<CPUInfo::X86Inf
   mapOptionalHex(IO, "AMD Extended Features", Info.AMDExtendedFeatures, 0);
 }
 
+void yaml::MappingTraits<MemoryInfo>::mapping(IO &IO, MemoryInfo &Info) {
+  mapRequiredHex(IO, "Base Address", Info.BaseAddress);
+  mapOptionalHex(IO, "Allocation Base", Info.AllocationBase, Info.BaseAddress);
+  mapRequiredAs<MemoryProtection>(IO, "Allocation Protect",
+                                  Info.AllocationProtect);
+  mapOptionalHex(IO, "Reserved0", Info.Reserved0, 0);
+  mapRequiredHex(IO, "Region Size", Info.RegionSize);
+  mapRequiredAs<MemoryState>(IO, "State", Info.State);
+  mapOptionalAs<MemoryProtection>(IO, "Protect", Info.Protect,
+                                  Info.AllocationProtect);
+  mapRequiredAs<MemoryType>(IO, "Type", Info.Type);
+  mapOptionalHex(IO, "Reserved1", Info.Reserved1, 0);
+}
+
 void yaml::MappingTraits<VSFixedFileInfo>::mapping(IO &IO,
                                                    VSFixedFileInfo &Info) {
   mapOptionalHex(IO, "Signature", Info.Signature, 0);
@@ -264,6 +301,10 @@ void yaml::MappingTraits<MemoryListStrea
       IO, Range.Entry, Range.Content);
 }
 
+static void streamMapping(yaml::IO &IO, MemoryInfoListStream &Stream) {
+  IO.mapRequired("Memory Ranges", Stream.Infos);
+}
+
 static void streamMapping(yaml::IO &IO, MemoryListStream &Stream) {
   IO.mapRequired("Memory Ranges", Stream.Entries);
 }
@@ -336,6 +377,9 @@ void yaml::MappingTraits<std::unique_ptr
   if (!IO.outputting())
     S = MinidumpYAML::Stream::create(Type);
   switch (S->Kind) {
+  case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
+    streamMapping(IO, llvm::cast<MemoryInfoListStream>(*S));
+    break;
   case MinidumpYAML::Stream::StreamKind::MemoryList:
     streamMapping(IO, llvm::cast<MemoryListStream>(*S));
     break;
@@ -362,6 +406,7 @@ StringRef yaml::MappingTraits<std::uniqu
   switch (S->Kind) {
   case MinidumpYAML::Stream::StreamKind::RawContent:
     return streamValidate(cast<RawContentStream>(*S));
+  case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
   case MinidumpYAML::Stream::StreamKind::MemoryList:
   case MinidumpYAML::Stream::StreamKind::ModuleList:
   case MinidumpYAML::Stream::StreamKind::SystemInfo:
@@ -384,6 +429,12 @@ Expected<std::unique_ptr<Stream>>
 Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
   StreamKind Kind = getKind(StreamDesc.Type);
   switch (Kind) {
+  case StreamKind::MemoryInfoList: {
+    if (auto ExpectedList = File.getMemoryInfoList())
+      return std::make_unique<MemoryInfoListStream>(*ExpectedList);
+    else
+      return ExpectedList.takeError();
+  }
   case StreamKind::MemoryList: {
     auto ExpectedList = File.getMemoryList();
     if (!ExpectedList)

Modified: llvm/trunk/test/tools/obj2yaml/basic-minidump.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/obj2yaml/basic-minidump.yaml?rev=374337&r1=374336&r2=374337&view=diff
==============================================================================
--- llvm/trunk/test/tools/obj2yaml/basic-minidump.yaml (original)
+++ llvm/trunk/test/tools/obj2yaml/basic-minidump.yaml Thu Oct 10 06:05:46 2019
@@ -55,6 +55,27 @@ Streams:
     Memory Ranges:   
       - Start of Memory Range: 0x7C7D7E7F80818283
         Content:               '8485868788'
+  - Type:            MemoryInfoList
+    Memory Ranges:
+      - Base Address:    0x0000000000000000
+        Allocation Protect: [  ]
+        Region Size:     0x0000000000010000
+        State:           [ MEM_FREE ]
+        Protect:         [ PAGE_NO_ACCESS ]
+        Type:            [  ]
+      - Base Address:    0x0000000000010000
+        Allocation Protect: [ PAGE_READ_WRITE ]
+        Region Size:     0x0000000000010000
+        State:           [ MEM_COMMIT ]
+        Type:            [ MEM_MAPPED ]
+      - Base Address:    0x0000000000020000
+        Allocation Base: 0x0000000000000000
+        Allocation Protect: [ PAGE_READ_WRITE, PAGE_WRITECOMBINE ]
+        Reserved0:       0xDEADBEEF
+        Region Size:     0x0000000000010000
+        State:           [ MEM_COMMIT, MEM_FREE ]
+        Type:            [ MEM_PRIVATE, MEM_MAPPED ]
+        Reserved1:       0xBAADF00D
 ...
 
 # CHECK:      --- !minidump
@@ -112,4 +133,25 @@ Streams:
 # CHECK-NEXT:     Memory Ranges:   
 # CHECK-NEXT:       - Start of Memory Range: 0x7C7D7E7F80818283
 # CHECK-NEXT:         Content:               '8485868788'
+# CHECK-NEXT:   - Type:            MemoryInfoList
+# CHECK-NEXT:     Memory Ranges:
+# CHECK-NEXT:       - Base Address:       0x0000000000000000
+# CHECK-NEXT:         Allocation Protect: [  ]
+# CHECK-NEXT:         Region Size:        0x0000000000010000
+# CHECK-NEXT:         State:              [ MEM_FREE ]
+# CHECK-NEXT:         Protect:            [ PAGE_NO_ACCESS ]
+# CHECK-NEXT:         Type:               [  ]
+# CHECK-NEXT:       - Base Address:       0x0000000000010000
+# CHECK-NEXT:         Allocation Protect: [ PAGE_READ_WRITE ]
+# CHECK-NEXT:         Region Size:        0x0000000000010000
+# CHECK-NEXT:         State:              [ MEM_COMMIT ]
+# CHECK-NEXT:         Type:               [ MEM_MAPPED ]
+# CHECK-NEXT:       - Base Address:       0x0000000000020000
+# CHECK-NEXT:         Allocation Base:    0x0000000000000000
+# CHECK-NEXT:         Allocation Protect: [ PAGE_READ_WRITE, PAGE_WRITECOMBINE ]
+# CHECK-NEXT:         Reserved0:          0xDEADBEEF
+# CHECK-NEXT:         Region Size:        0x0000000000010000
+# CHECK-NEXT:         State:              [ MEM_COMMIT, MEM_FREE ]
+# CHECK-NEXT:         Type:               [ MEM_PRIVATE, MEM_MAPPED ]
+# CHECK-NEXT:         Reserved1:          0xBAADF00D
 # CHECK-NEXT: ...




More information about the llvm-commits mailing list