LLVM: lib/ObjectYAML/MinidumpYAML.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

11using namespace llvm;

14

15

16

17

18template

20 typename EndianType::value_type Default) {

22}

23

24

25template <typename MapType, typename EndianType>

27 EndianType &Val) {

28 MapType Mapped = static_cast<typename EndianType::value_type>(Val);

30 Val = static_cast<typename EndianType::value_type>(Mapped);

31}

32

33

34

35template <typename MapType, typename EndianType>

38 MapType Mapped = static_cast<typename EndianType::value_type>(Val);

40 Val = static_cast<typename EndianType::value_type>(Mapped);

41}

42

43namespace {

44

45template struct HexType;

46template <> struct HexType<support::ulittle16_t> { using type = yaml::Hex16; };

47template <> struct HexType<support::ulittle32_t> { using type = yaml::Hex32; };

48template <> struct HexType<support::ulittle64_t> { using type = yaml::Hex64; };

49}

50

51

52template

54 EndianType &Val) {

56}

57

58

59

60template

62 EndianType &Val,

63 typename EndianType::value_type Default) {

65}

66

68

70 switch (Type) {

71 case StreamType::Exception:

73 case StreamType::MemoryInfoList:

75 case StreamType::MemoryList:

77 case StreamType::Memory64List:

79 case StreamType::ModuleList:

81 case StreamType::SystemInfo:

83 case StreamType::LinuxCPUInfo:

84 case StreamType::LinuxProcStatus:

85 case StreamType::LinuxLSBRelease:

86 case StreamType::LinuxCMDLine:

87 case StreamType::LinuxMaps:

88 case StreamType::LinuxProcStat:

89 case StreamType::LinuxProcUptime:

91 case StreamType::ThreadList:

93 default:

95 }

96}

97

100 switch (Kind) {

102 return std::make_unique();

104 return std::make_unique();

106 return std::make_unique();

108 return std::make_unique();

110 return std::make_unique();

112 return std::make_unique(Type);

114 return std::make_unique();

116 return std::make_unique(Type);

118 return std::make_unique();

119 }

121}

122

125#define HANDLE_MDMP_PROTECT(CODE, NAME, NATIVENAME) \

126 IO.bitSetCase(Protect, #NATIVENAME, MemoryProtection::NAME);

127#include "llvm/BinaryFormat/MinidumpConstants.def"

128}

129

131#define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME) \

132 IO.bitSetCase(State, #NATIVENAME, MemoryState::NAME);

133#include "llvm/BinaryFormat/MinidumpConstants.def"

134}

135

137#define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME) \

138 IO.bitSetCase(Type, #NATIVENAME, MemoryType::NAME);

139#include "llvm/BinaryFormat/MinidumpConstants.def"

140}

141

142void yaml::ScalarEnumerationTraits::enumeration(

144#define HANDLE_MDMP_ARCH(CODE, NAME) \

145 IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);

146#include "llvm/BinaryFormat/MinidumpConstants.def"

147 IO.enumFallback(Arch);

148}

149

150void yaml::ScalarEnumerationTraits::enumeration(IO &IO,

152#define HANDLE_MDMP_PLATFORM(CODE, NAME) \

153 IO.enumCase(Plat, #NAME, OSPlatform::NAME);

154#include "llvm/BinaryFormat/MinidumpConstants.def"

155 IO.enumFallback(Plat);

156}

157

158void yaml::ScalarEnumerationTraits::enumeration(IO &IO,

160#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME) \

161 IO.enumCase(Type, #NAME, StreamType::NAME);

162#include "llvm/BinaryFormat/MinidumpConstants.def"

163 IO.enumFallback(Type);

164}

165

166void yaml::MappingTraitsCPUInfo::ArmInfo::mapping(IO &IO,

167 CPUInfo::ArmInfo &Info) {

170}

171

172namespace {

173template <std::size_t N> struct FixedSizeHex {

174 FixedSizeHex(uint8_t (&Storage)[N]) : Storage(Storage) {}

175

176 uint8_t (&Storage)[N];

177};

178}

179

180namespace llvm {

181namespace yaml {

182template <std::size_t N> struct ScalarTraits<FixedSizeHex<N>> {

186

189 return "Invalid hex digit in input";

190 if (Scalar.size() < 2 * N)

191 return "String too short";

192 if (Scalar.size() > 2 * N)

193 return "String too long";

195 return "";

196 }

197

199};

200}

201}

202void yaml::MappingTraitsCPUInfo::OtherInfo::mapping(

203 IO &IO, CPUInfo::OtherInfo &Info) {

204 FixedSizeHex<sizeof(Info.ProcessorFeatures)> Features(Info.ProcessorFeatures);

205 IO.mapRequired("Features", Features);

206}

207

208namespace {

209

210template <std::size_t N> struct FixedSizeString {

211 FixedSizeString(char (&Storage)[N]) : Storage(Storage) {}

212

213 char (&Storage)[N];

214};

215}

216

217namespace llvm {

218namespace yaml {

219template <std::size_t N> struct ScalarTraits<FixedSizeString<N>> {

223

226 return "String too short";

228 return "String too long";

230 return "";

231 }

232

234};

235}

236}

237

238void yaml::MappingTraitsCPUInfo::X86Info::mapping(IO &IO,

239 CPUInfo::X86Info &Info) {

240 FixedSizeString<sizeof(Info.VendorID)> VendorID(Info.VendorID);

241 IO.mapRequired("Vendor ID", VendorID);

242

245 mapOptionalHex(IO, "AMD Extended Features", Info.AMDExtendedFeatures, 0);

246}

247

248void yaml::MappingTraits::mapping(IO &IO, MemoryInfo &Info) {

252 Info.AllocationProtect);

257 Info.AllocationProtect);

260}

261

262void yaml::MappingTraitsMemory64ListStream::entry\_type::mapping(

263 IO &IO, Memory64ListStream::entry_type &Mem) {

264 MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(

266}

267

268void yaml::MappingTraits::mapping(IO &IO,

269 VSFixedFileInfo &Info) {

274 mapOptionalHex(IO, "Product Version High", Info.ProductVersionHigh, 0);

275 mapOptionalHex(IO, "Product Version Low", Info.ProductVersionLow, 0);

283}

284

285void yaml::MappingTraitsModuleListStream::entry\_type::mapping(

287 mapRequiredHex(IO, "Base of Image", M.Entry.BaseOfImage);

288 mapRequiredHex(IO, "Size of Image", M.Entry.SizeOfImage);

290 mapOptional(IO, "Time Date Stamp", M.Entry.TimeDateStamp, 0);

291 IO.mapRequired("Module Name", M.Name);

292 IO.mapOptional("Version Info", M.Entry.VersionInfo, VSFixedFileInfo());

293 IO.mapRequired("CodeView Record", M.CvRecord);

294 IO.mapOptional("Misc Record", M.MiscRecord, yaml::BinaryRef());

297}

298

303

305 if (Stream.Size.value < Stream.Content.binary_size())

306 return "Stream size must be greater or equal to the content size";

307 return "";

308}

309

310void yaml::MappingTraitsMemoryListStream::entry\_type::mapping(

312 MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(

314}

315

319

323

327

329 for (auto &Entry : Stream.Entries) {

330 if (Entry.Entry.DataSize < Entry.Content.binary_size())

331 return "Memory region size must be greater or equal to the content size";

332 }

333 return "";

334}

335

338}

339

343 mapOptional(IO, "Processor Level", Info.ProcessorLevel, 0);

344 mapOptional(IO, "Processor Revision", Info.ProcessorRevision, 0);

345 IO.mapOptional("Number of Processors", Info.NumberOfProcessors, 0);

355 case ProcessorArchitecture::X86:

356 case ProcessorArchitecture::AMD64:

358 break;

359 case ProcessorArchitecture::ARM:

360 case ProcessorArchitecture::ARM64:

361 case ProcessorArchitecture::BP_ARM64:

363 break;

364 default:

366 break;

367 }

368}

369

373

374void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(

375 IO &IO, MemoryDescriptor &Memory, BinaryRef &Content) {

376 mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);

377 IO.mapRequired("Content", Content);

378}

379

380void yaml::MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(

381 IO &IO, MemoryDescriptor_64 &Memory, BinaryRef &Content) {

382 mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);

383 IO.mapRequired("Content", Content);

384 mapOptional(IO, "Data Size", Memory.DataSize, Content.binary_size());

385}

386

387void yaml::MappingTraitsThreadListStream::entry\_type::mapping(

390 mapOptionalHex(IO, "Suspend Count", T.Entry.SuspendCount, 0);

391 mapOptionalHex(IO, "Priority Class", T.Entry.PriorityClass, 0);

393 mapOptionalHex(IO, "Environment Block", T.Entry.EnvironmentBlock, 0);

394 IO.mapRequired("Context", T.Context);

395 IO.mapRequired("Stack", T.Entry.Stack, T.Stack);

396}

397

400}

401

404 IO.mapRequired("Exception Record", Stream.MDExceptionStream.ExceptionRecord);

406}

407

408void yaml::MappingTraitsminidump::Exception::mapping(

409 yaml::IO &IO, minidump::Exception &Exception) {

415

417 SmallString<16> Name("Parameter ");

418 Twine(Index).toVector(Name);

420

421 if (Index < Exception.NumberParameters)

423 else

425 }

426}

427

428void yaml::MappingTraits<std::unique_ptr>::mapping(

429 yaml::IO &IO, std::unique_ptrMinidumpYAML::Stream &S) {

432 Type = S->Type;

434

437 switch (S->Kind) {

438 case MinidumpYAML::Stream::StreamKind::Exception:

440 break;

441 case MinidumpYAML::Stream::StreamKind::MemoryInfoList:

443 break;

444 case MinidumpYAML::Stream::StreamKind::MemoryList:

446 break;

447 case MinidumpYAML::Stream::StreamKind::Memory64List:

449 break;

450 case MinidumpYAML::Stream::StreamKind::ModuleList:

452 break;

453 case MinidumpYAML::Stream::StreamKind::RawContent:

455 break;

456 case MinidumpYAML::Stream::StreamKind::SystemInfo:

458 break;

459 case MinidumpYAML::Stream::StreamKind::TextContent:

461 break;

462 case MinidumpYAML::Stream::StreamKind::ThreadList:

464 break;

465 }

466}

467

468std::string yaml::MappingTraits<std::unique_ptr>::validate(

469 yaml::IO &IO, std::unique_ptrMinidumpYAML::Stream &S) {

470 switch (S->Kind) {

471 case MinidumpYAML::Stream::StreamKind::RawContent:

473 case MinidumpYAML::Stream::StreamKind::Memory64List:

475 case MinidumpYAML::Stream::StreamKind::Exception:

476 case MinidumpYAML::Stream::StreamKind::MemoryInfoList:

477 case MinidumpYAML::Stream::StreamKind::MemoryList:

478 case MinidumpYAML::Stream::StreamKind::ModuleList:

479 case MinidumpYAML::Stream::StreamKind::SystemInfo:

480 case MinidumpYAML::Stream::StreamKind::TextContent:

481 case MinidumpYAML::Stream::StreamKind::ThreadList:

482 return "";

483 }

485}

486

487void yaml::MappingTraits::mapping(IO &IO, Object &O) {

488 IO.mapTag("!minidump", true);

489 mapOptionalHex(IO, "Signature", O.Header.Signature, Header::MagicSignature);

490 mapOptionalHex(IO, "Version", O.Header.Version, Header::MagicVersion);

492 IO.mapRequired("Streams", O.Streams);

493}

494

495Expected<std::unique_ptr>

498 switch (Kind) {

501 File.getExceptionStream(StreamDesc);

502 if (!ExpectedExceptionStream)

503 return ExpectedExceptionStream.takeError();

505 File.getRawData(ExpectedExceptionStream->ThreadContext);

506 if (!ExpectedThreadContext)

507 return ExpectedThreadContext.takeError();

508 return std::make_unique(*ExpectedExceptionStream,

509 *ExpectedThreadContext);

510 }

512 if (auto ExpectedList = File.getMemoryInfoList())

513 return std::make_unique(*ExpectedList);

514 else

515 return ExpectedList.takeError();

516 }

518 auto ExpectedList = File.getMemoryList();

519 if (!ExpectedList)

520 return ExpectedList.takeError();

521 std::vectorMemoryListStream::entry\_type Ranges;

523 auto ExpectedContent = File.getRawData(MD.Memory);

524 if (!ExpectedContent)

525 return ExpectedContent.takeError();

526 Ranges.push_back({MD, *ExpectedContent});

527 }

528 return std::make_unique(std::move(Ranges));

529 }

532 auto Memory64List = File.getMemory64List(Err);

533 std::vectorMemory64ListStream::entry\_type Ranges;

535 Ranges.push_back({Pair.first, Pair.second});

536 }

537

538 if (Err)

539 return Err;

540 return std::make_unique(std::move(Ranges));

541 }

543 auto ExpectedList = File.getModuleList();

544 if (!ExpectedList)

545 return ExpectedList.takeError();

546 std::vectorModuleListStream::entry\_type Modules;

547 for (const Module &M : *ExpectedList) {

548 auto ExpectedName = File.getString(M.ModuleNameRVA);

549 if (!ExpectedName)

550 return ExpectedName.takeError();

551 auto ExpectedCv = File.getRawData(M.CvRecord);

552 if (!ExpectedCv)

553 return ExpectedCv.takeError();

554 auto ExpectedMisc = File.getRawData(M.MiscRecord);

555 if (!ExpectedMisc)

556 return ExpectedMisc.takeError();

557 Modules.push_back(

558 {M, std::move(*ExpectedName), *ExpectedCv, *ExpectedMisc});

559 }

560 return std::make_unique(std::move(Modules));

561 }

563 return std::make_unique(StreamDesc.Type,

564 File.getRawStream(StreamDesc));

566 auto ExpectedInfo = File.getSystemInfo();

567 if (!ExpectedInfo)

568 return ExpectedInfo.takeError();

569 auto ExpectedCSDVersion = File.getString(ExpectedInfo->CSDVersionRVA);

570 if (!ExpectedCSDVersion)

571 return ExpectedInfo.takeError();

572 return std::make_unique(*ExpectedInfo,

573 std::move(*ExpectedCSDVersion));

574 }

576 return std::make_unique(

577 StreamDesc.Type, toStringRef(File.getRawStream(StreamDesc)));

579 auto ExpectedList = File.getThreadList();

580 if (!ExpectedList)

581 return ExpectedList.takeError();

582 std::vectorThreadListStream::entry\_type Threads;

583 for (const Thread &T : *ExpectedList) {

584 auto ExpectedStack = File.getRawData(T.Stack.Memory);

585 if (!ExpectedStack)

586 return ExpectedStack.takeError();

587 auto ExpectedContext = File.getRawData(T.Context);

588 if (!ExpectedContext)

589 return ExpectedContext.takeError();

590 Threads.push_back({T, *ExpectedStack, *ExpectedContext});

591 }

592 return std::make_unique(std::move(Threads));

593 }

594 }

596}

597

599 std::vector<std::unique_ptr> Streams;

600 Streams.reserve(File.streams().size());

601 for (const Directory &StreamDesc : File.streams()) {

602 auto ExpectedStream = Stream::create(StreamDesc, File);

603 if (!ExpectedStream)

604 return ExpectedStream.takeError();

605 Streams.push_back(std::move(*ExpectedStream));

606 }

607 return Object(File.header(), std::move(Streams));

608}

Analysis containing CSE Info

static void mapOptionalHex(yaml::IO &IO, const char *Key, EndianType &Val, typename EndianType::value_type Default)

Perform an optional yaml-mapping of an endian-aware type as an appropriately-sized hex value.

Definition MinidumpYAML.cpp:61

static void mapRequiredAs(yaml::IO &IO, const char *Key, EndianType &Val)

Yaml-map an endian-aware type EndianType as some other type MapType.

Definition MinidumpYAML.cpp:26

static std::string streamValidate(RawContentStream &Stream)

Definition MinidumpYAML.cpp:304

static void mapOptionalAs(yaml::IO &IO, const char *Key, EndianType &Val, MapType Default)

Perform an optional yaml-mapping of an endian-aware type EndianType as some other type MapType.

Definition MinidumpYAML.cpp:36

static void mapRequiredHex(yaml::IO &IO, const char *Key, EndianType &Val)

Yaml-map an endian-aware type as an appropriately-sized hex value.

Definition MinidumpYAML.cpp:53

static void streamMapping(yaml::IO &IO, RawContentStream &Stream)

Definition MinidumpYAML.cpp:299

static void mapOptional(yaml::IO &IO, const char *Key, EndianType &Val, typename EndianType::value_type Default)

Perform an optional yaml-mapping of an endian-aware type EndianType.

Definition MinidumpYAML.cpp:19

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

OptimizedStructLayoutField Field

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

A Module instance is used to store all the information related to an LLVM module.

StringRef - Represent a constant reference to a string, i.e.

The instances of the Type class are immutable: once they are created, they are never changed.

A class providing access to the contents of a minidump file.

This class implements an extremely fast bulk output stream that can only output to a stream.

virtual bool outputting() const =0

void mapOptional(StringRef Key, T &Val)

void mapRequired(StringRef Key, T &Val)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

VendorID

AArch64 build attributes vendors IDs (a.k.a subsection name)

detail::ListStream< detail::ParsedModule > ModuleListStream

detail::ListStream< detail::ParsedMemoryDescriptor > MemoryListStream

detail::ListStream< detail::ParsedThread > ThreadListStream

ProcessorArchitecture

The processor architecture of the system that generated this minidump.

StreamType

The type of a minidump stream identifies its contents.

OSPlatform

The OS Platform of the system that generated this minidump.

detail::packed_endian_specific_integral< uint64_t, llvm::endianness::little, unaligned > ulittle64_t

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t

QuotingType

Describe which type of quotes should be used when quoting is necessary.

QuotingType needsQuotes(StringRef S, bool ForcePreserveAsString=true)

This is an optimization pass for GlobalISel generic memory operations.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

std::string fromHex(StringRef Input)

Convert hexadecimal string Input to its binary representation. The return string is half the size of ...

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

ArrayRef(const T &OneElt) -> ArrayRef< T >

OutputIt copy(R &&Range, OutputIt Out)

void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)

Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

bool isHexDigit(char C)

Checks if character C is a hexadecimal numeric character.

StringRef toStringRef(bool B)

Construct a string ref from a boolean.

ExceptionStream minidump stream.

A structure containing the list of MemoryInfo entries comprising a MemoryInfoList stream.

std::vector< std::unique_ptr< Stream > > Streams

The list of streams in this minidump object.

static Expected< Object > create(const object::MinidumpFile &File)

Definition MinidumpYAML.cpp:598

A minidump stream represented as a sequence of hex bytes.

The base class for all minidump streams.

static std::unique_ptr< Stream > create(minidump::StreamType Type)

Create an empty stream of the given Type.

Definition MinidumpYAML.cpp:98

static StreamKind getKind(minidump::StreamType Type)

Get the stream Kind used for representing streams of a given Type.

Definition MinidumpYAML.cpp:69

const minidump::StreamType Type

SystemInfo minidump stream.

A StringRef, which is printed using YAML block notation.

detail::ParsedModule entry_type

std::vector< entry_type > Entries

minidump::MemoryDescriptor_64 Entry

Specifies the location and type of a single stream in the minidump file.

support::little_t< StreamType > Type

Describes a single memory range (both its VM address and where to find it in the file) of the process...

The SystemInfo stream, containing various information about the system where this minidump was genera...

Describes a single thread in the minidump file.

This class should be specialized by any integer type that is a union of bit values and the YAML repre...

static QuotingType mustQuote(StringRef S)

Definition MinidumpYAML.cpp:198

static StringRef input(StringRef Scalar, void *, FixedSizeHex< N > &Fixed)

Definition MinidumpYAML.cpp:187

static void output(const FixedSizeHex< N > &Fixed, void *, raw_ostream &OS)

Definition MinidumpYAML.cpp:183

static QuotingType mustQuote(StringRef S)

Definition MinidumpYAML.cpp:233

static StringRef input(StringRef Scalar, void *, FixedSizeString< N > &Fixed)

Definition MinidumpYAML.cpp:224

static void output(const FixedSizeString< N > &Fixed, void *, raw_ostream &OS)

Definition MinidumpYAML.cpp:220

This class should be specialized by type that requires custom conversion to/from a yaml scalar.