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. DataExtractor(StringRef Data,bool IsLittleEndian,uint8_t AddressSize)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. getData()31 StringRef getData() const { return Data; } 32 /// \brief Get the endianess for this extractor. isLittleEndian()33 bool isLittleEndian() const { return IsLittleEndian; } 34 /// \brief Get the address size for this extractor. getAddressSize()35 uint8_t getAddressSize() const { return AddressSize; } 36 /// \brief Set the address size for this extractor. setAddressSize(uint8_t Size)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. getAddress(uint32_t * offset_ptr)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. isValidOffset(uint32_t offset)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. isValidOffsetForDataOfSize(uint32_t offset,uint32_t length)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. isValidOffsetForAddress(uint32_t offset)358 bool isValidOffsetForAddress(uint32_t offset) const { 359 return isValidOffsetForDataOfSize(offset, AddressSize); 360 } 361 }; 362 363 } // namespace llvm 364 365 #endif 366