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