@@ -3112,10 +3112,32 @@ struct DIEVisitor {
3112
3112
SmallVector<AbbrevContent> AbbrevContents;
3113
3113
};
3114
3114
3115
+ DIEVisitor () = delete ;
3116
+
3117
+ DIEVisitor (ArrayRef<StringRef> AbbrevEntries,
3118
+ BinaryStreamReader DistinctReader, StringRef DistinctData,
3119
+ std::function<void (StringRef)> HeaderCallback,
3120
+ std::function<void (dwarf::Tag, uint64_t )> StartTagCallback,
3121
+ std::function<void (dwarf::Attribute, dwarf::Form, StringRef, bool )>
3122
+ AttrCallback,
3123
+ std::function<void (bool )> EndTagCallback,
3124
+ std::function<void (StringRef)> NewBlockCallback)
3125
+ : AbbrevEntries(AbbrevEntries), DistinctReader(DistinctReader),
3126
+ DistinctData (DistinctData), HeaderCallback(HeaderCallback),
3127
+ StartTagCallback(StartTagCallback), AttrCallback(AttrCallback),
3128
+ EndTagCallback(EndTagCallback), NewBlockCallback(NewBlockCallback) {
3129
+ AbbrevEntryCache.reserve (AbbrevEntries.size ());
3130
+ for (unsigned I = 0 ; I < AbbrevEntries.size (); I++) {
3131
+ if (Error E = materializeAbbrevDIE (encodeAbbrevIndex (I)))
3132
+ report_fatal_error (std::move (E));
3133
+ }
3134
+ }
3135
+
3115
3136
Error visitDIERef (DIEDedupeTopLevelRef Ref);
3116
3137
Error visitDIERef (ArrayRef<DIEDataRef> &DIEChildrenStack);
3117
- Error visitDIEAttrs (AbbrevEntryReader &AbbrevReader,
3118
- BinaryStreamReader &Reader, StringRef DIEData);
3138
+ Error visitDIEAttrs (BinaryStreamReader &DataReader, StringRef DIEData,
3139
+ ArrayRef<AbbrevContent> DIEContents);
3140
+ Error materializeAbbrevDIE (unsigned AbbrevIdx);
3119
3141
3120
3142
SmallVector<AbbrevEntry> AbbrevEntryCache;
3121
3143
ArrayRef<StringRef> AbbrevEntries;
@@ -3130,38 +3152,31 @@ struct DIEVisitor {
3130
3152
std::function<void (StringRef)> NewBlockCallback;
3131
3153
};
3132
3154
3133
- Error DIEVisitor::visitDIEAttrs (AbbrevEntryReader &AbbrevReader ,
3134
- BinaryStreamReader &DataReader ,
3135
- StringRef DIEData ) {
3155
+ Error DIEVisitor::visitDIEAttrs (BinaryStreamReader &DataReader ,
3156
+ StringRef DIEData ,
3157
+ ArrayRef<AbbrevContent> DIEContents ) {
3136
3158
constexpr auto IsLittleEndian = true ;
3137
3159
constexpr auto AddrSize = 8 ;
3138
3160
constexpr auto FormParams =
3139
3161
dwarf::FormParams{4 /* Version*/ , AddrSize, dwarf::DwarfFormat::DWARF32};
3140
3162
3141
- while (true ) {
3142
- Expected<dwarf::Attribute> Attr = AbbrevReader.readAttr ();
3143
- if (!Attr)
3144
- return Attr.takeError ();
3145
- if (*Attr == getEndOfAttributesMarker ())
3146
- break ;
3147
-
3148
- Expected<dwarf::Form> Form = AbbrevReader.readForm ();
3149
- if (!Form)
3150
- return Form.takeError ();
3151
-
3152
- bool DataInDistinct = doesntDedup (*Form, *Attr);
3163
+ for (auto Contents : DIEContents) {
3164
+ bool DataInDistinct = Contents.FormInDistinctData ;
3153
3165
auto &ReaderForData = DataInDistinct ? DistinctReader : DataReader;
3154
3166
StringRef DataToUse = DataInDistinct ? DistinctData : DIEData;
3155
3167
Expected<uint64_t > FormSize =
3156
- getFormSize (*Form, FormParams, DataToUse, ReaderForData.getOffset (),
3157
- IsLittleEndian, AddrSize);
3168
+ Contents.FormSize
3169
+ ? *Contents.FormSize
3170
+ : getFormSize (Contents.Form , FormParams, DataToUse,
3171
+ ReaderForData.getOffset (), IsLittleEndian, AddrSize);
3158
3172
if (!FormSize)
3159
3173
return FormSize.takeError ();
3160
3174
3161
3175
ArrayRef<char > RawBytes;
3162
3176
if (auto E = ReaderForData.readArray (RawBytes, *FormSize))
3163
3177
return E;
3164
- AttrCallback (*Attr, *Form, toStringRef (RawBytes), DataInDistinct);
3178
+ AttrCallback (Contents.Attr , Contents.Form , toStringRef (RawBytes),
3179
+ DataInDistinct);
3165
3180
}
3166
3181
return Error::success ();
3167
3182
}
@@ -3180,6 +3195,111 @@ static AbbrevEntryReader getAbbrevEntryReader(ArrayRef<StringRef> AbbrevEntries,
3180
3195
return AbbrevEntryReader (AbbrevData);
3181
3196
}
3182
3197
3198
+ static std::optional<uint8_t > getNonULEBFormSize (dwarf::Form Form,
3199
+ dwarf::FormParams FP) {
3200
+ switch (Form) {
3201
+ case dwarf::DW_FORM_addr:
3202
+ return FP.AddrSize ;
3203
+ case dwarf::DW_FORM_ref_addr:
3204
+ return FP.getRefAddrByteSize ();
3205
+ case dwarf::DW_FORM_exprloc:
3206
+ case dwarf::DW_FORM_block:
3207
+ case dwarf::DW_FORM_block1:
3208
+ case dwarf::DW_FORM_block2:
3209
+ case dwarf::DW_FORM_block4:
3210
+ case dwarf::DW_FORM_sdata:
3211
+ case dwarf::DW_FORM_udata:
3212
+ case dwarf::DW_FORM_ref_udata:
3213
+ case dwarf::DW_FORM_ref4_cas:
3214
+ case dwarf::DW_FORM_strp_cas:
3215
+ case dwarf::DW_FORM_rnglistx:
3216
+ case dwarf::DW_FORM_loclistx:
3217
+ case dwarf::DW_FORM_GNU_addr_index:
3218
+ case dwarf::DW_FORM_GNU_str_index:
3219
+ case dwarf::DW_FORM_addrx:
3220
+ case dwarf::DW_FORM_strx:
3221
+ case dwarf::DW_FORM_LLVM_addrx_offset:
3222
+ case dwarf::DW_FORM_string:
3223
+ case dwarf::DW_FORM_indirect:
3224
+ return std::nullopt;
3225
+
3226
+ case dwarf::DW_FORM_implicit_const:
3227
+ case dwarf::DW_FORM_flag_present:
3228
+ return 0 ;
3229
+ case dwarf::DW_FORM_data1:
3230
+ case dwarf::DW_FORM_ref1:
3231
+ case dwarf::DW_FORM_flag:
3232
+ case dwarf::DW_FORM_strx1:
3233
+ case dwarf::DW_FORM_addrx1:
3234
+ return 1 ;
3235
+ case dwarf::DW_FORM_data2:
3236
+ case dwarf::DW_FORM_ref2:
3237
+ case dwarf::DW_FORM_strx2:
3238
+ case dwarf::DW_FORM_addrx2:
3239
+ return 2 ;
3240
+ case dwarf::DW_FORM_strx3:
3241
+ return 3 ;
3242
+ case dwarf::DW_FORM_data4:
3243
+ case dwarf::DW_FORM_ref4:
3244
+ case dwarf::DW_FORM_ref_sup4:
3245
+ case dwarf::DW_FORM_strx4:
3246
+ case dwarf::DW_FORM_addrx4:
3247
+ return 4 ;
3248
+ case dwarf::DW_FORM_ref_sig8:
3249
+ case dwarf::DW_FORM_data8:
3250
+ case dwarf::DW_FORM_ref8:
3251
+ case dwarf::DW_FORM_ref_sup8:
3252
+ return 8 ;
3253
+ case dwarf::DW_FORM_data16:
3254
+ return 16 ;
3255
+ case dwarf::DW_FORM_strp:
3256
+ case dwarf::DW_FORM_sec_offset:
3257
+ case dwarf::DW_FORM_GNU_ref_alt:
3258
+ case dwarf::DW_FORM_GNU_strp_alt:
3259
+ case dwarf::DW_FORM_line_strp:
3260
+ case dwarf::DW_FORM_strp_sup:
3261
+ return FP.getDwarfOffsetByteSize ();
3262
+ case dwarf::DW_FORM_addrx3:
3263
+ case dwarf::DW_FORM_lo_user:
3264
+ llvm_unreachable (" usupported form" );
3265
+ break ;
3266
+ }
3267
+ }
3268
+
3269
+ Error DIEVisitor::materializeAbbrevDIE (unsigned AbbrevIdx) {
3270
+ constexpr auto AddrSize = 8 ;
3271
+ constexpr auto FormParams =
3272
+ dwarf::FormParams{4 /* Version*/ , AddrSize, dwarf::DwarfFormat::DWARF32};
3273
+
3274
+ AbbrevEntryReader AbbrevReader =
3275
+ getAbbrevEntryReader (AbbrevEntries, AbbrevIdx);
3276
+ Expected<dwarf::Tag> MaybeTag = AbbrevReader.readTag ();
3277
+ if (!MaybeTag)
3278
+ return MaybeTag.takeError ();
3279
+
3280
+ Expected<bool > MaybeHasChildren = AbbrevReader.readHasChildren ();
3281
+ if (!MaybeHasChildren)
3282
+ return MaybeHasChildren.takeError ();
3283
+
3284
+ SmallVector<AbbrevContent> AbbrevVector;
3285
+ while (true ) {
3286
+ Expected<dwarf::Attribute> Attr = AbbrevReader.readAttr ();
3287
+ if (!Attr)
3288
+ return Attr.takeError ();
3289
+ if (*Attr == getEndOfAttributesMarker ())
3290
+ break ;
3291
+
3292
+ Expected<dwarf::Form> Form = AbbrevReader.readForm ();
3293
+ if (!Form)
3294
+ return Form.takeError ();
3295
+ AbbrevVector.push_back ({*Attr, *Form, doesntDedup (*Form, *Attr),
3296
+ getNonULEBFormSize (*Form, FormParams)});
3297
+ }
3298
+ AbbrevEntryCache.push_back (
3299
+ {*MaybeTag, *MaybeHasChildren, std::move (AbbrevVector)});
3300
+ return Error::success ();
3301
+ }
3302
+
3183
3303
// / Restores the state of the \p Reader and \p Data
3184
3304
// / arguments to a previous state. The algorithm in visitDIERefs is an iterative
3185
3305
// / implementation of a Depth First Search, and this function is used to
@@ -3232,25 +3352,18 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
3232
3352
}
3233
3353
3234
3354
// If we have a legitimate AbbrevIdx, materialize the current DIE.
3235
- AbbrevEntryReader AbbrevReader =
3236
- getAbbrevEntryReader (AbbrevEntries, AbbrevIdx);
3237
-
3238
- if (Expected<dwarf::Tag> MaybeTag = AbbrevReader.readTag ())
3239
- StartTagCallback (*MaybeTag, AbbrevIdx);
3240
- else
3241
- return MaybeTag.takeError ();
3242
-
3243
- Expected<bool > MaybeHasChildren = AbbrevReader.readHasChildren ();
3244
- if (!MaybeHasChildren)
3245
- return MaybeHasChildren.takeError ();
3355
+ auto &AbbrevEntryCacheVal =
3356
+ AbbrevEntryCache[decodeAbbrevIndexAsAbbrevSetIdx (AbbrevIdx)];
3357
+ StartTagCallback (AbbrevEntryCacheVal.Tag , AbbrevIdx);
3246
3358
3247
- if (auto E = visitDIEAttrs (AbbrevReader, Reader, Data))
3359
+ if (auto E =
3360
+ visitDIEAttrs (Reader, Data, AbbrevEntryCacheVal.AbbrevContents ))
3248
3361
return E;
3249
3362
3250
3363
// If the current DIE doesn't have any children, the current CAS Object will
3251
3364
// not contain any more data, pop the stack to continue materializing its
3252
3365
// parent's siblings that may exist.
3253
- if (!*MaybeHasChildren ) {
3366
+ if (!AbbrevEntryCacheVal. HasChildren ) {
3254
3367
if (!StackOfNodes.empty () && Reader.empty ())
3255
3368
popStack (Reader, Data, StackOfNodes);
3256
3369
EndTagCallback (false /* HadChildren*/ );
@@ -3322,8 +3435,8 @@ Error mccasformats::v1::visitDebugInfo(
3322
3435
HeaderCallback (toStringRef (HeaderData));
3323
3436
3324
3437
append_range (TotAbbrevEntries, LoadedTopRef->AbbrevEntries );
3325
- DIEVisitor Visitor{{}, TotAbbrevEntries, DistinctReader ,
3326
- DistinctData, HeaderCallback, StartTagCallback,
3327
- AttrCallback, EndTagCallback, NewBlockCallback};
3438
+ DIEVisitor Visitor{TotAbbrevEntries, DistinctReader, DistinctData ,
3439
+ HeaderCallback, StartTagCallback, AttrCallback ,
3440
+ EndTagCallback, NewBlockCallback};
3328
3441
return Visitor.visitDIERef (LoadedTopRef->RootDIE );
3329
3442
}
0 commit comments