labath created this revision. labath added reviewers: amccarth, jhenderson, clayborg. Herald added a project: LLVM.
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. Repository: rL LLVM https://reviews.llvm.org/D68645 Files: include/llvm/BinaryFormat/Minidump.h include/llvm/ObjectYAML/MinidumpYAML.h lib/ObjectYAML/MinidumpEmitter.cpp lib/ObjectYAML/MinidumpYAML.cpp test/tools/obj2yaml/basic-minidump.yaml
Index: test/tools/obj2yaml/basic-minidump.yaml =================================================================== --- test/tools/obj2yaml/basic-minidump.yaml +++ test/tools/obj2yaml/basic-minidump.yaml @@ -55,6 +55,27 @@ 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 @@ # 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: ... Index: lib/ObjectYAML/MinidumpYAML.cpp =================================================================== --- lib/ObjectYAML/MinidumpYAML.cpp +++ lib/ObjectYAML/MinidumpYAML.cpp @@ -69,6 +69,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,13 @@ Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) { StreamKind Kind = getKind(StreamDesc.Type); switch (Kind) { + case StreamKind::MemoryInfoList: { + auto ExpectedList = File.getMemoryInfoList(); + if (!ExpectedList) + return ExpectedList.takeError(); + return std::make_unique<MemoryInfoListStream>( + std::vector<MemoryInfo>(ExpectedList->begin(), ExpectedList->end())); + } case StreamKind::MemoryList: { auto ExpectedList = File.getMemoryList(); if (!ExpectedList) Index: lib/ObjectYAML/MinidumpEmitter.cpp =================================================================== --- lib/ObjectYAML/MinidumpEmitter.cpp +++ lib/ObjectYAML/MinidumpEmitter.cpp @@ -158,6 +158,16 @@ Result.Location.RVA = File.tell(); Optional<size_t> DataEnd; switch (S.Kind) { + case Stream::StreamKind::MemoryInfoList: { + MemoryInfoListStream &InfoList = cast<MemoryInfoListStream>(S); + minidump::MemoryInfoListHeader Header; + Header.SizeOfHeader = sizeof(minidump::MemoryInfoListHeader); + Header.SizeOfEntry = sizeof(minidump::MemoryInfo); + Header.NumberOfEntries = InfoList.Infos.size(); + File.allocateNewObject<minidump::MemoryInfoListHeader>(Header); + File.allocateArray(makeArrayRef(InfoList.Infos)); + break; + } case Stream::StreamKind::MemoryList: DataEnd = layout(File, cast<MemoryListStream>(S)); break; Index: include/llvm/ObjectYAML/MinidumpYAML.h =================================================================== --- include/llvm/ObjectYAML/MinidumpYAML.h +++ include/llvm/ObjectYAML/MinidumpYAML.h @@ -26,6 +26,7 @@ /// 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,25 @@ 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; + + explicit MemoryInfoListStream(std::vector<minidump::MemoryInfo> Infos) + : Stream(StreamKind::MemoryInfoList, + minidump::StreamType::MemoryInfoList), + Infos(std::move(Infos)) {} + + MemoryInfoListStream() + : Stream(StreamKind::MemoryInfoList, + minidump::StreamType::MemoryInfoList) {} + + 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 { @@ -207,6 +227,10 @@ } // 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 +238,7 @@ 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 +252,7 @@ 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) Index: include/llvm/BinaryFormat/Minidump.h =================================================================== --- include/llvm/BinaryFormat/Minidump.h +++ include/llvm/BinaryFormat/Minidump.h @@ -84,11 +84,13 @@ 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 {
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits