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/DebugSymbolRVASubsection.h"
21 #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
22 #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
23 #include "llvm/Support/BinaryStreamReader.h"
24 #include "llvm/Support/BinaryStreamRef.h"
25 
26 using namespace llvm;
27 using namespace llvm::codeview;
28 
29 DebugSubsectionState::DebugSubsectionState() {}
30 
31 DebugSubsectionState::DebugSubsectionState(
32     const DebugStringTableSubsectionRef &Strings)
33     : Strings(&Strings) {}
34 
35 DebugSubsectionState::DebugSubsectionState(
36     const DebugStringTableSubsectionRef &Strings,
37     const DebugChecksumsSubsectionRef &Checksums)
38     : Strings(&Strings), Checksums(&Checksums) {}
39 
40 void DebugSubsectionState::initializeStrings(const DebugSubsectionRecord &SR) {
41   assert(SR.kind() == DebugSubsectionKind::StringTable);
42   assert(!Strings && "Found a string table even though we already have one!");
43 
44   OwnedStrings = llvm::make_unique<DebugStringTableSubsectionRef>();
45   consumeError(OwnedStrings->initialize(SR.getRecordData()));
46   Strings = OwnedStrings.get();
47 }
48 
49 void DebugSubsectionState::initializeChecksums(
50     const DebugSubsectionRecord &FCR) {
51   assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
52   if (Checksums)
53     return;
54 
55   OwnedChecksums = llvm::make_unique<DebugChecksumsSubsectionRef>();
56   consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
57   Checksums = OwnedChecksums.get();
58 }
59 
60 Error llvm::codeview::visitDebugSubsection(const DebugSubsectionRecord &R,
61                                            DebugSubsectionVisitor &V,
62                                            const DebugSubsectionState &State) {
63   BinaryStreamReader Reader(R.getRecordData());
64   switch (R.kind()) {
65   case DebugSubsectionKind::Lines: {
66     DebugLinesSubsectionRef Fragment;
67     if (auto EC = Fragment.initialize(Reader))
68       return EC;
69 
70     return V.visitLines(Fragment, State);
71   }
72   case DebugSubsectionKind::FileChecksums: {
73     DebugChecksumsSubsectionRef Fragment;
74     if (auto EC = Fragment.initialize(Reader))
75       return EC;
76 
77     return V.visitFileChecksums(Fragment, State);
78   }
79   case DebugSubsectionKind::InlineeLines: {
80     DebugInlineeLinesSubsectionRef Fragment;
81     if (auto EC = Fragment.initialize(Reader))
82       return EC;
83     return V.visitInlineeLines(Fragment, State);
84   }
85   case DebugSubsectionKind::CrossScopeExports: {
86     DebugCrossModuleExportsSubsectionRef Section;
87     if (auto EC = Section.initialize(Reader))
88       return EC;
89     return V.visitCrossModuleExports(Section, State);
90   }
91   case DebugSubsectionKind::CrossScopeImports: {
92     DebugCrossModuleImportsSubsectionRef Section;
93     if (auto EC = Section.initialize(Reader))
94       return EC;
95     return V.visitCrossModuleImports(Section, State);
96   }
97   case DebugSubsectionKind::Symbols: {
98     DebugSymbolsSubsectionRef Section;
99     if (auto EC = Section.initialize(Reader))
100       return EC;
101     return V.visitSymbols(Section, State);
102   }
103   case DebugSubsectionKind::StringTable: {
104     DebugStringTableSubsectionRef Section;
105     if (auto EC = Section.initialize(Reader))
106       return EC;
107     return V.visitStringTable(Section, State);
108   }
109   case DebugSubsectionKind::FrameData: {
110     DebugFrameDataSubsectionRef Section;
111     if (auto EC = Section.initialize(Reader))
112       return EC;
113     return V.visitFrameData(Section, State);
114   }
115   case DebugSubsectionKind::CoffSymbolRVA: {
116     DebugSymbolRVASubsectionRef Section;
117     if (auto EC = Section.initialize(Reader))
118       return EC;
119     return V.visitCOFFSymbolRVAs(Section, State);
120   }
121   default: {
122     DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
123     return V.visitUnknown(Fragment);
124   }
125   }
126 }
127