Home | History | Annotate | Download | only in DWARF
      1 //===- DWARFFormValue.h -----------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H
     11 #define LLVM_DEBUGINFO_DWARFFORMVALUE_H
     12 
     13 #include "llvm/ADT/ArrayRef.h"
     14 #include "llvm/ADT/None.h"
     15 #include "llvm/ADT/Optional.h"
     16 #include "llvm/BinaryFormat/Dwarf.h"
     17 #include "llvm/DebugInfo/DIContext.h"
     18 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
     19 #include <cstdint>
     20 
     21 namespace llvm {
     22 
     23 class DWARFUnit;
     24 class raw_ostream;
     25 
     26 /// A helper struct for DWARFFormValue methods, providing information that
     27 /// allows it to know the byte size of DW_FORM values that vary in size
     28 /// depending on the DWARF version, address byte size, or DWARF32/DWARF64.
     29 struct DWARFFormParams {
     30   uint16_t Version;
     31   uint8_t AddrSize;
     32   dwarf::DwarfFormat Format;
     33 
     34   /// The definition of the size of form DW_FORM_ref_addr depends on the
     35   /// version. In DWARF v2 it's the size of an address; after that, it's the
     36   /// size of a reference.
     37   uint8_t getRefAddrByteSize() const {
     38     if (Version == 2)
     39       return AddrSize;
     40     return getDwarfOffsetByteSize();
     41   }
     42 
     43   /// The size of a reference is determined by the DWARF 32/64-bit format.
     44   uint8_t getDwarfOffsetByteSize() const {
     45     switch (Format) {
     46     case dwarf::DwarfFormat::DWARF32:
     47       return 4;
     48     case dwarf::DwarfFormat::DWARF64:
     49       return 8;
     50     }
     51     llvm_unreachable("Invalid Format value");
     52   }
     53 };
     54 
     55 class DWARFFormValue {
     56 public:
     57   enum FormClass {
     58     FC_Unknown,
     59     FC_Address,
     60     FC_Block,
     61     FC_Constant,
     62     FC_String,
     63     FC_Flag,
     64     FC_Reference,
     65     FC_Indirect,
     66     FC_SectionOffset,
     67     FC_Exprloc
     68   };
     69 
     70 private:
     71   struct ValueType {
     72     ValueType() { uval = 0; }
     73 
     74     union {
     75       uint64_t uval;
     76       int64_t sval;
     77       const char *cstr;
     78     };
     79     const uint8_t *data = nullptr;
     80     uint64_t SectionIndex;      /// Section index for reference forms.
     81   };
     82 
     83   dwarf::Form Form;             /// Form for this value.
     84   ValueType Value;              /// Contains all data for the form.
     85   const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
     86 
     87 public:
     88   DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
     89 
     90   dwarf::Form getForm() const { return Form; }
     91   uint64_t getRawUValue() const { return Value.uval; }
     92   uint64_t getSectionIndex() const { return Value.SectionIndex; }
     93   void setForm(dwarf::Form F) { Form = F; }
     94   void setUValue(uint64_t V) { Value.uval = V; }
     95   void setSValue(int64_t V) { Value.sval = V; }
     96   void setPValue(const char *V) { Value.cstr = V; }
     97 
     98   void setBlockValue(const ArrayRef<uint8_t> &Data) {
     99     Value.data = Data.data();
    100     setUValue(Data.size());
    101   }
    102 
    103   bool isFormClass(FormClass FC) const;
    104   const DWARFUnit *getUnit() const { return U; }
    105   void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const;
    106 
    107   /// Extracts a value in \p Data at offset \p *OffsetPtr.
    108   ///
    109   /// The passed DWARFUnit is allowed to be nullptr, in which case some
    110   /// kind of forms that depend on Unit information are disallowed.
    111   /// \param Data The DWARFDataExtractor to use.
    112   /// \param OffsetPtr The offset within \p Data where the data starts.
    113   /// \param U The optional DWARFUnit supplying information for some forms.
    114   /// \returns whether the extraction succeeded.
    115   bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr,
    116                     const DWARFUnit *U);
    117 
    118   bool isInlinedCStr() const {
    119     return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr;
    120   }
    121 
    122   /// getAsFoo functions below return the extracted value as Foo if only
    123   /// DWARFFormValue has form class is suitable for representing Foo.
    124   Optional<uint64_t> getAsReference() const;
    125   Optional<uint64_t> getAsUnsignedConstant() const;
    126   Optional<int64_t> getAsSignedConstant() const;
    127   Optional<const char *> getAsCString() const;
    128   Optional<uint64_t> getAsAddress() const;
    129   Optional<uint64_t> getAsSectionOffset() const;
    130   Optional<ArrayRef<uint8_t>> getAsBlock() const;
    131   Optional<uint64_t> getAsCStringOffset() const;
    132   Optional<uint64_t> getAsReferenceUVal() const;
    133 
    134   /// Get the fixed byte size for a given form.
    135   ///
    136   /// If the form has a fixed byte size, then an Optional with a value will be
    137   /// returned. If the form is always encoded using a variable length storage
    138   /// format (ULEB or SLEB numbers or blocks) then None will be returned.
    139   ///
    140   /// \param Form DWARF form to get the fixed byte size for.
    141   /// \param FormParams DWARF parameters to help interpret forms.
    142   /// \returns Optional<uint8_t> value with the fixed byte size or None if
    143   /// \p Form doesn't have a fixed byte size.
    144   static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
    145                                             const DWARFFormParams FormParams);
    146 
    147   /// Skip a form's value in \p DebugInfoData at the offset specified by
    148   /// \p OffsetPtr.
    149   ///
    150   /// Skips the bytes for the current form and updates the offset.
    151   ///
    152   /// \param DebugInfoData The data where we want to skip the value.
    153   /// \param OffsetPtr A reference to the offset that will be updated.
    154   /// \param Params DWARF parameters to help interpret forms.
    155   /// \returns true on success, false if the form was not skipped.
    156   bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
    157                  const DWARFFormParams Params) const {
    158     return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params);
    159   }
    160 
    161   /// Skip a form's value in \p DebugInfoData at the offset specified by
    162   /// \p OffsetPtr.
    163   ///
    164   /// Skips the bytes for the specified form and updates the offset.
    165   ///
    166   /// \param Form The DW_FORM enumeration that indicates the form to skip.
    167   /// \param DebugInfoData The data where we want to skip the value.
    168   /// \param OffsetPtr A reference to the offset that will be updated.
    169   /// \param FormParams DWARF parameters to help interpret forms.
    170   /// \returns true on success, false if the form was not skipped.
    171   static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
    172                         uint32_t *OffsetPtr, const DWARFFormParams FormParams);
    173 
    174 private:
    175   void dumpString(raw_ostream &OS) const;
    176 };
    177 
    178 namespace dwarf {
    179 
    180 /// Take an optional DWARFFormValue and try to extract a string value from it.
    181 ///
    182 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    183 /// \returns an optional value that contains a value if the form value
    184 /// was valid and was a string.
    185 inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) {
    186   if (V)
    187     return V->getAsCString();
    188   return None;
    189 }
    190 
    191 /// Take an optional DWARFFormValue and extract a string value from it.
    192 ///
    193 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    194 /// \param Default the default value to return in case of failure.
    195 /// \returns the string value or Default if the V doesn't have a value or the
    196 /// form value's encoding wasn't a string.
    197 inline const char *toString(const Optional<DWARFFormValue> &V,
    198                             const char *Default) {
    199   return toString(V).getValueOr(Default);
    200 }
    201 
    202 /// Take an optional DWARFFormValue and try to extract an unsigned constant.
    203 ///
    204 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    205 /// \returns an optional value that contains a value if the form value
    206 /// was valid and has a unsigned constant form.
    207 inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) {
    208   if (V)
    209     return V->getAsUnsignedConstant();
    210   return None;
    211 }
    212 
    213 /// Take an optional DWARFFormValue and extract a unsigned constant.
    214 ///
    215 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    216 /// \param Default the default value to return in case of failure.
    217 /// \returns the extracted unsigned value or Default if the V doesn't have a
    218 /// value or the form value's encoding wasn't an unsigned constant form.
    219 inline uint64_t toUnsigned(const Optional<DWARFFormValue> &V,
    220                            uint64_t Default) {
    221   return toUnsigned(V).getValueOr(Default);
    222 }
    223 
    224 /// Take an optional DWARFFormValue and try to extract an reference.
    225 ///
    226 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    227 /// \returns an optional value that contains a value if the form value
    228 /// was valid and has a reference form.
    229 inline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) {
    230   if (V)
    231     return V->getAsReference();
    232   return None;
    233 }
    234 
    235 /// Take an optional DWARFFormValue and extract a reference.
    236 ///
    237 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    238 /// \param Default the default value to return in case of failure.
    239 /// \returns the extracted reference value or Default if the V doesn't have a
    240 /// value or the form value's encoding wasn't a reference form.
    241 inline uint64_t toReference(const Optional<DWARFFormValue> &V,
    242                             uint64_t Default) {
    243   return toReference(V).getValueOr(Default);
    244 }
    245 
    246 /// Take an optional DWARFFormValue and try to extract an signed constant.
    247 ///
    248 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    249 /// \returns an optional value that contains a value if the form value
    250 /// was valid and has a signed constant form.
    251 inline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) {
    252   if (V)
    253     return V->getAsSignedConstant();
    254   return None;
    255 }
    256 
    257 /// Take an optional DWARFFormValue and extract a signed integer.
    258 ///
    259 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    260 /// \param Default the default value to return in case of failure.
    261 /// \returns the extracted signed integer value or Default if the V doesn't
    262 /// have a value or the form value's encoding wasn't a signed integer form.
    263 inline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) {
    264   return toSigned(V).getValueOr(Default);
    265 }
    266 
    267 /// Take an optional DWARFFormValue and try to extract an address.
    268 ///
    269 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    270 /// \returns an optional value that contains a value if the form value
    271 /// was valid and has a address form.
    272 inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) {
    273   if (V)
    274     return V->getAsAddress();
    275   return None;
    276 }
    277 
    278 /// Take an optional DWARFFormValue and extract a address.
    279 ///
    280 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    281 /// \param Default the default value to return in case of failure.
    282 /// \returns the extracted address value or Default if the V doesn't have a
    283 /// value or the form value's encoding wasn't an address form.
    284 inline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) {
    285   return toAddress(V).getValueOr(Default);
    286 }
    287 
    288 /// Take an optional DWARFFormValue and try to extract an section offset.
    289 ///
    290 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    291 /// \returns an optional value that contains a value if the form value
    292 /// was valid and has a section offset form.
    293 inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) {
    294   if (V)
    295     return V->getAsSectionOffset();
    296   return None;
    297 }
    298 
    299 /// Take an optional DWARFFormValue and extract a section offset.
    300 ///
    301 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    302 /// \param Default the default value to return in case of failure.
    303 /// \returns the extracted section offset value or Default if the V doesn't
    304 /// have a value or the form value's encoding wasn't a section offset form.
    305 inline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V,
    306                                 uint64_t Default) {
    307   return toSectionOffset(V).getValueOr(Default);
    308 }
    309 
    310 /// Take an optional DWARFFormValue and try to extract block data.
    311 ///
    312 /// \param V and optional DWARFFormValue to attempt to extract the value from.
    313 /// \returns an optional value that contains a value if the form value
    314 /// was valid and has a block form.
    315 inline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) {
    316   if (V)
    317     return V->getAsBlock();
    318   return None;
    319 }
    320 
    321 } // end namespace dwarf
    322 
    323 } // end namespace llvm
    324 
    325 #endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H
    326