@@ -47,10 +47,11 @@ class DWARFUnitSectionBase {
47
47
// / Returns the Unit that contains the given section offset in the
48
48
// / same section this Unit originated from.
49
49
virtual DWARFUnit *getUnitForOffset (uint32_t Offset) const = 0;
50
+ virtual DWARFUnit *getUnitForIndexEntry (const DWARFUnitIndex::Entry &E) = 0;
50
51
51
52
void parse (DWARFContext &C, const DWARFSection &Section);
52
53
void parseDWO (DWARFContext &C, const DWARFSection &DWOSection,
53
- DWARFUnitIndex *Index = nullptr );
54
+ bool Lazy = false );
54
55
55
56
protected:
56
57
~DWARFUnitSectionBase () = default ;
@@ -59,7 +60,7 @@ class DWARFUnitSectionBase {
59
60
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
60
61
StringRef SS, const DWARFSection &SOS,
61
62
const DWARFSection *AOS, const DWARFSection &LS,
62
- bool isLittleEndian, bool isDWO) = 0;
63
+ bool isLittleEndian, bool isDWO, bool Lazy ) = 0;
63
64
};
64
65
65
66
const DWARFUnitIndex &getDWARFUnitIndex (DWARFContext &Context,
@@ -70,6 +71,7 @@ template<typename UnitType>
70
71
class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1 >,
71
72
public DWARFUnitSectionBase {
72
73
bool Parsed = false ;
74
+ std::function<std::unique_ptr<UnitType>(uint32_t )> Parser;
73
75
74
76
public:
75
77
using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>;
@@ -82,29 +84,76 @@ class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
82
84
[](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
83
85
return LHS < RHS->getNextUnitOffset ();
84
86
});
85
- if (CU != this ->end ())
87
+ if (CU != this ->end () && (*CU)-> getOffset () <= Offset )
86
88
return CU->get ();
87
89
return nullptr ;
88
90
}
91
+ UnitType *getUnitForIndexEntry (const DWARFUnitIndex::Entry &E) override {
92
+ const auto *CUOff = E.getOffset (DW_SECT_INFO);
93
+ if (!CUOff)
94
+ return nullptr ;
95
+
96
+ auto Offset = CUOff->Offset ;
97
+
98
+ auto *CU = std::upper_bound (
99
+ this ->begin (), this ->end (), CUOff->Offset ,
100
+ [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
101
+ return LHS < RHS->getNextUnitOffset ();
102
+ });
103
+ if (CU != this ->end () && (*CU)->getOffset () <= Offset)
104
+ return CU->get ();
105
+
106
+ if (!Parser)
107
+ return nullptr ;
108
+
109
+ auto U = Parser (Offset);
110
+ if (!U)
111
+ U = nullptr ;
112
+
113
+ auto *NewCU = U.get ();
114
+ this ->insert (CU, std::move (U));
115
+ return NewCU;
116
+ }
89
117
90
118
private:
91
119
void parseImpl (DWARFContext &Context, const DWARFSection &Section,
92
120
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
93
121
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
94
- const DWARFSection &LS, bool LE, bool IsDWO) override {
122
+ const DWARFSection &LS, bool LE, bool IsDWO,
123
+ bool Lazy) override {
95
124
if (Parsed)
96
125
return ;
97
- const auto &Index = getDWARFUnitIndex (Context, UnitType::Section);
98
126
DataExtractor Data (Section.Data , LE, 0 );
127
+ if (!Parser) {
128
+ const DWARFUnitIndex *Index = nullptr ;
129
+ if (IsDWO)
130
+ Index = &getDWARFUnitIndex (Context, UnitType::Section);
131
+ Parser = [=, &Context, &Section, &SOS,
132
+ &LS](uint32_t Offset) -> std::unique_ptr<UnitType> {
133
+ if (!Data.isValidOffset (Offset))
134
+ return nullptr ;
135
+ auto U = llvm::make_unique<UnitType>(
136
+ Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, *this ,
137
+ Index ? Index->getFromOffset (Offset) : nullptr );
138
+ if (!U->extract (Data, &Offset))
139
+ return nullptr ;
140
+ return U;
141
+ };
142
+ }
143
+ if (Lazy)
144
+ return ;
145
+ auto I = this ->begin ();
99
146
uint32_t Offset = 0 ;
100
147
while (Data.isValidOffset (Offset)) {
101
- auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
102
- AOS, LS, LE, IsDWO, *this ,
103
- Index.getFromOffset (Offset));
104
- if (!U->extract (Data, &Offset))
148
+ if (I != this ->end () && (*I)->getOffset () == Offset) {
149
+ ++I;
150
+ continue ;
151
+ }
152
+ auto U = Parser (Offset);
153
+ if (!U)
105
154
break ;
106
- this -> push_back ( std::move (U) );
107
- Offset = this ->back ()-> getNextUnitOffset ( );
155
+ Offset = U-> getNextUnitOffset ( );
156
+ I = std::next ( this ->insert (I, std::move (U)) );
108
157
}
109
158
Parsed = true ;
110
159
}
0 commit comments