Commit 7bb5fc05 authored by Nico Weber's avatar Nico Weber
Browse files

llvm-pdbdump: Fix several smaller issues with injected source compression handling

- getCompression() used to return a PDB_SourceCompression even though
  the docs for IDiaInjectedSource are explicit about the return value
  being compiler-dependent. Return an uint32_t instead, and make the
  printing code handle unknown values better by printing "Unknown" and
  the int value instead of not printing any compression.

- Print compressed contents as hex dump, not as string.

- Add compression type "DotNet", which is used (at least) by csc.exe,
  the C# compiler. Also add a lengthy comment describing the stream
  contents (derived from looking at the raw hex contents long enough
  to see the GUIDs, which led me to the roslyn and mono implementations
  for handling this).

- The native injected source dumper was dumping the contents of the
  whole data stream -- but csc.exe writes a stream that's padded with
  zero bytes to the next 512 boundary, and the dia api doesn't display
  those padding bytes. So make NativeInjectedSource::getCode() do the
  same thing.

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

llvm-svn: 366386
parent 7872d76a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ public:
  std::string getFileName() const override;
  std::string getObjectFileName() const override;
  std::string getVirtualFileName() const override;
  PDB_SourceCompression getCompression() const override;
  uint32_t getCompression() const override;
  std::string getCode() const override;

private:
+4 −2
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
#ifndef LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H
#define LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H

#include "PDBTypes.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <string>
@@ -32,7 +31,10 @@ public:
  virtual std::string getFileName() const = 0;
  virtual std::string getObjectFileName() const = 0;
  virtual std::string getVirtualFileName() const = 0;
  virtual PDB_SourceCompression getCompression() const = 0;
  // The returned value depends on the PDB producer,
  // but 0 is guaranteed to mean "no compression".
  // The enum PDB_SourceCompression lists known return values.
  virtual uint32_t getCompression() const = 0;
  virtual std::string getCode() const = 0;
};
} // namespace pdb
+1 −2
Original line number Diff line number Diff line
@@ -37,13 +37,12 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag);
raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine);
raw_ostream &operator<<(raw_ostream &OS,
                        const PDB_SourceCompression &Compression);

raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version);
raw_ostream &operator<<(raw_ostream &OS, const TagStats &Stats);

raw_ostream& dumpPDBSourceCompression(raw_ostream& OS, uint32_t Compression);

template <typename T>
void dumpSymbolField(raw_ostream &OS, StringRef Name, T Value, int Indent) {
+63 −5
Original line number Diff line number Diff line
@@ -146,11 +146,69 @@ enum class PDB_Machine {
  WceMipsV2 = 0x169
};

enum class PDB_SourceCompression {
// A struct with an inner unnamed enum with explicit underlying type resuls
// in an enum class that can implicitly convert to the underlying type, which
// is convenient for this enum.
struct PDB_SourceCompression {
  enum : uint32_t {
    // No compression. Produced e.g. by `link.exe /natvis:foo.natvis`.
    None,
    // Not known what produces this.
    RunLengthEncoded,
    // Not known what produces this.
    Huffman,
    // Not known what produces this.
    LZ,
    // Produced e.g. by `csc /debug`. The encoded data is its own mini-stream
    // with the following layout (in little endian):
    //   GUID LanguageTypeGuid;
    //   GUID LanguageVendorGuid;
    //   GUID DocumentTypeGuid;
    //   GUID HashFunctionGuid;
    //   uint32_t HashDataSize;
    //   uint32_t CompressedDataSize;
    // Followed by HashDataSize bytes containing a hash checksum,
    // followed by CompressedDataSize bytes containing source contents.
    //
    // CompressedDataSize can be 0, in this case only the hash data is present.
    // (CompressedDataSize is != 0 e.g. if `/embed` is passed to csc.exe.)
    // The compressed data format is:
    //   uint32_t UncompressedDataSize;
    // If UncompressedDataSize is 0, the data is stored uncompressed and
    // CompressedDataSize stores the uncompressed size.
    // If UncompressedDataSize is != 0, then the data is in raw deflate
    // encoding as described in rfc1951.
    //
    // A GUID is 16 bytes, stored in the usual
    //   uint32_t
    //   uint16_t
    //   uint16_t
    //   uint8_t[24]
    // layout.
    //
    // Well-known GUIDs for LanguageTypeGuid are:
    //   63a08714-fc37-11d2-904c-00c04fa302a1 C
    //   3a12d0b7-c26c-11d0-b442-00a0244a1dd2 C++
    //   3f5162f8-07c6-11d3-9053-00c04fa302a1 C#
    //   af046cd1-d0e1-11d2-977c-00a0c9b4d50c Cobol
    //   ab4f38c9-b6e6-43ba-be3b-58080b2ccce3 F#
    //   3a12d0b4-c26c-11d0-b442-00a0244a1dd2 Java
    //   3a12d0b6-c26c-11d0-b442-00a0244a1dd2 JScript
    //   af046cd2-d0e1-11d2-977c-00a0c9b4d50c Pascal
    //   3a12d0b8-c26c-11d0-b442-00a0244a1dd2 Visual Basic
    //
    // Well-known GUIDs for LanguageVendorGuid are:
    //   994b45c4-e6e9-11d2-903f-00c04fa302a1 Microsoft
    //
    // Well-known GUIDs for DocumentTypeGuid are:
    //   5a869d0b-6611-11d3-bd2a-0000f80849bd Text
    //
    // Well-known GUIDs for HashFunctionGuid are:
    //   406ea660-64cf-4c82-b6f0-42d48172a799 MD5    (HashDataSize is 16)
    //   ff1816ec-aa5e-4d10-87f7-6f4963833460 SHA1   (HashDataSize is 20)
    //   8829d00f-11b8-4213-878b-770e8597ac16 SHA256 (HashDataSize is 32)
    DotNet = 101,
  };
};

/// These values correspond to the CV_call_e enumeration, and are documented
+2 −2
Original line number Diff line number Diff line
@@ -41,11 +41,11 @@ std::string DIAInjectedSource::getVirtualFileName() const {
                          &IDiaInjectedSource::get_virtualFilename);
}

PDB_SourceCompression DIAInjectedSource::getCompression() const {
uint32_t DIAInjectedSource::getCompression() const {
  DWORD Compression = 0;
  if (S_OK != SourceFile->get_sourceCompression(&Compression))
    return PDB_SourceCompression::None;
  return static_cast<PDB_SourceCompression>(Compression);
  return static_cast<uint32_t>(Compression);
}

std::string DIAInjectedSource::getCode() const {
Loading