]> granicus.if.org Git - llvm/commitdiff
[pdb] Support CoffSymbolRVA debug subsection.
authorZachary Turner <zturner@google.com>
Fri, 9 Jun 2017 20:46:52 +0000 (20:46 +0000)
committerZachary Turner <zturner@google.com>
Fri, 9 Jun 2017 20:46:52 +0000 (20:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305108 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h [new file with mode: 0644]
lib/DebugInfo/CodeView/CMakeLists.txt
lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp [new file with mode: 0644]
lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
tools/llvm-pdbutil/LLVMOutputStyle.cpp
tools/llvm-pdbutil/llvm-pdbutil.cpp
tools/llvm-pdbutil/llvm-pdbutil.h

index 419ce34922e54ba68eb31ac53eede07de7c44e7f..d4a3d9195a3667446d30d78a4b02ce6995d0f27b 100644 (file)
@@ -27,6 +27,7 @@ class DebugCrossModuleImportsSubsectionRef;
 class DebugFrameDataSubsectionRef;
 class DebugLinesSubsectionRef;
 class DebugStringTableSubsectionRef;
+class DebugSymbolRVASubsectionRef;
 class DebugSymbolsSubsectionRef;
 class DebugUnknownSubsectionRef;
 
@@ -108,6 +109,8 @@ public:
 
   virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
                                const DebugSubsectionState &State) = 0;
+  virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
+                                    const DebugSubsectionState &State) = 0;
 };
 
 Error visitDebugSubsection(const DebugSubsectionRecord &R,
diff --git a/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h b/include/llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h
new file mode 100644 (file)
index 0000000..ad58a29
--- /dev/null
@@ -0,0 +1,59 @@
+//===- DebugSymbolRVASubsection.h -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+class DebugSymbolRVASubsectionRef final : public DebugSubsectionRef {
+public:
+  typedef FixedStreamArray<support::ulittle32_t> ArrayType;
+
+  DebugSymbolRVASubsectionRef();
+
+  static bool classof(const DebugSubsectionRef *S) {
+    return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+  }
+
+  ArrayType::Iterator begin() const { return RVAs.begin(); }
+  ArrayType::Iterator end() const { return RVAs.end(); }
+
+  Error initialize(BinaryStreamReader &Reader);
+
+private:
+  ArrayType RVAs;
+};
+
+class DebugSymbolRVASubsection final : public DebugSubsection {
+public:
+  DebugSymbolRVASubsection();
+
+  static bool classof(const DebugSubsection *S) {
+    return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
+  }
+
+  Error commit(BinaryStreamWriter &Writer) const override;
+  uint32_t calculateSerializedSize() const override;
+
+  void addRVA(uint32_t RVA) { RVAs.push_back(support::ulittle32_t(RVA)); }
+
+private:
+  std::vector<support::ulittle32_t> RVAs;
+};
+} // namespace codeview
+} // namespace llvm
+
+#endif
index c543a6e9ae1cac4511f334d66c990c399836524d..2f9e8981b698af0341c27d9d32f6325e405dd46e 100644 (file)
@@ -13,6 +13,7 @@ add_llvm_library(LLVMDebugInfoCodeView
   DebugSubsection.cpp
   DebugSubsectionRecord.cpp
   DebugSubsectionVisitor.cpp
+  DebugSymbolRVASubsection.cpp
   DebugSymbolsSubsection.cpp
   EnumTables.cpp
   Formatters.cpp
index be56ea191980b20937fd8087fa833aa8fe45fbc2..8550107741ce796f66ca6ea2de4d3499243dc690 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
 #include "llvm/Support/BinaryStreamReader.h"
@@ -111,6 +112,12 @@ Error llvm::codeview::visitDebugSubsection(const DebugSubsectionRecord &R,
       return EC;
     return V.visitFrameData(Section, State);
   }
+  case DebugSubsectionKind::CoffSymbolRVA: {
+    DebugSymbolRVASubsectionRef Section;
+    if (auto EC = Section.initialize(Reader))
+      return EC;
+    return V.visitCOFFSymbolRVAs(Section, State);
+  }
   default: {
     DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
     return V.visitUnknown(Fragment);
diff --git a/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp b/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp
new file mode 100644 (file)
index 0000000..5f91b68
--- /dev/null
@@ -0,0 +1,31 @@
+//===- DebugSymbolRVASubsection.cpp ------------------------------*- C++-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+DebugSymbolRVASubsectionRef::DebugSymbolRVASubsectionRef()
+    : DebugSubsectionRef(DebugSubsectionKind::CoffSymbolRVA) {}
+
+Error DebugSymbolRVASubsectionRef::initialize(BinaryStreamReader &Reader) {
+  return Reader.readArray(RVAs, Reader.bytesRemaining() / sizeof(uint32_t));
+}
+
+DebugSymbolRVASubsection::DebugSymbolRVASubsection()
+    : DebugSubsection(DebugSubsectionKind::CoffSymbolRVA) {}
+
+Error DebugSymbolRVASubsection::commit(BinaryStreamWriter &Writer) const {
+  return Writer.writeArray(makeArrayRef(RVAs));
+}
+
+uint32_t DebugSymbolRVASubsection::calculateSerializedSize() const {
+  return RVAs.size() * sizeof(uint32_t);
+}
index 3bcedd02d47de4893f8cf851c13a883107222089..08a4bb715fac4f18d0f0fc34633838915f375aad 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
+#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@@ -208,6 +209,21 @@ struct YAMLFrameDataSubsection : public YAMLSubsectionBase {
 
   std::vector<YAMLFrameData> Frames;
 };
+
+struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase {
+  YAMLCoffSymbolRVASubsection()
+      : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
+
+  void map(IO &IO) override;
+  std::unique_ptr<DebugSubsection>
+  toCodeViewSubsection(BumpPtrAllocator &Allocator,
+                       DebugStringTableSubsection *Strings,
+                       DebugChecksumsSubsection *Checksums) const override;
+  static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
+  fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
+
+  std::vector<uint32_t> RVAs;
+};
 }
 
 void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
@@ -337,6 +353,11 @@ void YAMLFrameDataSubsection::map(IO &IO) {
   IO.mapRequired("Frames", Frames);
 }
 
+void YAMLCoffSymbolRVASubsection::map(IO &IO) {
+  IO.mapTag("!COFFSymbolRVAs", true);
+  IO.mapRequired("RVAs", RVAs);
+}
+
 void MappingTraits<YAMLDebugSubsection>::mapping(
     IO &IO, YAMLDebugSubsection &Subsection) {
   if (!IO.outputting()) {
@@ -359,6 +380,8 @@ void MappingTraits<YAMLDebugSubsection>::mapping(
       Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>();
     } else if (IO.mapTag("!FrameData")) {
       Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>();
+    } else if (IO.mapTag("!COFFSymbolRVAs")) {
+      Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>();
     } else {
       llvm_unreachable("Unexpected subsection tag!");
     }
@@ -502,6 +525,16 @@ std::unique_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
   return std::move(Result);
 }
 
+std::unique_ptr<DebugSubsection>
+YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
+    BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
+    DebugChecksumsSubsection *Checksums) const {
+  auto Result = llvm::make_unique<DebugSymbolRVASubsection>();
+  for (const auto &RVA : RVAs)
+    Result->addRVA(RVA);
+  return std::move(Result);
+}
+
 static Expected<SourceFileChecksumEntry>
 convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
                    const FileChecksumEntry &CS) {
@@ -698,6 +731,16 @@ YAMLFrameDataSubsection::fromCodeViewSubsection(
   return Result;
 }
 
+Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
+YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(
+    const DebugSymbolRVASubsectionRef &Section) {
+  auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>();
+  for (const auto &RVA : Section) {
+    Result->RVAs.push_back(RVA);
+  }
+  return Result;
+}
+
 Expected<std::vector<std::unique_ptr<DebugSubsection>>>
 llvm::CodeViewYAML::toCodeViewSubsectionList(
     BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
@@ -782,6 +825,8 @@ struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
                      const DebugSubsectionState &State) override;
   Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
                        const DebugSubsectionState &State) override;
+  Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
+                            const DebugSubsectionState &State) override;
 
   YAMLDebugSubsection Subsection;
 };
@@ -871,6 +916,15 @@ Error SubsectionConversionVisitor::visitFrameData(
   Subsection.Subsection = *Result;
   return Error::success();
 }
+
+Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
+    DebugSymbolRVASubsectionRef &RVAs, const DebugSubsectionState &State) {
+  auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
+  if (!Result)
+    return Result.takeError();
+  Subsection.Subsection = *Result;
+  return Error::success();
+}
 }
 
 Expected<YAMLDebugSubsection> YAMLDebugSubsection::fromCodeViewSubection(
index 8096ceda9428ac503674c88079e0a343a6f1c6e9..824f88f8efd089f4942bf9cec77e20db53cfff55 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
+#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
@@ -286,6 +287,16 @@ public:
     return Error::success();
   }
 
+  Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
+                            const DebugSubsectionState &State) override {
+    if (!opts::checkModuleSubsection(opts::ModuleSubsection::CoffSymbolRVAs))
+      return Error::success();
+
+    ListScope D(P, "COFF Symbol RVAs");
+    P.printHexList("RVAs", RVAs);
+    return Error::success();
+  }
+
 private:
   Error dumpTypeRecord(StringRef Label, TypeIndex Index) {
     CompactTypeDumpVisitor CTDV(IPI, Index, &P);
index fa2a5bdd9d3b1ab6c231f9c4753e49a43cf6ff7b..f6b6a156a7674cdd775a3ac9a904f88158db45b0 100644 (file)
@@ -442,6 +442,8 @@ cl::list<ModuleSubsection> DumpModuleSubsections(
         clEnumValN(ModuleSubsection::Symbols, "symbols",
                    "Symbols (DEBUG_S_SYMBOLS subsection) (not typically "
                    "present in PDB file)"),
+        clEnumValN(ModuleSubsection::CoffSymbolRVAs, "rvas",
+                   "COFF Symbol RVAs (DEBUG_S_COFF_SYMBOL_RVA subsection)"),
         clEnumValN(ModuleSubsection::Unknown, "unknown",
                    "Any subsection not covered by another option"),
         clEnumValN(ModuleSubsection::All, "all", "All known subsections")),
index 4f3665237c7d6b8429ede3beef6f21987db689a7..f1699d0bb557535bec7ee0c2b9a41ee46cc62e3e 100644 (file)
@@ -37,6 +37,7 @@ enum class ModuleSubsection {
   StringTable,
   Symbols,
   FrameData,
+  CoffSymbolRVAs,
   All
 };