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