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