llvm.org GIT mirror llvm / 76c210d
Revert "[codeview] Make obj2yaml/yaml2obj support .debug$S..." This is causing failures on linux bots with an invalid stream read. It doesn't repro in any configuration on Windows, so reverting until I have a chance to investigate on Linux. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305371 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 3 years ago
24 changed file(s) with 326 addition(s) and 585 deletion(s). Raw diff Collapse all Expand all
4848 Error commit(BinaryStreamWriter &Writer) const override;
4949
5050 void addFrameData(const FrameData &Frame);
51 void setFrames(ArrayRef Frames);
5251
5352 private:
5453 std::vector Frames;
4848
4949 class DebugSubsectionRecordBuilder {
5050 public:
51 DebugSubsectionRecordBuilder(std::shared_ptr Subsection,
51 DebugSubsectionRecordBuilder(std::unique_ptr Subsection,
5252 CodeViewContainer Container);
5353 uint32_t calculateSerializedLength();
5454 Error commit(BinaryStreamWriter &Writer) const;
5555
5656 private:
57 std::shared_ptr Subsection;
57 std::unique_ptr Subsection;
5858 CodeViewContainer Container;
5959 };
6060
6363 template <> struct VarStreamArrayExtractor {
6464 Error operator()(BinaryStreamRef Stream, uint32_t &Length,
6565 codeview::DebugSubsectionRecord &Info) {
66 // FIXME: We need to pass the container type through to this function. In
67 // practice this isn't super important since the subsection header describes
68 // its length and we can just skip it. It's more important when writing.
6966 if (auto EC = codeview::DebugSubsectionRecord::initialize(
7067 Stream, Info, codeview::CodeViewContainer::Pdb))
7168 return EC;
1111
1212 #include "llvm/DebugInfo/CodeView/CodeView.h"
1313 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
14 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
1514 #include "llvm/Support/Error.h"
1615 #include
1716
3029 class DebugSymbolRVASubsectionRef;
3130 class DebugSymbolsSubsectionRef;
3231 class DebugUnknownSubsectionRef;
33 class StringsAndChecksumsRef;
32
33 struct DebugSubsectionState {
34 public:
35 // If no subsections are known about initially, we find as much as we can.
36 DebugSubsectionState();
37
38 // If only a string table subsection is given, we find a checksums subsection.
39 explicit DebugSubsectionState(const DebugStringTableSubsectionRef &Strings);
40
41 // If both subsections are given, we don't need to find anything.
42 DebugSubsectionState(const DebugStringTableSubsectionRef &Strings,
43 const DebugChecksumsSubsectionRef &Checksums);
44
45 template void initialize(T &&FragmentRange) {
46 for (const DebugSubsectionRecord &R : FragmentRange) {
47 if (Strings && Checksums)
48 return;
49 if (R.kind() == DebugSubsectionKind::FileChecksums) {
50 initializeChecksums(R);
51 continue;
52 }
53 if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
54 // While in practice we should never encounter a string table even
55 // though the string table is already initialized, in theory it's
56 // possible. PDBs are supposed to have one global string table and
57 // then this subsection should not appear. Whereas object files are
58 // supposed to have this subsection appear exactly once. However,
59 // for testing purposes it's nice to be able to test this subsection
60 // independently of one format or the other, so for some tests we
61 // manually construct a PDB that contains this subsection in addition
62 // to a global string table.
63 initializeStrings(R);
64 continue;
65 }
66 }
67 }
68
69 const DebugStringTableSubsectionRef &strings() const { return *Strings; }
70 const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
71
72 private:
73 void initializeStrings(const DebugSubsectionRecord &SR);
74 void initializeChecksums(const DebugSubsectionRecord &FCR);
75
76 std::unique_ptr OwnedStrings;
77 std::unique_ptr OwnedChecksums;
78
79 const DebugStringTableSubsectionRef *Strings = nullptr;
80 const DebugChecksumsSubsectionRef *Checksums = nullptr;
81 };
3482
3583 class DebugSubsectionVisitor {
3684 public:
4088 return Error::success();
4189 }
4290 virtual Error visitLines(DebugLinesSubsectionRef &Lines,
43 const StringsAndChecksumsRef &State) = 0;
91 const DebugSubsectionState &State) = 0;
4492 virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
45 const StringsAndChecksumsRef &State) = 0;
93 const DebugSubsectionState &State) = 0;
4694 virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
47 const StringsAndChecksumsRef &State) = 0;
95 const DebugSubsectionState &State) = 0;
4896 virtual Error
4997 visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
50 const StringsAndChecksumsRef &State) = 0;
98 const DebugSubsectionState &State) = 0;
5199 virtual Error
52100 visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE,
53 const StringsAndChecksumsRef &State) = 0;
101 const DebugSubsectionState &State) = 0;
54102
55103 virtual Error visitStringTable(DebugStringTableSubsectionRef &ST,
56 const StringsAndChecksumsRef &State) = 0;
104 const DebugSubsectionState &State) = 0;
57105
58106 virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE,
59 const StringsAndChecksumsRef &State) = 0;
107 const DebugSubsectionState &State) = 0;
60108
61109 virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
62 const StringsAndChecksumsRef &State) = 0;
110 const DebugSubsectionState &State) = 0;
63111 virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
64 const StringsAndChecksumsRef &State) = 0;
112 const DebugSubsectionState &State) = 0;
65113 };
66114
67115 Error visitDebugSubsection(const DebugSubsectionRecord &R,
68116 DebugSubsectionVisitor &V,
69 const StringsAndChecksumsRef &State);
117 const DebugSubsectionState &State);
70118
71119 namespace detail {
72120 template
73121 Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
74 StringsAndChecksumsRef &State) {
122 DebugSubsectionState &State) {
75123 State.initialize(std::forward(FragmentRange));
76124
77125 for (const DebugSubsectionRecord &L : FragmentRange) {
84132
85133 template
86134 Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
87 StringsAndChecksumsRef State;
135 DebugSubsectionState State;
88136 return detail::visitDebugSubsections(std::forward(FragmentRange), V,
89137 State);
90138 }
92140 template
93141 Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
94142 const DebugStringTableSubsectionRef &Strings) {
95 StringsAndChecksumsRef State(Strings);
143 DebugSubsectionState State(Strings);
96144 return detail::visitDebugSubsections(std::forward(FragmentRange), V,
97145 State);
98146 }
101149 Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
102150 const DebugStringTableSubsectionRef &Strings,
103151 const DebugChecksumsSubsectionRef &Checksums) {
104 StringsAndChecksumsRef State(Strings, Checksums);
152 DebugSubsectionState State(Strings, Checksums);
105153 return detail::visitDebugSubsections(std::forward(FragmentRange), V,
106154 State);
107155 }
+0
-104
include/llvm/DebugInfo/CodeView/StringsAndChecksums.h less more
None //===- StringsAndChecksums.h ------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H
10 #define LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H
11
12 #include "llvm/DebugInfo/CodeView/CodeView.h"
13 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
14
15 #include
16
17 namespace llvm {
18 namespace codeview {
19
20 class DebugSubsectionRecord;
21 class DebugChecksumsSubsectionRef;
22 class DebugStringTableSubsectionRef;
23 class DebugChecksumsSubsection;
24 class DebugStringTableSubsection;
25
26 class StringsAndChecksumsRef {
27 public:
28 // If no subsections are known about initially, we find as much as we can.
29 StringsAndChecksumsRef();
30
31 // If only a string table subsection is given, we find a checksums subsection.
32 explicit StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings);
33
34 // If both subsections are given, we don't need to find anything.
35 StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings,
36 const DebugChecksumsSubsectionRef &Checksums);
37
38 template void initialize(T &&FragmentRange) {
39 for (const DebugSubsectionRecord &R : FragmentRange) {
40 if (Strings && Checksums)
41 return;
42 if (R.kind() == DebugSubsectionKind::FileChecksums) {
43 initializeChecksums(R);
44 continue;
45 }
46 if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
47 // While in practice we should never encounter a string table even
48 // though the string table is already initialized, in theory it's
49 // possible. PDBs are supposed to have one global string table and
50 // then this subsection should not appear. Whereas object files are
51 // supposed to have this subsection appear exactly once. However,
52 // for testing purposes it's nice to be able to test this subsection
53 // independently of one format or the other, so for some tests we
54 // manually construct a PDB that contains this subsection in addition
55 // to a global string table.
56 initializeStrings(R);
57 continue;
58 }
59 }
60 }
61
62 const DebugStringTableSubsectionRef &strings() const { return *Strings; }
63 const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
64
65 bool hasStrings() const { return Strings != nullptr; }
66 bool hasChecksums() const { return Checksums != nullptr; }
67
68 private:
69 void initializeStrings(const DebugSubsectionRecord &SR);
70 void initializeChecksums(const DebugSubsectionRecord &FCR);
71
72 std::unique_ptr OwnedStrings;
73 std::unique_ptr OwnedChecksums;
74
75 const DebugStringTableSubsectionRef *Strings = nullptr;
76 const DebugChecksumsSubsectionRef *Checksums = nullptr;
77 };
78
79 class StringsAndChecksums {
80 public:
81 using StringsPtr = std::shared_ptr;
82 using ChecksumsPtr = std::shared_ptr;
83 // If no subsections are known about initially, we find as much as we can.
84 StringsAndChecksums() {}
85
86 void setStrings(const StringsPtr &SP) { Strings = SP; }
87 void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; }
88
89 const StringsPtr &strings() const { return Strings; }
90 const ChecksumsPtr &checksums() const { return Checksums; }
91
92 bool hasStrings() const { return Strings != nullptr; }
93 bool hasChecksums() const { return Checksums != nullptr; }
94
95 private:
96 StringsPtr Strings;
97 ChecksumsPtr Checksums;
98 };
99
100 } // namespace codeview
101 } // namespace llvm
102
103 #endif
4949 void addSymbol(codeview::CVSymbol Symbol);
5050
5151 void
52 addDebugSubsection(std::shared_ptr Subsection);
52 addDebugSubsection(std::unique_ptr Subsection);
5353
5454 uint16_t getStreamIndex() const;
5555 StringRef getModuleName() const { return ModuleName; }
4040 uint32_t calculateSerializedSize() const;
4141 Error commit(BinaryStreamWriter &Writer) const;
4242
43 void setStrings(const codeview::DebugStringTableSubsection &Strings);
43 codeview::DebugStringTableSubsection &getStrings() { return Strings; }
44 const codeview::DebugStringTableSubsection &getStrings() const {
45 return Strings;
46 }
4447
4548 private:
4649 uint32_t calculateHashTableSize() const;
1515
1616 #include "llvm/ADT/Optional.h"
1717 #include "llvm/BinaryFormat/COFF.h"
18 #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
19 #include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
2018 #include "llvm/ObjectYAML/YAML.h"
2119
2220 namespace llvm {
5755 COFF::section Header;
5856 unsigned Alignment = 0;
5957 yaml::BinaryRef SectionData;
60 std::vector DebugS;
61 std::vector DebugT;
6258 std::vector Relocations;
6359 StringRef Name;
6460 Section();
2727 class DebugChecksumsSubsectionRef;
2828 class DebugStringTableSubsection;
2929 class DebugChecksumsSubsection;
30 class StringsAndChecksums;
31 class StringsAndChecksumsRef;
3230 }
3331 namespace CodeViewYAML {
3432
104102
105103 struct YAMLDebugSubsection {
106104 static Expected
107 fromCodeViewSubection(const codeview::StringsAndChecksumsRef &SC,
105 fromCodeViewSubection(const codeview::DebugStringTableSubsectionRef &Strings,
106 const codeview::DebugChecksumsSubsectionRef &Checksums,
108107 const codeview::DebugSubsectionRecord &SS);
109108
110109 std::shared_ptr Subsection;
111110 };
112111
113 struct DebugSubsectionState {};
114
115 Expectedshared_ptr>>
112 Expectedunique_ptr>>
116113 toCodeViewSubsectionList(BumpPtrAllocator &Allocator,
117114 ArrayRef Subsections,
118 const codeview::StringsAndChecksums &SC);
115 codeview::DebugStringTableSubsection &Strings);
116 Expected>>
117 toCodeViewSubsectionList(
118 BumpPtrAllocator &Allocator, ArrayRef Subsections,
119 std::unique_ptr &TakeStrings,
120 codeview::DebugStringTableSubsection *StringsRef);
119121
120 std::vector
121 fromDebugS(ArrayRef Data, const codeview::StringsAndChecksumsRef &SC);
122
123 void initializeStringsAndChecksums(ArrayRef Sections,
124 codeview::StringsAndChecksums &SC);
122 std::unique_ptr
123 findStringTable(ArrayRef Sections);
125124
126125 } // namespace CodeViewYAML
127126 } // namespace llvm
4040 codeview::CVType toCodeViewRecord(codeview::TypeTableBuilder &TS) const;
4141 static Expected fromCodeViewRecord(codeview::CVType Type);
4242 };
43
44 std::vector fromDebugT(ArrayRef DebugT);
45 ArrayRef toDebugT(ArrayRef, BumpPtrAllocator &Alloc);
4643 } // namespace CodeViewYAML
4744 } // namespace llvm
4845
1919 LazyRandomTypeCollection.cpp
2020 Line.cpp
2121 RecordSerialization.cpp
22 StringsAndChecksums.cpp
2322 SymbolRecordMapping.cpp
2423 SymbolDumper.cpp
2524 SymbolSerializer.cpp
3231 TypeSerializer.cpp
3332 TypeStreamMerger.cpp
3433 TypeTableCollection.cpp
35
34
3635 ADDITIONAL_HEADER_DIRS
3736 ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/CodeView
3837 )
5757 uint32_t Begin = Writer.getOffset();
5858 uint32_t End = Begin + StringSize;
5959
60 // Write a null string at the beginning.
61 if (auto EC = Writer.writeCString(StringRef()))
62 return EC;
63
6460 for (auto &Pair : Strings) {
6561 StringRef S = Pair.getKey();
6662 uint32_t Offset = Begin + Pair.getValue();
7167 }
7268
7369 Writer.setOffset(End);
74 assert((End - Begin) == StringSize);
7570 return Error::success();
7671 }
7772
4949 BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
5050
5151 DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
52 std::shared_ptr Subsection, CodeViewContainer Container)
52 std::unique_ptr Subsection, CodeViewContainer Container)
5353 : Subsection(std::move(Subsection)), Container(Container) {}
5454
5555 uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
2525 using namespace llvm;
2626 using namespace llvm::codeview;
2727
28 Error llvm::codeview::visitDebugSubsection(
29 const DebugSubsectionRecord &R, DebugSubsectionVisitor &V,
30 const StringsAndChecksumsRef &State) {
28 DebugSubsectionState::DebugSubsectionState() {}
29
30 DebugSubsectionState::DebugSubsectionState(
31 const DebugStringTableSubsectionRef &Strings)
32 : Strings(&Strings) {}
33
34 DebugSubsectionState::DebugSubsectionState(
35 const DebugStringTableSubsectionRef &Strings,
36 const DebugChecksumsSubsectionRef &Checksums)
37 : Strings(&Strings), Checksums(&Checksums) {}
38
39 void DebugSubsectionState::initializeStrings(const DebugSubsectionRecord &SR) {
40 assert(SR.kind() == DebugSubsectionKind::StringTable);
41 assert(!Strings && "Found a string table even though we already have one!");
42
43 OwnedStrings = llvm::make_unique();
44 consumeError(OwnedStrings->initialize(SR.getRecordData()));
45 Strings = OwnedStrings.get();
46 }
47
48 void DebugSubsectionState::initializeChecksums(
49 const DebugSubsectionRecord &FCR) {
50 assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
51 if (Checksums)
52 return;
53
54 OwnedChecksums = llvm::make_unique();
55 consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
56 Checksums = OwnedChecksums.get();
57 }
58
59 Error llvm::codeview::visitDebugSubsection(const DebugSubsectionRecord &R,
60 DebugSubsectionVisitor &V,
61 const DebugSubsectionState &State) {
3162 BinaryStreamReader Reader(R.getRecordData());
3263 switch (R.kind()) {
3364 case DebugSubsectionKind::Lines: {
+0
-48
lib/DebugInfo/CodeView/StringsAndChecksums.cpp less more
None //===- StringsAndChecksums.cpp ----------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
10 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
11 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
12 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
13
14 using namespace llvm;
15 using namespace llvm::codeview;
16
17 StringsAndChecksumsRef::StringsAndChecksumsRef() {}
18
19 StringsAndChecksumsRef::StringsAndChecksumsRef(
20 const DebugStringTableSubsectionRef &Strings)
21 : Strings(&Strings) {}
22
23 StringsAndChecksumsRef::StringsAndChecksumsRef(
24 const DebugStringTableSubsectionRef &Strings,
25 const DebugChecksumsSubsectionRef &Checksums)
26 : Strings(&Strings), Checksums(&Checksums) {}
27
28 void StringsAndChecksumsRef::initializeStrings(
29 const DebugSubsectionRecord &SR) {
30 assert(SR.kind() == DebugSubsectionKind::StringTable);
31 assert(!Strings && "Found a string table even though we already have one!");
32
33 OwnedStrings = llvm::make_unique();
34 consumeError(OwnedStrings->initialize(SR.getRecordData()));
35 Strings = OwnedStrings.get();
36 }
37
38 void StringsAndChecksumsRef::initializeChecksums(
39 const DebugSubsectionRecord &FCR) {
40 assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
41 if (Checksums)
42 return;
43
44 OwnedChecksums = llvm::make_unique();
45 consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
46 Checksums = OwnedChecksums.get();
47 }
176176 }
177177
178178 void DbiModuleDescriptorBuilder::addDebugSubsection(
179 std::shared_ptr Subsection) {
179 std::unique_ptr Subsection) {
180180 assert(Subsection);
181181 C13Builders.push_back(llvm::make_unique(
182182 std::move(Subsection), CodeViewContainer::Pdb));
4949 Size += calculateHashTableSize();
5050 Size += sizeof(uint32_t); // The /names stream ends with the string count.
5151 return Size;
52 }
53
54 void PDBStringTableBuilder::setStrings(
55 const codeview::DebugStringTableSubsection &Strings) {
56 this->Strings = Strings;
5752 }
5853
5954 Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const {
487487 IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U);
488488 IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U);
489489 IO.mapOptional("Alignment", Sec.Alignment, 0U);
490
491 // If this is a .debug$S or .debug$T section parse the semantic representation
492 // of the symbols/types. If it is any other kind of section, just deal in raw
493 // bytes.
494 IO.mapOptional("SectionData", Sec.SectionData);
495 if (Sec.Name == ".debug$S")
496 IO.mapOptional("Subsections", Sec.DebugS);
497 else if (Sec.Name == ".debug$T")
498 IO.mapOptional("Types", Sec.DebugT);
499
490 IO.mapRequired("SectionData", Sec.SectionData);
500491 IO.mapOptional("Relocations", Sec.Relocations);
501492 }
502493
2727 #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
2828 #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
2929 #include "llvm/DebugInfo/CodeView/EnumTables.h"
30 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
3130 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
3231 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
3332 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
7574 virtual ~YAMLSubsectionBase() {}
7675
7776 virtual void map(IO &IO) = 0;
78 virtual std::shared_ptr
77 virtual std::unique_ptr
7978 toCodeViewSubsection(BumpPtrAllocator &Allocator,
80 const codeview::StringsAndChecksums &SC) const = 0;
79 DebugStringTableSubsection *UseStrings,
80 DebugChecksumsSubsection *UseChecksums) const = 0;
8181 };
8282 }
8383 }
8989 : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}
9090
9191 void map(IO &IO) override;
92 std::shared_ptr
92 std::unique_ptr
9393 toCodeViewSubsection(BumpPtrAllocator &Allocator,
94 const codeview::StringsAndChecksums &SC) const override;
94 DebugStringTableSubsection *Strings,
95 DebugChecksumsSubsection *Checksums) const override;
9596 static Expected>
9697 fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
9798 const DebugChecksumsSubsectionRef &FC);
103104 YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}
104105
105106 void map(IO &IO) override;
106 std::shared_ptr
107 std::unique_ptr
107108 toCodeViewSubsection(BumpPtrAllocator &Allocator,
108 const codeview::StringsAndChecksums &SC) const override;
109 DebugStringTableSubsection *Strings,
110 DebugChecksumsSubsection *Checksums) const override;
109111 static Expected>
110112 fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
111113 const DebugChecksumsSubsectionRef &Checksums,
119121 : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}
120122
121123 void map(IO &IO) override;
122 std::shared_ptr
124 std::unique_ptr
123125 toCodeViewSubsection(BumpPtrAllocator &Allocator,
124 const codeview::StringsAndChecksums &SC) const override;
126 DebugStringTableSubsection *Strings,
127 DebugChecksumsSubsection *Checksums) const override;
125128 static Expected>
126129 fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
127130 const DebugChecksumsSubsectionRef &Checksums,
135138 : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {}
136139
137140 void map(IO &IO) override;
138 std::shared_ptr
141 std::unique_ptr
139142 toCodeViewSubsection(BumpPtrAllocator &Allocator,
140 const codeview::StringsAndChecksums &SC) const override;
143 DebugStringTableSubsection *Strings,
144 DebugChecksumsSubsection *Checksums) const override;
141145 static Expected>
142146 fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports);
143147
149153 : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {}
150154
151155 void map(IO &IO) override;
152 std::shared_ptr
156 std::unique_ptr
153157 toCodeViewSubsection(BumpPtrAllocator &Allocator,
154 const codeview::StringsAndChecksums &SC) const override;
158 DebugStringTableSubsection *Strings,
159 DebugChecksumsSubsection *Checksums) const override;
155160 static Expected>
156161 fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
157162 const DebugCrossModuleImportsSubsectionRef &Imports);
163168 YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {}
164169
165170 void map(IO &IO) override;
166 std::shared_ptr
171 std::unique_ptr
167172 toCodeViewSubsection(BumpPtrAllocator &Allocator,
168 const codeview::StringsAndChecksums &SC) const override;
173 DebugStringTableSubsection *Strings,
174 DebugChecksumsSubsection *Checksums) const override;
169175 static Expected>
170176 fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols);
171177
177183 : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {}
178184
179185 void map(IO &IO) override;
180 std::shared_ptr
186 std::unique_ptr
181187 toCodeViewSubsection(BumpPtrAllocator &Allocator,
182 const codeview::StringsAndChecksums &SC) const override;
188 DebugStringTableSubsection *Strings,
189 DebugChecksumsSubsection *Checksums) const override;
183190 static Expected>
184191 fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings);
185192
191198 : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {}
192199
193200 void map(IO &IO) override;
194 std::shared_ptr
201 std::unique_ptr
195202 toCodeViewSubsection(BumpPtrAllocator &Allocator,
196 const codeview::StringsAndChecksums &SC) const override;
203 DebugStringTableSubsection *Strings,
204 DebugChecksumsSubsection *Checksums) const override;
197205 static Expected>
198206 fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
199207 const DebugFrameDataSubsectionRef &Frames);
206214 : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
207215
208216 void map(IO &IO) override;
209 std::shared_ptr
217 std::unique_ptr
210218 toCodeViewSubsection(BumpPtrAllocator &Allocator,
211 const codeview::StringsAndChecksums &SC) const override;
219 DebugStringTableSubsection *Strings,
220 DebugChecksumsSubsection *Checksums) const override;
212221 static Expected>
213222 fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
214223
390399 return nullptr;
391400 }
392401
393 std::shared_ptr YAMLChecksumsSubsection::toCodeViewSubsection(
394 BumpPtrAllocator &Allocator,
395 const codeview::StringsAndChecksums &SC) const {
396 assert(SC.hasStrings());
397 auto Result = std::make_shared(*SC.strings());
402 std::unique_ptr YAMLChecksumsSubsection::toCodeViewSubsection(
403 BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings,
404 DebugChecksumsSubsection *UseChecksums) const {
405 assert(UseStrings && !UseChecksums);
406 auto Result = llvm::make_unique(*UseStrings);
398407 for (const auto &CS : Checksums) {
399408 Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
400409 }
401 return Result;
402 }
403
404 std::shared_ptr YAMLLinesSubsection::toCodeViewSubsection(
405 BumpPtrAllocator &Allocator,
406 const codeview::StringsAndChecksums &SC) const {
407 assert(SC.hasStrings() && SC.hasChecksums());
410 return std::move(Result);
411 }
412
413 std::unique_ptr YAMLLinesSubsection::toCodeViewSubsection(
414 BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings,
415 DebugChecksumsSubsection *UseChecksums) const {
416 assert(UseStrings && UseChecksums);
408417 auto Result =
409 std::make_shared(*SC.checksums(), *SC.strings());
418 llvm::make_unique(*UseChecksums, *UseStrings);
410419 Result->setCodeSize(Lines.CodeSize);
411420 Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
412421 Result->setFlags(Lines.Flags);
428437 }
429438 }
430439 }
431 return Result;
432 }
433
434 std::shared_ptr
440 return llvm::cast(std::move(Result));
441 }
442
443 std::unique_ptr
435444 YAMLInlineeLinesSubsection::toCodeViewSubsection(
436 BumpPtrAllocator &Allocator,
437 const codeview::StringsAndChecksums &SC) const {
438 assert(SC.hasChecksums());
439 auto Result = std::make_shared(
440 *SC.checksums(), InlineeLines.HasExtraFiles);
445 BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings,
446 DebugChecksumsSubsection *UseChecksums) const {
447 assert(UseChecksums);
448 auto Result = llvm::make_unique(
449 *UseChecksums, InlineeLines.HasExtraFiles);
441450
442451 for (const auto &Site : InlineeLines.Sites) {
443452 Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
449458 Result->addExtraFile(EF);
450459 }
451460 }
452 return Result;
453 }
454
455 std::shared_ptr
461 return llvm::cast(std::move(Result));
462 }
463
464 std::unique_ptr
456465 YAMLCrossModuleExportsSubsection::toCodeViewSubsection(
457 BumpPtrAllocator &Allocator,
458 const codeview::StringsAndChecksums &SC) const {
459 auto Result = std::make_shared();
466 BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
467 DebugChecksumsSubsection *Checksums) const {
468 auto Result = llvm::make_unique();
460469 for (const auto &M : Exports)
461470 Result->addMapping(M.Local, M.Global);
462 return Result;
463 }
464
465 std::shared_ptr
471 return llvm::cast(std::move(Result));
472 }
473
474 std::unique_ptr
466475 YAMLCrossModuleImportsSubsection::toCodeViewSubsection(
467 BumpPtrAllocator &Allocator,
468 const codeview::StringsAndChecksums &SC) const {
469 assert(SC.hasStrings());
470
471 auto Result =
472 std::make_shared(*SC.strings());
476 BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
477 DebugChecksumsSubsection *Checksums) const {
478 auto Result = llvm::make_unique(*Strings);
473479 for (const auto &M : Imports) {
474480 for (const auto Id : M.ImportIds)
475481 Result->addImport(M.ModuleName, Id);
476482 }
477 return Result;
478 }
479
480 std::shared_ptr YAMLSymbolsSubsection::toCodeViewSubsection(
481 BumpPtrAllocator &Allocator,
482 const codeview::StringsAndChecksums &SC) const {
483 auto Result = std::make_shared();
483 return llvm::cast(std::move(Result));
484 }
485
486 std::unique_ptr YAMLSymbolsSubsection::toCodeViewSubsection(
487 BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
488 DebugChecksumsSubsection *Checksums) const {
489 auto Result = llvm::make_unique();
484490 for (const auto &Sym : Symbols)
485491 Result->addSymbol(
486492 Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile));
487 return Result;
488 }
489
490 std::shared_ptr
493 return std::move(Result);
494 }
495
496 std::unique_ptr
491497 YAMLStringTableSubsection::toCodeViewSubsection(
492 BumpPtrAllocator &Allocator,
493 const codeview::StringsAndChecksums &SC) const {
494 auto Result = std::make_shared();
498 BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
499 DebugChecksumsSubsection *Checksums) const {
500 auto Result = llvm::make_unique();
495501 for (const auto &Str : this->Strings)
496502 Result->insert(Str);
497 return Result;
498 }
499
500 std::shared_ptr YAMLFrameDataSubsection::toCodeViewSubsection(
501 BumpPtrAllocator &Allocator,
502 const codeview::StringsAndChecksums &SC) const {
503 assert(SC.hasStrings());
504
505 auto Result = std::make_shared();
503 return std::move(Result);
504 }
505
506 std::unique_ptr YAMLFrameDataSubsection::toCodeViewSubsection(
507 BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
508 DebugChecksumsSubsection *Checksums) const {
509 assert(Strings);
510 auto Result = llvm::make_unique();
506511 for (const auto &YF : Frames) {
507512 codeview::FrameData F;
508513 F.CodeSize = YF.CodeSize;
513518 F.PrologSize = YF.PrologSize;
514519 F.RvaStart = YF.RvaStart;
515520 F.SavedRegsSize = YF.SavedRegsSize;
516 F.FrameFunc = SC.strings()->insert(YF.FrameFunc);
521 F.FrameFunc = Strings->insert(YF.FrameFunc);
517522 Result->addFrameData(F);
518523 }
519 return Result;
520 }
521
522 std::shared_ptr
524 return std::move(Result);
525 }
526
527 std::unique_ptr
523528 YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
524 BumpPtrAllocator &Allocator,
525 const codeview::StringsAndChecksums &SC) const {
526 auto Result = std::make_shared();
529 BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
530 DebugChecksumsSubsection *Checksums) const {
531 auto Result = llvm::make_unique();
527532 for (const auto &RVA : RVAs)
528533 Result->addRVA(RVA);
529 return Result;
534 return std::move(Result);
530535 }
531536
532537 static Expected
735740 return Result;
736741 }
737742
738 Expectedshared_ptr>>
743 Expectedunique_ptr>>
739744 llvm::CodeViewYAML::toCodeViewSubsectionList(
740745 BumpPtrAllocator &Allocator, ArrayRef Subsections,
741 const codeview::StringsAndChecksums &SC) {
742 std::vector> Result;
746 DebugStringTableSubsection &Strings) {
747 std::vector> Result;
743748 if (Subsections.empty())
744749 return std::move(Result);
745750
751 auto Checksums = findChecksums(Subsections);
752 std::unique_ptr ChecksumsBase;
753 if (Checksums)
754 ChecksumsBase =
755 Checksums->toCodeViewSubsection(Allocator, &Strings, nullptr);
756 DebugChecksumsSubsection *CS =
757 static_cast(ChecksumsBase.get());
746758 for (const auto &SS : Subsections) {
747 std::shared_ptr CVS;
748 CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC);
759 // We've already converted the checksums subsection, don't do it
760 // twice.
761 std::unique_ptr CVS;
762 if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums)
763 CVS = std::move(ChecksumsBase);
764 else
765 CVS = SS.Subsection->toCodeViewSubsection(Allocator, &Strings, CS);
766 assert(CVS != nullptr);
767 Result.push_back(std::move(CVS));
768 }
769 return std::move(Result);
770 }
771
772 Expected>>
773 llvm::CodeViewYAML::toCodeViewSubsectionList(
774 BumpPtrAllocator &Allocator, ArrayRef Subsections,
775 std::unique_ptr &TakeStrings,
776 DebugStringTableSubsection *StringsRef) {
777 std::vector> Result;
778 if (Subsections.empty())
779 return std::move(Result);
780
781 auto Checksums = findChecksums(Subsections);
782
783 std::unique_ptr ChecksumsBase;
784 if (Checksums)
785 ChecksumsBase =
786 Checksums->toCodeViewSubsection(Allocator, StringsRef, nullptr);
787 DebugChecksumsSubsection *CS =
788 static_cast(ChecksumsBase.get());
789 for (const auto &SS : Subsections) {
790 // We've already converted the checksums and string table subsection, don't
791 // do it twice.
792 std::unique_ptr CVS;
793 if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums)
794 CVS = std::move(ChecksumsBase);
795 else if (SS.Subsection->Kind == DebugSubsectionKind::StringTable) {
796 assert(TakeStrings && "No string table!");
797 CVS = std::move(TakeStrings);
798 } else
799 CVS = SS.Subsection->toCodeViewSubsection(Allocator, StringsRef, CS);
749800 assert(CVS != nullptr);
750801 Result.push_back(std::move(CVS));
751802 }
758809
759810 Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
760811 Error visitLines(DebugLinesSubsectionRef &Lines,
761 const StringsAndChecksumsRef &State) override;
812 const DebugSubsectionState &State) override;
762813 Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
763 const StringsAndChecksumsRef &State) override;
814 const DebugSubsectionState &State) override;
764815 Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
765 const StringsAndChecksumsRef &State) override;
816 const DebugSubsectionState &State) override;
766817 Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums,
767 const StringsAndChecksumsRef &State) override;
818 const DebugSubsectionState &State) override;
768819 Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees,
769 const StringsAndChecksumsRef &State) override;
820 const DebugSubsectionState &State) override;
770821 Error visitStringTable(DebugStringTableSubsectionRef &ST,
771 const StringsAndChecksumsRef &State) override;
822 const DebugSubsectionState &State) override;
772823 Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
773 const StringsAndChecksumsRef &State) override;
824 const DebugSubsectionState &State) override;
774825 Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
775 const StringsAndChecksumsRef &State) override;
826 const DebugSubsectionState &State) override;
776827 Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
777 const StringsAndChecksumsRef &State) override;
828 const DebugSubsectionState &State) override;
778829
779830 YAMLDebugSubsection Subsection;
780831 };
785836 }
786837
787838 Error SubsectionConversionVisitor::visitLines(
788 DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) {
839 DebugLinesSubsectionRef &Lines, const DebugSubsectionState &State) {
789840 auto Result = YAMLLinesSubsection::fromCodeViewSubsection(
790841 State.strings(), State.checksums(), Lines);
791842 if (!Result)
795846 }
796847
797848 Error SubsectionConversionVisitor::visitFileChecksums(
798 DebugChecksumsSubsectionRef &Checksums,
799 const StringsAndChecksumsRef &State) {
849 DebugChecksumsSubsectionRef &Checksums, const DebugSubsectionState &State) {
800850 auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(),
801851 Checksums);
802852 if (!Result)
807857
808858 Error SubsectionConversionVisitor::visitInlineeLines(
809859 DebugInlineeLinesSubsectionRef &Inlinees,
810 const StringsAndChecksumsRef &State) {
860 const DebugSubsectionState &State) {
811861 auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
812862 State.strings(), State.checksums(), Inlinees);
813863 if (!Result)
818868
819869 Error SubsectionConversionVisitor::visitCrossModuleExports(
820870 DebugCrossModuleExportsSubsectionRef &Exports,
821 const StringsAndChecksumsRef &State) {
871 const DebugSubsectionState &State) {
822872 auto Result =
823873 YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports);
824874 if (!Result)
829879
830880 Error SubsectionConversionVisitor::visitCrossModuleImports(
831881 DebugCrossModuleImportsSubsectionRef &Imports,
832 const StringsAndChecksumsRef &State) {
882 const DebugSubsectionState &State) {
833883 auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
834884 State.strings(), Imports);
835885 if (!Result)
839889 }
840890
841891 Error SubsectionConversionVisitor::visitStringTable(
842 DebugStringTableSubsectionRef &Strings,
843 const StringsAndChecksumsRef &State) {
892 DebugStringTableSubsectionRef &Strings, const DebugSubsectionState &State) {
844893 auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings);
845894 if (!Result)
846895 return Result.takeError();
849898 }
850899
851900 Error SubsectionConversionVisitor::visitSymbols(
852 DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) {
901 DebugSymbolsSubsectionRef &Symbols, const DebugSubsectionState &State) {
853902 auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols);
854903 if (!Result)
855904 return Result.takeError();
858907 }
859908
860909 Error SubsectionConversionVisitor::visitFrameData(
861 DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) {
910 DebugFrameDataSubsectionRef &Frames, const DebugSubsectionState &State) {
862911 auto Result =
863912 YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames);
864913 if (!Result)
868917 }
869918
870919 Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
871 DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) {
920 DebugSymbolRVASubsectionRef &RVAs, const DebugSubsectionState &State) {
872921 auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
873922 if (!Result)
874923 return Result.takeError();
877926 }
878927 }
879928
880 Expected
881 YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC,
882 const DebugSubsectionRecord &SS) {
929 Expected YAMLDebugSubsection::fromCodeViewSubection(
930 const DebugStringTableSubsectionRef &Strings,
931 const DebugChecksumsSubsectionRef &Checksums,
932 const DebugSubsectionRecord &SS) {
933 DebugSubsectionState State(Strings, Checksums);
883934 SubsectionConversionVisitor V;
884 if (auto EC = visitDebugSubsection(SS, V, SC))
935 if (auto EC = visitDebugSubsection(SS, V, State))
885936 return std::move(EC);
886937
887938 return V.Subsection;
888939 }
889940
890 std::vector
891 llvm::CodeViewYAML::fromDebugS(ArrayRef Data,
892 const StringsAndChecksumsRef &SC) {
893 BinaryStreamReader Reader(Data, support::little);
894 uint32_t Magic;
895
896 ExitOnError Err("Invalid .debug$S section!");
897 Err(Reader.readInteger(Magic));
898 assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
899
900 DebugSubsectionArray Subsections;
901 Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
902
903 std::vector Result;
904
905 for (const auto &SS : Subsections) {
906 auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS));
907 Result.push_back(YamlSS);
908 }
909 return Result;
910 }
911
912 void llvm::CodeViewYAML::initializeStringsAndChecksums(
913 ArrayRef Sections, codeview::StringsAndChecksums &SC) {
914 // String Table and Checksums subsections don't use the allocator.
915 BumpPtrAllocator Allocator;
916
917 // It's possible for checksums and strings to even appear in different debug$S
918 // sections, so we have to make this a stateful function that can build up
919 // the strings and checksums field over multiple iterations.
920
921 // File Checksums require the string table, but may become before it, so we
922 // have to scan for strings first, then scan for checksums again from the
923 // beginning.
924 if (!SC.hasStrings()) {
925 for (const auto &SS : Sections) {
926 if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
927 continue;
928
929 auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
930 SC.setStrings(
931 std::static_pointer_cast(Result));
932 break;
933 }
934 }
935
936 if (SC.hasStrings() && !SC.hasChecksums()) {
937 for (const auto &SS : Sections) {
938 if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums)
939 continue;
940
941 auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
942 SC.setChecksums(
943 std::static_pointer_cast(Result));
944 break;
945 }
946 }
947 }
941 std::unique_ptr
942 llvm::CodeViewYAML::findStringTable(ArrayRef Sections) {
943 for (const auto &SS : Sections) {
944 if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
945 continue;
946
947 // String Table doesn't use the allocator.
948 BumpPtrAllocator Allocator;
949 auto Result =
950 SS.Subsection->toCodeViewSubsection(Allocator, nullptr, nullptr);
951 return llvm::cast(std::move(Result));
952 }
953 return nullptr;
954 }
713713 default: { llvm_unreachable("Unknown member kind!"); }
714714 }
715715 }
716
717 std::vector
718 llvm::CodeViewYAML::fromDebugT(ArrayRef DebugT) {
719 ExitOnError Err("Invalid .debug$T section!");
720 BinaryStreamReader Reader(DebugT, support::little);
721 CVTypeArray Types;
722 uint32_t Magic;
723
724 Err(Reader.readInteger(Magic));
725 assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$T section!");
726
727 std::vector Result;
728 Err(Reader.readArray(Types, Reader.bytesRemaining()));
729 for (const auto &T : Types) {
730 auto CVT = Err(LeafRecord::fromCodeViewRecord(T));
731 Result.push_back(CVT);
732 }
733 return Result;
734 }
735
736 ArrayRef llvm::CodeViewYAML::toDebugT(ArrayRef Leafs,
737 BumpPtrAllocator &Alloc) {
738 TypeTableBuilder TTB(Alloc, false);
739 uint32_t Size = sizeof(uint32_t);
740 for (const auto &Leaf : Leafs) {
741 CVType T = Leaf.toCodeViewRecord(TTB);
742 Size += T.length();
743 assert(T.length() % 4 == 0 && "Improper type record alignment!");
744 }
745 uint8_t *ResultBuffer = Alloc.Allocate(Size);
746 MutableArrayRef Output(ResultBuffer, Size);
747 BinaryStreamWriter Writer(Output, support::little);
748 ExitOnError Err("Error writing type record to .debug$T section");
749 Err(Writer.writeInteger(COFF::DEBUG_SECTION_MAGIC));
750 for (const auto &R : TTB.records()) {
751 Err(Writer.writeBytes(R));
752 }
753 assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!");
754 return Output;
755 }
2727 #include "llvm/DebugInfo/CodeView/EnumTables.h"
2828 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
2929 #include "llvm/DebugInfo/CodeView/Line.h"
30 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
3130 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
3231 #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
3332 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
105104 }
106105
107106 Error visitLines(DebugLinesSubsectionRef &Lines,
108 const StringsAndChecksumsRef &State) override {
107 const DebugSubsectionState &State) override {
109108 if (!opts::checkModuleSubsection(opts::ModuleSubsection::Lines))
110109 return Error::success();
111110
146145 }
147146
148147 Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
149 const StringsAndChecksumsRef &State) override {
148 const DebugSubsectionState &State) override {
150149 if (!opts::checkModuleSubsection(opts::ModuleSubsection::FileChecksums))
151150 return Error::success();
152151
164163 }
165164
166165 Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
167 const StringsAndChecksumsRef &State) override {
166 const DebugSubsectionState &State) override {
168167 if (!opts::checkModuleSubsection(opts::ModuleSubsection::InlineeLines))
169168 return Error::success();
170169
191190 }
192191
193192 Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
194 const StringsAndChecksumsRef &State) override {
193 const DebugSubsectionState &State) override {
195194 if (!opts::checkModuleSubsection(opts::ModuleSubsection::CrossScopeExports))
196195 return Error::success();
197196
205204 }
206205
207206 Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSI,
208 const StringsAndChecksumsRef &State) override {
207 const DebugSubsectionState &State) override {
209208 if (!opts::checkModuleSubsection(opts::ModuleSubsection::CrossScopeImports))
210209 return Error::success();
211210
222221 }
223222
224223 Error visitFrameData(DebugFrameDataSubsectionRef &FD,
225 const StringsAndChecksumsRef &State) override {
224 const DebugSubsectionState &State) override {
226225 if (!opts::checkModuleSubsection(opts::ModuleSubsection::FrameData))
227226 return Error::success();
228227
248247 }
249248
250249 Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
251 const StringsAndChecksumsRef &State) override {
250 const DebugSubsectionState &State) override {
252251 if (!opts::checkModuleSubsection(opts::ModuleSubsection::Symbols))
253252 return Error::success();
254253 ListScope L(P, "Symbols");
270269 }
271270
272271 Error visitStringTable(DebugStringTableSubsectionRef &Strings,
273 const StringsAndChecksumsRef &State) override {
272 const DebugSubsectionState &State) override {
274273 if (!opts::checkModuleSubsection(opts::ModuleSubsection::StringTable))
275274 return Error::success();
276275
288287 }
289288
290289 Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
291 const StringsAndChecksumsRef &State) override {
290 const DebugSubsectionState &State) override {
292291 if (!opts::checkModuleSubsection(opts::ModuleSubsection::CoffSymbolRVAs))
293292 return Error::success();
294293
309308 return EC;
310309 }
311310 }
312
311
313312 if (!Success) {
314313 P.printString(
315314 llvm::formatv("Index: {0:x} (unknown function)", Index.getIndex())
318317 return Error::success();
319318 }
320319 Error printFileName(StringRef Label, uint32_t Offset,
321 const StringsAndChecksumsRef &State) {
320 const DebugSubsectionState &State) {
322321 if (auto Result = getNameFromChecksumsBuffer(Offset, State)) {
323322 P.printString(Label, *Result);
324323 return Error::success();
327326 }
328327
329328 Expected
330 getNameFromStringTable(uint32_t Offset, const StringsAndChecksumsRef &State) {
329 getNameFromStringTable(uint32_t Offset, const DebugSubsectionState &State) {
331330 return State.strings().getString(Offset);
332331 }
333332
334333 Expected
335334 getNameFromChecksumsBuffer(uint32_t Offset,
336 const StringsAndChecksumsRef &State) {
335 const DebugSubsectionState &State) {
337336 auto Array = State.checksums().getArray();
338337 auto ChecksumIter = Array.at(Offset);
339338 if (ChecksumIter == Array.end())
1717 #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
1818 #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
1919 #include "llvm/DebugInfo/CodeView/Line.h"
20 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
2120 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
2221 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
2322 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
236235 if (!ExpectedChecksums)
237236 return ExpectedChecksums.takeError();
238237
239 StringsAndChecksumsRef SC(ExpectedST->getStringTable(),
240 *ExpectedChecksums);
241
242238 for (const auto &SS : ModS.subsections()) {
243239 opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind());
244240 if (!opts::checkModuleSubsection(OptionKind))
245241 continue;
246242
247243 auto Converted =
248 CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(SC, SS);
244 CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(
245 ExpectedST->getStringTable(), *ExpectedChecksums, SS);
249246 if (!Converted)
250247 return Converted.takeError();
251248 DMI.Subsections.push_back(*Converted);
3434 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
3535 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
3636 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
37 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
3837 #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
3938 #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
4039 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
511510 for (uint32_t I = 0; I < kSpecialStreamCount; ++I)
512511 ExitOnErr(Builder.getMsfBuilder().addStream(0));
513512
514 StringsAndChecksums Strings;
515 Strings.setStrings(std::make_shared());
516
517513 if (YamlObj.StringTable.hasValue()) {
514 auto &Strings = Builder.getStringTableBuilder();
518515 for (auto S : *YamlObj.StringTable)
519 Strings.strings()->insert(S);
516 Strings.insert(S);
520517 }
521518
522519 pdb::yaml::PdbInfoStream DefaultInfoStream;
533530 InfoBuilder.setVersion(Info.Version);
534531 for (auto F : Info.Features)
535532 InfoBuilder.addFeature(F);
533
534 auto &Strings = Builder.getStringTableBuilder().getStrings();
536535
537536 const auto &Dbi = YamlObj.DbiStream.getValueOr(DefaultDbiStream);
538537 auto &DbiBuilder = Builder.getDbiBuilder();
557556 }
558557 }
559558
560 // Each module has its own checksum subsection, so scan for it every time.
561 Strings.setChecksums(nullptr);
562 CodeViewYAML::initializeStringsAndChecksums(MI.Subsections, Strings);
563
564559 auto CodeViewSubsections = ExitOnErr(CodeViewYAML::toCodeViewSubsectionList(
565560 Allocator, MI.Subsections, Strings));
566561 for (auto &SS : CodeViewSubsections) {
567 ModiBuilder.addDebugSubsection(SS);
562 ModiBuilder.addDebugSubsection(std::move(SS));
568563 }
569564 }
570565
583578 CVType Type = R.toCodeViewRecord(Allocator);
584579 IpiBuilder.addTypeRecord(Type.RecordData, None);
585580 }
586
587 Builder.getStringTableBuilder().setStrings(*Strings.strings());
588581
589582 ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile));
590583 }
77 //===----------------------------------------------------------------------===//
88
99 #include "obj2yaml.h"
10 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
11 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
12 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
1310 #include "llvm/Object/COFF.h"
1411 #include "llvm/ObjectYAML/COFFYAML.h"
15 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
16 #include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
1712 #include "llvm/Support/ErrorHandling.h"
1813 #include "llvm/Support/YAMLTraits.h"
1914
10398 YAMLObj.Header.Characteristics = Obj.getCharacteristics();
10499 }
105100
106 static void
107 initializeFileAndStringTable(const llvm::object::COFFObjectFile &Obj,
108 codeview::StringsAndChecksumsRef &SC) {
109
110 ExitOnError Err("Invalid .debug$S section!");
111 // Iterate all .debug$S sections looking for the checksums and string table.
112 // Exit as soon as both sections are found.
113 for (const auto &S : Obj.sections()) {
114 if (SC.hasStrings() && SC.hasChecksums())
115 break;
116
117 StringRef SectionName;
118 S.getName(SectionName);
119 ArrayRef sectionData;
120 if (SectionName != ".debug$S")
121 continue;
122
123 const object::coff_section *COFFSection = Obj.getCOFFSection(S);
124
125 Obj.getSectionContents(COFFSection, sectionData);
126
127 BinaryStreamReader Reader(sectionData, support::little);
128 uint32_t Magic;
129
130 Err(Reader.readInteger(Magic));
131 assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
132
133 codeview::DebugSubsectionArray Subsections;
134 Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
135
136 SC.initialize(Subsections);
137 }
138 }
139
140101 void COFFDumper::dumpSections(unsigned NumSections) {
141102 std::vector &YAMLSections = YAMLObj.Sections;
142 codeview::StringsAndChecksumsRef SC;
143 initializeFileAndStringTable(Obj, SC);
144
145103 for (const auto &ObjSection : Obj.sections()) {
146104 const object::coff_section *COFFSection = Obj.getCOFFSection(ObjSection);
147105 COFFYAML::Section NewYAMLSection;
149107 NewYAMLSection.Header.Characteristics = COFFSection->Characteristics;
150108 NewYAMLSection.Header.VirtualAddress = ObjSection.getAddress();
151109 NewYAMLSection.Header.VirtualSize = COFFSection->VirtualSize;
152 NewYAMLSection.Header.NumberOfLineNumbers =
153 COFFSection->NumberOfLinenumbers;
154 NewYAMLSection.Header.NumberOfRelocations =
155 COFFSection->NumberOfRelocations;
156 NewYAMLSection.Header.PointerToLineNumbers =
157 COFFSection->PointerToLinenumbers;
158 NewYAMLSection.Header.PointerToRawData = COFFSection->PointerToRawData;
159 NewYAMLSection.Header.PointerToRelocations =
160 COFFSection->PointerToRelocations;
161 NewYAMLSection.Header.SizeOfRawData = COFFSection->SizeOfRawData;
162110 NewYAMLSection.Alignment = ObjSection.getAlignment();
163111 assert(NewYAMLSection.Alignment <= 8192);
164112
166114 if (!ObjSection.isBSS())
167115 Obj.getSectionContents(COFFSection, sectionData);
168116 NewYAMLSection.SectionData = yaml::BinaryRef(sectionData);
169
170 if (NewYAMLSection.Name == ".debug$S")
171 NewYAMLSection.DebugS = CodeViewYAML::fromDebugS(sectionData, SC);
172 else if (NewYAMLSection.Name == ".debug$T")
173 NewYAMLSection.DebugT = CodeViewYAML::fromDebugT(sectionData);
174117
175118 std::vector Relocations;
176119 for (const auto &Reloc : ObjSection.relocations()) {
1616 #include "llvm/ADT/StringExtras.h"
1717 #include "llvm/ADT/StringMap.h"
1818 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
20 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
2119 #include "llvm/Object/COFF.h"
2220 #include "llvm/ObjectYAML/ObjectYAML.h"
2321 #include "llvm/Support/Endian.h"
143141
144142 COFFYAML::Object &Obj;
145143
146 codeview::StringsAndChecksums StringsAndChecksums;
147 BumpPtrAllocator Allocator;
148144 StringMap StringTableMap;
149145 std::string StringTable;
150146 uint32_t SectionTableStart;
168164 enum { DOSStubSize = 128 };
169165 }
170166
171 static yaml::BinaryRef
172 toDebugS(ArrayRef Subsections,
173 const codeview::StringsAndChecksums &SC, BumpPtrAllocator &Allocator) {
174 using namespace codeview;
175 ExitOnError Err("Error occurred writing .debug$S section");
176 auto CVSS =
177 Err(CodeViewYAML::toCodeViewSubsectionList(Allocator, Subsections, SC));
178
179 std::vector Builders;
180 uint32_t Size = sizeof(uint32_t);
181 for (auto &SS : CVSS) {
182 DebugSubsectionRecordBuilder B(SS, CodeViewContainer::ObjectFile);
183 Size += B.calculateSerializedLength();
184 Builders.push_back(std::move(B));
185 }
186 uint8_t *Buffer = Allocator.Allocate(Size);
187 MutableArrayRef Output(Buffer, Size);
188 BinaryStreamWriter Writer(Output, support::little);
189
190 Err(Writer.writeInteger(COFF::DEBUG_SECTION_MAGIC));
191 for (const auto &B : Builders) {
192 Err(B.commit(Writer));
193 }
194 return {Output};
195 }
196
197167 // Take a CP and assign addresses and sizes to everything. Returns false if the
198168 // layout is not valid to do.
199169 static bool layoutCOFF(COFFParser &CP) {
208178 uint32_t CurrentSectionDataOffset =
209179 CP.SectionTableStart + CP.SectionTableSize;
210180
211 for (COFFYAML::Section &S : CP.Obj.Sections) {
212 // We support specifying exactly one of SectionData or Subsections. So if
213 // there is already some SectionData, then we don't need to do any of this.
214 if (S.Name == ".debug$S" && S.SectionData.binary_size() == 0) {
215 CodeViewYAML::initializeStringsAndChecksums(S.DebugS,
216 CP.StringsAndChecksums);
217 if (CP.StringsAndChecksums.hasChecksums() &&
218 CP.StringsAndChecksums.hasStrings())
219 break;
220 }
221 }
222
223181 // Assign each section data address consecutively.
224182 for (COFFYAML::Section &S : CP.Obj.Sections) {
225 if (S.Name == ".debug$S") {
226 if (S.SectionData.binary_size() == 0) {
227 assert(CP.StringsAndChecksums.hasStrings() &&
228 "Object file does not have debug string table!");
229
230 S.SectionData =
231 toDebugS(S.DebugS, CP.StringsAndChecksums, CP.Allocator);
232 }
233 } else if (S.Name == ".debug$T") {
234 if (S.SectionData.binary_size() == 0)
235 S.SectionData = CodeViewYAML::toDebugT(S.DebugT, CP.Allocator);
236 }
237
238183 if (S.SectionData.binary_size() > 0) {
239184 CurrentSectionDataOffset = alignTo(CurrentSectionDataOffset,
240185 CP.isPE() ? CP.getFileAlignment() : 4);
597542 errs() << "yaml2obj: Failed to layout optional header for COFF file!\n";
598543 return 1;
599544 }
600
601545 if (!layoutCOFF(CP)) {
602546 errs() << "yaml2obj: Failed to layout COFF file!\n";
603547 return 1;