Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:41

0001 //===- DWARFFormValue.h -----------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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; /// Section index for reference forms.
0054   };
0055 
0056 private:
0057   dwarf::Form Form; /// Form for this value.
0058   dwarf::DwarfFormat Format =
0059       dwarf::DWARF32;           /// Remember the DWARF format at extract time.
0060   ValueType Value;              /// Contains all data for the form.
0061   const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
0062   const DWARFContext *C = nullptr; /// Context for extract time.
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   /// Extracts a value in \p Data at offset \p *OffsetPtr. The information
0095   /// in \p FormParams is needed to interpret some forms. The optional
0096   /// \p Context and \p Unit allows extracting information if the form refers
0097   /// to other sections (e.g., .debug_str).
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   /// getAsFoo functions below return the extracted value as Foo if only
0109   /// DWARFFormValue has form class is suitable for representing Foo.
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   /// Correctly extract any file paths from a form value.
0124   ///
0125   /// These attributes can be in the from DW_AT_decl_file or DW_AT_call_file
0126   /// attributes. We need to use the file index in the correct DWARFUnit's line
0127   /// table prologue, and each DWARFFormValue has the DWARFUnit the form value
0128   /// was extracted from.
0129   ///
0130   /// \param Kind The kind of path to extract.
0131   ///
0132   /// \returns A valid string value on success, or std::nullopt if the form
0133   /// class is not FC_Constant, or if the file index is not valid.
0134   std::optional<std::string>
0135   getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const;
0136 
0137   /// Skip a form's value in \p DebugInfoData at the offset specified by
0138   /// \p OffsetPtr.
0139   ///
0140   /// Skips the bytes for the current form and updates the offset.
0141   ///
0142   /// \param DebugInfoData The data where we want to skip the value.
0143   /// \param OffsetPtr A reference to the offset that will be updated.
0144   /// \param Params DWARF parameters to help interpret forms.
0145   /// \returns true on success, false if the form was not skipped.
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   /// Skip a form's value in \p DebugInfoData at the offset specified by
0152   /// \p OffsetPtr.
0153   ///
0154   /// Skips the bytes for the specified form and updates the offset.
0155   ///
0156   /// \param Form The DW_FORM enumeration that indicates the form to skip.
0157   /// \param DebugInfoData The data where we want to skip the value.
0158   /// \param OffsetPtr A reference to the offset that will be updated.
0159   /// \param FormParams DWARF parameters to help interpret forms.
0160   /// \returns true on success, false if the form was not skipped.
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 /// Take an optional DWARFFormValue and try to extract a string value from it.
0172 ///
0173 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0174 /// \returns an optional value that contains a value if the form value
0175 /// was valid and was a string.
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 /// Take an optional DWARFFormValue and try to extract a string value from it.
0189 ///
0190 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0191 /// \returns an optional value that contains a value if the form value
0192 /// was valid and was a string.
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 /// Take an optional DWARFFormValue and extract a string value from it.
0208 ///
0209 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0210 /// \param Default the default value to return in case of failure.
0211 /// \returns the string value or Default if the V doesn't have a value or the
0212 /// form value's encoding wasn't a string.
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 /// Take an optional DWARFFormValue and try to extract an unsigned constant.
0221 ///
0222 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0223 /// \returns an optional value that contains a value if the form value
0224 /// was valid and has a unsigned constant form.
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 /// Take an optional DWARFFormValue and extract a unsigned constant.
0233 ///
0234 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0235 /// \param Default the default value to return in case of failure.
0236 /// \returns the extracted unsigned value or Default if the V doesn't have a
0237 /// value or the form value's encoding wasn't an unsigned constant form.
0238 inline uint64_t toUnsigned(const std::optional<DWARFFormValue> &V,
0239                            uint64_t Default) {
0240   return toUnsigned(V).value_or(Default);
0241 }
0242 
0243 /// Take an optional DWARFFormValue and try to extract a relative offset
0244 /// reference.
0245 ///
0246 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0247 /// \returns an optional value that contains a value if the form value
0248 /// was valid and has a relative reference form.
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 /// Take an optional DWARFFormValue and extract a relative offset reference.
0257 ///
0258 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0259 /// \param Default the default value to return in case of failure.
0260 /// \returns the extracted reference value or Default if the V doesn't have a
0261 /// value or the form value's encoding wasn't a relative offset reference form.
0262 inline uint64_t toRelativeReference(const std::optional<DWARFFormValue> &V,
0263                                     uint64_t Default) {
0264   return toRelativeReference(V).value_or(Default);
0265 }
0266 
0267 /// Take an optional DWARFFormValue and try to extract an absolute debug info
0268 /// offset reference.
0269 ///
0270 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0271 /// \returns an optional value that contains a value if the form value
0272 /// was valid and has an (absolute) debug info offset reference form.
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 /// Take an optional DWARFFormValue and extract an absolute debug info offset
0281 /// reference.
0282 ///
0283 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0284 /// \param Default the default value to return in case of failure.
0285 /// \returns the extracted reference value or Default if the V doesn't have a
0286 /// value or the form value's encoding wasn't an absolute debug info offset
0287 /// reference form.
0288 inline uint64_t toDebugInfoReference(const std::optional<DWARFFormValue> &V,
0289                                      uint64_t Default) {
0290   return toDebugInfoReference(V).value_or(Default);
0291 }
0292 
0293 /// Take an optional DWARFFormValue and try to extract a signature reference.
0294 ///
0295 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0296 /// \returns an optional value that contains a value if the form value
0297 /// was valid and has a signature reference form.
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 /// Take an optional DWARFFormValue and extract a signature reference.
0306 ///
0307 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0308 /// \param Default the default value to return in case of failure.
0309 /// \returns the extracted reference value or Default if the V doesn't have a
0310 /// value or the form value's encoding wasn't a signature reference form.
0311 inline uint64_t toSignatureReference(const std::optional<DWARFFormValue> &V,
0312                                      uint64_t Default) {
0313   return toSignatureReference(V).value_or(Default);
0314 }
0315 
0316 /// Take an optional DWARFFormValue and try to extract a supplementary debug
0317 /// info reference.
0318 ///
0319 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0320 /// \returns an optional value that contains a value if the form value
0321 /// was valid and has a supplementary reference form.
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 /// Take an optional DWARFFormValue and extract a supplementary debug info
0330 /// reference.
0331 ///
0332 /// \param V an optional DWARFFormValue to attempt to extract the value from.
0333 /// \param Default the default value to return in case of failure.
0334 /// \returns the extracted reference value or Default if the V doesn't have a
0335 /// value or the form value's encoding wasn't a supplementary reference form.
0336 inline uint64_t toSupplementaryReference(const std::optional<DWARFFormValue> &V,
0337                                          uint64_t Default) {
0338   return toSupplementaryReference(V).value_or(Default);
0339 }
0340 
0341 /// Take an optional DWARFFormValue and try to extract an signed constant.
0342 ///
0343 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0344 /// \returns an optional value that contains a value if the form value
0345 /// was valid and has a signed constant form.
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 /// Take an optional DWARFFormValue and extract a signed integer.
0353 ///
0354 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0355 /// \param Default the default value to return in case of failure.
0356 /// \returns the extracted signed integer value or Default if the V doesn't
0357 /// have a value or the form value's encoding wasn't a signed integer form.
0358 inline int64_t toSigned(const std::optional<DWARFFormValue> &V,
0359                         int64_t Default) {
0360   return toSigned(V).value_or(Default);
0361 }
0362 
0363 /// Take an optional DWARFFormValue and try to extract an address.
0364 ///
0365 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0366 /// \returns an optional value that contains a value if the form value
0367 /// was valid and has a address form.
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 /// Take an optional DWARFFormValue and extract a address.
0383 ///
0384 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0385 /// \param Default the default value to return in case of failure.
0386 /// \returns the extracted address value or Default if the V doesn't have a
0387 /// value or the form value's encoding wasn't an address form.
0388 inline uint64_t toAddress(const std::optional<DWARFFormValue> &V,
0389                           uint64_t Default) {
0390   return toAddress(V).value_or(Default);
0391 }
0392 
0393 /// Take an optional DWARFFormValue and try to extract an section offset.
0394 ///
0395 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0396 /// \returns an optional value that contains a value if the form value
0397 /// was valid and has a section offset form.
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 /// Take an optional DWARFFormValue and extract a section offset.
0406 ///
0407 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0408 /// \param Default the default value to return in case of failure.
0409 /// \returns the extracted section offset value or Default if the V doesn't
0410 /// have a value or the form value's encoding wasn't a section offset form.
0411 inline uint64_t toSectionOffset(const std::optional<DWARFFormValue> &V,
0412                                 uint64_t Default) {
0413   return toSectionOffset(V).value_or(Default);
0414 }
0415 
0416 /// Take an optional DWARFFormValue and try to extract block data.
0417 ///
0418 /// \param V and optional DWARFFormValue to attempt to extract the value from.
0419 /// \returns an optional value that contains a value if the form value
0420 /// was valid and has a block form.
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 /// Check whether specified \p Form belongs to the \p FC class.
0429 /// \param Form an attribute form.
0430 /// \param FC an attribute form class to check.
0431 /// \param DwarfVersion the version of DWARF debug info keeping the attribute.
0432 /// \returns true if specified \p Form belongs to the \p FC class.
0433 bool doesFormBelongToClass(dwarf::Form Form, DWARFFormValue::FormClass FC,
0434                            uint16_t DwarfVersion);
0435 
0436 } // end namespace dwarf
0437 
0438 } // end namespace llvm
0439 
0440 #endif // LLVM_DEBUGINFO_DWARF_DWARFFORMVALUE_H