1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
#pragma once
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//===-- 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
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
|