[llvm] r305366 - [codeview] Make obj2yaml/yaml2obj support .debug$S/T sections.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 13 22:31:01 PDT 2017
Author: zturner
Date: Wed Jun 14 00:31:00 2017
New Revision: 305366
URL: http://llvm.org/viewvc/llvm-project?rev=305366&view=rev
Log:
[codeview] Make obj2yaml/yaml2obj support .debug$S/T sections.
This allows us to use yaml2obj and obj2yaml to round-trip CodeView
symbol and type information without having to manually specify the bytes
of the section. This makes for much easier to maintain tests. See the
tests under lld/COFF in this patch for example. Before they just said
SectionData: <blob> whereas now we can use meaningful record
descriptions. Note that it still supports the SectionData yaml field,
which could be useful for initializing a section to invalid bytes for
testing, for example.
Differential Revision: https://reviews.llvm.org/D34127
Added:
llvm/trunk/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
llvm/trunk/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
Modified:
llvm/trunk/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
llvm/trunk/include/llvm/ObjectYAML/COFFYAML.h
llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
llvm/trunk/lib/ObjectYAML/COFFYAML.cpp
llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp
llvm/trunk/tools/llvm-pdbutil/LLVMOutputStyle.cpp
llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp
llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
llvm/trunk/tools/obj2yaml/coff2yaml.cpp
llvm/trunk/tools/yaml2obj/yaml2coff.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h Wed Jun 14 00:31:00 2017
@@ -49,6 +49,7 @@ public:
Error commit(BinaryStreamWriter &Writer) const override;
void addFrameData(const FrameData &Frame);
+ void setFrames(ArrayRef<FrameData> Frames);
private:
std::vector<FrameData> Frames;
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h Wed Jun 14 00:31:00 2017
@@ -49,13 +49,13 @@ private:
class DebugSubsectionRecordBuilder {
public:
- DebugSubsectionRecordBuilder(std::unique_ptr<DebugSubsection> Subsection,
+ DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
CodeViewContainer Container);
uint32_t calculateSerializedLength();
Error commit(BinaryStreamWriter &Writer) const;
private:
- std::unique_ptr<DebugSubsection> Subsection;
+ std::shared_ptr<DebugSubsection> Subsection;
CodeViewContainer Container;
};
@@ -64,6 +64,9 @@ private:
template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
Error operator()(BinaryStreamRef Stream, uint32_t &Length,
codeview::DebugSubsectionRecord &Info) {
+ // FIXME: We need to pass the container type through to this function. In
+ // practice this isn't super important since the subsection header describes
+ // its length and we can just skip it. It's more important when writing.
if (auto EC = codeview::DebugSubsectionRecord::initialize(
Stream, Info, codeview::CodeViewContainer::Pdb))
return EC;
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h Wed Jun 14 00:31:00 2017
@@ -30,56 +30,7 @@ class DebugStringTableSubsectionRef;
class DebugSymbolRVASubsectionRef;
class DebugSymbolsSubsectionRef;
class DebugUnknownSubsectionRef;
-
-struct DebugSubsectionState {
-public:
- // If no subsections are known about initially, we find as much as we can.
- DebugSubsectionState();
-
- // If only a string table subsection is given, we find a checksums subsection.
- explicit DebugSubsectionState(const DebugStringTableSubsectionRef &Strings);
-
- // If both subsections are given, we don't need to find anything.
- DebugSubsectionState(const DebugStringTableSubsectionRef &Strings,
- const DebugChecksumsSubsectionRef &Checksums);
-
- template <typename T> void initialize(T &&FragmentRange) {
- for (const DebugSubsectionRecord &R : FragmentRange) {
- if (Strings && Checksums)
- return;
- if (R.kind() == DebugSubsectionKind::FileChecksums) {
- initializeChecksums(R);
- continue;
- }
- if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
- // While in practice we should never encounter a string table even
- // though the string table is already initialized, in theory it's
- // possible. PDBs are supposed to have one global string table and
- // then this subsection should not appear. Whereas object files are
- // supposed to have this subsection appear exactly once. However,
- // for testing purposes it's nice to be able to test this subsection
- // independently of one format or the other, so for some tests we
- // manually construct a PDB that contains this subsection in addition
- // to a global string table.
- initializeStrings(R);
- continue;
- }
- }
- }
-
- const DebugStringTableSubsectionRef &strings() const { return *Strings; }
- const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
-
-private:
- void initializeStrings(const DebugSubsectionRecord &SR);
- void initializeChecksums(const DebugSubsectionRecord &FCR);
-
- std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
- std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
-
- const DebugStringTableSubsectionRef *Strings = nullptr;
- const DebugChecksumsSubsectionRef *Checksums = nullptr;
-};
+class StringsAndChecksumsRef;
class DebugSubsectionVisitor {
public:
@@ -89,38 +40,38 @@ public:
return Error::success();
}
virtual Error visitLines(DebugLinesSubsectionRef &Lines,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error
visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error
visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitStringTable(DebugStringTableSubsectionRef &ST,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
};
Error visitDebugSubsection(const DebugSubsectionRecord &R,
DebugSubsectionVisitor &V,
- const DebugSubsectionState &State);
+ const StringsAndChecksumsRef &State);
namespace detail {
template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
- DebugSubsectionState &State) {
+ StringsAndChecksumsRef &State) {
State.initialize(std::forward<T>(FragmentRange));
for (const DebugSubsectionRecord &L : FragmentRange) {
@@ -133,7 +84,7 @@ Error visitDebugSubsections(T &&Fragment
template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
- DebugSubsectionState State;
+ StringsAndChecksumsRef State;
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State);
}
@@ -141,7 +92,7 @@ Error visitDebugSubsections(T &&Fragment
template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
const DebugStringTableSubsectionRef &Strings) {
- DebugSubsectionState State(Strings);
+ StringsAndChecksumsRef State(Strings);
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State);
}
@@ -150,7 +101,7 @@ template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &Checksums) {
- DebugSubsectionState State(Strings, Checksums);
+ StringsAndChecksumsRef State(Strings, Checksums);
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State);
}
Added: llvm/trunk/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h?rev=305366&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h Wed Jun 14 00:31:00 2017
@@ -0,0 +1,103 @@
+//===- StringsAndChecksums.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_STRINGS_AND_CHECKSUMS_H
+#define LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+
+#include <memory>
+
+namespace llvm {
+namespace codeview {
+
+class DebugSubsectionRecord;
+class DebugChecksumsSubsectionRef;
+class DebugStringTableSubsectionRef;
+class DebugChecksumsSubsection;
+class DebugStringTableSubsection;
+
+class StringsAndChecksumsRef {
+public:
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksumsRef();
+
+ // If only a string table subsection is given, we find a checksums subsection.
+ explicit StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings);
+
+ // If both subsections are given, we don't need to find anything.
+ StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums);
+
+ template <typename T> void initialize(T &&FragmentRange) {
+ for (const DebugSubsectionRecord &R : FragmentRange) {
+ if (Strings && Checksums)
+ return;
+ if (R.kind() == DebugSubsectionKind::FileChecksums) {
+ initializeChecksums(R);
+ continue;
+ }
+ if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
+ // While in practice we should never encounter a string table even
+ // though the string table is already initialized, in theory it's
+ // possible. PDBs are supposed to have one global string table and
+ // then this subsection should not appear. Whereas object files are
+ // supposed to have this subsection appear exactly once. However,
+ // for testing purposes it's nice to be able to test this subsection
+ // independently of one format or the other, so for some tests we
+ // manually construct a PDB that contains this subsection in addition
+ // to a global string table.
+ initializeStrings(R);
+ continue;
+ }
+ }
+ }
+
+ const DebugStringTableSubsectionRef &strings() const { return *Strings; }
+ const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ void initializeStrings(const DebugSubsectionRecord &SR);
+ void initializeChecksums(const DebugSubsectionRecord &FCR);
+
+ std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
+ std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
+
+ const DebugStringTableSubsectionRef *Strings = nullptr;
+ const DebugChecksumsSubsectionRef *Checksums = nullptr;
+};
+
+class StringsAndChecksums {
+public:
+ using StringsPtr = std::shared_ptr<DebugStringTableSubsection>;
+ using ChecksumsPtr = std::shared_ptr<DebugChecksumsSubsection>;
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksums() {}
+
+ void setStrings(const StringsPtr &SP) { Strings = SP; }
+ void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; }
+
+ const StringsPtr &strings() const { return Strings; }
+ const ChecksumsPtr &checksums() const { return Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ StringsPtr Strings;
+ ChecksumsPtr Checksums;
+};
+
+} // namespace codeview
+} // namespace llvm
+
+#endif
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h Wed Jun 14 00:31:00 2017
@@ -50,7 +50,7 @@ public:
void addSymbol(codeview::CVSymbol Symbol);
void
- addDebugSubsection(std::unique_ptr<codeview::DebugSubsection> Subsection);
+ addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
uint16_t getStreamIndex() const;
StringRef getModuleName() const { return ModuleName; }
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h Wed Jun 14 00:31:00 2017
@@ -41,10 +41,7 @@ public:
uint32_t calculateSerializedSize() const;
Error commit(BinaryStreamWriter &Writer) const;
- codeview::DebugStringTableSubsection &getStrings() { return Strings; }
- const codeview::DebugStringTableSubsection &getStrings() const {
- return Strings;
- }
+ void setStrings(const codeview::DebugStringTableSubsection &Strings);
private:
uint32_t calculateHashTableSize() const;
Modified: llvm/trunk/include/llvm/ObjectYAML/COFFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/COFFYAML.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/COFFYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/COFFYAML.h Wed Jun 14 00:31:00 2017
@@ -16,6 +16,8 @@
#include "llvm/ADT/Optional.h"
#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
+#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
#include "llvm/ObjectYAML/YAML.h"
namespace llvm {
@@ -56,6 +58,8 @@ namespace COFFYAML {
COFF::section Header;
unsigned Alignment = 0;
yaml::BinaryRef SectionData;
+ std::vector<CodeViewYAML::YAMLDebugSubsection> DebugS;
+ std::vector<CodeViewYAML::LeafRecord> DebugT;
std::vector<Relocation> Relocations;
StringRef Name;
Section();
Modified: llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h Wed Jun 14 00:31:00 2017
@@ -28,6 +28,8 @@ class DebugStringTableSubsectionRef;
class DebugChecksumsSubsectionRef;
class DebugStringTableSubsection;
class DebugChecksumsSubsection;
+class StringsAndChecksums;
+class StringsAndChecksumsRef;
}
namespace CodeViewYAML {
@@ -103,25 +105,24 @@ struct InlineeInfo {
struct YAMLDebugSubsection {
static Expected<YAMLDebugSubsection>
- fromCodeViewSubection(const codeview::DebugStringTableSubsectionRef &Strings,
- const codeview::DebugChecksumsSubsectionRef &Checksums,
+ fromCodeViewSubection(const codeview::StringsAndChecksumsRef &SC,
const codeview::DebugSubsectionRecord &SS);
std::shared_ptr<detail::YAMLSubsectionBase> Subsection;
};
-Expected<std::vector<std::unique_ptr<codeview::DebugSubsection>>>
+struct DebugSubsectionState {};
+
+Expected<std::vector<std::shared_ptr<codeview::DebugSubsection>>>
toCodeViewSubsectionList(BumpPtrAllocator &Allocator,
ArrayRef<YAMLDebugSubsection> Subsections,
- codeview::DebugStringTableSubsection &Strings);
-Expected<std::vector<std::unique_ptr<codeview::DebugSubsection>>>
-toCodeViewSubsectionList(
- BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
- std::unique_ptr<codeview::DebugStringTableSubsection> &TakeStrings,
- codeview::DebugStringTableSubsection *StringsRef);
+ const codeview::StringsAndChecksums &SC);
+
+std::vector<YAMLDebugSubsection>
+fromDebugS(ArrayRef<uint8_t> Data, const codeview::StringsAndChecksumsRef &SC);
-std::unique_ptr<codeview::DebugStringTableSubsection>
-findStringTable(ArrayRef<YAMLDebugSubsection> Sections);
+void initializeStringsAndChecksums(ArrayRef<YAMLDebugSubsection> Sections,
+ codeview::StringsAndChecksums &SC);
} // namespace CodeViewYAML
} // namespace llvm
Modified: llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h Wed Jun 14 00:31:00 2017
@@ -41,6 +41,9 @@ struct LeafRecord {
codeview::CVType toCodeViewRecord(codeview::TypeTableBuilder &TS) const;
static Expected<LeafRecord> fromCodeViewRecord(codeview::CVType Type);
};
+
+std::vector<LeafRecord> fromDebugT(ArrayRef<uint8_t> DebugT);
+ArrayRef<uint8_t> toDebugT(ArrayRef<LeafRecord>, BumpPtrAllocator &Alloc);
} // namespace CodeViewYAML
} // namespace llvm
Modified: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt Wed Jun 14 00:31:00 2017
@@ -20,6 +20,7 @@ add_llvm_library(LLVMDebugInfoCodeView
LazyRandomTypeCollection.cpp
Line.cpp
RecordSerialization.cpp
+ StringsAndChecksums.cpp
SymbolRecordMapping.cpp
SymbolDumper.cpp
SymbolSerializer.cpp
@@ -32,7 +33,7 @@ add_llvm_library(LLVMDebugInfoCodeView
TypeSerializer.cpp
TypeStreamMerger.cpp
TypeTableCollection.cpp
-
+
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/CodeView
)
Modified: llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp Wed Jun 14 00:31:00 2017
@@ -58,6 +58,10 @@ Error DebugStringTableSubsection::commit
uint32_t Begin = Writer.getOffset();
uint32_t End = Begin + StringSize;
+ // Write a null string at the beginning.
+ if (auto EC = Writer.writeCString(StringRef()))
+ return EC;
+
for (auto &Pair : Strings) {
StringRef S = Pair.getKey();
uint32_t Offset = Begin + Pair.getValue();
@@ -68,6 +72,7 @@ Error DebugStringTableSubsection::commit
}
Writer.setOffset(End);
+ assert((End - Begin) == StringSize);
return Error::success();
}
Modified: llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp Wed Jun 14 00:31:00 2017
@@ -50,7 +50,7 @@ DebugSubsectionKind DebugSubsectionRecor
BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
- std::unique_ptr<DebugSubsection> Subsection, CodeViewContainer Container)
+ std::shared_ptr<DebugSubsection> Subsection, CodeViewContainer Container)
: Subsection(std::move(Subsection)), Container(Container) {}
uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
Modified: llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp Wed Jun 14 00:31:00 2017
@@ -26,40 +26,9 @@
using namespace llvm;
using namespace llvm::codeview;
-DebugSubsectionState::DebugSubsectionState() {}
-
-DebugSubsectionState::DebugSubsectionState(
- const DebugStringTableSubsectionRef &Strings)
- : Strings(&Strings) {}
-
-DebugSubsectionState::DebugSubsectionState(
- const DebugStringTableSubsectionRef &Strings,
- const DebugChecksumsSubsectionRef &Checksums)
- : Strings(&Strings), Checksums(&Checksums) {}
-
-void DebugSubsectionState::initializeStrings(const DebugSubsectionRecord &SR) {
- assert(SR.kind() == DebugSubsectionKind::StringTable);
- assert(!Strings && "Found a string table even though we already have one!");
-
- OwnedStrings = llvm::make_unique<DebugStringTableSubsectionRef>();
- consumeError(OwnedStrings->initialize(SR.getRecordData()));
- Strings = OwnedStrings.get();
-}
-
-void DebugSubsectionState::initializeChecksums(
- const DebugSubsectionRecord &FCR) {
- assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
- if (Checksums)
- return;
-
- OwnedChecksums = llvm::make_unique<DebugChecksumsSubsectionRef>();
- consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
- Checksums = OwnedChecksums.get();
-}
-
-Error llvm::codeview::visitDebugSubsection(const DebugSubsectionRecord &R,
- DebugSubsectionVisitor &V,
- const DebugSubsectionState &State) {
+Error llvm::codeview::visitDebugSubsection(
+ const DebugSubsectionRecord &R, DebugSubsectionVisitor &V,
+ const StringsAndChecksumsRef &State) {
BinaryStreamReader Reader(R.getRecordData());
switch (R.kind()) {
case DebugSubsectionKind::Lines: {
Added: llvm/trunk/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/StringsAndChecksums.cpp?rev=305366&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/StringsAndChecksums.cpp (added)
+++ llvm/trunk/lib/DebugInfo/CodeView/StringsAndChecksums.cpp Wed Jun 14 00:31:00 2017
@@ -0,0 +1,48 @@
+//===- StringsAndChecksums.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/StringsAndChecksums.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+StringsAndChecksumsRef::StringsAndChecksumsRef() {}
+
+StringsAndChecksumsRef::StringsAndChecksumsRef(
+ const DebugStringTableSubsectionRef &Strings)
+ : Strings(&Strings) {}
+
+StringsAndChecksumsRef::StringsAndChecksumsRef(
+ const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums)
+ : Strings(&Strings), Checksums(&Checksums) {}
+
+void StringsAndChecksumsRef::initializeStrings(
+ const DebugSubsectionRecord &SR) {
+ assert(SR.kind() == DebugSubsectionKind::StringTable);
+ assert(!Strings && "Found a string table even though we already have one!");
+
+ OwnedStrings = llvm::make_unique<DebugStringTableSubsectionRef>();
+ consumeError(OwnedStrings->initialize(SR.getRecordData()));
+ Strings = OwnedStrings.get();
+}
+
+void StringsAndChecksumsRef::initializeChecksums(
+ const DebugSubsectionRecord &FCR) {
+ assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
+ if (Checksums)
+ return;
+
+ OwnedChecksums = llvm::make_unique<DebugChecksumsSubsectionRef>();
+ consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
+ Checksums = OwnedChecksums.get();
+}
Modified: llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp Wed Jun 14 00:31:00 2017
@@ -177,7 +177,7 @@ Error DbiModuleDescriptorBuilder::commit
}
void DbiModuleDescriptorBuilder::addDebugSubsection(
- std::unique_ptr<DebugSubsection> Subsection) {
+ std::shared_ptr<DebugSubsection> Subsection) {
assert(Subsection);
C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
std::move(Subsection), CodeViewContainer::Pdb));
Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp Wed Jun 14 00:31:00 2017
@@ -52,6 +52,11 @@ uint32_t PDBStringTableBuilder::calculat
return Size;
}
+void PDBStringTableBuilder::setStrings(
+ const codeview::DebugStringTableSubsection &Strings) {
+ this->Strings = Strings;
+}
+
Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const {
// Write a header
PDBStringTableHeader H;
Modified: llvm/trunk/lib/ObjectYAML/COFFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/COFFYAML.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/COFFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/COFFYAML.cpp Wed Jun 14 00:31:00 2017
@@ -488,7 +488,16 @@ void MappingTraits<COFFYAML::Section>::m
IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U);
IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U);
IO.mapOptional("Alignment", Sec.Alignment, 0U);
- IO.mapRequired("SectionData", Sec.SectionData);
+
+ // If this is a .debug$S or .debug$T section parse the semantic representation
+ // of the symbols/types. If it is any other kind of section, just deal in raw
+ // bytes.
+ IO.mapOptional("SectionData", Sec.SectionData);
+ if (Sec.Name == ".debug$S")
+ IO.mapOptional("Subsections", Sec.DebugS);
+ else if (Sec.Name == ".debug$T")
+ IO.mapOptional("Types", Sec.DebugT);
+
IO.mapOptional("Relocations", Sec.Relocations);
}
Modified: llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp Wed Jun 14 00:31:00 2017
@@ -28,6 +28,7 @@
#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
@@ -75,10 +76,9 @@ struct YAMLSubsectionBase {
virtual ~YAMLSubsectionBase() {}
virtual void map(IO &IO) = 0;
- virtual std::unique_ptr<DebugSubsection>
+ virtual std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *UseStrings,
- DebugChecksumsSubsection *UseChecksums) const = 0;
+ const codeview::StringsAndChecksums &SC) const = 0;
};
}
}
@@ -90,10 +90,9 @@ struct YAMLChecksumsSubsection : public
: YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLChecksumsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &FC);
@@ -105,10 +104,9 @@ struct YAMLLinesSubsection : public YAML
YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &Checksums,
@@ -122,10 +120,9 @@ struct YAMLInlineeLinesSubsection : publ
: YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &Checksums,
@@ -139,10 +136,9 @@ struct YAMLCrossModuleExportsSubsection
: YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports);
@@ -154,10 +150,9 @@ struct YAMLCrossModuleImportsSubsection
: YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
const DebugCrossModuleImportsSubsectionRef &Imports);
@@ -169,10 +164,9 @@ struct YAMLSymbolsSubsection : public YA
YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLSymbolsSubsection>>
fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols);
@@ -184,10 +178,9 @@ struct YAMLStringTableSubsection : publi
: YAMLSubsectionBase(DebugSubsectionKind::StringTable) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLStringTableSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings);
@@ -199,10 +192,9 @@ struct YAMLFrameDataSubsection : public
: YAMLSubsectionBase(DebugSubsectionKind::FrameData) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLFrameDataSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
const DebugFrameDataSubsectionRef &Frames);
@@ -215,10 +207,9 @@ struct YAMLCoffSymbolRVASubsection : pub
: YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
void map(IO &IO) override;
- std::unique_ptr<DebugSubsection>
+ std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
- DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const override;
+ const codeview::StringsAndChecksums &SC) const override;
static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
@@ -400,23 +391,23 @@ findChecksums(ArrayRef<YAMLDebugSubsecti
return nullptr;
}
-std::unique_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings,
- DebugChecksumsSubsection *UseChecksums) const {
- assert(UseStrings && !UseChecksums);
- auto Result = llvm::make_unique<DebugChecksumsSubsection>(*UseStrings);
+std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ assert(SC.hasStrings());
+ auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings());
for (const auto &CS : Checksums) {
Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
}
return std::move(Result);
}
-std::unique_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings,
- DebugChecksumsSubsection *UseChecksums) const {
- assert(UseStrings && UseChecksums);
+std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ assert(SC.hasStrings() && SC.hasChecksums());
auto Result =
- llvm::make_unique<DebugLinesSubsection>(*UseChecksums, *UseStrings);
+ std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings());
Result->setCodeSize(Lines.CodeSize);
Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
Result->setFlags(Lines.Flags);
@@ -438,16 +429,16 @@ std::unique_ptr<DebugSubsection> YAMLLin
}
}
}
- return llvm::cast<DebugSubsection>(std::move(Result));
+ return std::move(Result);
}
-std::unique_ptr<DebugSubsection>
+std::shared_ptr<DebugSubsection>
YAMLInlineeLinesSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings,
- DebugChecksumsSubsection *UseChecksums) const {
- assert(UseChecksums);
- auto Result = llvm::make_unique<DebugInlineeLinesSubsection>(
- *UseChecksums, InlineeLines.HasExtraFiles);
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ assert(SC.hasChecksums());
+ auto Result = std::make_shared<DebugInlineeLinesSubsection>(
+ *SC.checksums(), InlineeLines.HasExtraFiles);
for (const auto &Site : InlineeLines.Sites) {
Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
@@ -459,55 +450,59 @@ YAMLInlineeLinesSubsection::toCodeViewSu
Result->addExtraFile(EF);
}
}
- return llvm::cast<DebugSubsection>(std::move(Result));
+ return std::move(Result);
}
-std::unique_ptr<DebugSubsection>
+std::shared_ptr<DebugSubsection>
YAMLCrossModuleExportsSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const {
- auto Result = llvm::make_unique<DebugCrossModuleExportsSubsection>();
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ auto Result = std::make_shared<DebugCrossModuleExportsSubsection>();
for (const auto &M : Exports)
Result->addMapping(M.Local, M.Global);
- return llvm::cast<DebugSubsection>(std::move(Result));
+ return std::move(Result);
}
-std::unique_ptr<DebugSubsection>
+std::shared_ptr<DebugSubsection>
YAMLCrossModuleImportsSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const {
- auto Result = llvm::make_unique<DebugCrossModuleImportsSubsection>(*Strings);
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ assert(SC.hasStrings());
+
+ auto Result =
+ std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings());
for (const auto &M : Imports) {
for (const auto Id : M.ImportIds)
Result->addImport(M.ModuleName, Id);
}
- return llvm::cast<DebugSubsection>(std::move(Result));
+ return std::move(Result);
}
-std::unique_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const {
- auto Result = llvm::make_unique<DebugSymbolsSubsection>();
+std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection(
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ auto Result = std::make_shared<DebugSymbolsSubsection>();
for (const auto &Sym : Symbols)
Result->addSymbol(
Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile));
return std::move(Result);
}
-std::unique_ptr<DebugSubsection>
+std::shared_ptr<DebugSubsection>
YAMLStringTableSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const {
- auto Result = llvm::make_unique<DebugStringTableSubsection>();
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ auto Result = std::make_shared<DebugStringTableSubsection>();
for (const auto &Str : this->Strings)
Result->insert(Str);
return std::move(Result);
}
-std::unique_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const {
- assert(Strings);
+std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
+ assert(SC.hasStrings());
+
auto Result = llvm::make_unique<DebugFrameDataSubsection>();
for (const auto &YF : Frames) {
codeview::FrameData F;
@@ -519,16 +514,16 @@ std::unique_ptr<DebugSubsection> YAMLFra
F.PrologSize = YF.PrologSize;
F.RvaStart = YF.RvaStart;
F.SavedRegsSize = YF.SavedRegsSize;
- F.FrameFunc = Strings->insert(YF.FrameFunc);
+ F.FrameFunc = SC.strings()->insert(YF.FrameFunc);
Result->addFrameData(F);
}
return std::move(Result);
}
-std::unique_ptr<DebugSubsection>
+std::shared_ptr<DebugSubsection>
YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
- BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
- DebugChecksumsSubsection *Checksums) const {
+ BumpPtrAllocator &Allocator,
+ const codeview::StringsAndChecksums &SC) const {
auto Result = llvm::make_unique<DebugSymbolRVASubsection>();
for (const auto &RVA : RVAs)
Result->addRVA(RVA);
@@ -741,63 +736,17 @@ YAMLCoffSymbolRVASubsection::fromCodeVie
return Result;
}
-Expected<std::vector<std::unique_ptr<DebugSubsection>>>
+Expected<std::vector<std::shared_ptr<DebugSubsection>>>
llvm::CodeViewYAML::toCodeViewSubsectionList(
BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
- DebugStringTableSubsection &Strings) {
- std::vector<std::unique_ptr<DebugSubsection>> Result;
+ const codeview::StringsAndChecksums &SC) {
+ std::vector<std::shared_ptr<DebugSubsection>> Result;
if (Subsections.empty())
return std::move(Result);
- auto Checksums = findChecksums(Subsections);
- std::unique_ptr<DebugSubsection> ChecksumsBase;
- if (Checksums)
- ChecksumsBase =
- Checksums->toCodeViewSubsection(Allocator, &Strings, nullptr);
- DebugChecksumsSubsection *CS =
- static_cast<DebugChecksumsSubsection *>(ChecksumsBase.get());
for (const auto &SS : Subsections) {
- // We've already converted the checksums subsection, don't do it
- // twice.
- std::unique_ptr<DebugSubsection> CVS;
- if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums)
- CVS = std::move(ChecksumsBase);
- else
- CVS = SS.Subsection->toCodeViewSubsection(Allocator, &Strings, CS);
- assert(CVS != nullptr);
- Result.push_back(std::move(CVS));
- }
- return std::move(Result);
-}
-
-Expected<std::vector<std::unique_ptr<codeview::DebugSubsection>>>
-llvm::CodeViewYAML::toCodeViewSubsectionList(
- BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
- std::unique_ptr<DebugStringTableSubsection> &TakeStrings,
- DebugStringTableSubsection *StringsRef) {
- std::vector<std::unique_ptr<DebugSubsection>> Result;
- if (Subsections.empty())
- return std::move(Result);
-
- auto Checksums = findChecksums(Subsections);
-
- std::unique_ptr<DebugSubsection> ChecksumsBase;
- if (Checksums)
- ChecksumsBase =
- Checksums->toCodeViewSubsection(Allocator, StringsRef, nullptr);
- DebugChecksumsSubsection *CS =
- static_cast<DebugChecksumsSubsection *>(ChecksumsBase.get());
- for (const auto &SS : Subsections) {
- // We've already converted the checksums and string table subsection, don't
- // do it twice.
- std::unique_ptr<DebugSubsection> CVS;
- if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums)
- CVS = std::move(ChecksumsBase);
- else if (SS.Subsection->Kind == DebugSubsectionKind::StringTable) {
- assert(TakeStrings && "No string table!");
- CVS = std::move(TakeStrings);
- } else
- CVS = SS.Subsection->toCodeViewSubsection(Allocator, StringsRef, CS);
+ std::shared_ptr<DebugSubsection> CVS;
+ CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC);
assert(CVS != nullptr);
Result.push_back(std::move(CVS));
}
@@ -810,23 +759,23 @@ struct SubsectionConversionVisitor : pub
Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
Error visitLines(DebugLinesSubsectionRef &Lines,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitStringTable(DebugStringTableSubsectionRef &ST,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
- const DebugSubsectionState &State) override;
+ const StringsAndChecksumsRef &State) override;
YAMLDebugSubsection Subsection;
};
@@ -837,7 +786,7 @@ Error SubsectionConversionVisitor::visit
}
Error SubsectionConversionVisitor::visitLines(
- DebugLinesSubsectionRef &Lines, const DebugSubsectionState &State) {
+ DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) {
auto Result = YAMLLinesSubsection::fromCodeViewSubsection(
State.strings(), State.checksums(), Lines);
if (!Result)
@@ -847,7 +796,8 @@ Error SubsectionConversionVisitor::visit
}
Error SubsectionConversionVisitor::visitFileChecksums(
- DebugChecksumsSubsectionRef &Checksums, const DebugSubsectionState &State) {
+ DebugChecksumsSubsectionRef &Checksums,
+ const StringsAndChecksumsRef &State) {
auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(),
Checksums);
if (!Result)
@@ -858,7 +808,7 @@ Error SubsectionConversionVisitor::visit
Error SubsectionConversionVisitor::visitInlineeLines(
DebugInlineeLinesSubsectionRef &Inlinees,
- const DebugSubsectionState &State) {
+ const StringsAndChecksumsRef &State) {
auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
State.strings(), State.checksums(), Inlinees);
if (!Result)
@@ -869,7 +819,7 @@ Error SubsectionConversionVisitor::visit
Error SubsectionConversionVisitor::visitCrossModuleExports(
DebugCrossModuleExportsSubsectionRef &Exports,
- const DebugSubsectionState &State) {
+ const StringsAndChecksumsRef &State) {
auto Result =
YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports);
if (!Result)
@@ -880,7 +830,7 @@ Error SubsectionConversionVisitor::visit
Error SubsectionConversionVisitor::visitCrossModuleImports(
DebugCrossModuleImportsSubsectionRef &Imports,
- const DebugSubsectionState &State) {
+ const StringsAndChecksumsRef &State) {
auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
State.strings(), Imports);
if (!Result)
@@ -890,7 +840,8 @@ Error SubsectionConversionVisitor::visit
}
Error SubsectionConversionVisitor::visitStringTable(
- DebugStringTableSubsectionRef &Strings, const DebugSubsectionState &State) {
+ DebugStringTableSubsectionRef &Strings,
+ const StringsAndChecksumsRef &State) {
auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings);
if (!Result)
return Result.takeError();
@@ -899,7 +850,7 @@ Error SubsectionConversionVisitor::visit
}
Error SubsectionConversionVisitor::visitSymbols(
- DebugSymbolsSubsectionRef &Symbols, const DebugSubsectionState &State) {
+ DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) {
auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols);
if (!Result)
return Result.takeError();
@@ -908,7 +859,7 @@ Error SubsectionConversionVisitor::visit
}
Error SubsectionConversionVisitor::visitFrameData(
- DebugFrameDataSubsectionRef &Frames, const DebugSubsectionState &State) {
+ DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) {
auto Result =
YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames);
if (!Result)
@@ -918,7 +869,7 @@ Error SubsectionConversionVisitor::visit
}
Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
- DebugSymbolRVASubsectionRef &RVAs, const DebugSubsectionState &State) {
+ DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) {
auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
if (!Result)
return Result.takeError();
@@ -927,29 +878,71 @@ Error SubsectionConversionVisitor::visit
}
}
-Expected<YAMLDebugSubsection> YAMLDebugSubsection::fromCodeViewSubection(
- const DebugStringTableSubsectionRef &Strings,
- const DebugChecksumsSubsectionRef &Checksums,
- const DebugSubsectionRecord &SS) {
- DebugSubsectionState State(Strings, Checksums);
+Expected<YAMLDebugSubsection>
+YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC,
+ const DebugSubsectionRecord &SS) {
SubsectionConversionVisitor V;
- if (auto EC = visitDebugSubsection(SS, V, State))
+ if (auto EC = visitDebugSubsection(SS, V, SC))
return std::move(EC);
return V.Subsection;
}
-std::unique_ptr<DebugStringTableSubsection>
-llvm::CodeViewYAML::findStringTable(ArrayRef<YAMLDebugSubsection> Sections) {
- for (const auto &SS : Sections) {
- if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
- continue;
+std::vector<YAMLDebugSubsection>
+llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data,
+ const StringsAndChecksumsRef &SC) {
+ BinaryStreamReader Reader(Data, support::little);
+ uint32_t Magic;
+
+ ExitOnError Err("Invalid .debug$S section!");
+ Err(Reader.readInteger(Magic));
+ assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
- // String Table doesn't use the allocator.
- BumpPtrAllocator Allocator;
- auto Result =
- SS.Subsection->toCodeViewSubsection(Allocator, nullptr, nullptr);
- return llvm::cast<DebugStringTableSubsection>(std::move(Result));
+ DebugSubsectionArray Subsections;
+ Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
+
+ std::vector<YAMLDebugSubsection> Result;
+
+ for (const auto &SS : Subsections) {
+ auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS));
+ Result.push_back(YamlSS);
+ }
+ return std::move(Result);
+}
+
+void llvm::CodeViewYAML::initializeStringsAndChecksums(
+ ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) {
+ // String Table and Checksums subsections don't use the allocator.
+ BumpPtrAllocator Allocator;
+
+ // It's possible for checksums and strings to even appear in different debug$S
+ // sections, so we have to make this a stateful function that can build up
+ // the strings and checksums field over multiple iterations.
+
+ // File Checksums require the string table, but may become before it, so we
+ // have to scan for strings first, then scan for checksums again from the
+ // beginning.
+ if (!SC.hasStrings()) {
+ for (const auto &SS : Sections) {
+ if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
+ continue;
+
+ auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
+ SC.setStrings(
+ std::static_pointer_cast<DebugStringTableSubsection>(Result));
+ break;
+ }
+ }
+
+ if (SC.hasStrings() && !SC.hasChecksums()) {
+ for (const auto &SS : Sections) {
+ if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums)
+ continue;
+
+ auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
+ SC.setChecksums(
+ std::static_pointer_cast<DebugChecksumsSubsection>(Result));
+ break;
+ }
}
- return nullptr;
}
Modified: llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp Wed Jun 14 00:31:00 2017
@@ -714,3 +714,43 @@ void MappingTraits<MemberRecord>::mappin
default: { llvm_unreachable("Unknown member kind!"); }
}
}
+
+std::vector<LeafRecord>
+llvm::CodeViewYAML::fromDebugT(ArrayRef<uint8_t> DebugT) {
+ ExitOnError Err("Invalid .debug$T section!");
+ BinaryStreamReader Reader(DebugT, support::little);
+ CVTypeArray Types;
+ uint32_t Magic;
+
+ Err(Reader.readInteger(Magic));
+ assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$T section!");
+
+ std::vector<LeafRecord> Result;
+ Err(Reader.readArray(Types, Reader.bytesRemaining()));
+ for (const auto &T : Types) {
+ auto CVT = Err(LeafRecord::fromCodeViewRecord(T));
+ Result.push_back(CVT);
+ }
+ return std::move(Result);
+}
+
+ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugT(ArrayRef<LeafRecord> Leafs,
+ BumpPtrAllocator &Alloc) {
+ TypeTableBuilder TTB(Alloc, false);
+ uint32_t Size = sizeof(uint32_t);
+ for (const auto &Leaf : Leafs) {
+ CVType T = Leaf.toCodeViewRecord(TTB);
+ Size += T.length();
+ assert(T.length() % 4 == 0 && "Improper type record alignment!");
+ }
+ uint8_t *ResultBuffer = Alloc.Allocate<uint8_t>(Size);
+ MutableArrayRef<uint8_t> Output(ResultBuffer, Size);
+ BinaryStreamWriter Writer(Output, support::little);
+ ExitOnError Err("Error writing type record to .debug$T section");
+ Err(Writer.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC));
+ for (const auto &R : TTB.records()) {
+ Err(Writer.writeBytes(R));
+ }
+ assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!");
+ return Output;
+}
Modified: llvm/trunk/tools/llvm-pdbutil/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/LLVMOutputStyle.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/LLVMOutputStyle.cpp Wed Jun 14 00:31:00 2017
@@ -28,6 +28,7 @@
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
@@ -105,7 +106,7 @@ public:
}
Error visitLines(DebugLinesSubsectionRef &Lines,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::Lines))
return Error::success();
@@ -146,7 +147,7 @@ public:
}
Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::FileChecksums))
return Error::success();
@@ -164,7 +165,7 @@ public:
}
Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::InlineeLines))
return Error::success();
@@ -191,7 +192,7 @@ public:
}
Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::CrossScopeExports))
return Error::success();
@@ -205,7 +206,7 @@ public:
}
Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSI,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::CrossScopeImports))
return Error::success();
@@ -222,7 +223,7 @@ public:
}
Error visitFrameData(DebugFrameDataSubsectionRef &FD,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::FrameData))
return Error::success();
@@ -248,7 +249,7 @@ public:
}
Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::Symbols))
return Error::success();
ListScope L(P, "Symbols");
@@ -270,7 +271,7 @@ public:
}
Error visitStringTable(DebugStringTableSubsectionRef &Strings,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::StringTable))
return Error::success();
@@ -288,7 +289,7 @@ public:
}
Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
- const DebugSubsectionState &State) override {
+ const StringsAndChecksumsRef &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::CoffSymbolRVAs))
return Error::success();
@@ -309,7 +310,7 @@ private:
return EC;
}
}
-
+
if (!Success) {
P.printString(
llvm::formatv("Index: {0:x} (unknown function)", Index.getIndex())
@@ -318,7 +319,7 @@ private:
return Error::success();
}
Error printFileName(StringRef Label, uint32_t Offset,
- const DebugSubsectionState &State) {
+ const StringsAndChecksumsRef &State) {
if (auto Result = getNameFromChecksumsBuffer(Offset, State)) {
P.printString(Label, *Result);
return Error::success();
@@ -327,13 +328,13 @@ private:
}
Expected<StringRef>
- getNameFromStringTable(uint32_t Offset, const DebugSubsectionState &State) {
+ getNameFromStringTable(uint32_t Offset, const StringsAndChecksumsRef &State) {
return State.strings().getString(Offset);
}
Expected<StringRef>
getNameFromChecksumsBuffer(uint32_t Offset,
- const DebugSubsectionState &State) {
+ const StringsAndChecksumsRef &State) {
auto Array = State.checksums().getArray();
auto ChecksumIter = Array.at(Offset);
if (ChecksumIter == Array.end())
Modified: llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/YAMLOutputStyle.cpp Wed Jun 14 00:31:00 2017
@@ -18,6 +18,7 @@
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
@@ -236,14 +237,16 @@ Error YAMLOutputStyle::dumpDbiStream() {
if (!ExpectedChecksums)
return ExpectedChecksums.takeError();
+ StringsAndChecksumsRef SC(ExpectedST->getStringTable(),
+ *ExpectedChecksums);
+
for (const auto &SS : ModS.subsections()) {
opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind());
if (!opts::checkModuleSubsection(OptionKind))
continue;
auto Converted =
- CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(
- ExpectedST->getStringTable(), *ExpectedChecksums, SS);
+ CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(SC, SS);
if (!Converted)
return Converted.takeError();
DMI.Subsections.push_back(*Converted);
Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Wed Jun 14 00:31:00 2017
@@ -35,6 +35,7 @@
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
@@ -511,10 +512,12 @@ static void yamlToPdb(StringRef Path) {
for (uint32_t I = 0; I < kSpecialStreamCount; ++I)
ExitOnErr(Builder.getMsfBuilder().addStream(0));
+ StringsAndChecksums Strings;
+ Strings.setStrings(std::make_shared<DebugStringTableSubsection>());
+
if (YamlObj.StringTable.hasValue()) {
- auto &Strings = Builder.getStringTableBuilder();
for (auto S : *YamlObj.StringTable)
- Strings.insert(S);
+ Strings.strings()->insert(S);
}
pdb::yaml::PdbInfoStream DefaultInfoStream;
@@ -532,8 +535,6 @@ static void yamlToPdb(StringRef Path) {
for (auto F : Info.Features)
InfoBuilder.addFeature(F);
- auto &Strings = Builder.getStringTableBuilder().getStrings();
-
const auto &Dbi = YamlObj.DbiStream.getValueOr(DefaultDbiStream);
auto &DbiBuilder = Builder.getDbiBuilder();
DbiBuilder.setAge(Dbi.Age);
@@ -557,10 +558,14 @@ static void yamlToPdb(StringRef Path) {
}
}
+ // Each module has its own checksum subsection, so scan for it every time.
+ Strings.setChecksums(nullptr);
+ CodeViewYAML::initializeStringsAndChecksums(MI.Subsections, Strings);
+
auto CodeViewSubsections = ExitOnErr(CodeViewYAML::toCodeViewSubsectionList(
Allocator, MI.Subsections, Strings));
for (auto &SS : CodeViewSubsections) {
- ModiBuilder.addDebugSubsection(std::move(SS));
+ ModiBuilder.addDebugSubsection(SS);
}
}
@@ -580,6 +585,8 @@ static void yamlToPdb(StringRef Path) {
IpiBuilder.addTypeRecord(Type.RecordData, None);
}
+ Builder.getStringTableBuilder().setStrings(*Strings.strings());
+
ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile));
}
Modified: llvm/trunk/tools/obj2yaml/coff2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/coff2yaml.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/coff2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/coff2yaml.cpp Wed Jun 14 00:31:00 2017
@@ -8,8 +8,13 @@
//===----------------------------------------------------------------------===//
#include "obj2yaml.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/Object/COFF.h"
#include "llvm/ObjectYAML/COFFYAML.h"
+#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
+#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/YAMLTraits.h"
@@ -99,8 +104,45 @@ void COFFDumper::dumpHeader() {
YAMLObj.Header.Characteristics = Obj.getCharacteristics();
}
+static void
+initializeFileAndStringTable(const llvm::object::COFFObjectFile &Obj,
+ codeview::StringsAndChecksumsRef &SC) {
+
+ ExitOnError Err("Invalid .debug$S section!");
+ // Iterate all .debug$S sections looking for the checksums and string table.
+ // Exit as soon as both sections are found.
+ for (const auto &S : Obj.sections()) {
+ if (SC.hasStrings() && SC.hasChecksums())
+ break;
+
+ StringRef SectionName;
+ S.getName(SectionName);
+ ArrayRef<uint8_t> sectionData;
+ if (SectionName != ".debug$S")
+ continue;
+
+ const object::coff_section *COFFSection = Obj.getCOFFSection(S);
+
+ Obj.getSectionContents(COFFSection, sectionData);
+
+ BinaryStreamReader Reader(sectionData, support::little);
+ uint32_t Magic;
+
+ Err(Reader.readInteger(Magic));
+ assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
+
+ codeview::DebugSubsectionArray Subsections;
+ Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
+
+ SC.initialize(Subsections);
+ }
+}
+
void COFFDumper::dumpSections(unsigned NumSections) {
std::vector<COFFYAML::Section> &YAMLSections = YAMLObj.Sections;
+ codeview::StringsAndChecksumsRef SC;
+ initializeFileAndStringTable(Obj, SC);
+
for (const auto &ObjSection : Obj.sections()) {
const object::coff_section *COFFSection = Obj.getCOFFSection(ObjSection);
COFFYAML::Section NewYAMLSection;
@@ -108,6 +150,16 @@ void COFFDumper::dumpSections(unsigned N
NewYAMLSection.Header.Characteristics = COFFSection->Characteristics;
NewYAMLSection.Header.VirtualAddress = ObjSection.getAddress();
NewYAMLSection.Header.VirtualSize = COFFSection->VirtualSize;
+ NewYAMLSection.Header.NumberOfLineNumbers =
+ COFFSection->NumberOfLinenumbers;
+ NewYAMLSection.Header.NumberOfRelocations =
+ COFFSection->NumberOfRelocations;
+ NewYAMLSection.Header.PointerToLineNumbers =
+ COFFSection->PointerToLinenumbers;
+ NewYAMLSection.Header.PointerToRawData = COFFSection->PointerToRawData;
+ NewYAMLSection.Header.PointerToRelocations =
+ COFFSection->PointerToRelocations;
+ NewYAMLSection.Header.SizeOfRawData = COFFSection->SizeOfRawData;
NewYAMLSection.Alignment = ObjSection.getAlignment();
assert(NewYAMLSection.Alignment <= 8192);
@@ -116,6 +168,11 @@ void COFFDumper::dumpSections(unsigned N
Obj.getSectionContents(COFFSection, sectionData);
NewYAMLSection.SectionData = yaml::BinaryRef(sectionData);
+ if (NewYAMLSection.Name == ".debug$S")
+ NewYAMLSection.DebugS = CodeViewYAML::fromDebugS(sectionData, SC);
+ else if (NewYAMLSection.Name == ".debug$T")
+ NewYAMLSection.DebugT = CodeViewYAML::fromDebugT(sectionData);
+
std::vector<COFFYAML::Relocation> Relocations;
for (const auto &Reloc : ObjSection.relocations()) {
const object::coff_relocation *reloc = Obj.getCOFFRelocation(Reloc);
Modified: llvm/trunk/tools/yaml2obj/yaml2coff.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2coff.cpp?rev=305366&r1=305365&r2=305366&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2coff.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2coff.cpp Wed Jun 14 00:31:00 2017
@@ -17,6 +17,8 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/Object/COFF.h"
#include "llvm/ObjectYAML/ObjectYAML.h"
#include "llvm/Support/Endian.h"
@@ -27,6 +29,33 @@
using namespace llvm;
+namespace {
+template <typename T> struct WeakishPtr {
+public:
+ WeakishPtr() : Ref(nullptr) {}
+
+ WeakishPtr(std::unique_ptr<T> Value)
+ : Ref(Value.get()), UniquePtr(std::move(Value)) {}
+
+ WeakishPtr(std::unique_ptr<T> &&Value)
+ : Ref(Value.get()), UniquePtr(std::move(Value)) {}
+
+ WeakishPtr<T> &operator=(std::unique_ptr<T> &&Value) {
+ Owned = std::move(Value);
+ Ref = Owned.get();
+ return *this;
+ }
+
+ T *get() { return Ref; }
+ T &operator*() { return *Ref; }
+
+ operator bool() const { return Ref != nullptr; }
+
+ T *Ref;
+ std::unique_ptr<T> Owned;
+};
+} // namespace
+
/// This parses a yaml stream that represents a COFF object file.
/// See docs/yaml2obj for the yaml scheema.
struct COFFParser {
@@ -142,6 +171,8 @@ struct COFFParser {
COFFYAML::Object &Obj;
+ codeview::StringsAndChecksums StringsAndChecksums;
+ BumpPtrAllocator Allocator;
StringMap<unsigned> StringTableMap;
std::string StringTable;
uint32_t SectionTableStart;
@@ -165,6 +196,32 @@ namespace {
enum { DOSStubSize = 128 };
}
+static yaml::BinaryRef
+toDebugS(ArrayRef<CodeViewYAML::YAMLDebugSubsection> Subsections,
+ const codeview::StringsAndChecksums &SC, BumpPtrAllocator &Allocator) {
+ using namespace codeview;
+ ExitOnError Err("Error occurred writing .debug$S section");
+ auto CVSS =
+ Err(CodeViewYAML::toCodeViewSubsectionList(Allocator, Subsections, SC));
+
+ std::vector<DebugSubsectionRecordBuilder> Builders;
+ uint32_t Size = sizeof(uint32_t);
+ for (auto &SS : CVSS) {
+ DebugSubsectionRecordBuilder B(SS, CodeViewContainer::ObjectFile);
+ Size += B.calculateSerializedLength();
+ Builders.push_back(std::move(B));
+ }
+ uint8_t *Buffer = Allocator.Allocate<uint8_t>(Size);
+ MutableArrayRef<uint8_t> Output(Buffer, Size);
+ BinaryStreamWriter Writer(Output, support::little);
+
+ Err(Writer.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC));
+ for (const auto &B : Builders) {
+ Err(B.commit(Writer));
+ }
+ return {Output};
+}
+
// Take a CP and assign addresses and sizes to everything. Returns false if the
// layout is not valid to do.
static bool layoutCOFF(COFFParser &CP) {
@@ -179,8 +236,33 @@ static bool layoutCOFF(COFFParser &CP) {
uint32_t CurrentSectionDataOffset =
CP.SectionTableStart + CP.SectionTableSize;
+ for (COFFYAML::Section &S : CP.Obj.Sections) {
+ // We support specifying exactly one of SectionData or Subsections. So if
+ // there is already some SectionData, then we don't need to do any of this.
+ if (S.Name == ".debug$S" && S.SectionData.binary_size() == 0) {
+ CodeViewYAML::initializeStringsAndChecksums(S.DebugS,
+ CP.StringsAndChecksums);
+ if (CP.StringsAndChecksums.hasChecksums() &&
+ CP.StringsAndChecksums.hasStrings())
+ break;
+ }
+ }
+
// Assign each section data address consecutively.
for (COFFYAML::Section &S : CP.Obj.Sections) {
+ if (S.Name == ".debug$S") {
+ if (S.SectionData.binary_size() == 0) {
+ assert(CP.StringsAndChecksums.hasStrings() &&
+ "Object file does not have debug string table!");
+
+ S.SectionData =
+ toDebugS(S.DebugS, CP.StringsAndChecksums, CP.Allocator);
+ }
+ } else if (S.Name == ".debug$T") {
+ if (S.SectionData.binary_size() == 0)
+ S.SectionData = CodeViewYAML::toDebugT(S.DebugT, CP.Allocator);
+ }
+
if (S.SectionData.binary_size() > 0) {
CurrentSectionDataOffset = alignTo(CurrentSectionDataOffset,
CP.isPE() ? CP.getFileAlignment() : 4);
@@ -543,6 +625,7 @@ int yaml2coff(llvm::COFFYAML::Object &Do
errs() << "yaml2obj: Failed to layout optional header for COFF file!\n";
return 1;
}
+
if (!layoutCOFF(CP)) {
errs() << "yaml2obj: Failed to layout COFF file!\n";
return 1;
More information about the llvm-commits
mailing list