Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===-- LVReader.h ----------------------------------------------*- C++ -*-===// |
| 2 | // |
||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
| 6 | // |
||
| 7 | //===----------------------------------------------------------------------===// |
||
| 8 | // |
||
| 9 | // This file defines the LVReader class, which is used to describe a debug |
||
| 10 | // information reader. |
||
| 11 | // |
||
| 12 | //===----------------------------------------------------------------------===// |
||
| 13 | |||
| 14 | #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVREADER_H |
||
| 15 | #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVREADER_H |
||
| 16 | |||
| 17 | #include "llvm/DebugInfo/LogicalView/Core/LVOptions.h" |
||
| 18 | #include "llvm/DebugInfo/LogicalView/Core/LVRange.h" |
||
| 19 | #include "llvm/Support/Errc.h" |
||
| 20 | #include "llvm/Support/Error.h" |
||
| 21 | #include "llvm/Support/ScopedPrinter.h" |
||
| 22 | #include "llvm/Support/ToolOutputFile.h" |
||
| 23 | #include <map> |
||
| 24 | |||
| 25 | namespace llvm { |
||
| 26 | namespace logicalview { |
||
| 27 | |||
| 28 | constexpr LVSectionIndex UndefinedSectionIndex = 0; |
||
| 29 | |||
| 30 | class LVScopeCompileUnit; |
||
| 31 | class LVObject; |
||
| 32 | |||
| 33 | class LVSplitContext final { |
||
| 34 | std::unique_ptr<ToolOutputFile> OutputFile; |
||
| 35 | std::string Location; |
||
| 36 | |||
| 37 | public: |
||
| 38 | LVSplitContext() = default; |
||
| 39 | LVSplitContext(const LVSplitContext &) = delete; |
||
| 40 | LVSplitContext &operator=(const LVSplitContext &) = delete; |
||
| 41 | ~LVSplitContext() = default; |
||
| 42 | |||
| 43 | Error createSplitFolder(StringRef Where); |
||
| 44 | std::error_code open(std::string Name, std::string Extension, |
||
| 45 | raw_ostream &OS); |
||
| 46 | void close() { |
||
| 47 | if (OutputFile) { |
||
| 48 | OutputFile->os().close(); |
||
| 49 | OutputFile = nullptr; |
||
| 50 | } |
||
| 51 | } |
||
| 52 | |||
| 53 | std::string getLocation() const { return Location; } |
||
| 54 | raw_fd_ostream &os() { return OutputFile->os(); } |
||
| 55 | }; |
||
| 56 | |||
| 57 | class LVReader { |
||
| 58 | LVBinaryType BinaryType; |
||
| 59 | |||
| 60 | // Context used by '--output=split' command line option. |
||
| 61 | LVSplitContext SplitContext; |
||
| 62 | |||
| 63 | // Compile Units DIE Offset => Scope. |
||
| 64 | using LVCompileUnits = std::map<LVOffset, LVScopeCompileUnit *>; |
||
| 65 | LVCompileUnits CompileUnits; |
||
| 66 | |||
| 67 | // Added elements to be used during elements comparison. |
||
| 68 | LVLines Lines; |
||
| 69 | LVScopes Scopes; |
||
| 70 | LVSymbols Symbols; |
||
| 71 | LVTypes Types; |
||
| 72 | |||
| 73 | // Create split folder. |
||
| 74 | Error createSplitFolder(); |
||
| 75 | bool OutputSplit = false; |
||
| 76 | |||
| 77 | protected: |
||
| 78 | LVScopeRoot *Root = nullptr; |
||
| 79 | std::string InputFilename; |
||
| 80 | std::string FileFormatName; |
||
| 81 | ScopedPrinter &W; |
||
| 82 | raw_ostream &OS; |
||
| 83 | LVScopeCompileUnit *CompileUnit = nullptr; |
||
| 84 | |||
| 85 | // Only for ELF format. The CodeView is handled in a different way. |
||
| 86 | LVSectionIndex DotTextSectionIndex = UndefinedSectionIndex; |
||
| 87 | |||
| 88 | // Record Compilation Unit entry. |
||
| 89 | void addCompileUnitOffset(LVOffset Offset, LVScopeCompileUnit *CompileUnit) { |
||
| 90 | CompileUnits.emplace(Offset, CompileUnit); |
||
| 91 | } |
||
| 92 | |||
| 93 | // Create the Scope Root. |
||
| 94 | virtual Error createScopes() { |
||
| 95 | Root = new LVScopeRoot(); |
||
| 96 | Root->setName(getFilename()); |
||
| 97 | if (options().getAttributeFormat()) |
||
| 98 | Root->setFileFormatName(FileFormatName); |
||
| 99 | return Error::success(); |
||
| 100 | } |
||
| 101 | |||
| 102 | // Return a pathname composed by: parent_path(InputFilename)/filename(From). |
||
| 103 | // This is useful when a type server (PDB file associated with an object |
||
| 104 | // file or a precompiled header file) or a DWARF split object have been |
||
| 105 | // moved from their original location. That is the case when running |
||
| 106 | // regression tests, where object files are created in one location and |
||
| 107 | // executed in a different location. |
||
| 108 | std::string createAlternativePath(StringRef From) { |
||
| 109 | // During the reader initialization, any backslashes in 'InputFilename' |
||
| 110 | // are converted to forward slashes. |
||
| 111 | SmallString<128> Path; |
||
| 112 | sys::path::append(Path, sys::path::Style::posix, |
||
| 113 | sys::path::parent_path(InputFilename), |
||
| 114 | sys::path::filename(sys::path::convert_to_slash( |
||
| 115 | From, sys::path::Style::windows))); |
||
| 116 | return std::string(Path); |
||
| 117 | } |
||
| 118 | |||
| 119 | virtual Error printScopes(); |
||
| 120 | virtual Error printMatchedElements(bool UseMatchedElements); |
||
| 121 | virtual void sortScopes() {} |
||
| 122 | |||
| 123 | public: |
||
| 124 | LVReader() = delete; |
||
| 125 | LVReader(StringRef InputFilename, StringRef FileFormatName, ScopedPrinter &W, |
||
| 126 | LVBinaryType BinaryType = LVBinaryType::NONE) |
||
| 127 | : BinaryType(BinaryType), OutputSplit(options().getOutputSplit()), |
||
| 128 | InputFilename(InputFilename), FileFormatName(FileFormatName), W(W), |
||
| 129 | OS(W.getOStream()) {} |
||
| 130 | LVReader(const LVReader &) = delete; |
||
| 131 | LVReader &operator=(const LVReader &) = delete; |
||
| 132 | virtual ~LVReader() { |
||
| 133 | if (Root) |
||
| 134 | delete Root; |
||
| 135 | } |
||
| 136 | |||
| 137 | StringRef getFilename(LVObject *Object, size_t Index) const; |
||
| 138 | StringRef getFilename() const { return InputFilename; } |
||
| 139 | void setFilename(std::string Name) { InputFilename = std::move(Name); } |
||
| 140 | StringRef getFileFormatName() const { return FileFormatName; } |
||
| 141 | |||
| 142 | raw_ostream &outputStream() { return OS; } |
||
| 143 | |||
| 144 | bool isBinaryTypeNone() const { return BinaryType == LVBinaryType::NONE; } |
||
| 145 | bool isBinaryTypeELF() const { return BinaryType == LVBinaryType::ELF; } |
||
| 146 | bool isBinaryTypeCOFF() const { return BinaryType == LVBinaryType::COFF; } |
||
| 147 | |||
| 148 | LVScopeCompileUnit *getCompileUnit() const { return CompileUnit; } |
||
| 149 | void setCompileUnit(LVScope *Scope) { |
||
| 150 | assert(Scope && Scope->isCompileUnit() && "Scope is not a compile unit"); |
||
| 151 | CompileUnit = static_cast<LVScopeCompileUnit *>(Scope); |
||
| 152 | } |
||
| 153 | |||
| 154 | // Access to the scopes root. |
||
| 155 | LVScopeRoot *getScopesRoot() const { return Root; } |
||
| 156 | |||
| 157 | Error doPrint(); |
||
| 158 | Error doLoad(); |
||
| 159 | |||
| 160 | virtual std::string getRegisterName(LVSmall Opcode, uint64_t Operands[2]) { |
||
| 161 | llvm_unreachable("Invalid instance reader."); |
||
| 162 | return {}; |
||
| 163 | } |
||
| 164 | |||
| 165 | LVSectionIndex getDotTextSectionIndex() const { return DotTextSectionIndex; } |
||
| 166 | virtual LVSectionIndex getSectionIndex(LVScope *Scope) { |
||
| 167 | return getDotTextSectionIndex(); |
||
| 168 | } |
||
| 169 | |||
| 170 | virtual bool isSystemEntry(LVElement *Element, StringRef Name = {}) const { |
||
| 171 | return false; |
||
| 172 | }; |
||
| 173 | |||
| 174 | // Access to split context. |
||
| 175 | LVSplitContext &getSplitContext() { return SplitContext; } |
||
| 176 | |||
| 177 | // In the case of element comparison, register that added element. |
||
| 178 | void notifyAddedElement(LVLine *Line) { |
||
| 179 | if (!options().getCompareContext() && options().getCompareLines()) |
||
| 180 | Lines.push_back(Line); |
||
| 181 | } |
||
| 182 | void notifyAddedElement(LVScope *Scope) { |
||
| 183 | if (!options().getCompareContext() && options().getCompareScopes()) |
||
| 184 | Scopes.push_back(Scope); |
||
| 185 | } |
||
| 186 | void notifyAddedElement(LVSymbol *Symbol) { |
||
| 187 | if (!options().getCompareContext() && options().getCompareSymbols()) |
||
| 188 | Symbols.push_back(Symbol); |
||
| 189 | } |
||
| 190 | void notifyAddedElement(LVType *Type) { |
||
| 191 | if (!options().getCompareContext() && options().getCompareTypes()) |
||
| 192 | Types.push_back(Type); |
||
| 193 | } |
||
| 194 | |||
| 195 | const LVLines &getLines() const { return Lines; } |
||
| 196 | const LVScopes &getScopes() const { return Scopes; } |
||
| 197 | const LVSymbols &getSymbols() const { return Symbols; } |
||
| 198 | const LVTypes &getTypes() const { return Types; } |
||
| 199 | |||
| 200 | // Conditions to print an object. |
||
| 201 | bool doPrintLine(const LVLine *Line) const { |
||
| 202 | return patterns().printElement(Line); |
||
| 203 | } |
||
| 204 | bool doPrintLocation(const LVLocation *Location) const { |
||
| 205 | return patterns().printObject(Location); |
||
| 206 | } |
||
| 207 | bool doPrintScope(const LVScope *Scope) const { |
||
| 208 | return patterns().printElement(Scope); |
||
| 209 | } |
||
| 210 | bool doPrintSymbol(const LVSymbol *Symbol) const { |
||
| 211 | return patterns().printElement(Symbol); |
||
| 212 | } |
||
| 213 | bool doPrintType(const LVType *Type) const { |
||
| 214 | return patterns().printElement(Type); |
||
| 215 | } |
||
| 216 | |||
| 217 | static LVReader &getInstance(); |
||
| 218 | static void setInstance(LVReader *Reader); |
||
| 219 | |||
| 220 | void print(raw_ostream &OS) const; |
||
| 221 | virtual void printRecords(raw_ostream &OS) const {} |
||
| 222 | |||
| 223 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
||
| 224 | void dump() const { print(dbgs()); } |
||
| 225 | #endif |
||
| 226 | }; |
||
| 227 | |||
| 228 | inline LVReader &getReader() { return LVReader::getInstance(); } |
||
| 229 | inline LVSplitContext &getReaderSplitContext() { |
||
| 230 | return getReader().getSplitContext(); |
||
| 231 | } |
||
| 232 | inline LVScopeCompileUnit *getReaderCompileUnit() { |
||
| 233 | return getReader().getCompileUnit(); |
||
| 234 | } |
||
| 235 | |||
| 236 | } // end namespace logicalview |
||
| 237 | } // end namespace llvm |
||
| 238 | |||
| 239 | #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVREADER_H |