1 //===-- LVBinaryReader.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 LVBinaryReader class, which is used to describe a 10 // binary reader. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H 15 #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H 16 17 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h" 18 #include "llvm/MC/MCAsmInfo.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 21 #include "llvm/MC/MCInstPrinter.h" 22 #include "llvm/MC/MCInstrInfo.h" 23 #include "llvm/MC/MCObjectFileInfo.h" 24 #include "llvm/MC/MCRegisterInfo.h" 25 #include "llvm/MC/MCSubtargetInfo.h" 26 #include "llvm/MC/TargetRegistry.h" 27 #include "llvm/Object/COFF.h" 28 #include "llvm/Object/ObjectFile.h" 29 30 namespace llvm { 31 namespace logicalview { 32 33 constexpr bool UpdateHighAddress = false; 34 35 // Logical scope, Section address, Section index, IsComdat. 36 struct LVSymbolTableEntry final { 37 LVScope *Scope = nullptr; 38 LVAddress Address = 0; 39 LVSectionIndex SectionIndex = 0; 40 bool IsComdat = false; 41 LVSymbolTableEntry() = default; 42 LVSymbolTableEntry(LVScope *Scope, LVAddress Address, 43 LVSectionIndex SectionIndex, bool IsComdat) 44 : Scope(Scope), Address(Address), SectionIndex(SectionIndex), 45 IsComdat(IsComdat) {} 46 }; 47 48 // Function names extracted from the object symbol table. 49 class LVSymbolTable final { 50 using LVSymbolNames = std::map<std::string, LVSymbolTableEntry>; 51 LVSymbolNames SymbolNames; 52 53 public: 54 LVSymbolTable() = default; 55 56 void add(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex = 0); 57 void add(StringRef Name, LVAddress Address, LVSectionIndex SectionIndex, 58 bool IsComdat); 59 LVSectionIndex update(LVScope *Function); 60 61 const LVSymbolTableEntry &getEntry(StringRef Name); 62 LVAddress getAddress(StringRef Name); 63 LVSectionIndex getIndex(StringRef Name); 64 bool getIsComdat(StringRef Name); 65 66 void print(raw_ostream &OS); 67 }; 68 69 class LVBinaryReader : public LVReader { 70 // Function names extracted from the object symbol table. 71 LVSymbolTable SymbolTable; 72 73 // It contains the LVLineDebug elements representing the inlined logical 74 // lines for the current compile unit, created by parsing the CodeView 75 // S_INLINESITE symbol annotation data. 76 using LVInlineeLine = std::map<LVScope *, std::unique_ptr<LVLines>>; 77 LVInlineeLine CUInlineeLines; 78 79 // Instruction lines for a logical scope. These instructions are fetched 80 // during its merge with the debug lines. 81 LVDoubleMap<LVSectionIndex, LVScope *, LVLines *> ScopeInstructions; 82 83 // Links the scope with its first assembler address line. 84 LVDoubleMap<LVSectionIndex, LVAddress, LVScope *> AssemblerMappings; 85 86 // Mapping from virtual address to section. 87 // The virtual address refers to the address where the section is loaded. 88 using LVSectionAddresses = std::map<LVSectionIndex, object::SectionRef>; 89 LVSectionAddresses SectionAddresses; 90 91 void addSectionAddress(const object::SectionRef &Section) { 92 if (SectionAddresses.find(Section.getAddress()) == SectionAddresses.end()) 93 SectionAddresses.emplace(Section.getAddress(), Section); 94 } 95 96 // Scopes with ranges for current compile unit. It is used to find a line 97 // giving its exact or closest address. To support comdat functions, all 98 // addresses for the same section are recorded in the same map. 99 using LVSectionRanges = std::map<LVSectionIndex, std::unique_ptr<LVRange>>; 100 LVSectionRanges SectionRanges; 101 102 // Image base and virtual address for Executable file. 103 uint64_t ImageBaseAddress = 0; 104 uint64_t VirtualAddress = 0; 105 106 // Object sections with machine code. 107 using LVSections = std::map<LVSectionIndex, object::SectionRef>; 108 LVSections Sections; 109 110 std::vector<std::unique_ptr<LVLines>> DiscoveredLines; 111 112 protected: 113 // It contains the LVLineDebug elements representing the logical lines for 114 // the current compile unit, created by parsing the debug line section. 115 LVLines CULines; 116 117 std::unique_ptr<const MCRegisterInfo> MRI; 118 std::unique_ptr<const MCAsmInfo> MAI; 119 std::unique_ptr<const MCSubtargetInfo> STI; 120 std::unique_ptr<const MCInstrInfo> MII; 121 std::unique_ptr<const MCDisassembler> MD; 122 std::unique_ptr<MCContext> MC; 123 std::unique_ptr<MCInstPrinter> MIP; 124 125 // Loads all info for the architecture of the provided object file. 126 Error loadGenericTargetInfo(StringRef TheTriple, StringRef TheFeatures); 127 128 virtual void mapRangeAddress(const object::ObjectFile &Obj) {} 129 virtual void mapRangeAddress(const object::ObjectFile &Obj, 130 const object::SectionRef &Section, 131 bool IsComdat) {} 132 133 // Create a mapping from virtual address to section. 134 void mapVirtualAddress(const object::ObjectFile &Obj); 135 void mapVirtualAddress(const object::COFFObjectFile &COFFObj); 136 137 Expected<std::pair<LVSectionIndex, object::SectionRef>> 138 getSection(LVScope *Scope, LVAddress Address, LVSectionIndex SectionIndex); 139 140 void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope); 141 void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope, 142 LVAddress LowerAddress, LVAddress UpperAddress); 143 LVRange *getSectionRanges(LVSectionIndex SectionIndex); 144 145 void includeInlineeLines(LVSectionIndex SectionIndex, LVScope *Function); 146 147 Error createInstructions(); 148 Error createInstructions(LVScope *Function, LVSectionIndex SectionIndex); 149 Error createInstructions(LVScope *Function, LVSectionIndex SectionIndex, 150 const LVNameInfo &NameInfo); 151 152 void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex); 153 void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex, 154 LVScope *Function); 155 156 public: 157 LVBinaryReader() = delete; 158 LVBinaryReader(StringRef Filename, StringRef FileFormatName, ScopedPrinter &W, 159 LVBinaryType BinaryType) 160 : LVReader(Filename, FileFormatName, W, BinaryType) {} 161 LVBinaryReader(const LVBinaryReader &) = delete; 162 LVBinaryReader &operator=(const LVBinaryReader &) = delete; 163 virtual ~LVBinaryReader() = default; 164 165 void addInlineeLines(LVScope *Scope, LVLines &Lines) { 166 CUInlineeLines.emplace(Scope, std::make_unique<LVLines>(std::move(Lines))); 167 } 168 169 // Convert Segment::Offset pair to absolute address. 170 LVAddress linearAddress(uint16_t Segment, uint32_t Offset, 171 LVAddress Addendum = 0) { 172 return ImageBaseAddress + (Segment * VirtualAddress) + Offset + Addendum; 173 } 174 175 void addToSymbolTable(StringRef Name, LVScope *Function, 176 LVSectionIndex SectionIndex = 0); 177 void addToSymbolTable(StringRef Name, LVAddress Address, 178 LVSectionIndex SectionIndex, bool IsComdat); 179 LVSectionIndex updateSymbolTable(LVScope *Function); 180 181 const LVSymbolTableEntry &getSymbolTableEntry(StringRef Name); 182 LVAddress getSymbolTableAddress(StringRef Name); 183 LVSectionIndex getSymbolTableIndex(StringRef Name); 184 bool getSymbolTableIsComdat(StringRef Name); 185 186 LVSectionIndex getSectionIndex(LVScope *Scope) override { 187 return Scope ? getSymbolTableIndex(Scope->getLinkageName()) 188 : DotTextSectionIndex; 189 } 190 191 void print(raw_ostream &OS) const; 192 193 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 194 void dump() const { print(dbgs()); } 195 #endif 196 }; 197 198 } // end namespace logicalview 199 } // end namespace llvm 200 201 #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H 202