File indexing completed on 2026-05-10 08:43:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H
0010 #define LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H
0011
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/BinaryFormat/Dwarf.h"
0014 #include "llvm/DebugInfo/DIContext.h"
0015 #include "llvm/Support/DataExtractor.h"
0016 #include <cstdint>
0017
0018 namespace llvm {
0019
0020 class DWARFContext;
0021 class DWARFObject;
0022 class DWARFDataExtractor;
0023 class DWARFUnit;
0024 class raw_ostream;
0025
0026 class DWARFFormValue {
0027 public:
0028 enum FormClass {
0029 FC_Unknown,
0030 FC_Address,
0031 FC_Block,
0032 FC_Constant,
0033 FC_String,
0034 FC_Flag,
0035 FC_Reference,
0036 FC_Indirect,
0037 FC_SectionOffset,
0038 FC_Exprloc
0039 };
0040
0041 struct ValueType {
0042 ValueType() { uval = 0; }
0043 ValueType(int64_t V) : sval(V) {}
0044 ValueType(uint64_t V) : uval(V) {}
0045 ValueType(const char *V) : cstr(V) {}
0046
0047 union {
0048 uint64_t uval;
0049 int64_t sval;
0050 const char *cstr;
0051 };
0052 const uint8_t *data = nullptr;
0053 uint64_t SectionIndex;
0054 };
0055
0056 private:
0057 dwarf::Form Form;
0058 dwarf::DwarfFormat Format =
0059 dwarf::DWARF32;
0060 ValueType Value;
0061 const DWARFUnit *U = nullptr;
0062 const DWARFContext *C = nullptr;
0063
0064 DWARFFormValue(dwarf::Form F, const ValueType &V) : Form(F), Value(V) {}
0065
0066 public:
0067 DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
0068
0069 static DWARFFormValue createFromSValue(dwarf::Form F, int64_t V);
0070 static DWARFFormValue createFromUValue(dwarf::Form F, uint64_t V);
0071 static DWARFFormValue createFromPValue(dwarf::Form F, const char *V);
0072 static DWARFFormValue createFromBlockValue(dwarf::Form F,
0073 ArrayRef<uint8_t> D);
0074 static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit,
0075 uint64_t *OffsetPtr);
0076 static std::optional<object::SectionedAddress>
0077 getAsSectionedAddress(const ValueType &Val, const dwarf::Form Form,
0078 const DWARFUnit *U);
0079
0080 dwarf::Form getForm() const { return Form; }
0081 uint64_t getRawUValue() const { return Value.uval; }
0082
0083 bool isFormClass(FormClass FC) const;
0084 const DWARFUnit *getUnit() const { return U; }
0085 void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const;
0086 void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts,
0087 object::SectionedAddress SA) const;
0088 void dumpAddress(raw_ostream &OS, uint64_t Address) const;
0089 static void dumpAddress(raw_ostream &OS, uint8_t AddressSize,
0090 uint64_t Address);
0091 static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
0092 DIDumpOptions DumpOpts, uint64_t SectionIndex);
0093
0094
0095
0096
0097
0098 bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
0099 dwarf::FormParams FormParams,
0100 const DWARFContext *Context = nullptr,
0101 const DWARFUnit *Unit = nullptr);
0102
0103 bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
0104 dwarf::FormParams FormParams, const DWARFUnit *U) {
0105 return extractValue(Data, OffsetPtr, FormParams, nullptr, U);
0106 }
0107
0108
0109
0110 std::optional<uint64_t> getAsRelativeReference() const;
0111 std::optional<uint64_t> getAsDebugInfoReference() const;
0112 std::optional<uint64_t> getAsSignatureReference() const;
0113 std::optional<uint64_t> getAsSupplementaryReference() const;
0114 std::optional<uint64_t> getAsUnsignedConstant() const;
0115 std::optional<int64_t> getAsSignedConstant() const;
0116 Expected<const char *> getAsCString() const;
0117 std::optional<uint64_t> getAsAddress() const;
0118 std::optional<object::SectionedAddress> getAsSectionedAddress() const;
0119 std::optional<uint64_t> getAsSectionOffset() const;
0120 std::optional<ArrayRef<uint8_t>> getAsBlock() const;
0121 std::optional<uint64_t> getAsCStringOffset() const;
0122 std::optional<uint64_t> getAsReferenceUVal() const;
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 std::optional<std::string>
0135 getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const;
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr,
0147 const dwarf::FormParams Params) const {
0148 return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params);
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
0162 uint64_t *OffsetPtr,
0163 const dwarf::FormParams FormParams);
0164
0165 private:
0166 void dumpString(raw_ostream &OS) const;
0167 };
0168
0169 namespace dwarf {
0170
0171
0172
0173
0174
0175
0176 inline std::optional<const char *>
0177 toString(const std::optional<DWARFFormValue> &V) {
0178 if (!V)
0179 return std::nullopt;
0180 Expected<const char*> E = V->getAsCString();
0181 if (!E) {
0182 consumeError(E.takeError());
0183 return std::nullopt;
0184 }
0185 return *E;
0186 }
0187
0188
0189
0190
0191
0192
0193 inline StringRef toStringRef(const std::optional<DWARFFormValue> &V,
0194 StringRef Default = {}) {
0195 if (!V)
0196 return Default;
0197 auto S = V->getAsCString();
0198 if (!S) {
0199 consumeError(S.takeError());
0200 return Default;
0201 }
0202 if (!*S)
0203 return Default;
0204 return *S;
0205 }
0206
0207
0208
0209
0210
0211
0212
0213 inline const char *toString(const std::optional<DWARFFormValue> &V,
0214 const char *Default) {
0215 if (auto E = toString(V))
0216 return *E;
0217 return Default;
0218 }
0219
0220
0221
0222
0223
0224
0225 inline std::optional<uint64_t>
0226 toUnsigned(const std::optional<DWARFFormValue> &V) {
0227 if (V)
0228 return V->getAsUnsignedConstant();
0229 return std::nullopt;
0230 }
0231
0232
0233
0234
0235
0236
0237
0238 inline uint64_t toUnsigned(const std::optional<DWARFFormValue> &V,
0239 uint64_t Default) {
0240 return toUnsigned(V).value_or(Default);
0241 }
0242
0243
0244
0245
0246
0247
0248
0249 inline std::optional<uint64_t>
0250 toRelativeReference(const std::optional<DWARFFormValue> &V) {
0251 if (V)
0252 return V->getAsRelativeReference();
0253 return std::nullopt;
0254 }
0255
0256
0257
0258
0259
0260
0261
0262 inline uint64_t toRelativeReference(const std::optional<DWARFFormValue> &V,
0263 uint64_t Default) {
0264 return toRelativeReference(V).value_or(Default);
0265 }
0266
0267
0268
0269
0270
0271
0272
0273 inline std::optional<uint64_t>
0274 toDebugInfoReference(const std::optional<DWARFFormValue> &V) {
0275 if (V)
0276 return V->getAsDebugInfoReference();
0277 return std::nullopt;
0278 }
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288 inline uint64_t toDebugInfoReference(const std::optional<DWARFFormValue> &V,
0289 uint64_t Default) {
0290 return toDebugInfoReference(V).value_or(Default);
0291 }
0292
0293
0294
0295
0296
0297
0298 inline std::optional<uint64_t>
0299 toSignatureReference(const std::optional<DWARFFormValue> &V) {
0300 if (V)
0301 return V->getAsSignatureReference();
0302 return std::nullopt;
0303 }
0304
0305
0306
0307
0308
0309
0310
0311 inline uint64_t toSignatureReference(const std::optional<DWARFFormValue> &V,
0312 uint64_t Default) {
0313 return toSignatureReference(V).value_or(Default);
0314 }
0315
0316
0317
0318
0319
0320
0321
0322 inline std::optional<uint64_t>
0323 toSupplementaryReference(const std::optional<DWARFFormValue> &V) {
0324 if (V)
0325 return V->getAsSupplementaryReference();
0326 return std::nullopt;
0327 }
0328
0329
0330
0331
0332
0333
0334
0335
0336 inline uint64_t toSupplementaryReference(const std::optional<DWARFFormValue> &V,
0337 uint64_t Default) {
0338 return toSupplementaryReference(V).value_or(Default);
0339 }
0340
0341
0342
0343
0344
0345
0346 inline std::optional<int64_t> toSigned(const std::optional<DWARFFormValue> &V) {
0347 if (V)
0348 return V->getAsSignedConstant();
0349 return std::nullopt;
0350 }
0351
0352
0353
0354
0355
0356
0357
0358 inline int64_t toSigned(const std::optional<DWARFFormValue> &V,
0359 int64_t Default) {
0360 return toSigned(V).value_or(Default);
0361 }
0362
0363
0364
0365
0366
0367
0368 inline std::optional<uint64_t>
0369 toAddress(const std::optional<DWARFFormValue> &V) {
0370 if (V)
0371 return V->getAsAddress();
0372 return std::nullopt;
0373 }
0374
0375 inline std::optional<object::SectionedAddress>
0376 toSectionedAddress(const std::optional<DWARFFormValue> &V) {
0377 if (V)
0378 return V->getAsSectionedAddress();
0379 return std::nullopt;
0380 }
0381
0382
0383
0384
0385
0386
0387
0388 inline uint64_t toAddress(const std::optional<DWARFFormValue> &V,
0389 uint64_t Default) {
0390 return toAddress(V).value_or(Default);
0391 }
0392
0393
0394
0395
0396
0397
0398 inline std::optional<uint64_t>
0399 toSectionOffset(const std::optional<DWARFFormValue> &V) {
0400 if (V)
0401 return V->getAsSectionOffset();
0402 return std::nullopt;
0403 }
0404
0405
0406
0407
0408
0409
0410
0411 inline uint64_t toSectionOffset(const std::optional<DWARFFormValue> &V,
0412 uint64_t Default) {
0413 return toSectionOffset(V).value_or(Default);
0414 }
0415
0416
0417
0418
0419
0420
0421 inline std::optional<ArrayRef<uint8_t>>
0422 toBlock(const std::optional<DWARFFormValue> &V) {
0423 if (V)
0424 return V->getAsBlock();
0425 return std::nullopt;
0426 }
0427
0428
0429
0430
0431
0432
0433 bool doesFormBelongToClass(dwarf::Form Form, DWARFFormValue::FormClass FC,
0434 uint16_t DwarfVersion);
0435
0436 }
0437
0438 }
0439
0440 #endif