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