| //===-- LVBinaryReader.h ----------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines the LVBinaryReader class, which is used to describe a |
| // binary reader. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H |
| #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H |
| |
| #include "llvm/DebugInfo/LogicalView/Core/LVReader.h" |
| #include "llvm/MC/MCAsmInfo.h" |
| #include "llvm/MC/MCContext.h" |
| #include "llvm/MC/MCDisassembler/MCDisassembler.h" |
| #include "llvm/MC/MCInstPrinter.h" |
| #include "llvm/MC/MCInstrInfo.h" |
| #include "llvm/MC/MCObjectFileInfo.h" |
| #include "llvm/MC/MCRegisterInfo.h" |
| #include "llvm/MC/MCSubtargetInfo.h" |
| #include "llvm/MC/TargetRegistry.h" |
| #include "llvm/Object/ObjectFile.h" |
| |
| namespace llvm { |
| namespace logicalview { |
| |
| constexpr bool UpdateHighAddress = false; |
| |
| // Logical scope, Section address, Section index, IsComdat. |
| struct LVSymbolTableEntry final { |
| LVScope *Scope = nullptr; |
| LVAddress Address = 0; |
| LVSectionIndex SectionIndex = 0; |
| bool IsComdat = false; |
| LVSymbolTableEntry() = default; |
| LVSymbolTableEntry(LVScope *Scope, LVAddress Address, |
| LVSectionIndex SectionIndex, bool IsComdat) |
| : Scope(Scope), Address(Address), SectionIndex(SectionIndex), |
| IsComdat(IsComdat) {} |
| }; |
| |
| // Function names extracted from the object symbol table. |
| class LVSymbolTable final { |
| using LVSymbolNames = std::map<std::string, LVSymbolTableEntry>; |
| LVSymbolNames SymbolNames; |
| |
| public: |
| LVSymbolTable() = default; |
| |
| void add(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex = 0); |
| void add(StringRef Name, LVAddress Address, LVSectionIndex SectionIndex, |
| bool IsComdat); |
| LVSectionIndex update(LVScope *Function); |
| |
| const LVSymbolTableEntry &getEntry(StringRef Name); |
| LVAddress getAddress(StringRef Name); |
| LVSectionIndex getIndex(StringRef Name); |
| bool getIsComdat(StringRef Name); |
| |
| void print(raw_ostream &OS); |
| }; |
| |
| class LVBinaryReader : public LVReader { |
| // Function names extracted from the object symbol table. |
| LVSymbolTable SymbolTable; |
| |
| // Instruction lines for a logical scope. These instructions are fetched |
| // during its merge with the debug lines. |
| LVDoubleMap<LVSectionIndex, LVScope *, LVLines *> ScopeInstructions; |
| |
| // Links the scope with its first assembler address line. |
| LVDoubleMap<LVSectionIndex, LVAddress, LVScope *> AssemblerMappings; |
| |
| // Mapping from virtual address to section. |
| // The virtual address refers to the address where the section is loaded. |
| using LVSectionAddresses = std::map<LVSectionIndex, object::SectionRef>; |
| LVSectionAddresses SectionAddresses; |
| |
| void addSectionAddress(const object::SectionRef &Section) { |
| if (SectionAddresses.find(Section.getAddress()) == SectionAddresses.end()) |
| SectionAddresses.emplace(Section.getAddress(), Section); |
| } |
| |
| // Scopes with ranges for current compile unit. It is used to find a line |
| // giving its exact or closest address. To support comdat functions, all |
| // addresses for the same section are recorded in the same map. |
| using LVSectionRanges = std::map<LVSectionIndex, LVRange *>; |
| LVSectionRanges SectionRanges; |
| |
| // Image base and virtual address for Executable file. |
| uint64_t ImageBaseAddress = 0; |
| uint64_t VirtualAddress = 0; |
| |
| // Object sections with machine code. |
| using LVSections = std::map<LVSectionIndex, object::SectionRef>; |
| LVSections Sections; |
| |
| protected: |
| // It contains the LVLineDebug elements representing the logical lines for |
| // the current compile unit, created by parsing the debug line section. |
| LVLines CULines; |
| |
| std::unique_ptr<const MCRegisterInfo> MRI; |
| std::unique_ptr<const MCAsmInfo> MAI; |
| std::unique_ptr<const MCSubtargetInfo> STI; |
| std::unique_ptr<const MCInstrInfo> MII; |
| std::unique_ptr<const MCDisassembler> MD; |
| std::unique_ptr<MCContext> MC; |
| std::unique_ptr<MCInstPrinter> MIP; |
| |
| // Loads all info for the architecture of the provided object file. |
| Error loadGenericTargetInfo(StringRef TheTriple, StringRef TheFeatures); |
| |
| virtual void mapRangeAddress(const object::ObjectFile &Obj) {} |
| virtual void mapRangeAddress(const object::ObjectFile &Obj, |
| const object::SectionRef &Section, |
| bool IsComdat) {} |
| |
| // Create a mapping from virtual address to section. |
| void mapVirtualAddress(const object::ObjectFile &Obj); |
| void mapVirtualAddress(const object::COFFObjectFile &COFFObj); |
| |
| Expected<std::pair<LVSectionIndex, object::SectionRef>> |
| getSection(LVScope *Scope, LVAddress Address, LVSectionIndex SectionIndex); |
| |
| void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope); |
| void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope, |
| LVAddress LowerAddress, LVAddress UpperAddress); |
| LVRange *getSectionRanges(LVSectionIndex SectionIndex); |
| |
| Error createInstructions(); |
| Error createInstructions(LVScope *Function, LVSectionIndex SectionIndex); |
| Error createInstructions(LVScope *Function, LVSectionIndex SectionIndex, |
| const LVNameInfo &NameInfo); |
| |
| void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex); |
| void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex, |
| LVScope *Function); |
| |
| public: |
| LVBinaryReader() = delete; |
| LVBinaryReader(StringRef Filename, StringRef FileFormatName, ScopedPrinter &W, |
| LVBinaryType BinaryType) |
| : LVReader(Filename, FileFormatName, W, BinaryType) {} |
| LVBinaryReader(const LVBinaryReader &) = delete; |
| LVBinaryReader &operator=(const LVBinaryReader &) = delete; |
| virtual ~LVBinaryReader(); |
| |
| void addToSymbolTable(StringRef Name, LVScope *Function, |
| LVSectionIndex SectionIndex = 0); |
| void addToSymbolTable(StringRef Name, LVAddress Address, |
| LVSectionIndex SectionIndex, bool IsComdat); |
| LVSectionIndex updateSymbolTable(LVScope *Function); |
| |
| const LVSymbolTableEntry &getSymbolTableEntry(StringRef Name); |
| LVAddress getSymbolTableAddress(StringRef Name); |
| LVSectionIndex getSymbolTableIndex(StringRef Name); |
| bool getSymbolTableIsComdat(StringRef Name); |
| |
| LVSectionIndex getSectionIndex(LVScope *Scope) override { |
| return Scope ? getSymbolTableIndex(Scope->getLinkageName()) |
| : DotTextSectionIndex; |
| } |
| |
| void print(raw_ostream &OS) const; |
| |
| #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
| void dump() const { print(dbgs()); } |
| #endif |
| }; |
| |
| } // end namespace logicalview |
| } // end namespace llvm |
| |
| #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H |