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