DataExtractor.h 31 KB

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