1 //===- DebugSubsectionVisitor.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
11 
12 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
13 #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
14 #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
15 #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
16 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
17 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
18 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
19 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
20 #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
21 #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
22 #include "llvm/Support/BinaryStreamReader.h"
23 #include "llvm/Support/BinaryStreamRef.h"
24 
25 using namespace llvm;
26 using namespace llvm::codeview;
27 
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<DebugStringTableSubsectionRef>();
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<DebugChecksumsSubsectionRef>();
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) {
62   BinaryStreamReader Reader(R.getRecordData());
63   switch (R.kind()) {
64   case DebugSubsectionKind::Lines: {
65     DebugLinesSubsectionRef Fragment;
66     if (auto EC = Fragment.initialize(Reader))
67       return EC;
68 
69     return V.visitLines(Fragment, State);
70   }
71   case DebugSubsectionKind::FileChecksums: {
72     DebugChecksumsSubsectionRef Fragment;
73     if (auto EC = Fragment.initialize(Reader))
74       return EC;
75 
76     return V.visitFileChecksums(Fragment, State);
77   }
78   case DebugSubsectionKind::InlineeLines: {
79     DebugInlineeLinesSubsectionRef Fragment;
80     if (auto EC = Fragment.initialize(Reader))
81       return EC;
82     return V.visitInlineeLines(Fragment, State);
83   }
84   case DebugSubsectionKind::CrossScopeExports: {
85     DebugCrossModuleExportsSubsectionRef Section;
86     if (auto EC = Section.initialize(Reader))
87       return EC;
88     return V.visitCrossModuleExports(Section, State);
89   }
90   case DebugSubsectionKind::CrossScopeImports: {
91     DebugCrossModuleImportsSubsectionRef Section;
92     if (auto EC = Section.initialize(Reader))
93       return EC;
94     return V.visitCrossModuleImports(Section, State);
95   }
96   case DebugSubsectionKind::Symbols: {
97     DebugSymbolsSubsectionRef Section;
98     if (auto EC = Section.initialize(Reader))
99       return EC;
100     return V.visitSymbols(Section, State);
101   }
102   case DebugSubsectionKind::StringTable: {
103     DebugStringTableSubsectionRef Section;
104     if (auto EC = Section.initialize(Reader))
105       return EC;
106     return V.visitStringTable(Section, State);
107   }
108   case DebugSubsectionKind::FrameData: {
109     DebugFrameDataSubsectionRef Section;
110     if (auto EC = Section.initialize(Reader))
111       return EC;
112     return V.visitFrameData(Section, State);
113   }
114   default: {
115     DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
116     return V.visitUnknown(Fragment);
117   }
118   }
119 }
120