diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-10 13:44:06 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-10 13:44:06 +0000 |
commit | 7ab83427af0f77b59941ceba41d509d7d097b065 (patch) | |
tree | cc41c05b1db454e3d802f34df75e636ee922ad87 /include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h | |
parent | d288ef4c1788d3a951a7558c68312c2d320612b1 (diff) |
Notes
Diffstat (limited to 'include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h')
-rw-r--r-- | include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h | 128 |
1 files changed, 112 insertions, 16 deletions
diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h b/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h index 55bef491c97ed..d4a3d9195a366 100644 --- a/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h +++ b/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h @@ -10,6 +10,8 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H #define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -20,9 +22,65 @@ namespace codeview { class DebugChecksumsSubsectionRef; class DebugSubsectionRecord; class DebugInlineeLinesSubsectionRef; +class DebugCrossModuleExportsSubsectionRef; +class DebugCrossModuleImportsSubsectionRef; +class DebugFrameDataSubsectionRef; class DebugLinesSubsectionRef; +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 DebugSubsectionVisitor { public: virtual ~DebugSubsectionVisitor() = default; @@ -30,34 +88,72 @@ public: virtual Error visitUnknown(DebugUnknownSubsectionRef &Unknown) { return Error::success(); } - virtual Error visitLines(DebugLinesSubsectionRef &Lines) { - return Error::success(); - } + virtual Error visitLines(DebugLinesSubsectionRef &Lines, + const DebugSubsectionState &State) = 0; + virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums, + const DebugSubsectionState &State) = 0; + virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees, + const DebugSubsectionState &State) = 0; + virtual Error + visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE, + const DebugSubsectionState &State) = 0; + virtual Error + visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE, + const DebugSubsectionState &State) = 0; - virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums) { - return Error::success(); - } + virtual Error visitStringTable(DebugStringTableSubsectionRef &ST, + const DebugSubsectionState &State) = 0; - virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees) { - return Error::success(); - } + virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE, + const DebugSubsectionState &State) = 0; - virtual Error finished() { return Error::success(); } + virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD, + const DebugSubsectionState &State) = 0; + virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs, + const DebugSubsectionState &State) = 0; }; Error visitDebugSubsection(const DebugSubsectionRecord &R, - DebugSubsectionVisitor &V); + DebugSubsectionVisitor &V, + const DebugSubsectionState &State); +namespace detail { template <typename T> -Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) { - for (const auto &L : FragmentRange) { - if (auto EC = visitDebugSubsection(L, V)) +Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V, + DebugSubsectionState &State) { + State.initialize(std::forward<T>(FragmentRange)); + + for (const DebugSubsectionRecord &L : FragmentRange) { + if (auto EC = visitDebugSubsection(L, V, State)) return EC; } - if (auto EC = V.finished()) - return EC; return Error::success(); } +} // namespace detail + +template <typename T> +Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) { + DebugSubsectionState State; + return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V, + State); +} + +template <typename T> +Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V, + const DebugStringTableSubsectionRef &Strings) { + DebugSubsectionState State(Strings); + return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V, + State); +} + +template <typename T> +Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V, + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums) { + DebugSubsectionState State(Strings, Checksums); + return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V, + State); +} } // end namespace codeview |