1 //===-- DataExtractor.h -----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_SUPPORT_DATAEXTRACTOR_H 10 #define LLVM_SUPPORT_DATAEXTRACTOR_H 11 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/Support/DataTypes.h" 14 #include "llvm/Support/Error.h" 15 16 namespace llvm { 17 18 /// An auxiliary type to facilitate extraction of 3-byte entities. 19 struct Uint24 { 20 uint8_t Bytes[3]; 21 Uint24(uint8_t U) { 22 Bytes[0] = Bytes[1] = Bytes[2] = U; 23 } 24 Uint24(uint8_t U0, uint8_t U1, uint8_t U2) { 25 Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2; 26 } 27 uint32_t getAsUint32(bool IsLittleEndian) const { 28 int LoIx = IsLittleEndian ? 0 : 2; 29 return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16); 30 } 31 }; 32 33 using uint24_t = Uint24; 34 static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3"); 35 36 /// Needed by swapByteOrder(). 37 inline uint24_t getSwappedBytes(uint24_t C) { 38 return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]); 39 } 40 41 class DataExtractor { 42 StringRef Data; 43 uint8_t IsLittleEndian; 44 uint8_t AddressSize; 45 public: 46 /// A class representing a position in a DataExtractor, as well as any error 47 /// encountered during extraction. It enables one to extract a sequence of 48 /// values without error-checking and then checking for errors in bulk at the 49 /// end. The class holds an Error object, so failing to check the result of 50 /// the parse will result in a runtime error. The error flag is sticky and 51 /// will cause all subsequent extraction functions to fail without even 52 /// attempting to parse and without updating the Cursor offset. After clearing 53 /// the error flag, one can again use the Cursor object for parsing. 54 class Cursor { 55 uint64_t Offset; 56 Error Err; 57 58 friend class DataExtractor; 59 60 public: 61 /// Construct a cursor for extraction from the given offset. 62 explicit Cursor(uint64_t Offset) : Offset(Offset), Err(Error::success()) {} 63 64 /// Checks whether the cursor is valid (i.e. no errors were encountered). In 65 /// case of errors, this does not clear the error flag -- one must call 66 /// takeError() instead. 67 explicit operator bool() { return !Err; } 68 69 /// Return the current position of this Cursor. In the error state this is 70 /// the position of the Cursor before the first error was encountered. 71 uint64_t tell() const { return Offset; } 72 73 /// Return error contained inside this Cursor, if any. Clears the internal 74 /// Cursor state. 75 Error takeError() { return std::move(Err); } 76 }; 77 78 /// Construct with a buffer that is owned by the caller. 79 /// 80 /// This constructor allows us to use data that is owned by the 81 /// caller. The data must stay around as long as this object is 82 /// valid. 83 DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize) 84 : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {} 85 DataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian, 86 uint8_t AddressSize) 87 : Data(StringRef(reinterpret_cast<const char *>(Data.data()), 88 Data.size())), 89 IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {} 90 91 /// Get the data pointed to by this extractor. 92 StringRef getData() const { return Data; } 93 /// Get the endianness for this extractor. 94 bool isLittleEndian() const { return IsLittleEndian; } 95 /// Get the address size for this extractor. 96 uint8_t getAddressSize() const { return AddressSize; } 97 /// Set the address size for this extractor. 98 void setAddressSize(uint8_t Size) { AddressSize = Size; } 99 100 /// Extract a C string from \a *offset_ptr. 101 /// 102 /// Returns a pointer to a C String from the data at the offset 103 /// pointed to by \a offset_ptr. A variable length NULL terminated C 104 /// string will be extracted and the \a offset_ptr will be 105 /// updated with the offset of the byte that follows the NULL 106 /// terminator byte. 107 /// 108 /// @param[in,out] OffsetPtr 109 /// A pointer to an offset within the data that will be advanced 110 /// by the appropriate number of bytes if the value is extracted 111 /// correctly. If the offset is out of bounds or there are not 112 /// enough bytes to extract this value, the offset will be left 113 /// unmodified. 114 /// 115 /// @param[in,out] Err 116 /// A pointer to an Error object. Upon return the Error object is set to 117 /// indicate the result (success/failure) of the function. If the Error 118 /// object is already set when calling this function, no extraction is 119 /// performed. 120 /// 121 /// @return 122 /// A pointer to the C string value in the data. If the offset 123 /// pointed to by \a offset_ptr is out of bounds, or if the 124 /// offset plus the length of the C string is out of bounds, 125 /// NULL will be returned. 126 const char *getCStr(uint64_t *OffsetPtr, Error *Err = nullptr) const { 127 return getCStrRef(OffsetPtr, Err).data(); 128 } 129 130 /// Extract a C string from the location given by the cursor. In case of an 131 /// extraction error, or if the cursor is already in an error state, a 132 /// nullptr is returned. 133 const char *getCStr(Cursor &C) const { return getCStrRef(C).data(); } 134 135 /// Extract a C string from \a *offset_ptr. 136 /// 137 /// Returns a StringRef for the C String from the data at the offset 138 /// pointed to by \a offset_ptr. A variable length NULL terminated C 139 /// string will be extracted and the \a offset_ptr will be 140 /// updated with the offset of the byte that follows the NULL 141 /// terminator byte. 142 /// 143 /// \param[in,out] OffsetPtr 144 /// A pointer to an offset within the data that will be advanced 145 /// by the appropriate number of bytes if the value is extracted 146 /// correctly. If the offset is out of bounds or there are not 147 /// enough bytes to extract this value, the offset will be left 148 /// unmodified. 149 /// 150 /// @param[in,out] Err 151 /// A pointer to an Error object. Upon return the Error object is set to 152 /// indicate the result (success/failure) of the function. If the Error 153 /// object is already set when calling this function, no extraction is 154 /// performed. 155 /// 156 /// \return 157 /// A StringRef for the C string value in the data. If the offset 158 /// pointed to by \a offset_ptr is out of bounds, or if the 159 /// offset plus the length of the C string is out of bounds, 160 /// a default-initialized StringRef will be returned. 161 StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err = nullptr) const; 162 163 /// Extract a C string (as a StringRef) from the location given by the cursor. 164 /// In case of an extraction error, or if the cursor is already in an error 165 /// state, a default-initialized StringRef is returned. 166 StringRef getCStrRef(Cursor &C) const { 167 return getCStrRef(&C.Offset, &C.Err); 168 } 169 170 /// Extract a fixed length string from \a *OffsetPtr and consume \a Length 171 /// bytes. 172 /// 173 /// Returns a StringRef for the string from the data at the offset 174 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted 175 /// and the \a OffsetPtr will be advanced by \a Length bytes. 176 /// 177 /// \param[in,out] OffsetPtr 178 /// A pointer to an offset within the data that will be advanced 179 /// by the appropriate number of bytes if the value is extracted 180 /// correctly. If the offset is out of bounds or there are not 181 /// enough bytes to extract this value, the offset will be left 182 /// unmodified. 183 /// 184 /// \param[in] Length 185 /// The length of the fixed length string to extract. If there are not 186 /// enough bytes in the data to extract the full string, the offset will 187 /// be left unmodified. 188 /// 189 /// \param[in] TrimChars 190 /// A set of characters to trim from the end of the string. Fixed length 191 /// strings are commonly either NULL terminated by one or more zero 192 /// bytes. Some clients have one or more spaces at the end of the string, 193 /// but a good default is to trim the NULL characters. 194 /// 195 /// \return 196 /// A StringRef for the C string value in the data. If the offset 197 /// pointed to by \a OffsetPtr is out of bounds, or if the 198 /// offset plus the length of the C string is out of bounds, 199 /// a default-initialized StringRef will be returned. 200 StringRef getFixedLengthString(uint64_t *OffsetPtr, 201 uint64_t Length, StringRef TrimChars = {"\0", 1}) const; 202 203 /// Extract a fixed number of bytes from the specified offset. 204 /// 205 /// Returns a StringRef for the bytes from the data at the offset 206 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted 207 /// and the \a OffsetPtr will be advanced by \a Length bytes. 208 /// 209 /// \param[in,out] OffsetPtr 210 /// A pointer to an offset within the data that will be advanced 211 /// by the appropriate number of bytes if the value is extracted 212 /// correctly. If the offset is out of bounds or there are not 213 /// enough bytes to extract this value, the offset will be left 214 /// unmodified. 215 /// 216 /// \param[in] Length 217 /// The number of bytes to extract. If there are not enough bytes in the 218 /// data to extract all of the bytes, the offset will be left unmodified. 219 /// 220 /// @param[in,out] Err 221 /// A pointer to an Error object. Upon return the Error object is set to 222 /// indicate the result (success/failure) of the function. If the Error 223 /// object is already set when calling this function, no extraction is 224 /// performed. 225 /// 226 /// \return 227 /// A StringRef for the extracted bytes. If the offset pointed to by 228 /// \a OffsetPtr is out of bounds, or if the offset plus the length 229 /// is out of bounds, a default-initialized StringRef will be returned. 230 StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length, 231 Error *Err = nullptr) const; 232 233 /// Extract a fixed number of bytes from the location given by the cursor. In 234 /// case of an extraction error, or if the cursor is already in an error 235 /// state, a default-initialized StringRef is returned. 236 StringRef getBytes(Cursor &C, uint64_t Length) { 237 return getBytes(&C.Offset, Length, &C.Err); 238 } 239 240 /// Extract an unsigned integer of size \a byte_size from \a 241 /// *offset_ptr. 242 /// 243 /// Extract a single unsigned integer value and update the offset 244 /// pointed to by \a offset_ptr. The size of the extracted integer 245 /// is specified by the \a byte_size argument. \a byte_size should 246 /// have a value greater than or equal to one and less than or equal 247 /// to eight since the return value is 64 bits wide. Any 248 /// \a byte_size values less than 1 or greater than 8 will result in 249 /// nothing being extracted, and zero being returned. 250 /// 251 /// @param[in,out] offset_ptr 252 /// A pointer to an offset within the data that will be advanced 253 /// by the appropriate number of bytes if the value is extracted 254 /// correctly. If the offset is out of bounds or there are not 255 /// enough bytes to extract this value, the offset will be left 256 /// unmodified. 257 /// 258 /// @param[in] byte_size 259 /// The size in byte of the integer to extract. 260 /// 261 /// @param[in,out] Err 262 /// A pointer to an Error object. Upon return the Error object is set to 263 /// indicate the result (success/failure) of the function. If the Error 264 /// object is already set when calling this function, no extraction is 265 /// performed. 266 /// 267 /// @return 268 /// The unsigned integer value that was extracted, or zero on 269 /// failure. 270 uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size, 271 Error *Err = nullptr) const; 272 273 /// Extract an unsigned integer of the given size from the location given by 274 /// the cursor. In case of an extraction error, or if the cursor is already in 275 /// an error state, zero is returned. 276 uint64_t getUnsigned(Cursor &C, uint32_t Size) const { 277 return getUnsigned(&C.Offset, Size, &C.Err); 278 } 279 280 /// Extract an signed integer of size \a byte_size from \a *offset_ptr. 281 /// 282 /// Extract a single signed integer value (sign extending if required) 283 /// and update the offset pointed to by \a offset_ptr. The size of 284 /// the extracted integer is specified by the \a byte_size argument. 285 /// \a byte_size should have a value greater than or equal to one 286 /// and less than or equal to eight since the return value is 64 287 /// bits wide. Any \a byte_size values less than 1 or greater than 288 /// 8 will result in nothing being extracted, and zero being returned. 289 /// 290 /// @param[in,out] offset_ptr 291 /// A pointer to an offset within the data that will be advanced 292 /// by the appropriate number of bytes if the value is extracted 293 /// correctly. If the offset is out of bounds or there are not 294 /// enough bytes to extract this value, the offset will be left 295 /// unmodified. 296 /// 297 /// @param[in] size 298 /// The size in bytes of the integer to extract. 299 /// 300 /// @return 301 /// The sign extended signed integer value that was extracted, 302 /// or zero on failure. 303 int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const; 304 305 //------------------------------------------------------------------ 306 /// Extract an pointer from \a *offset_ptr. 307 /// 308 /// Extract a single pointer from the data and update the offset 309 /// pointed to by \a offset_ptr. The size of the extracted pointer 310 /// is \a getAddressSize(), so the address size has to be 311 /// set correctly prior to extracting any pointer values. 312 /// 313 /// @param[in,out] offset_ptr 314 /// A pointer to an offset within the data that will be advanced 315 /// by the appropriate number of bytes if the value is extracted 316 /// correctly. If the offset is out of bounds or there are not 317 /// enough bytes to extract this value, the offset will be left 318 /// unmodified. 319 /// 320 /// @return 321 /// The extracted pointer value as a 64 integer. 322 uint64_t getAddress(uint64_t *offset_ptr) const { 323 return getUnsigned(offset_ptr, AddressSize); 324 } 325 326 /// Extract a pointer-sized unsigned integer from the location given by the 327 /// cursor. In case of an extraction error, or if the cursor is already in 328 /// an error state, zero is returned. 329 uint64_t getAddress(Cursor &C) const { return getUnsigned(C, AddressSize); } 330 331 /// Extract a uint8_t value from \a *offset_ptr. 332 /// 333 /// Extract a single uint8_t from the binary data at the offset 334 /// pointed to by \a offset_ptr, and advance the offset on success. 335 /// 336 /// @param[in,out] offset_ptr 337 /// A pointer to an offset within the data that will be advanced 338 /// by the appropriate number of bytes if the value is extracted 339 /// correctly. If the offset is out of bounds or there are not 340 /// enough bytes to extract this value, the offset will be left 341 /// unmodified. 342 /// 343 /// @param[in,out] Err 344 /// A pointer to an Error object. Upon return the Error object is set to 345 /// indicate the result (success/failure) of the function. If the Error 346 /// object is already set when calling this function, no extraction is 347 /// performed. 348 /// 349 /// @return 350 /// The extracted uint8_t value. 351 uint8_t getU8(uint64_t *offset_ptr, Error *Err = nullptr) const; 352 353 /// Extract a single uint8_t value from the location given by the cursor. In 354 /// case of an extraction error, or if the cursor is already in an error 355 /// state, zero is returned. 356 uint8_t getU8(Cursor &C) const { return getU8(&C.Offset, &C.Err); } 357 358 /// Extract \a count uint8_t values from \a *offset_ptr. 359 /// 360 /// Extract \a count uint8_t values from the binary data at the 361 /// offset pointed to by \a offset_ptr, and advance the offset on 362 /// success. The extracted values are copied into \a dst. 363 /// 364 /// @param[in,out] offset_ptr 365 /// A pointer to an offset within the data that will be advanced 366 /// by the appropriate number of bytes if the value is extracted 367 /// correctly. If the offset is out of bounds or there are not 368 /// enough bytes to extract this value, the offset will be left 369 /// unmodified. 370 /// 371 /// @param[out] dst 372 /// A buffer to copy \a count uint8_t values into. \a dst must 373 /// be large enough to hold all requested data. 374 /// 375 /// @param[in] count 376 /// The number of uint8_t values to extract. 377 /// 378 /// @return 379 /// \a dst if all values were properly extracted and copied, 380 /// NULL otherise. 381 uint8_t *getU8(uint64_t *offset_ptr, uint8_t *dst, uint32_t count) const; 382 383 /// Extract \a Count uint8_t values from the location given by the cursor and 384 /// store them into the destination buffer. In case of an extraction error, or 385 /// if the cursor is already in an error state, a nullptr is returned and the 386 /// destination buffer is left unchanged. 387 uint8_t *getU8(Cursor &C, uint8_t *Dst, uint32_t Count) const; 388 389 /// Extract \a Count uint8_t values from the location given by the cursor and 390 /// store them into the destination vector. The vector is resized to fit the 391 /// extracted data. In case of an extraction error, or if the cursor is 392 /// already in an error state, the destination vector is left unchanged and 393 /// cursor is placed into an error state. 394 void getU8(Cursor &C, SmallVectorImpl<uint8_t> &Dst, uint32_t Count) const { 395 if (isValidOffsetForDataOfSize(C.Offset, Count)) 396 Dst.resize(Count); 397 398 // This relies on the fact that getU8 will not attempt to write to the 399 // buffer if isValidOffsetForDataOfSize(C.Offset, Count) is false. 400 getU8(C, Dst.data(), Count); 401 } 402 403 //------------------------------------------------------------------ 404 /// Extract a uint16_t value from \a *offset_ptr. 405 /// 406 /// Extract a single uint16_t from the binary data at the offset 407 /// pointed to by \a offset_ptr, and update the offset on success. 408 /// 409 /// @param[in,out] offset_ptr 410 /// A pointer to an offset within the data that will be advanced 411 /// by the appropriate number of bytes if the value is extracted 412 /// correctly. If the offset is out of bounds or there are not 413 /// enough bytes to extract this value, the offset will be left 414 /// unmodified. 415 /// 416 /// @param[in,out] Err 417 /// A pointer to an Error object. Upon return the Error object is set to 418 /// indicate the result (success/failure) of the function. If the Error 419 /// object is already set when calling this function, no extraction is 420 /// performed. 421 /// 422 /// @return 423 /// The extracted uint16_t value. 424 //------------------------------------------------------------------ 425 uint16_t getU16(uint64_t *offset_ptr, Error *Err = nullptr) const; 426 427 /// Extract a single uint16_t value from the location given by the cursor. In 428 /// case of an extraction error, or if the cursor is already in an error 429 /// state, zero is returned. 430 uint16_t getU16(Cursor &C) const { return getU16(&C.Offset, &C.Err); } 431 432 /// Extract \a count uint16_t values from \a *offset_ptr. 433 /// 434 /// Extract \a count uint16_t values from the binary data at the 435 /// offset pointed to by \a offset_ptr, and advance the offset on 436 /// success. The extracted values are copied into \a dst. 437 /// 438 /// @param[in,out] offset_ptr 439 /// A pointer to an offset within the data that will be advanced 440 /// by the appropriate number of bytes if the value is extracted 441 /// correctly. If the offset is out of bounds or there are not 442 /// enough bytes to extract this value, the offset will be left 443 /// unmodified. 444 /// 445 /// @param[out] dst 446 /// A buffer to copy \a count uint16_t values into. \a dst must 447 /// be large enough to hold all requested data. 448 /// 449 /// @param[in] count 450 /// The number of uint16_t values to extract. 451 /// 452 /// @return 453 /// \a dst if all values were properly extracted and copied, 454 /// NULL otherise. 455 uint16_t *getU16(uint64_t *offset_ptr, uint16_t *dst, uint32_t count) const; 456 457 /// Extract a 24-bit unsigned value from \a *offset_ptr and return it 458 /// in a uint32_t. 459 /// 460 /// Extract 3 bytes from the binary data at the offset pointed to by 461 /// \a offset_ptr, construct a uint32_t from them and update the offset 462 /// on success. 463 /// 464 /// @param[in,out] OffsetPtr 465 /// A pointer to an offset within the data that will be advanced 466 /// by the 3 bytes if the value is extracted correctly. If the offset 467 /// is out of bounds or there are not enough bytes to extract this value, 468 /// the offset will be left unmodified. 469 /// 470 /// @param[in,out] Err 471 /// A pointer to an Error object. Upon return the Error object is set to 472 /// indicate the result (success/failure) of the function. If the Error 473 /// object is already set when calling this function, no extraction is 474 /// performed. 475 /// 476 /// @return 477 /// The extracted 24-bit value represented in a uint32_t. 478 uint32_t getU24(uint64_t *OffsetPtr, Error *Err = nullptr) const; 479 480 /// Extract a single 24-bit unsigned value from the location given by the 481 /// cursor. In case of an extraction error, or if the cursor is already in an 482 /// error state, zero is returned. 483 uint32_t getU24(Cursor &C) const { return getU24(&C.Offset, &C.Err); } 484 485 /// Extract a uint32_t value from \a *offset_ptr. 486 /// 487 /// Extract a single uint32_t from the binary data at the offset 488 /// pointed to by \a offset_ptr, and update the offset on success. 489 /// 490 /// @param[in,out] offset_ptr 491 /// A pointer to an offset within the data that will be advanced 492 /// by the appropriate number of bytes if the value is extracted 493 /// correctly. If the offset is out of bounds or there are not 494 /// enough bytes to extract this value, the offset will be left 495 /// unmodified. 496 /// 497 /// @param[in,out] Err 498 /// A pointer to an Error object. Upon return the Error object is set to 499 /// indicate the result (success/failure) of the function. If the Error 500 /// object is already set when calling this function, no extraction is 501 /// performed. 502 /// 503 /// @return 504 /// The extracted uint32_t value. 505 uint32_t getU32(uint64_t *offset_ptr, Error *Err = nullptr) const; 506 507 /// Extract a single uint32_t value from the location given by the cursor. In 508 /// case of an extraction error, or if the cursor is already in an error 509 /// state, zero is returned. 510 uint32_t getU32(Cursor &C) const { return getU32(&C.Offset, &C.Err); } 511 512 /// Extract \a count uint32_t values from \a *offset_ptr. 513 /// 514 /// Extract \a count uint32_t values from the binary data at the 515 /// offset pointed to by \a offset_ptr, and advance the offset on 516 /// success. The extracted values are copied into \a dst. 517 /// 518 /// @param[in,out] offset_ptr 519 /// A pointer to an offset within the data that will be advanced 520 /// by the appropriate number of bytes if the value is extracted 521 /// correctly. If the offset is out of bounds or there are not 522 /// enough bytes to extract this value, the offset will be left 523 /// unmodified. 524 /// 525 /// @param[out] dst 526 /// A buffer to copy \a count uint32_t values into. \a dst must 527 /// be large enough to hold all requested data. 528 /// 529 /// @param[in] count 530 /// The number of uint32_t values to extract. 531 /// 532 /// @return 533 /// \a dst if all values were properly extracted and copied, 534 /// NULL otherise. 535 uint32_t *getU32(uint64_t *offset_ptr, uint32_t *dst, uint32_t count) const; 536 537 /// Extract a uint64_t value from \a *offset_ptr. 538 /// 539 /// Extract a single uint64_t from the binary data at the offset 540 /// pointed to by \a offset_ptr, and update the offset on success. 541 /// 542 /// @param[in,out] offset_ptr 543 /// A pointer to an offset within the data that will be advanced 544 /// by the appropriate number of bytes if the value is extracted 545 /// correctly. If the offset is out of bounds or there are not 546 /// enough bytes to extract this value, the offset will be left 547 /// unmodified. 548 /// 549 /// @param[in,out] Err 550 /// A pointer to an Error object. Upon return the Error object is set to 551 /// indicate the result (success/failure) of the function. If the Error 552 /// object is already set when calling this function, no extraction is 553 /// performed. 554 /// 555 /// @return 556 /// The extracted uint64_t value. 557 uint64_t getU64(uint64_t *offset_ptr, Error *Err = nullptr) const; 558 559 /// Extract a single uint64_t value from the location given by the cursor. In 560 /// case of an extraction error, or if the cursor is already in an error 561 /// state, zero is returned. 562 uint64_t getU64(Cursor &C) const { return getU64(&C.Offset, &C.Err); } 563 564 /// Extract \a count uint64_t values from \a *offset_ptr. 565 /// 566 /// Extract \a count uint64_t values from the binary data at the 567 /// offset pointed to by \a offset_ptr, and advance the offset on 568 /// success. The extracted values are copied into \a dst. 569 /// 570 /// @param[in,out] offset_ptr 571 /// A pointer to an offset within the data that will be advanced 572 /// by the appropriate number of bytes if the value is extracted 573 /// correctly. If the offset is out of bounds or there are not 574 /// enough bytes to extract this value, the offset will be left 575 /// unmodified. 576 /// 577 /// @param[out] dst 578 /// A buffer to copy \a count uint64_t values into. \a dst must 579 /// be large enough to hold all requested data. 580 /// 581 /// @param[in] count 582 /// The number of uint64_t values to extract. 583 /// 584 /// @return 585 /// \a dst if all values were properly extracted and copied, 586 /// NULL otherise. 587 uint64_t *getU64(uint64_t *offset_ptr, uint64_t *dst, uint32_t count) const; 588 589 /// Extract a signed LEB128 value from \a *offset_ptr. 590 /// 591 /// Extracts an signed LEB128 number from this object's data 592 /// starting at the offset pointed to by \a offset_ptr. The offset 593 /// pointed to by \a offset_ptr will be updated with the offset of 594 /// the byte following the last extracted byte. 595 /// 596 /// @param[in,out] OffsetPtr 597 /// A pointer to an offset within the data that will be advanced 598 /// by the appropriate number of bytes if the value is extracted 599 /// correctly. If the offset is out of bounds or there are not 600 /// enough bytes to extract this value, the offset will be left 601 /// unmodified. 602 /// 603 /// @param[in,out] Err 604 /// A pointer to an Error object. Upon return the Error object is set to 605 /// indicate the result (success/failure) of the function. If the Error 606 /// object is already set when calling this function, no extraction is 607 /// performed. 608 /// 609 /// @return 610 /// The extracted signed integer value. 611 int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err = nullptr) const; 612 613 /// Extract an signed LEB128 value from the location given by the cursor. 614 /// In case of an extraction error, or if the cursor is already in an error 615 /// state, zero is returned. 616 int64_t getSLEB128(Cursor &C) const { return getSLEB128(&C.Offset, &C.Err); } 617 618 /// Extract a unsigned LEB128 value from \a *offset_ptr. 619 /// 620 /// Extracts an unsigned LEB128 number from this object's data 621 /// starting at the offset pointed to by \a offset_ptr. The offset 622 /// pointed to by \a offset_ptr will be updated with the offset of 623 /// the byte following the last extracted byte. 624 /// 625 /// @param[in,out] offset_ptr 626 /// A pointer to an offset within the data that will be advanced 627 /// by the appropriate number of bytes if the value is extracted 628 /// correctly. If the offset is out of bounds or there are not 629 /// enough bytes to extract this value, the offset will be left 630 /// unmodified. 631 /// 632 /// @param[in,out] Err 633 /// A pointer to an Error object. Upon return the Error object is set to 634 /// indicate the result (success/failure) of the function. If the Error 635 /// object is already set when calling this function, no extraction is 636 /// performed. 637 /// 638 /// @return 639 /// The extracted unsigned integer value. 640 uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err = nullptr) const; 641 642 /// Extract an unsigned LEB128 value from the location given by the cursor. 643 /// In case of an extraction error, or if the cursor is already in an error 644 /// state, zero is returned. 645 uint64_t getULEB128(Cursor &C) const { return getULEB128(&C.Offset, &C.Err); } 646 647 /// Advance the Cursor position by the given number of bytes. No-op if the 648 /// cursor is in an error state. 649 void skip(Cursor &C, uint64_t Length) const; 650 651 /// Return true iff the cursor is at the end of the buffer, regardless of the 652 /// error state of the cursor. The only way both eof and error states can be 653 /// true is if one attempts a read while the cursor is at the very end of the 654 /// data buffer. 655 bool eof(const Cursor &C) const { return size() == C.Offset; } 656 657 /// Test the validity of \a offset. 658 /// 659 /// @return 660 /// \b true if \a offset is a valid offset into the data in this 661 /// object, \b false otherwise. 662 bool isValidOffset(uint64_t offset) const { return size() > offset; } 663 664 /// Test the availability of \a length bytes of data from \a offset. 665 /// 666 /// @return 667 /// \b true if \a offset is a valid offset and there are \a 668 /// length bytes available at that offset, \b false otherwise. 669 bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const { 670 return offset + length >= offset && isValidOffset(offset + length - 1); 671 } 672 673 /// Test the availability of enough bytes of data for a pointer from 674 /// \a offset. The size of a pointer is \a getAddressSize(). 675 /// 676 /// @return 677 /// \b true if \a offset is a valid offset and there are enough 678 /// bytes for a pointer available at that offset, \b false 679 /// otherwise. 680 bool isValidOffsetForAddress(uint64_t offset) const { 681 return isValidOffsetForDataOfSize(offset, AddressSize); 682 } 683 684 /// Return the number of bytes in the underlying buffer. 685 size_t size() const { return Data.size(); } 686 687 protected: 688 // Make it possible for subclasses to access these fields without making them 689 // public. 690 static uint64_t &getOffset(Cursor &C) { return C.Offset; } 691 static Error &getError(Cursor &C) { return C.Err; } 692 693 private: 694 /// If it is possible to read \a Size bytes at offset \a Offset, returns \b 695 /// true. Otherwise, returns \b false. If \a E is not nullptr, also sets the 696 /// error object to indicate an error. 697 bool prepareRead(uint64_t Offset, uint64_t Size, Error *E) const; 698 699 template <typename T> T getU(uint64_t *OffsetPtr, Error *Err) const; 700 template <typename T> 701 T *getUs(uint64_t *OffsetPtr, T *Dst, uint32_t Count, Error *Err) const; 702 }; 703 704 } // namespace llvm 705 706 #endif 707