Home | History | Annotate | Download | only in Support
      1 //===-- DataExtractor.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_SUPPORT_DATAEXTRACTOR_H
     11 #define LLVM_SUPPORT_DATAEXTRACTOR_H
     12 
     13 #include "llvm/ADT/StringRef.h"
     14 #include "llvm/Support/DataTypes.h"
     15 
     16 namespace llvm {
     17 class DataExtractor {
     18   StringRef Data;
     19   uint8_t IsLittleEndian;
     20   uint8_t AddressSize;
     21 public:
     22   /// Construct with a buffer that is owned by the caller.
     23   ///
     24   /// This constructor allows us to use data that is owned by the
     25   /// caller. The data must stay around as long as this object is
     26   /// valid.
     27   DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
     28     : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
     29 
     30   /// \brief Get the data pointed to by this extractor.
     31   StringRef getData() const { return Data; }
     32   /// \brief Get the endianess for this extractor.
     33   bool isLittleEndian() const { return IsLittleEndian; }
     34   /// \brief Get the address size for this extractor.
     35   uint8_t getAddressSize() const { return AddressSize; }
     36   /// \brief Set the address size for this extractor.
     37   void setAddressSize(uint8_t Size) { AddressSize = Size; }
     38 
     39   /// Extract a C string from \a *offset_ptr.
     40   ///
     41   /// Returns a pointer to a C String from the data at the offset
     42   /// pointed to by \a offset_ptr. A variable length NULL terminated C
     43   /// string will be extracted and the \a offset_ptr will be
     44   /// updated with the offset of the byte that follows the NULL
     45   /// terminator byte.
     46   ///
     47   /// @param[in,out] offset_ptr
     48   ///     A pointer to an offset within the data that will be advanced
     49   ///     by the appropriate number of bytes if the value is extracted
     50   ///     correctly. If the offset is out of bounds or there are not
     51   ///     enough bytes to extract this value, the offset will be left
     52   ///     unmodified.
     53   ///
     54   /// @return
     55   ///     A pointer to the C string value in the data. If the offset
     56   ///     pointed to by \a offset_ptr is out of bounds, or if the
     57   ///     offset plus the length of the C string is out of bounds,
     58   ///     NULL will be returned.
     59   const char *getCStr(uint32_t *offset_ptr) const;
     60 
     61   /// Extract an unsigned integer of size \a byte_size from \a
     62   /// *offset_ptr.
     63   ///
     64   /// Extract a single unsigned integer value and update the offset
     65   /// pointed to by \a offset_ptr. The size of the extracted integer
     66   /// is specified by the \a byte_size argument. \a byte_size should
     67   /// have a value greater than or equal to one and less than or equal
     68   /// to eight since the return value is 64 bits wide. Any
     69   /// \a byte_size values less than 1 or greater than 8 will result in
     70   /// nothing being extracted, and zero being returned.
     71   ///
     72   /// @param[in,out] offset_ptr
     73   ///     A pointer to an offset within the data that will be advanced
     74   ///     by the appropriate number of bytes if the value is extracted
     75   ///     correctly. If the offset is out of bounds or there are not
     76   ///     enough bytes to extract this value, the offset will be left
     77   ///     unmodified.
     78   ///
     79   /// @param[in] byte_size
     80   ///     The size in byte of the integer to extract.
     81   ///
     82   /// @return
     83   ///     The unsigned integer value that was extracted, or zero on
     84   ///     failure.
     85   uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const;
     86 
     87   /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
     88   ///
     89   /// Extract a single signed integer value (sign extending if required)
     90   /// and update the offset pointed to by \a offset_ptr. The size of
     91   /// the extracted integer is specified by the \a byte_size argument.
     92   /// \a byte_size should have a value greater than or equal to one
     93   /// and less than or equal to eight since the return value is 64
     94   /// bits wide. Any \a byte_size values less than 1 or greater than
     95   /// 8 will result in nothing being extracted, and zero being returned.
     96   ///
     97   /// @param[in,out] offset_ptr
     98   ///     A pointer to an offset within the data that will be advanced
     99   ///     by the appropriate number of bytes if the value is extracted
    100   ///     correctly. If the offset is out of bounds or there are not
    101   ///     enough bytes to extract this value, the offset will be left
    102   ///     unmodified.
    103   ///
    104   /// @param[in] size
    105   ///     The size in bytes of the integer to extract.
    106   ///
    107   /// @return
    108   ///     The sign extended signed integer value that was extracted,
    109   ///     or zero on failure.
    110   int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const;
    111 
    112   //------------------------------------------------------------------
    113   /// Extract an pointer from \a *offset_ptr.
    114   ///
    115   /// Extract a single pointer from the data and update the offset
    116   /// pointed to by \a offset_ptr. The size of the extracted pointer
    117   /// is \a getAddressSize(), so the address size has to be
    118   /// set correctly prior to extracting any pointer values.
    119   ///
    120   /// @param[in,out] offset_ptr
    121   ///     A pointer to an offset within the data that will be advanced
    122   ///     by the appropriate number of bytes if the value is extracted
    123   ///     correctly. If the offset is out of bounds or there are not
    124   ///     enough bytes to extract this value, the offset will be left
    125   ///     unmodified.
    126   ///
    127   /// @return
    128   ///     The extracted pointer value as a 64 integer.
    129   uint64_t getAddress(uint32_t *offset_ptr) const {
    130     return getUnsigned(offset_ptr, AddressSize);
    131   }
    132 
    133   /// Extract a uint8_t value from \a *offset_ptr.
    134   ///
    135   /// Extract a single uint8_t from the binary data at the offset
    136   /// pointed to by \a offset_ptr, and advance the offset on success.
    137   ///
    138   /// @param[in,out] offset_ptr
    139   ///     A pointer to an offset within the data that will be advanced
    140   ///     by the appropriate number of bytes if the value is extracted
    141   ///     correctly. If the offset is out of bounds or there are not
    142   ///     enough bytes to extract this value, the offset will be left
    143   ///     unmodified.
    144   ///
    145   /// @return
    146   ///     The extracted uint8_t value.
    147   uint8_t getU8(uint32_t *offset_ptr) const;
    148 
    149   /// Extract \a count uint8_t values from \a *offset_ptr.
    150   ///
    151   /// Extract \a count uint8_t values from the binary data at the
    152   /// offset pointed to by \a offset_ptr, and advance the offset on
    153   /// success. The extracted values are copied into \a dst.
    154   ///
    155   /// @param[in,out] offset_ptr
    156   ///     A pointer to an offset within the data that will be advanced
    157   ///     by the appropriate number of bytes if the value is extracted
    158   ///     correctly. If the offset is out of bounds or there are not
    159   ///     enough bytes to extract this value, the offset will be left
    160   ///     unmodified.
    161   ///
    162   /// @param[out] dst
    163   ///     A buffer to copy \a count uint8_t values into. \a dst must
    164   ///     be large enough to hold all requested data.
    165   ///
    166   /// @param[in] count
    167   ///     The number of uint8_t values to extract.
    168   ///
    169   /// @return
    170   ///     \a dst if all values were properly extracted and copied,
    171   ///     NULL otherise.
    172   uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const;
    173 
    174   //------------------------------------------------------------------
    175   /// Extract a uint16_t value from \a *offset_ptr.
    176   ///
    177   /// Extract a single uint16_t from the binary data at the offset
    178   /// pointed to by \a offset_ptr, and update the offset on success.
    179   ///
    180   /// @param[in,out] offset_ptr
    181   ///     A pointer to an offset within the data that will be advanced
    182   ///     by the appropriate number of bytes if the value is extracted
    183   ///     correctly. If the offset is out of bounds or there are not
    184   ///     enough bytes to extract this value, the offset will be left
    185   ///     unmodified.
    186   ///
    187   /// @return
    188   ///     The extracted uint16_t value.
    189   //------------------------------------------------------------------
    190   uint16_t getU16(uint32_t *offset_ptr) const;
    191 
    192   /// Extract \a count uint16_t values from \a *offset_ptr.
    193   ///
    194   /// Extract \a count uint16_t values from the binary data at the
    195   /// offset pointed to by \a offset_ptr, and advance the offset on
    196   /// success. The extracted values are copied into \a dst.
    197   ///
    198   /// @param[in,out] offset_ptr
    199   ///     A pointer to an offset within the data that will be advanced
    200   ///     by the appropriate number of bytes if the value is extracted
    201   ///     correctly. If the offset is out of bounds or there are not
    202   ///     enough bytes to extract this value, the offset will be left
    203   ///     unmodified.
    204   ///
    205   /// @param[out] dst
    206   ///     A buffer to copy \a count uint16_t values into. \a dst must
    207   ///     be large enough to hold all requested data.
    208   ///
    209   /// @param[in] count
    210   ///     The number of uint16_t values to extract.
    211   ///
    212   /// @return
    213   ///     \a dst if all values were properly extracted and copied,
    214   ///     NULL otherise.
    215   uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
    216 
    217   /// Extract a uint32_t value from \a *offset_ptr.
    218   ///
    219   /// Extract a single uint32_t from the binary data at the offset
    220   /// pointed to by \a offset_ptr, and update the offset on success.
    221   ///
    222   /// @param[in,out] offset_ptr
    223   ///     A pointer to an offset within the data that will be advanced
    224   ///     by the appropriate number of bytes if the value is extracted
    225   ///     correctly. If the offset is out of bounds or there are not
    226   ///     enough bytes to extract this value, the offset will be left
    227   ///     unmodified.
    228   ///
    229   /// @return
    230   ///     The extracted uint32_t value.
    231   uint32_t getU32(uint32_t *offset_ptr) const;
    232 
    233   /// Extract \a count uint32_t values from \a *offset_ptr.
    234   ///
    235   /// Extract \a count uint32_t values from the binary data at the
    236   /// offset pointed to by \a offset_ptr, and advance the offset on
    237   /// success. The extracted values are copied into \a dst.
    238   ///
    239   /// @param[in,out] offset_ptr
    240   ///     A pointer to an offset within the data that will be advanced
    241   ///     by the appropriate number of bytes if the value is extracted
    242   ///     correctly. If the offset is out of bounds or there are not
    243   ///     enough bytes to extract this value, the offset will be left
    244   ///     unmodified.
    245   ///
    246   /// @param[out] dst
    247   ///     A buffer to copy \a count uint32_t values into. \a dst must
    248   ///     be large enough to hold all requested data.
    249   ///
    250   /// @param[in] count
    251   ///     The number of uint32_t values to extract.
    252   ///
    253   /// @return
    254   ///     \a dst if all values were properly extracted and copied,
    255   ///     NULL otherise.
    256   uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const;
    257 
    258   /// Extract a uint64_t value from \a *offset_ptr.
    259   ///
    260   /// Extract a single uint64_t from the binary data at the offset
    261   /// pointed to by \a offset_ptr, and update the offset on success.
    262   ///
    263   /// @param[in,out] offset_ptr
    264   ///     A pointer to an offset within the data that will be advanced
    265   ///     by the appropriate number of bytes if the value is extracted
    266   ///     correctly. If the offset is out of bounds or there are not
    267   ///     enough bytes to extract this value, the offset will be left
    268   ///     unmodified.
    269   ///
    270   /// @return
    271   ///     The extracted uint64_t value.
    272   uint64_t getU64(uint32_t *offset_ptr) const;
    273 
    274   /// Extract \a count uint64_t values from \a *offset_ptr.
    275   ///
    276   /// Extract \a count uint64_t values from the binary data at the
    277   /// offset pointed to by \a offset_ptr, and advance the offset on
    278   /// success. The extracted values are copied into \a dst.
    279   ///
    280   /// @param[in,out] offset_ptr
    281   ///     A pointer to an offset within the data that will be advanced
    282   ///     by the appropriate number of bytes if the value is extracted
    283   ///     correctly. If the offset is out of bounds or there are not
    284   ///     enough bytes to extract this value, the offset will be left
    285   ///     unmodified.
    286   ///
    287   /// @param[out] dst
    288   ///     A buffer to copy \a count uint64_t values into. \a dst must
    289   ///     be large enough to hold all requested data.
    290   ///
    291   /// @param[in] count
    292   ///     The number of uint64_t values to extract.
    293   ///
    294   /// @return
    295   ///     \a dst if all values were properly extracted and copied,
    296   ///     NULL otherise.
    297   uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const;
    298 
    299   /// Extract a signed LEB128 value from \a *offset_ptr.
    300   ///
    301   /// Extracts an signed LEB128 number from this object's data
    302   /// starting at the offset pointed to by \a offset_ptr. The offset
    303   /// pointed to by \a offset_ptr will be updated with the offset of
    304   /// the byte following the last extracted byte.
    305   ///
    306   /// @param[in,out] offset_ptr
    307   ///     A pointer to an offset within the data that will be advanced
    308   ///     by the appropriate number of bytes if the value is extracted
    309   ///     correctly. If the offset is out of bounds or there are not
    310   ///     enough bytes to extract this value, the offset will be left
    311   ///     unmodified.
    312   ///
    313   /// @return
    314   ///     The extracted signed integer value.
    315   int64_t getSLEB128(uint32_t *offset_ptr) const;
    316 
    317   /// Extract a unsigned LEB128 value from \a *offset_ptr.
    318   ///
    319   /// Extracts an unsigned LEB128 number from this object's data
    320   /// starting at the offset pointed to by \a offset_ptr. The offset
    321   /// pointed to by \a offset_ptr will be updated with the offset of
    322   /// the byte following the last extracted byte.
    323   ///
    324   /// @param[in,out] offset_ptr
    325   ///     A pointer to an offset within the data that will be advanced
    326   ///     by the appropriate number of bytes if the value is extracted
    327   ///     correctly. If the offset is out of bounds or there are not
    328   ///     enough bytes to extract this value, the offset will be left
    329   ///     unmodified.
    330   ///
    331   /// @return
    332   ///     The extracted unsigned integer value.
    333   uint64_t getULEB128(uint32_t *offset_ptr) const;
    334 
    335   /// Test the validity of \a offset.
    336   ///
    337   /// @return
    338   ///     \b true if \a offset is a valid offset into the data in this
    339   ///     object, \b false otherwise.
    340   bool isValidOffset(uint32_t offset) const { return Data.size() > offset; }
    341 
    342   /// Test the availability of \a length bytes of data from \a offset.
    343   ///
    344   /// @return
    345   ///     \b true if \a offset is a valid offset and there are \a
    346   ///     length bytes available at that offset, \b false otherwise.
    347   bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
    348     return offset + length >= offset && isValidOffset(offset + length - 1);
    349   }
    350 
    351   /// Test the availability of enough bytes of data for a pointer from
    352   /// \a offset. The size of a pointer is \a getAddressSize().
    353   ///
    354   /// @return
    355   ///     \b true if \a offset is a valid offset and there are enough
    356   ///     bytes for a pointer available at that offset, \b false
    357   ///     otherwise.
    358   bool isValidOffsetForAddress(uint32_t offset) const {
    359     return isValidOffsetForDataOfSize(offset, AddressSize);
    360   }
    361 };
    362 
    363 } // namespace llvm
    364 
    365 #endif
    366