|
|
|||
File indexing completed on 2026-05-10 08:44:29
0001 //===-- DataExtractor.h -----------------------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLVM_SUPPORT_DATAEXTRACTOR_H 0010 #define LLVM_SUPPORT_DATAEXTRACTOR_H 0011 0012 #include "llvm/ADT/StringRef.h" 0013 #include "llvm/Support/DataTypes.h" 0014 #include "llvm/Support/Error.h" 0015 0016 namespace llvm { 0017 0018 /// An auxiliary type to facilitate extraction of 3-byte entities. 0019 struct Uint24 { 0020 uint8_t Bytes[3]; 0021 Uint24(uint8_t U) { 0022 Bytes[0] = Bytes[1] = Bytes[2] = U; 0023 } 0024 Uint24(uint8_t U0, uint8_t U1, uint8_t U2) { 0025 Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2; 0026 } 0027 uint32_t getAsUint32(bool IsLittleEndian) const { 0028 int LoIx = IsLittleEndian ? 0 : 2; 0029 return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16); 0030 } 0031 }; 0032 0033 using uint24_t = Uint24; 0034 static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3"); 0035 0036 /// Needed by swapByteOrder(). 0037 inline uint24_t getSwappedBytes(uint24_t C) { 0038 return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]); 0039 } 0040 0041 class DataExtractor { 0042 StringRef Data; 0043 uint8_t IsLittleEndian; 0044 uint8_t AddressSize; 0045 public: 0046 /// A class representing a position in a DataExtractor, as well as any error 0047 /// encountered during extraction. It enables one to extract a sequence of 0048 /// values without error-checking and then checking for errors in bulk at the 0049 /// end. The class holds an Error object, so failing to check the result of 0050 /// the parse will result in a runtime error. The error flag is sticky and 0051 /// will cause all subsequent extraction functions to fail without even 0052 /// attempting to parse and without updating the Cursor offset. After clearing 0053 /// the error flag, one can again use the Cursor object for parsing. 0054 class Cursor { 0055 uint64_t Offset; 0056 Error Err; 0057 0058 friend class DataExtractor; 0059 0060 public: 0061 /// Construct a cursor for extraction from the given offset. 0062 explicit Cursor(uint64_t Offset) : Offset(Offset), Err(Error::success()) {} 0063 0064 /// Checks whether the cursor is valid (i.e. no errors were encountered). In 0065 /// case of errors, this does not clear the error flag -- one must call 0066 /// takeError() instead. 0067 explicit operator bool() { return !Err; } 0068 0069 /// Return the current position of this Cursor. In the error state this is 0070 /// the position of the Cursor before the first error was encountered. 0071 uint64_t tell() const { return Offset; } 0072 0073 /// Set the cursor to the new offset. This does not impact the error state. 0074 void seek(uint64_t NewOffSet) { Offset = NewOffSet; } 0075 0076 /// Return error contained inside this Cursor, if any. Clears the internal 0077 /// Cursor state. 0078 Error takeError() { return std::move(Err); } 0079 }; 0080 0081 /// Construct with a buffer that is owned by the caller. 0082 /// 0083 /// This constructor allows us to use data that is owned by the 0084 /// caller. The data must stay around as long as this object is 0085 /// valid. 0086 DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize) 0087 : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {} 0088 DataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian, 0089 uint8_t AddressSize) 0090 : Data(StringRef(reinterpret_cast<const char *>(Data.data()), 0091 Data.size())), 0092 IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {} 0093 0094 /// Get the data pointed to by this extractor. 0095 StringRef getData() const { return Data; } 0096 /// Get the endianness for this extractor. 0097 bool isLittleEndian() const { return IsLittleEndian; } 0098 /// Get the address size for this extractor. 0099 uint8_t getAddressSize() const { return AddressSize; } 0100 /// Set the address size for this extractor. 0101 void setAddressSize(uint8_t Size) { AddressSize = Size; } 0102 0103 /// Extract a C string from \a *offset_ptr. 0104 /// 0105 /// Returns a pointer to a C String from the data at the offset 0106 /// pointed to by \a offset_ptr. A variable length NULL terminated C 0107 /// string will be extracted and the \a offset_ptr will be 0108 /// updated with the offset of the byte that follows the NULL 0109 /// terminator byte. 0110 /// 0111 /// @param[in,out] OffsetPtr 0112 /// A pointer to an offset within the data that will be advanced 0113 /// by the appropriate number of bytes if the value is extracted 0114 /// correctly. If the offset is out of bounds or there are not 0115 /// enough bytes to extract this value, the offset will be left 0116 /// unmodified. 0117 /// 0118 /// @param[in,out] Err 0119 /// A pointer to an Error object. Upon return the Error object is set to 0120 /// indicate the result (success/failure) of the function. If the Error 0121 /// object is already set when calling this function, no extraction is 0122 /// performed. 0123 /// 0124 /// @return 0125 /// A pointer to the C string value in the data. If the offset 0126 /// pointed to by \a offset_ptr is out of bounds, or if the 0127 /// offset plus the length of the C string is out of bounds, 0128 /// NULL will be returned. 0129 const char *getCStr(uint64_t *OffsetPtr, Error *Err = nullptr) const { 0130 return getCStrRef(OffsetPtr, Err).data(); 0131 } 0132 0133 /// Extract a C string from the location given by the cursor. In case of an 0134 /// extraction error, or if the cursor is already in an error state, a 0135 /// nullptr is returned. 0136 const char *getCStr(Cursor &C) const { return getCStrRef(C).data(); } 0137 0138 /// Extract a C string from \a *offset_ptr. 0139 /// 0140 /// Returns a StringRef for the C String from the data at the offset 0141 /// pointed to by \a offset_ptr. A variable length NULL terminated C 0142 /// string will be extracted and the \a offset_ptr will be 0143 /// updated with the offset of the byte that follows the NULL 0144 /// terminator byte. 0145 /// 0146 /// \param[in,out] OffsetPtr 0147 /// A pointer to an offset within the data that will be advanced 0148 /// by the appropriate number of bytes if the value is extracted 0149 /// correctly. If the offset is out of bounds or there are not 0150 /// enough bytes to extract this value, the offset will be left 0151 /// unmodified. 0152 /// 0153 /// @param[in,out] Err 0154 /// A pointer to an Error object. Upon return the Error object is set to 0155 /// indicate the result (success/failure) of the function. If the Error 0156 /// object is already set when calling this function, no extraction is 0157 /// performed. 0158 /// 0159 /// \return 0160 /// A StringRef for the C string value in the data. If the offset 0161 /// pointed to by \a offset_ptr is out of bounds, or if the 0162 /// offset plus the length of the C string is out of bounds, 0163 /// a default-initialized StringRef will be returned. 0164 StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err = nullptr) const; 0165 0166 /// Extract a C string (as a StringRef) from the location given by the cursor. 0167 /// In case of an extraction error, or if the cursor is already in an error 0168 /// state, a default-initialized StringRef is returned. 0169 StringRef getCStrRef(Cursor &C) const { 0170 return getCStrRef(&C.Offset, &C.Err); 0171 } 0172 0173 /// Extract a fixed length string from \a *OffsetPtr and consume \a Length 0174 /// bytes. 0175 /// 0176 /// Returns a StringRef for the string from the data at the offset 0177 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted 0178 /// and the \a OffsetPtr will be advanced by \a Length bytes. 0179 /// 0180 /// \param[in,out] OffsetPtr 0181 /// A pointer to an offset within the data that will be advanced 0182 /// by the appropriate number of bytes if the value is extracted 0183 /// correctly. If the offset is out of bounds or there are not 0184 /// enough bytes to extract this value, the offset will be left 0185 /// unmodified. 0186 /// 0187 /// \param[in] Length 0188 /// The length of the fixed length string to extract. If there are not 0189 /// enough bytes in the data to extract the full string, the offset will 0190 /// be left unmodified. 0191 /// 0192 /// \param[in] TrimChars 0193 /// A set of characters to trim from the end of the string. Fixed length 0194 /// strings are commonly either NULL terminated by one or more zero 0195 /// bytes. Some clients have one or more spaces at the end of the string, 0196 /// but a good default is to trim the NULL characters. 0197 /// 0198 /// \return 0199 /// A StringRef for the C string value in the data. If the offset 0200 /// pointed to by \a OffsetPtr is out of bounds, or if the 0201 /// offset plus the length of the C string is out of bounds, 0202 /// a default-initialized StringRef will be returned. 0203 StringRef getFixedLengthString(uint64_t *OffsetPtr, 0204 uint64_t Length, StringRef TrimChars = {"\0", 1}) const; 0205 0206 /// Extract a fixed number of bytes from the specified offset. 0207 /// 0208 /// Returns a StringRef for the bytes from the data at the offset 0209 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted 0210 /// and the \a OffsetPtr will be advanced by \a Length bytes. 0211 /// 0212 /// \param[in,out] OffsetPtr 0213 /// A pointer to an offset within the data that will be advanced 0214 /// by the appropriate number of bytes if the value is extracted 0215 /// correctly. If the offset is out of bounds or there are not 0216 /// enough bytes to extract this value, the offset will be left 0217 /// unmodified. 0218 /// 0219 /// \param[in] Length 0220 /// The number of bytes to extract. If there are not enough bytes in the 0221 /// data to extract all of the bytes, the offset will be left unmodified. 0222 /// 0223 /// @param[in,out] Err 0224 /// A pointer to an Error object. Upon return the Error object is set to 0225 /// indicate the result (success/failure) of the function. If the Error 0226 /// object is already set when calling this function, no extraction is 0227 /// performed. 0228 /// 0229 /// \return 0230 /// A StringRef for the extracted bytes. If the offset pointed to by 0231 /// \a OffsetPtr is out of bounds, or if the offset plus the length 0232 /// is out of bounds, a default-initialized StringRef will be returned. 0233 StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length, 0234 Error *Err = nullptr) const; 0235 0236 /// Extract a fixed number of bytes from the location given by the cursor. In 0237 /// case of an extraction error, or if the cursor is already in an error 0238 /// state, a default-initialized StringRef is returned. 0239 StringRef getBytes(Cursor &C, uint64_t Length) { 0240 return getBytes(&C.Offset, Length, &C.Err); 0241 } 0242 0243 /// Extract an unsigned integer of size \a byte_size from \a 0244 /// *offset_ptr. 0245 /// 0246 /// Extract a single unsigned integer value and update the offset 0247 /// pointed to by \a offset_ptr. The size of the extracted integer 0248 /// is specified by the \a byte_size argument. \a byte_size should 0249 /// have a value greater than or equal to one and less than or equal 0250 /// to eight since the return value is 64 bits wide. Any 0251 /// \a byte_size values less than 1 or greater than 8 will result in 0252 /// nothing being extracted, and zero being returned. 0253 /// 0254 /// @param[in,out] offset_ptr 0255 /// A pointer to an offset within the data that will be advanced 0256 /// by the appropriate number of bytes if the value is extracted 0257 /// correctly. If the offset is out of bounds or there are not 0258 /// enough bytes to extract this value, the offset will be left 0259 /// unmodified. 0260 /// 0261 /// @param[in] byte_size 0262 /// The size in byte of the integer to extract. 0263 /// 0264 /// @param[in,out] Err 0265 /// A pointer to an Error object. Upon return the Error object is set to 0266 /// indicate the result (success/failure) of the function. If the Error 0267 /// object is already set when calling this function, no extraction is 0268 /// performed. 0269 /// 0270 /// @return 0271 /// The unsigned integer value that was extracted, or zero on 0272 /// failure. 0273 uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size, 0274 Error *Err = nullptr) const; 0275 0276 /// Extract an unsigned integer of the given size from the location given by 0277 /// the cursor. In case of an extraction error, or if the cursor is already in 0278 /// an error state, zero is returned. 0279 uint64_t getUnsigned(Cursor &C, uint32_t Size) const { 0280 return getUnsigned(&C.Offset, Size, &C.Err); 0281 } 0282 0283 /// Extract an signed integer of size \a byte_size from \a *offset_ptr. 0284 /// 0285 /// Extract a single signed integer value (sign extending if required) 0286 /// and update the offset pointed to by \a offset_ptr. The size of 0287 /// the extracted integer is specified by the \a byte_size argument. 0288 /// \a byte_size should have a value greater than or equal to one 0289 /// and less than or equal to eight since the return value is 64 0290 /// bits wide. Any \a byte_size values less than 1 or greater than 0291 /// 8 will result in nothing being extracted, and zero being returned. 0292 /// 0293 /// @param[in,out] offset_ptr 0294 /// A pointer to an offset within the data that will be advanced 0295 /// by the appropriate number of bytes if the value is extracted 0296 /// correctly. If the offset is out of bounds or there are not 0297 /// enough bytes to extract this value, the offset will be left 0298 /// unmodified. 0299 /// 0300 /// @param[in] size 0301 /// The size in bytes of the integer to extract. 0302 /// 0303 /// @return 0304 /// The sign extended signed integer value that was extracted, 0305 /// or zero on failure. 0306 int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const; 0307 0308 //------------------------------------------------------------------ 0309 /// Extract an pointer from \a *offset_ptr. 0310 /// 0311 /// Extract a single pointer from the data and update the offset 0312 /// pointed to by \a offset_ptr. The size of the extracted pointer 0313 /// is \a getAddressSize(), so the address size has to be 0314 /// set correctly prior to extracting any pointer values. 0315 /// 0316 /// @param[in,out] offset_ptr 0317 /// A pointer to an offset within the data that will be advanced 0318 /// by the appropriate number of bytes if the value is extracted 0319 /// correctly. If the offset is out of bounds or there are not 0320 /// enough bytes to extract this value, the offset will be left 0321 /// unmodified. 0322 /// 0323 /// @return 0324 /// The extracted pointer value as a 64 integer. 0325 uint64_t getAddress(uint64_t *offset_ptr) const { 0326 return getUnsigned(offset_ptr, AddressSize); 0327 } 0328 0329 /// Extract a pointer-sized unsigned integer from the location given by the 0330 /// cursor. In case of an extraction error, or if the cursor is already in 0331 /// an error state, zero is returned. 0332 uint64_t getAddress(Cursor &C) const { return getUnsigned(C, AddressSize); } 0333 0334 /// Extract a uint8_t value from \a *offset_ptr. 0335 /// 0336 /// Extract a single uint8_t from the binary data at the offset 0337 /// pointed to by \a offset_ptr, and advance the offset on success. 0338 /// 0339 /// @param[in,out] offset_ptr 0340 /// A pointer to an offset within the data that will be advanced 0341 /// by the appropriate number of bytes if the value is extracted 0342 /// correctly. If the offset is out of bounds or there are not 0343 /// enough bytes to extract this value, the offset will be left 0344 /// unmodified. 0345 /// 0346 /// @param[in,out] Err 0347 /// A pointer to an Error object. Upon return the Error object is set to 0348 /// indicate the result (success/failure) of the function. If the Error 0349 /// object is already set when calling this function, no extraction is 0350 /// performed. 0351 /// 0352 /// @return 0353 /// The extracted uint8_t value. 0354 uint8_t getU8(uint64_t *offset_ptr, Error *Err = nullptr) const; 0355 0356 /// Extract a single uint8_t value from the location given by the cursor. In 0357 /// case of an extraction error, or if the cursor is already in an error 0358 /// state, zero is returned. 0359 uint8_t getU8(Cursor &C) const { return getU8(&C.Offset, &C.Err); } 0360 0361 /// Extract \a count uint8_t values from \a *offset_ptr. 0362 /// 0363 /// Extract \a count uint8_t values from the binary data at the 0364 /// offset pointed to by \a offset_ptr, and advance the offset on 0365 /// success. The extracted values are copied into \a dst. 0366 /// 0367 /// @param[in,out] offset_ptr 0368 /// A pointer to an offset within the data that will be advanced 0369 /// by the appropriate number of bytes if the value is extracted 0370 /// correctly. If the offset is out of bounds or there are not 0371 /// enough bytes to extract this value, the offset will be left 0372 /// unmodified. 0373 /// 0374 /// @param[out] dst 0375 /// A buffer to copy \a count uint8_t values into. \a dst must 0376 /// be large enough to hold all requested data. 0377 /// 0378 /// @param[in] count 0379 /// The number of uint8_t values to extract. 0380 /// 0381 /// @return 0382 /// \a dst if all values were properly extracted and copied, 0383 /// NULL otherise. 0384 uint8_t *getU8(uint64_t *offset_ptr, uint8_t *dst, uint32_t count) const; 0385 0386 /// Extract \a Count uint8_t values from the location given by the cursor and 0387 /// store them into the destination buffer. In case of an extraction error, or 0388 /// if the cursor is already in an error state, a nullptr is returned and the 0389 /// destination buffer is left unchanged. 0390 uint8_t *getU8(Cursor &C, uint8_t *Dst, uint32_t Count) const; 0391 0392 /// Extract \a Count uint8_t values from the location given by the cursor and 0393 /// store them into the destination vector. The vector is resized to fit the 0394 /// extracted data. In case of an extraction error, or if the cursor is 0395 /// already in an error state, the destination vector is left unchanged and 0396 /// cursor is placed into an error state. 0397 void getU8(Cursor &C, SmallVectorImpl<uint8_t> &Dst, uint32_t Count) const { 0398 if (isValidOffsetForDataOfSize(C.Offset, Count)) 0399 Dst.resize(Count); 0400 0401 // This relies on the fact that getU8 will not attempt to write to the 0402 // buffer if isValidOffsetForDataOfSize(C.Offset, Count) is false. 0403 getU8(C, Dst.data(), Count); 0404 } 0405 0406 //------------------------------------------------------------------ 0407 /// Extract a uint16_t value from \a *offset_ptr. 0408 /// 0409 /// Extract a single uint16_t from the binary data at the offset 0410 /// pointed to by \a offset_ptr, and update the offset on success. 0411 /// 0412 /// @param[in,out] offset_ptr 0413 /// A pointer to an offset within the data that will be advanced 0414 /// by the appropriate number of bytes if the value is extracted 0415 /// correctly. If the offset is out of bounds or there are not 0416 /// enough bytes to extract this value, the offset will be left 0417 /// unmodified. 0418 /// 0419 /// @param[in,out] Err 0420 /// A pointer to an Error object. Upon return the Error object is set to 0421 /// indicate the result (success/failure) of the function. If the Error 0422 /// object is already set when calling this function, no extraction is 0423 /// performed. 0424 /// 0425 /// @return 0426 /// The extracted uint16_t value. 0427 //------------------------------------------------------------------ 0428 uint16_t getU16(uint64_t *offset_ptr, Error *Err = nullptr) const; 0429 0430 /// Extract a single uint16_t value from the location given by the cursor. In 0431 /// case of an extraction error, or if the cursor is already in an error 0432 /// state, zero is returned. 0433 uint16_t getU16(Cursor &C) const { return getU16(&C.Offset, &C.Err); } 0434 0435 /// Extract \a count uint16_t values from \a *offset_ptr. 0436 /// 0437 /// Extract \a count uint16_t values from the binary data at the 0438 /// offset pointed to by \a offset_ptr, and advance the offset on 0439 /// success. The extracted values are copied into \a dst. 0440 /// 0441 /// @param[in,out] offset_ptr 0442 /// A pointer to an offset within the data that will be advanced 0443 /// by the appropriate number of bytes if the value is extracted 0444 /// correctly. If the offset is out of bounds or there are not 0445 /// enough bytes to extract this value, the offset will be left 0446 /// unmodified. 0447 /// 0448 /// @param[out] dst 0449 /// A buffer to copy \a count uint16_t values into. \a dst must 0450 /// be large enough to hold all requested data. 0451 /// 0452 /// @param[in] count 0453 /// The number of uint16_t values to extract. 0454 /// 0455 /// @return 0456 /// \a dst if all values were properly extracted and copied, 0457 /// NULL otherise. 0458 uint16_t *getU16(uint64_t *offset_ptr, uint16_t *dst, uint32_t count) const; 0459 0460 /// Extract a 24-bit unsigned value from \a *offset_ptr and return it 0461 /// in a uint32_t. 0462 /// 0463 /// Extract 3 bytes from the binary data at the offset pointed to by 0464 /// \a offset_ptr, construct a uint32_t from them and update the offset 0465 /// on success. 0466 /// 0467 /// @param[in,out] OffsetPtr 0468 /// A pointer to an offset within the data that will be advanced 0469 /// by the 3 bytes if the value is extracted correctly. If the offset 0470 /// is out of bounds or there are not enough bytes to extract this value, 0471 /// the offset will be left unmodified. 0472 /// 0473 /// @param[in,out] Err 0474 /// A pointer to an Error object. Upon return the Error object is set to 0475 /// indicate the result (success/failure) of the function. If the Error 0476 /// object is already set when calling this function, no extraction is 0477 /// performed. 0478 /// 0479 /// @return 0480 /// The extracted 24-bit value represented in a uint32_t. 0481 uint32_t getU24(uint64_t *OffsetPtr, Error *Err = nullptr) const; 0482 0483 /// Extract a single 24-bit unsigned value from the location given by the 0484 /// cursor. In case of an extraction error, or if the cursor is already in an 0485 /// error state, zero is returned. 0486 uint32_t getU24(Cursor &C) const { return getU24(&C.Offset, &C.Err); } 0487 0488 /// Extract a uint32_t value from \a *offset_ptr. 0489 /// 0490 /// Extract a single uint32_t from the binary data at the offset 0491 /// pointed to by \a offset_ptr, and update the offset on success. 0492 /// 0493 /// @param[in,out] offset_ptr 0494 /// A pointer to an offset within the data that will be advanced 0495 /// by the appropriate number of bytes if the value is extracted 0496 /// correctly. If the offset is out of bounds or there are not 0497 /// enough bytes to extract this value, the offset will be left 0498 /// unmodified. 0499 /// 0500 /// @param[in,out] Err 0501 /// A pointer to an Error object. Upon return the Error object is set to 0502 /// indicate the result (success/failure) of the function. If the Error 0503 /// object is already set when calling this function, no extraction is 0504 /// performed. 0505 /// 0506 /// @return 0507 /// The extracted uint32_t value. 0508 uint32_t getU32(uint64_t *offset_ptr, Error *Err = nullptr) const; 0509 0510 /// Extract a single uint32_t value from the location given by the cursor. In 0511 /// case of an extraction error, or if the cursor is already in an error 0512 /// state, zero is returned. 0513 uint32_t getU32(Cursor &C) const { return getU32(&C.Offset, &C.Err); } 0514 0515 /// Extract \a count uint32_t values from \a *offset_ptr. 0516 /// 0517 /// Extract \a count uint32_t values from the binary data at the 0518 /// offset pointed to by \a offset_ptr, and advance the offset on 0519 /// success. The extracted values are copied into \a dst. 0520 /// 0521 /// @param[in,out] offset_ptr 0522 /// A pointer to an offset within the data that will be advanced 0523 /// by the appropriate number of bytes if the value is extracted 0524 /// correctly. If the offset is out of bounds or there are not 0525 /// enough bytes to extract this value, the offset will be left 0526 /// unmodified. 0527 /// 0528 /// @param[out] dst 0529 /// A buffer to copy \a count uint32_t values into. \a dst must 0530 /// be large enough to hold all requested data. 0531 /// 0532 /// @param[in] count 0533 /// The number of uint32_t values to extract. 0534 /// 0535 /// @return 0536 /// \a dst if all values were properly extracted and copied, 0537 /// NULL otherise. 0538 uint32_t *getU32(uint64_t *offset_ptr, uint32_t *dst, uint32_t count) const; 0539 0540 /// Extract a uint64_t value from \a *offset_ptr. 0541 /// 0542 /// Extract a single uint64_t from the binary data at the offset 0543 /// pointed to by \a offset_ptr, and update the offset on success. 0544 /// 0545 /// @param[in,out] offset_ptr 0546 /// A pointer to an offset within the data that will be advanced 0547 /// by the appropriate number of bytes if the value is extracted 0548 /// correctly. If the offset is out of bounds or there are not 0549 /// enough bytes to extract this value, the offset will be left 0550 /// unmodified. 0551 /// 0552 /// @param[in,out] Err 0553 /// A pointer to an Error object. Upon return the Error object is set to 0554 /// indicate the result (success/failure) of the function. If the Error 0555 /// object is already set when calling this function, no extraction is 0556 /// performed. 0557 /// 0558 /// @return 0559 /// The extracted uint64_t value. 0560 uint64_t getU64(uint64_t *offset_ptr, Error *Err = nullptr) const; 0561 0562 /// Extract a single uint64_t value from the location given by the cursor. In 0563 /// case of an extraction error, or if the cursor is already in an error 0564 /// state, zero is returned. 0565 uint64_t getU64(Cursor &C) const { return getU64(&C.Offset, &C.Err); } 0566 0567 /// Extract \a count uint64_t values from \a *offset_ptr. 0568 /// 0569 /// Extract \a count uint64_t values from the binary data at the 0570 /// offset pointed to by \a offset_ptr, and advance the offset on 0571 /// success. The extracted values are copied into \a dst. 0572 /// 0573 /// @param[in,out] offset_ptr 0574 /// A pointer to an offset within the data that will be advanced 0575 /// by the appropriate number of bytes if the value is extracted 0576 /// correctly. If the offset is out of bounds or there are not 0577 /// enough bytes to extract this value, the offset will be left 0578 /// unmodified. 0579 /// 0580 /// @param[out] dst 0581 /// A buffer to copy \a count uint64_t values into. \a dst must 0582 /// be large enough to hold all requested data. 0583 /// 0584 /// @param[in] count 0585 /// The number of uint64_t values to extract. 0586 /// 0587 /// @return 0588 /// \a dst if all values were properly extracted and copied, 0589 /// NULL otherise. 0590 uint64_t *getU64(uint64_t *offset_ptr, uint64_t *dst, uint32_t count) const; 0591 0592 /// Extract a signed LEB128 value from \a *offset_ptr. 0593 /// 0594 /// Extracts an signed LEB128 number from this object's data 0595 /// starting at the offset pointed to by \a offset_ptr. The offset 0596 /// pointed to by \a offset_ptr will be updated with the offset of 0597 /// the byte following the last extracted byte. 0598 /// 0599 /// @param[in,out] OffsetPtr 0600 /// A pointer to an offset within the data that will be advanced 0601 /// by the appropriate number of bytes if the value is extracted 0602 /// correctly. If the offset is out of bounds or there are not 0603 /// enough bytes to extract this value, the offset will be left 0604 /// unmodified. 0605 /// 0606 /// @param[in,out] Err 0607 /// A pointer to an Error object. Upon return the Error object is set to 0608 /// indicate the result (success/failure) of the function. If the Error 0609 /// object is already set when calling this function, no extraction is 0610 /// performed. 0611 /// 0612 /// @return 0613 /// The extracted signed integer value. 0614 int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err = nullptr) const; 0615 0616 /// Extract an signed LEB128 value from the location given by the cursor. 0617 /// In case of an extraction error, or if the cursor is already in an error 0618 /// state, zero is returned. 0619 int64_t getSLEB128(Cursor &C) const { return getSLEB128(&C.Offset, &C.Err); } 0620 0621 /// Extract a unsigned LEB128 value from \a *offset_ptr. 0622 /// 0623 /// Extracts an unsigned LEB128 number from this object's data 0624 /// starting at the offset pointed to by \a offset_ptr. The offset 0625 /// pointed to by \a offset_ptr will be updated with the offset of 0626 /// the byte following the last extracted byte. 0627 /// 0628 /// @param[in,out] offset_ptr 0629 /// A pointer to an offset within the data that will be advanced 0630 /// by the appropriate number of bytes if the value is extracted 0631 /// correctly. If the offset is out of bounds or there are not 0632 /// enough bytes to extract this value, the offset will be left 0633 /// unmodified. 0634 /// 0635 /// @param[in,out] Err 0636 /// A pointer to an Error object. Upon return the Error object is set to 0637 /// indicate the result (success/failure) of the function. If the Error 0638 /// object is already set when calling this function, no extraction is 0639 /// performed. 0640 /// 0641 /// @return 0642 /// The extracted unsigned integer value. 0643 uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err = nullptr) const; 0644 0645 /// Extract an unsigned LEB128 value from the location given by the cursor. 0646 /// In case of an extraction error, or if the cursor is already in an error 0647 /// state, zero is returned. 0648 uint64_t getULEB128(Cursor &C) const { return getULEB128(&C.Offset, &C.Err); } 0649 0650 /// Advance the Cursor position by the given number of bytes. No-op if the 0651 /// cursor is in an error state. 0652 void skip(Cursor &C, uint64_t Length) const; 0653 0654 /// Return true iff the cursor is at the end of the buffer, regardless of the 0655 /// error state of the cursor. The only way both eof and error states can be 0656 /// true is if one attempts a read while the cursor is at the very end of the 0657 /// data buffer. 0658 bool eof(const Cursor &C) const { return size() == C.Offset; } 0659 0660 /// Test the validity of \a offset. 0661 /// 0662 /// @return 0663 /// \b true if \a offset is a valid offset into the data in this 0664 /// object, \b false otherwise. 0665 bool isValidOffset(uint64_t offset) const { return size() > offset; } 0666 0667 /// Test the availability of \a length bytes of data from \a offset. 0668 /// 0669 /// @return 0670 /// \b true if \a offset is a valid offset and there are \a 0671 /// length bytes available at that offset, \b false otherwise. 0672 bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const { 0673 return offset + length >= offset && isValidOffset(offset + length - 1); 0674 } 0675 0676 /// Test the availability of enough bytes of data for a pointer from 0677 /// \a offset. The size of a pointer is \a getAddressSize(). 0678 /// 0679 /// @return 0680 /// \b true if \a offset is a valid offset and there are enough 0681 /// bytes for a pointer available at that offset, \b false 0682 /// otherwise. 0683 bool isValidOffsetForAddress(uint64_t offset) const { 0684 return isValidOffsetForDataOfSize(offset, AddressSize); 0685 } 0686 0687 /// Return the number of bytes in the underlying buffer. 0688 size_t size() const { return Data.size(); } 0689 0690 protected: 0691 // Make it possible for subclasses to access these fields without making them 0692 // public. 0693 static uint64_t &getOffset(Cursor &C) { return C.Offset; } 0694 static Error &getError(Cursor &C) { return C.Err; } 0695 0696 private: 0697 /// If it is possible to read \a Size bytes at offset \a Offset, returns \b 0698 /// true. Otherwise, returns \b false. If \a E is not nullptr, also sets the 0699 /// error object to indicate an error. 0700 bool prepareRead(uint64_t Offset, uint64_t Size, Error *E) const; 0701 0702 template <typename T> T getU(uint64_t *OffsetPtr, Error *Err) const; 0703 template <typename T> 0704 T *getUs(uint64_t *OffsetPtr, T *Dst, uint32_t Count, Error *Err) const; 0705 }; 0706 0707 } // namespace llvm 0708 0709 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|