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