diff options
Diffstat (limited to 'include/lldb/Core/DataExtractor.h')
-rw-r--r-- | include/lldb/Core/DataExtractor.h | 2498 |
1 files changed, 1204 insertions, 1294 deletions
diff --git a/include/lldb/Core/DataExtractor.h b/include/lldb/Core/DataExtractor.h index 51ecade2d374..89cc00548e46 100644 --- a/include/lldb/Core/DataExtractor.h +++ b/include/lldb/Core/DataExtractor.h @@ -38,1305 +38,1215 @@ namespace lldb_private { /// /// @see DataBuffer //---------------------------------------------------------------------- -class DataExtractor -{ +class DataExtractor { public: - //------------------------------------------------------------------ - /// @typedef DataExtractor::Type - /// @brief Type enumerations used in the dump routines. - /// @see DataExtractor::Dump() - /// @see DataExtractor::DumpRawHexBytes() - //------------------------------------------------------------------ - typedef enum - { - TypeUInt8, ///< Format output as unsigned 8 bit integers - TypeChar, ///< Format output as characters - TypeUInt16, ///< Format output as unsigned 16 bit integers - TypeUInt32, ///< Format output as unsigned 32 bit integers - TypeUInt64, ///< Format output as unsigned 64 bit integers - TypePointer, ///< Format output as pointers - TypeULEB128, ///< Format output as ULEB128 numbers - TypeSLEB128 ///< Format output as SLEB128 numbers - } Type; - - static void - DumpHexBytes (Stream *s, - const void *src, - size_t src_len, - uint32_t bytes_per_line, - lldb::addr_t base_addr); // Pass LLDB_INVALID_ADDRESS to not show address at start of line - - //------------------------------------------------------------------ - /// Default constructor. - /// - /// Initialize all members to a default empty state. - //------------------------------------------------------------------ - DataExtractor (); - - //------------------------------------------------------------------ - /// Construct with a buffer that is owned by the caller. - /// - /// This constructor allows us to use data that is owned by the - /// caller. The data must stay around as long as this object is - /// valid. - /// - /// @param[in] data - /// A pointer to caller owned data. - /// - /// @param[in] data_length - /// The length in bytes of \a data. - /// - /// @param[in] byte_order - /// A byte order of the data that we are extracting from. - /// - /// @param[in] addr_size - /// A new address byte size value. - /// - /// @param[in] target_byte_size - /// A size of a target byte in 8-bit host bytes - //------------------------------------------------------------------ - DataExtractor (const void* data, lldb::offset_t data_length, lldb::ByteOrder byte_order, uint32_t addr_size, uint32_t target_byte_size = 1); - - //------------------------------------------------------------------ - /// Construct with shared data. - /// - /// Copies the data shared pointer which adds a reference to the - /// contained in \a data_sp. The shared data reference is reference - /// counted to ensure the data lives as long as anyone still has a - /// valid shared pointer to the data in \a data_sp. - /// - /// @param[in] data_sp - /// A shared pointer to data. - /// - /// @param[in] byte_order - /// A byte order of the data that we are extracting from. - /// - /// @param[in] addr_size - /// A new address byte size value. - /// - /// @param[in] target_byte_size - /// A size of a target byte in 8-bit host bytes - //------------------------------------------------------------------ - DataExtractor (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint32_t addr_size, uint32_t target_byte_size = 1); - - //------------------------------------------------------------------ - /// Construct with a subset of \a data. - /// - /// Initialize this object with a subset of the data bytes in \a - /// data. If \a data contains shared data, then a reference to the - /// shared data will be added to ensure the shared data stays around - /// as long as any objects have references to the shared data. The - /// byte order value and the address size settings are copied from \a - /// data. If \a offset is not a valid offset in \a data, then no - /// reference to the shared data will be added. If there are not - /// \a length bytes available in \a data starting at \a offset, - /// the length will be truncated to contain as many bytes as - /// possible. - /// - /// @param[in] data - /// Another DataExtractor object that contains data. - /// - /// @param[in] offset - /// The offset into \a data at which the subset starts. - /// - /// @param[in] length - /// The length in bytes of the subset of data. - /// - /// @param[in] target_byte_size - /// A size of a target byte in 8-bit host bytes - //------------------------------------------------------------------ - DataExtractor (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length, uint32_t target_byte_size = 1); - - DataExtractor (const DataExtractor& rhs); - - //------------------------------------------------------------------ - /// Assignment operator. - /// - /// Copies all data, byte order and address size settings from \a rhs into - /// this object. If \a rhs contains shared data, a reference to that - /// shared data will be added. - /// - /// @param[in] rhs - /// Another DataExtractor object to copy. - /// - /// @return - /// A const reference to this object. - //------------------------------------------------------------------ - const DataExtractor& - operator= (const DataExtractor& rhs); - - //------------------------------------------------------------------ - /// Destructor - /// - /// If this object contains a valid shared data reference, the - /// reference count on the data will be decremented, and if zero, - /// the data will be freed. - //------------------------------------------------------------------ - ~DataExtractor (); - - //------------------------------------------------------------------ - /// Clears the object state. - /// - /// Clears the object contents back to a default invalid state, and - /// release any references to shared data that this object may - /// contain. - //------------------------------------------------------------------ - void - Clear (); - - //------------------------------------------------------------------ - /// Dumps the binary data as \a type objects to stream \a s (or to - /// Log() if \a s is nullptr) starting \a offset bytes into the data - /// and stopping after dumping \a length bytes. The offset into the - /// data is displayed at the beginning of each line and can be - /// offset by base address \a base_addr. \a num_per_line objects - /// will be displayed on each line. - /// - /// @param[in] s - /// The stream to dump the output to. If nullptr the output will - /// be dumped to Log(). - /// - /// @param[in] offset - /// The offset into the data at which to start dumping. - /// - /// @param[in] length - /// The number of bytes to dump. - /// - /// @param[in] base_addr - /// The base address that gets added to the offset displayed on - /// each line. - /// - /// @param[in] num_per_line - /// The number of \a type objects to display on each line. - /// - /// @param[in] type - /// The type of objects to use when dumping data from this - /// object. See DataExtractor::Type. - /// - /// @param[in] type_format - /// The optional format to use for the \a type objects. If this - /// is nullptr, the default format for the \a type will be used. - /// - /// @return - /// The offset at which dumping ended. - //------------------------------------------------------------------ - lldb::offset_t - PutToLog(Log *log, - lldb::offset_t offset, - lldb::offset_t length, - uint64_t base_addr, - uint32_t num_per_line, - Type type, - const char *type_format = nullptr) const; - - //------------------------------------------------------------------ - /// Dumps \a item_count objects into the stream \a s. - /// - /// Dumps \a item_count objects using \a item_format, each of which - /// are \a item_byte_size bytes long starting at offset \a offset - /// bytes into the contained data, into the stream \a s. \a - /// num_per_line objects will be dumped on each line before a new - /// line will be output. If \a base_addr is a valid address, then - /// each new line of output will be preceded by the address value - /// plus appropriate offset, and a colon and space. Bitfield values - /// can be dumped by calling this function multiple times with the - /// same start offset, format and size, yet differing \a - /// item_bit_size and \a item_bit_offset values. - /// - /// @param[in] s - /// The stream to dump the output to. This value can not be nullptr. - /// - /// @param[in] offset - /// The offset into the data at which to start dumping. - /// - /// @param[in] item_format - /// The format to use when dumping each item. - /// - /// @param[in] item_byte_size - /// The byte size of each item. - /// - /// @param[in] item_count - /// The number of items to dump. - /// - /// @param[in] num_per_line - /// The number of items to display on each line. - /// - /// @param[in] base_addr - /// The base address that gets added to the offset displayed on - /// each line if the value is valid. Is \a base_addr is - /// LLDB_INVALID_ADDRESS then no address values will be prepended - /// to any lines. - /// - /// @param[in] item_bit_size - /// If the value to display is a bitfield, this value should - /// be the number of bits that the bitfield item has within the - /// item's byte size value. This function will need to be called - /// multiple times with identical \a offset and \a item_byte_size - /// values in order to display multiple bitfield values that - /// exist within the same integer value. If the items being - /// displayed are not bitfields, this value should be zero. - /// - /// @param[in] item_bit_offset - /// If the value to display is a bitfield, this value should - /// be the offset in bits, or shift right amount, that the - /// bitfield item occupies within the item's byte size value. - /// This function will need to be called multiple times with - /// identical \a offset and \a item_byte_size values in order - /// to display multiple bitfield values that exist within the - /// same integer value. If the items being displayed are not - /// bitfields, this value should be zero. - /// - /// @return - /// The offset at which dumping ended. - //------------------------------------------------------------------ - lldb::offset_t - Dump(Stream *s, - lldb::offset_t offset, - lldb::Format item_format, - size_t item_byte_size, - size_t item_count, - size_t num_per_line, - uint64_t base_addr, - uint32_t item_bit_size, - uint32_t item_bit_offset, - ExecutionContextScope *exe_scope = nullptr) const; - - //------------------------------------------------------------------ - /// Dump a UUID value at \a offset. - /// - /// Dump a UUID starting at \a offset bytes into this object's data. - /// If the stream \a s is nullptr, the output will be sent to Log(). - /// - /// @param[in] s - /// The stream to dump the output to. If nullptr the output will - /// be dumped to Log(). - /// - /// @param[in] offset - /// The offset into the data at which to extract and dump a - /// UUID value. - //------------------------------------------------------------------ - void - DumpUUID (Stream *s, lldb::offset_t offset) const; - - //------------------------------------------------------------------ - /// Extract an arbitrary number of bytes in the specified byte - /// order. - /// - /// Attemps to extract \a length bytes starting at \a offset bytes - /// into this data in the requested byte order (\a dst_byte_order) - /// and place the results in \a dst. \a dst must be at least \a - /// length bytes long. - /// - /// @param[in] offset - /// The offset in bytes into the contained data at which to - /// start extracting. - /// - /// @param[in] length - /// The number of bytes to extract. - /// - /// @param[in] dst_byte_order - /// A byte order of the data that we want when the value in - /// copied to \a dst. - /// - /// @param[out] dst - /// The buffer that will receive the extracted value if there - /// are enough bytes available in the current data. - /// - /// @return - /// The number of bytes that were extracted which will be \a - /// length when the value is successfully extracted, or zero - /// if there aren't enough bytes at the specified offset. - //------------------------------------------------------------------ - size_t - ExtractBytes (lldb::offset_t offset, lldb::offset_t length, lldb::ByteOrder dst_byte_order, void *dst) const; - - //------------------------------------------------------------------ - /// Extract an address from \a *offset_ptr. - /// - /// Extract a single address from the data and update the offset - /// pointed to by \a offset_ptr. The size of the extracted address - /// comes from the \a m_addr_size member variable and should be - /// set correctly prior to extracting any address values. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted address value. - //------------------------------------------------------------------ - uint64_t - GetAddress (lldb::offset_t *offset_ptr) const; - - uint64_t - GetAddress_unchecked (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Get the current address size. - /// - /// Return the size in bytes of any address values this object will - /// extract. - /// - /// @return - /// The size in bytes of address values that will be extracted. - //------------------------------------------------------------------ - uint32_t - GetAddressByteSize () const - { - return m_addr_size; - } - - //------------------------------------------------------------------ - /// Get the number of bytes contained in this object. - /// - /// @return - /// The total number of bytes of data this object refers to. - //------------------------------------------------------------------ - uint64_t - GetByteSize () const - { - return m_end - m_start; - } - - //------------------------------------------------------------------ - /// Extract a C string from \a *offset_ptr. - /// - /// Returns a pointer to a C String from the data at the offset - /// pointed to by \a offset_ptr. A variable length NULL terminated C - /// string will be extracted and the \a offset_ptr will be - /// updated with the offset of the byte that follows the NULL - /// terminator byte. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// A pointer to the C string value in the data. If the offset - /// pointed to by \a offset_ptr is out of bounds, or if the - /// offset plus the length of the C string is out of bounds, - /// nullptr will be returned. - //------------------------------------------------------------------ - const char * - GetCStr (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Extract a C string from \a *offset_ptr with field size \a len. - /// - /// Returns a pointer to a C String from the data at the offset - /// pointed to by \a offset_ptr, with a field length of \a len. - /// A NULL terminated C string will be extracted and the \a offset_ptr - /// will be updated with the offset of the byte that follows the fixed - /// length field. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// A pointer to the C string value in the data. If the offset - /// pointed to by \a offset_ptr is out of bounds, or if the - /// offset plus the length of the field is out of bounds, or if - /// the field does not contain a NULL terminator byte, nullptr will - /// be returned. - const char * - GetCStr (lldb::offset_t *offset_ptr, lldb::offset_t len) const; - - //------------------------------------------------------------------ - /// Extract \a length bytes from \a *offset_ptr. - /// - /// Returns a pointer to a bytes in this object's data at the offset - /// pointed to by \a offset_ptr. If \a length is zero or too large, - /// then the offset pointed to by \a offset_ptr will not be updated - /// and nullptr will be returned. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[in] length - /// The optional length of a string to extract. If the value is - /// zero, a NULL terminated C string will be extracted. - /// - /// @return - /// A pointer to the bytes in this object's data if the offset - /// and length are valid, or nullptr otherwise. - //------------------------------------------------------------------ - const void* - GetData (lldb::offset_t *offset_ptr, lldb::offset_t length) const - { - const uint8_t *ptr = PeekData (*offset_ptr, length); - if (ptr) - *offset_ptr += length; - return ptr; - } - - //------------------------------------------------------------------ - /// Copy \a length bytes from \a *offset, without swapping bytes. - /// - /// @param[in] offset - /// The offset into this data from which to start copying - /// - /// @param[in] length - /// The length of the data to copy from this object - /// - /// @param[out] dst - /// The buffer to place the output data. - /// - /// @return - /// Returns the number of bytes that were copied, or zero if - /// anything goes wrong. - //------------------------------------------------------------------ - lldb::offset_t - CopyData (lldb::offset_t offset, - lldb::offset_t length, - void *dst) const; - - //------------------------------------------------------------------ - /// Copy \a dst_len bytes from \a *offset_ptr and ensure the copied - /// data is treated as a value that can be swapped to match the - /// specified byte order. - /// - /// For values that are larger than the supported integer sizes, - /// this function can be used to extract data in a specified byte - /// order. It can also be used to copy a smaller integer value from - /// to a larger value. The extra bytes left over will be padded - /// correctly according to the byte order of this object and the - /// \a dst_byte_order. This can be very handy when say copying a - /// partial data value into a register. - /// - /// @param[in] src_offset - /// The offset into this data from which to start copying an - /// endian entity - /// - /// @param[in] src_len - /// The length of the endian data to copy from this object - /// into the \a dst object - /// - /// @param[out] dst - /// The buffer where to place the endian data. The data might - /// need to be byte swapped (and appropriately padded with - /// zeroes if \a src_len != \a dst_len) if \a dst_byte_order - /// does not match the byte order in this object. - /// - /// @param[in] dst_len - /// The length number of bytes that the endian value will - /// occupy is \a dst. - /// - /// @param[in] byte_order - /// The byte order that the endian value should be in the \a dst - /// buffer. - /// - /// @return - /// Returns the number of bytes that were copied, or zero if - /// anything goes wrong. - //------------------------------------------------------------------ - lldb::offset_t - CopyByteOrderedData (lldb::offset_t src_offset, - lldb::offset_t src_len, - void *dst, - lldb::offset_t dst_len, - lldb::ByteOrder dst_byte_order) const; - - //------------------------------------------------------------------ - /// Get the data end pointer. - /// - /// @return - /// Returns a pointer to the next byte contained in this - /// object's data, or nullptr of there is no data in this object. - //------------------------------------------------------------------ - const uint8_t * - GetDataEnd () const - { - return m_end; - } - - //------------------------------------------------------------------ - /// Get the shared data offset. - /// - /// Get the offset of the first byte of data in the shared data (if - /// any). - /// - /// @return - /// If this object contains shared data, this function returns - /// the offset in bytes into that shared data, zero otherwise. - //------------------------------------------------------------------ - size_t - GetSharedDataOffset () const; - - //------------------------------------------------------------------ - /// Get the data start pointer. - /// - /// @return - /// Returns a pointer to the first byte contained in this - /// object's data, or nullptr of there is no data in this object. - //------------------------------------------------------------------ - const uint8_t * - GetDataStart () const - { - return m_start; - } - - //------------------------------------------------------------------ - /// Extract a float from \a *offset_ptr. - /// - /// Extract a single float value. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The floating value that was extracted, or zero on failure. - //------------------------------------------------------------------ - float - GetFloat (lldb::offset_t *offset_ptr) const; - - double - GetDouble (lldb::offset_t *offset_ptr) const; - - long double - GetLongDouble (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Extract a GNU encoded pointer value from \a *offset_ptr. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[in] eh_ptr_enc - /// The GNU pointer encoding type. - /// - /// @param[in] pc_rel_addr - /// The PC relative address to use when the encoding is - /// \c DW_GNU_EH_PE_pcrel. - /// - /// @param[in] text_addr - /// The text (code) relative address to use when the encoding is - /// \c DW_GNU_EH_PE_textrel. - /// - /// @param[in] data_addr - /// The data relative address to use when the encoding is - /// \c DW_GNU_EH_PE_datarel. - /// - /// @return - /// The extracted GNU encoded pointer value. - //------------------------------------------------------------------ - uint64_t - GetGNUEHPointer (lldb::offset_t *offset_ptr, - uint32_t eh_ptr_enc, - lldb::addr_t pc_rel_addr, - lldb::addr_t text_addr, - lldb::addr_t data_addr); - - //------------------------------------------------------------------ - /// Extract an integer of size \a byte_size from \a *offset_ptr. - /// - /// Extract a single integer value and update the offset pointed to - /// by \a offset_ptr. The size of the extracted integer is specified - /// by the \a byte_size argument. \a byte_size should have a value - /// >= 1 and <= 4 since the return value is only 32 bits wide. Any - /// \a byte_size values less than 1 or greater than 4 will result in - /// nothing being extracted, and zero being returned. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[in] byte_size - /// The size in byte of the integer to extract. - /// - /// @return - /// The integer value that was extracted, or zero on failure. - //------------------------------------------------------------------ - uint32_t - GetMaxU32 (lldb::offset_t *offset_ptr, size_t byte_size) const; - - //------------------------------------------------------------------ - /// Extract an unsigned integer of size \a byte_size from \a - /// *offset_ptr. - /// - /// Extract a single unsigned integer value and update the offset - /// pointed to by \a offset_ptr. The size of the extracted integer - /// is specified by the \a byte_size argument. \a byte_size should - /// have a value greater than or equal to one and less than or equal - /// to eight since the return value is 64 bits wide. Any - /// \a byte_size values less than 1 or greater than 8 will result in - /// nothing being extracted, and zero being returned. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[in] byte_size - /// The size in byte of the integer to extract. - /// - /// @return - /// The unsigned integer value that was extracted, or zero on - /// failure. - //------------------------------------------------------------------ - uint64_t - GetMaxU64 (lldb::offset_t *offset_ptr, size_t byte_size) const; - - uint64_t - GetMaxU64_unchecked (lldb::offset_t *offset_ptr, size_t byte_size) const; - - //------------------------------------------------------------------ - /// Extract an signed integer of size \a byte_size from \a *offset_ptr. - /// - /// Extract a single signed integer value (sign extending if required) - /// and update the offset pointed to by \a offset_ptr. The size of - /// the extracted integer is specified by the \a byte_size argument. - /// \a byte_size should have a value greater than or equal to one - /// and less than or equal to eight since the return value is 64 - /// bits wide. Any \a byte_size values less than 1 or greater than - /// 8 will result in nothing being extracted, and zero being returned. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[in] byte_size - /// The size in byte of the integer to extract. - /// - /// @return - /// The sign extended signed integer value that was extracted, - /// or zero on failure. - //------------------------------------------------------------------ - int64_t - GetMaxS64 (lldb::offset_t *offset_ptr, size_t size) const; - - //------------------------------------------------------------------ - /// Extract an unsigned integer of size \a byte_size from \a - /// *offset_ptr, then extract the bitfield from this value if - /// \a bitfield_bit_size is non-zero. - /// - /// Extract a single unsigned integer value and update the offset - /// pointed to by \a offset_ptr. The size of the extracted integer - /// is specified by the \a byte_size argument. \a byte_size should - /// have a value greater than or equal to one and less than or equal - /// to 8 since the return value is 64 bits wide. Any - /// \a byte_size values less than 1 or greater than 8 will result in - /// nothing being extracted, and zero being returned. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[in] byte_size - /// The size in byte of the integer to extract. - /// - /// @param[in] bitfield_bit_size - /// The size in bits of the bitfield value to extract, or zero - /// to just extract the entire integer value. - /// - /// @param[in] bitfield_bit_offset - /// The bit offset of the bitfield value in the extracted - /// integer. For little-endian data, this is the offset of - /// the LSB of the bitfield from the LSB of the integer. - /// For big-endian data, this is the offset of the MSB of the - /// bitfield from the MSB of the integer. - /// - /// @return - /// The unsigned bitfield integer value that was extracted, or - /// zero on failure. - //------------------------------------------------------------------ - uint64_t - GetMaxU64Bitfield (lldb::offset_t *offset_ptr, - size_t size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset) const; - - //------------------------------------------------------------------ - /// Extract an signed integer of size \a byte_size from \a - /// *offset_ptr, then extract and signe extend the bitfield from - /// this value if \a bitfield_bit_size is non-zero. - /// - /// Extract a single signed integer value (sign extending if required) - /// and update the offset pointed to by \a offset_ptr. The size of - /// the extracted integer is specified by the \a byte_size argument. - /// \a byte_size should have a value greater than or equal to one - /// and less than or equal to eight since the return value is 64 - /// bits wide. Any \a byte_size values less than 1 or greater than - /// 8 will result in nothing being extracted, and zero being returned. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[in] byte_size - /// The size in bytes of the integer to extract. - /// - /// @param[in] bitfield_bit_size - /// The size in bits of the bitfield value to extract, or zero - /// to just extract the entire integer value. - /// - /// @param[in] bitfield_bit_offset - /// The bit offset of the bitfield value in the extracted - /// integer. For little-endian data, this is the offset of - /// the LSB of the bitfield from the LSB of the integer. - /// For big-endian data, this is the offset of the MSB of the - /// bitfield from the MSB of the integer. - /// - /// @return - /// The signed bitfield integer value that was extracted, or - /// zero on failure. - //------------------------------------------------------------------ - int64_t - GetMaxS64Bitfield (lldb::offset_t *offset_ptr, - size_t size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset) const; - - //------------------------------------------------------------------ - /// Extract an pointer from \a *offset_ptr. - /// - /// Extract a single pointer from the data and update the offset - /// pointed to by \a offset_ptr. The size of the extracted pointer - /// comes from the \a m_addr_size member variable and should be - /// set correctly prior to extracting any pointer values. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted pointer value as a 64 integer. - //------------------------------------------------------------------ - uint64_t - GetPointer (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Get the current byte order value. - /// - /// @return - /// The current byte order value from this object's internal - /// state. - //------------------------------------------------------------------ - lldb::ByteOrder - GetByteOrder() const - { - return m_byte_order; - } - - //------------------------------------------------------------------ - /// Extract a uint8_t value from \a *offset_ptr. - /// - /// Extract a single uint8_t from the binary data at the offset - /// pointed to by \a offset_ptr, and advance the offset on success. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted uint8_t value. - //------------------------------------------------------------------ - uint8_t - GetU8 ( lldb::offset_t *offset_ptr) const; - - uint8_t - GetU8_unchecked (lldb::offset_t *offset_ptr) const - { - uint8_t val = m_start[*offset_ptr]; - *offset_ptr += 1; - return val; - } - - uint16_t - GetU16_unchecked (lldb::offset_t *offset_ptr) const; - - uint32_t - GetU32_unchecked (lldb::offset_t *offset_ptr) const; - - uint64_t - GetU64_unchecked (lldb::offset_t *offset_ptr) const; - //------------------------------------------------------------------ - /// Extract \a count uint8_t values from \a *offset_ptr. - /// - /// Extract \a count uint8_t values from the binary data at the - /// offset pointed to by \a offset_ptr, and advance the offset on - /// success. The extracted values are copied into \a dst. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[out] dst - /// A buffer to copy \a count uint8_t values into. \a dst must - /// be large enough to hold all requested data. - /// - /// @param[in] count - /// The number of uint8_t values to extract. - /// - /// @return - /// \a dst if all values were properly extracted and copied, - /// nullptr otherwise. - //------------------------------------------------------------------ - void * - GetU8 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; - - //------------------------------------------------------------------ - /// Extract a uint16_t value from \a *offset_ptr. - /// - /// Extract a single uint16_t from the binary data at the offset - /// pointed to by \a offset_ptr, and update the offset on success. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted uint16_t value. - //------------------------------------------------------------------ - uint16_t - GetU16 (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Extract \a count uint16_t values from \a *offset_ptr. - /// - /// Extract \a count uint16_t values from the binary data at the - /// offset pointed to by \a offset_ptr, and advance the offset on - /// success. The extracted values are copied into \a dst. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[out] dst - /// A buffer to copy \a count uint16_t values into. \a dst must - /// be large enough to hold all requested data. - /// - /// @param[in] count - /// The number of uint16_t values to extract. - /// - /// @return - /// \a dst if all values were properly extracted and copied, - /// nullptr otherwise. - //------------------------------------------------------------------ - void * - GetU16 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; - - //------------------------------------------------------------------ - /// Extract a uint32_t value from \a *offset_ptr. - /// - /// Extract a single uint32_t from the binary data at the offset - /// pointed to by \a offset_ptr, and update the offset on success. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted uint32_t value. - //------------------------------------------------------------------ - uint32_t - GetU32 (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Extract \a count uint32_t values from \a *offset_ptr. - /// - /// Extract \a count uint32_t values from the binary data at the - /// offset pointed to by \a offset_ptr, and advance the offset on - /// success. The extracted values are copied into \a dst. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[out] dst - /// A buffer to copy \a count uint32_t values into. \a dst must - /// be large enough to hold all requested data. - /// - /// @param[in] count - /// The number of uint32_t values to extract. - /// - /// @return - /// \a dst if all values were properly extracted and copied, - /// nullptr otherwise. - //------------------------------------------------------------------ - void * - GetU32 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; - - //------------------------------------------------------------------ - /// Extract a uint64_t value from \a *offset_ptr. - /// - /// Extract a single uint64_t from the binary data at the offset - /// pointed to by \a offset_ptr, and update the offset on success. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted uint64_t value. - //------------------------------------------------------------------ - uint64_t - GetU64 (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Extract \a count uint64_t values from \a *offset_ptr. - /// - /// Extract \a count uint64_t values from the binary data at the - /// offset pointed to by \a offset_ptr, and advance the offset on - /// success. The extracted values are copied into \a dst. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @param[out] dst - /// A buffer to copy \a count uint64_t values into. \a dst must - /// be large enough to hold all requested data. - /// - /// @param[in] count - /// The number of uint64_t values to extract. - /// - /// @return - /// \a dst if all values were properly extracted and copied, - /// nullptr otherwise. - //------------------------------------------------------------------ - void * - GetU64 ( lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; - - //------------------------------------------------------------------ - /// Extract a signed LEB128 value from \a *offset_ptr. - /// - /// Extracts an signed LEB128 number from this object's data - /// starting at the offset pointed to by \a offset_ptr. The offset - /// pointed to by \a offset_ptr will be updated with the offset of - /// the byte following the last extracted byte. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted signed integer value. - //------------------------------------------------------------------ - int64_t - GetSLEB128 (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Extract a unsigned LEB128 value from \a *offset_ptr. - /// - /// Extracts an unsigned LEB128 number from this object's data - /// starting at the offset pointed to by \a offset_ptr. The offset - /// pointed to by \a offset_ptr will be updated with the offset of - /// the byte following the last extracted byte. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - /// The extracted unsigned integer value. - //------------------------------------------------------------------ - uint64_t - GetULEB128 (lldb::offset_t *offset_ptr) const; - - lldb::DataBufferSP & - GetSharedDataBuffer () - { - return m_data_sp; - } - - //------------------------------------------------------------------ - /// Peek at a C string at \a offset. - /// - /// Peeks at a string in the contained data. No verification is done - /// to make sure the entire string lies within the bounds of this - /// object's data, only \a offset is verified to be a valid offset. - /// - /// @param[in] offset - /// An offset into the data. - /// - /// @return - /// A non-nullptr C string pointer if \a offset is a valid offset, - /// nullptr otherwise. - //------------------------------------------------------------------ - const char * - PeekCStr (lldb::offset_t offset) const; - - //------------------------------------------------------------------ - /// Peek at a bytes at \a offset. - /// - /// Returns a pointer to \a length bytes at \a offset as long as - /// there are \a length bytes available starting at \a offset. - /// - /// @return - /// A non-nullptr data pointer if \a offset is a valid offset and - /// there are \a length bytes available at that offset, nullptr - /// otherwise. - //------------------------------------------------------------------ - const uint8_t* - PeekData (lldb::offset_t offset, lldb::offset_t length) const - { - if (length > 0 && ValidOffsetForDataOfSize(offset, length)) - return m_start + offset; - return nullptr; - } - - //------------------------------------------------------------------ - /// Set the address byte size. - /// - /// Set the size in bytes that will be used when extracting any - /// address and pointer values from data contained in this object. - /// - /// @param[in] addr_size - /// The size in bytes to use when extracting addresses. - //------------------------------------------------------------------ - void - SetAddressByteSize (uint32_t addr_size) - { + //------------------------------------------------------------------ + /// @typedef DataExtractor::Type + /// @brief Type enumerations used in the dump routines. + /// @see DataExtractor::Dump() + /// @see DataExtractor::DumpRawHexBytes() + //------------------------------------------------------------------ + typedef enum { + TypeUInt8, ///< Format output as unsigned 8 bit integers + TypeChar, ///< Format output as characters + TypeUInt16, ///< Format output as unsigned 16 bit integers + TypeUInt32, ///< Format output as unsigned 32 bit integers + TypeUInt64, ///< Format output as unsigned 64 bit integers + TypePointer, ///< Format output as pointers + TypeULEB128, ///< Format output as ULEB128 numbers + TypeSLEB128 ///< Format output as SLEB128 numbers + } Type; + + static void DumpHexBytes(Stream *s, const void *src, size_t src_len, + uint32_t bytes_per_line, + lldb::addr_t base_addr); // Pass LLDB_INVALID_ADDRESS + // to not show address at + // start of line + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize all members to a default empty state. + //------------------------------------------------------------------ + DataExtractor(); + + //------------------------------------------------------------------ + /// Construct with a buffer that is owned by the caller. + /// + /// This constructor allows us to use data that is owned by the + /// caller. The data must stay around as long as this object is + /// valid. + /// + /// @param[in] data + /// A pointer to caller owned data. + /// + /// @param[in] data_length + /// The length in bytes of \a data. + /// + /// @param[in] byte_order + /// A byte order of the data that we are extracting from. + /// + /// @param[in] addr_size + /// A new address byte size value. + /// + /// @param[in] target_byte_size + /// A size of a target byte in 8-bit host bytes + //------------------------------------------------------------------ + DataExtractor(const void *data, lldb::offset_t data_length, + lldb::ByteOrder byte_order, uint32_t addr_size, + uint32_t target_byte_size = 1); + + //------------------------------------------------------------------ + /// Construct with shared data. + /// + /// Copies the data shared pointer which adds a reference to the + /// contained in \a data_sp. The shared data reference is reference + /// counted to ensure the data lives as long as anyone still has a + /// valid shared pointer to the data in \a data_sp. + /// + /// @param[in] data_sp + /// A shared pointer to data. + /// + /// @param[in] byte_order + /// A byte order of the data that we are extracting from. + /// + /// @param[in] addr_size + /// A new address byte size value. + /// + /// @param[in] target_byte_size + /// A size of a target byte in 8-bit host bytes + //------------------------------------------------------------------ + DataExtractor(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order, + uint32_t addr_size, uint32_t target_byte_size = 1); + + //------------------------------------------------------------------ + /// Construct with a subset of \a data. + /// + /// Initialize this object with a subset of the data bytes in \a + /// data. If \a data contains shared data, then a reference to the + /// shared data will be added to ensure the shared data stays around + /// as long as any objects have references to the shared data. The + /// byte order value and the address size settings are copied from \a + /// data. If \a offset is not a valid offset in \a data, then no + /// reference to the shared data will be added. If there are not + /// \a length bytes available in \a data starting at \a offset, + /// the length will be truncated to contain as many bytes as + /// possible. + /// + /// @param[in] data + /// Another DataExtractor object that contains data. + /// + /// @param[in] offset + /// The offset into \a data at which the subset starts. + /// + /// @param[in] length + /// The length in bytes of the subset of data. + /// + /// @param[in] target_byte_size + /// A size of a target byte in 8-bit host bytes + //------------------------------------------------------------------ + DataExtractor(const DataExtractor &data, lldb::offset_t offset, + lldb::offset_t length, uint32_t target_byte_size = 1); + + DataExtractor(const DataExtractor &rhs); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Copies all data, byte order and address size settings from \a rhs into + /// this object. If \a rhs contains shared data, a reference to that + /// shared data will be added. + /// + /// @param[in] rhs + /// Another DataExtractor object to copy. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const DataExtractor &operator=(const DataExtractor &rhs); + + //------------------------------------------------------------------ + /// Destructor + /// + /// If this object contains a valid shared data reference, the + /// reference count on the data will be decremented, and if zero, + /// the data will be freed. + //------------------------------------------------------------------ + ~DataExtractor(); + + //------------------------------------------------------------------ + /// Clears the object state. + /// + /// Clears the object contents back to a default invalid state, and + /// release any references to shared data that this object may + /// contain. + //------------------------------------------------------------------ + void Clear(); + + //------------------------------------------------------------------ + /// Dumps the binary data as \a type objects to stream \a s (or to + /// Log() if \a s is nullptr) starting \a offset bytes into the data + /// and stopping after dumping \a length bytes. The offset into the + /// data is displayed at the beginning of each line and can be + /// offset by base address \a base_addr. \a num_per_line objects + /// will be displayed on each line. + /// + /// @param[in] s + /// The stream to dump the output to. If nullptr the output will + /// be dumped to Log(). + /// + /// @param[in] offset + /// The offset into the data at which to start dumping. + /// + /// @param[in] length + /// The number of bytes to dump. + /// + /// @param[in] base_addr + /// The base address that gets added to the offset displayed on + /// each line. + /// + /// @param[in] num_per_line + /// The number of \a type objects to display on each line. + /// + /// @param[in] type + /// The type of objects to use when dumping data from this + /// object. See DataExtractor::Type. + /// + /// @param[in] type_format + /// The optional format to use for the \a type objects. If this + /// is nullptr, the default format for the \a type will be used. + /// + /// @return + /// The offset at which dumping ended. + //------------------------------------------------------------------ + lldb::offset_t PutToLog(Log *log, lldb::offset_t offset, + lldb::offset_t length, uint64_t base_addr, + uint32_t num_per_line, Type type, + const char *type_format = nullptr) const; + + //------------------------------------------------------------------ + /// Dumps \a item_count objects into the stream \a s. + /// + /// Dumps \a item_count objects using \a item_format, each of which + /// are \a item_byte_size bytes long starting at offset \a offset + /// bytes into the contained data, into the stream \a s. \a + /// num_per_line objects will be dumped on each line before a new + /// line will be output. If \a base_addr is a valid address, then + /// each new line of output will be preceded by the address value + /// plus appropriate offset, and a colon and space. Bitfield values + /// can be dumped by calling this function multiple times with the + /// same start offset, format and size, yet differing \a + /// item_bit_size and \a item_bit_offset values. + /// + /// @param[in] s + /// The stream to dump the output to. This value can not be nullptr. + /// + /// @param[in] offset + /// The offset into the data at which to start dumping. + /// + /// @param[in] item_format + /// The format to use when dumping each item. + /// + /// @param[in] item_byte_size + /// The byte size of each item. + /// + /// @param[in] item_count + /// The number of items to dump. + /// + /// @param[in] num_per_line + /// The number of items to display on each line. + /// + /// @param[in] base_addr + /// The base address that gets added to the offset displayed on + /// each line if the value is valid. Is \a base_addr is + /// LLDB_INVALID_ADDRESS then no address values will be prepended + /// to any lines. + /// + /// @param[in] item_bit_size + /// If the value to display is a bitfield, this value should + /// be the number of bits that the bitfield item has within the + /// item's byte size value. This function will need to be called + /// multiple times with identical \a offset and \a item_byte_size + /// values in order to display multiple bitfield values that + /// exist within the same integer value. If the items being + /// displayed are not bitfields, this value should be zero. + /// + /// @param[in] item_bit_offset + /// If the value to display is a bitfield, this value should + /// be the offset in bits, or shift right amount, that the + /// bitfield item occupies within the item's byte size value. + /// This function will need to be called multiple times with + /// identical \a offset and \a item_byte_size values in order + /// to display multiple bitfield values that exist within the + /// same integer value. If the items being displayed are not + /// bitfields, this value should be zero. + /// + /// @return + /// The offset at which dumping ended. + //------------------------------------------------------------------ + lldb::offset_t Dump(Stream *s, lldb::offset_t offset, + lldb::Format item_format, size_t item_byte_size, + size_t item_count, size_t num_per_line, + uint64_t base_addr, uint32_t item_bit_size, + uint32_t item_bit_offset, + ExecutionContextScope *exe_scope = nullptr) const; + + //------------------------------------------------------------------ + /// Dump a UUID value at \a offset. + /// + /// Dump a UUID starting at \a offset bytes into this object's data. + /// If the stream \a s is nullptr, the output will be sent to Log(). + /// + /// @param[in] s + /// The stream to dump the output to. If nullptr the output will + /// be dumped to Log(). + /// + /// @param[in] offset + /// The offset into the data at which to extract and dump a + /// UUID value. + //------------------------------------------------------------------ + void DumpUUID(Stream *s, lldb::offset_t offset) const; + + //------------------------------------------------------------------ + /// Extract an arbitrary number of bytes in the specified byte + /// order. + /// + /// Attemps to extract \a length bytes starting at \a offset bytes + /// into this data in the requested byte order (\a dst_byte_order) + /// and place the results in \a dst. \a dst must be at least \a + /// length bytes long. + /// + /// @param[in] offset + /// The offset in bytes into the contained data at which to + /// start extracting. + /// + /// @param[in] length + /// The number of bytes to extract. + /// + /// @param[in] dst_byte_order + /// A byte order of the data that we want when the value in + /// copied to \a dst. + /// + /// @param[out] dst + /// The buffer that will receive the extracted value if there + /// are enough bytes available in the current data. + /// + /// @return + /// The number of bytes that were extracted which will be \a + /// length when the value is successfully extracted, or zero + /// if there aren't enough bytes at the specified offset. + //------------------------------------------------------------------ + size_t ExtractBytes(lldb::offset_t offset, lldb::offset_t length, + lldb::ByteOrder dst_byte_order, void *dst) const; + + //------------------------------------------------------------------ + /// Extract an address from \a *offset_ptr. + /// + /// Extract a single address from the data and update the offset + /// pointed to by \a offset_ptr. The size of the extracted address + /// comes from the \a m_addr_size member variable and should be + /// set correctly prior to extracting any address values. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted address value. + //------------------------------------------------------------------ + uint64_t GetAddress(lldb::offset_t *offset_ptr) const; + + uint64_t GetAddress_unchecked(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Get the current address size. + /// + /// Return the size in bytes of any address values this object will + /// extract. + /// + /// @return + /// The size in bytes of address values that will be extracted. + //------------------------------------------------------------------ + uint32_t GetAddressByteSize() const { return m_addr_size; } + + //------------------------------------------------------------------ + /// Get the number of bytes contained in this object. + /// + /// @return + /// The total number of bytes of data this object refers to. + //------------------------------------------------------------------ + uint64_t GetByteSize() const { return m_end - m_start; } + + //------------------------------------------------------------------ + /// Extract a C string from \a *offset_ptr. + /// + /// Returns a pointer to a C String from the data at the offset + /// pointed to by \a offset_ptr. A variable length NULL terminated C + /// string will be extracted and the \a offset_ptr will be + /// updated with the offset of the byte that follows the NULL + /// terminator byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// A pointer to the C string value in the data. If the offset + /// pointed to by \a offset_ptr is out of bounds, or if the + /// offset plus the length of the C string is out of bounds, + /// nullptr will be returned. + //------------------------------------------------------------------ + const char *GetCStr(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract a C string from \a *offset_ptr with field size \a len. + /// + /// Returns a pointer to a C String from the data at the offset + /// pointed to by \a offset_ptr, with a field length of \a len. + /// A NULL terminated C string will be extracted and the \a offset_ptr + /// will be updated with the offset of the byte that follows the fixed + /// length field. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// A pointer to the C string value in the data. If the offset + /// pointed to by \a offset_ptr is out of bounds, or if the + /// offset plus the length of the field is out of bounds, or if + /// the field does not contain a NULL terminator byte, nullptr will + /// be returned. + const char *GetCStr(lldb::offset_t *offset_ptr, lldb::offset_t len) const; + + //------------------------------------------------------------------ + /// Extract \a length bytes from \a *offset_ptr. + /// + /// Returns a pointer to a bytes in this object's data at the offset + /// pointed to by \a offset_ptr. If \a length is zero or too large, + /// then the offset pointed to by \a offset_ptr will not be updated + /// and nullptr will be returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] length + /// The optional length of a string to extract. If the value is + /// zero, a NULL terminated C string will be extracted. + /// + /// @return + /// A pointer to the bytes in this object's data if the offset + /// and length are valid, or nullptr otherwise. + //------------------------------------------------------------------ + const void *GetData(lldb::offset_t *offset_ptr, lldb::offset_t length) const { + const uint8_t *ptr = PeekData(*offset_ptr, length); + if (ptr) + *offset_ptr += length; + return ptr; + } + + //------------------------------------------------------------------ + /// Copy \a length bytes from \a *offset, without swapping bytes. + /// + /// @param[in] offset + /// The offset into this data from which to start copying + /// + /// @param[in] length + /// The length of the data to copy from this object + /// + /// @param[out] dst + /// The buffer to place the output data. + /// + /// @return + /// Returns the number of bytes that were copied, or zero if + /// anything goes wrong. + //------------------------------------------------------------------ + lldb::offset_t CopyData(lldb::offset_t offset, lldb::offset_t length, + void *dst) const; + + //------------------------------------------------------------------ + /// Copy \a dst_len bytes from \a *offset_ptr and ensure the copied + /// data is treated as a value that can be swapped to match the + /// specified byte order. + /// + /// For values that are larger than the supported integer sizes, + /// this function can be used to extract data in a specified byte + /// order. It can also be used to copy a smaller integer value from + /// to a larger value. The extra bytes left over will be padded + /// correctly according to the byte order of this object and the + /// \a dst_byte_order. This can be very handy when say copying a + /// partial data value into a register. + /// + /// @param[in] src_offset + /// The offset into this data from which to start copying an + /// endian entity + /// + /// @param[in] src_len + /// The length of the endian data to copy from this object + /// into the \a dst object + /// + /// @param[out] dst + /// The buffer where to place the endian data. The data might + /// need to be byte swapped (and appropriately padded with + /// zeroes if \a src_len != \a dst_len) if \a dst_byte_order + /// does not match the byte order in this object. + /// + /// @param[in] dst_len + /// The length number of bytes that the endian value will + /// occupy is \a dst. + /// + /// @param[in] byte_order + /// The byte order that the endian value should be in the \a dst + /// buffer. + /// + /// @return + /// Returns the number of bytes that were copied, or zero if + /// anything goes wrong. + //------------------------------------------------------------------ + lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset, + lldb::offset_t src_len, void *dst, + lldb::offset_t dst_len, + lldb::ByteOrder dst_byte_order) const; + + //------------------------------------------------------------------ + /// Get the data end pointer. + /// + /// @return + /// Returns a pointer to the next byte contained in this + /// object's data, or nullptr of there is no data in this object. + //------------------------------------------------------------------ + const uint8_t *GetDataEnd() const { return m_end; } + + //------------------------------------------------------------------ + /// Get the shared data offset. + /// + /// Get the offset of the first byte of data in the shared data (if + /// any). + /// + /// @return + /// If this object contains shared data, this function returns + /// the offset in bytes into that shared data, zero otherwise. + //------------------------------------------------------------------ + size_t GetSharedDataOffset() const; + + //------------------------------------------------------------------ + /// Get the data start pointer. + /// + /// @return + /// Returns a pointer to the first byte contained in this + /// object's data, or nullptr of there is no data in this object. + //------------------------------------------------------------------ + const uint8_t *GetDataStart() const { return m_start; } + + //------------------------------------------------------------------ + /// Extract a float from \a *offset_ptr. + /// + /// Extract a single float value. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The floating value that was extracted, or zero on failure. + //------------------------------------------------------------------ + float GetFloat(lldb::offset_t *offset_ptr) const; + + double GetDouble(lldb::offset_t *offset_ptr) const; + + long double GetLongDouble(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract a GNU encoded pointer value from \a *offset_ptr. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] eh_ptr_enc + /// The GNU pointer encoding type. + /// + /// @param[in] pc_rel_addr + /// The PC relative address to use when the encoding is + /// \c DW_GNU_EH_PE_pcrel. + /// + /// @param[in] text_addr + /// The text (code) relative address to use when the encoding is + /// \c DW_GNU_EH_PE_textrel. + /// + /// @param[in] data_addr + /// The data relative address to use when the encoding is + /// \c DW_GNU_EH_PE_datarel. + /// + /// @return + /// The extracted GNU encoded pointer value. + //------------------------------------------------------------------ + uint64_t GetGNUEHPointer(lldb::offset_t *offset_ptr, uint32_t eh_ptr_enc, + lldb::addr_t pc_rel_addr, lldb::addr_t text_addr, + lldb::addr_t data_addr); + + //------------------------------------------------------------------ + /// Extract an integer of size \a byte_size from \a *offset_ptr. + /// + /// Extract a single integer value and update the offset pointed to + /// by \a offset_ptr. The size of the extracted integer is specified + /// by the \a byte_size argument. \a byte_size should have a value + /// >= 1 and <= 4 since the return value is only 32 bits wide. Any + /// \a byte_size values less than 1 or greater than 4 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The integer value that was extracted, or zero on failure. + //------------------------------------------------------------------ + uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const; + + //------------------------------------------------------------------ + /// Extract an unsigned integer of size \a byte_size from \a + /// *offset_ptr. + /// + /// Extract a single unsigned integer value and update the offset + /// pointed to by \a offset_ptr. The size of the extracted integer + /// is specified by the \a byte_size argument. \a byte_size should + /// have a value greater than or equal to one and less than or equal + /// to eight since the return value is 64 bits wide. Any + /// \a byte_size values less than 1 or greater than 8 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The unsigned integer value that was extracted, or zero on + /// failure. + //------------------------------------------------------------------ + uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const; + + uint64_t GetMaxU64_unchecked(lldb::offset_t *offset_ptr, + size_t byte_size) const; + + //------------------------------------------------------------------ + /// Extract an signed integer of size \a byte_size from \a *offset_ptr. + /// + /// Extract a single signed integer value (sign extending if required) + /// and update the offset pointed to by \a offset_ptr. The size of + /// the extracted integer is specified by the \a byte_size argument. + /// \a byte_size should have a value greater than or equal to one + /// and less than or equal to eight since the return value is 64 + /// bits wide. Any \a byte_size values less than 1 or greater than + /// 8 will result in nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The sign extended signed integer value that was extracted, + /// or zero on failure. + //------------------------------------------------------------------ + int64_t GetMaxS64(lldb::offset_t *offset_ptr, size_t size) const; + + //------------------------------------------------------------------ + /// Extract an unsigned integer of size \a byte_size from \a + /// *offset_ptr, then extract the bitfield from this value if + /// \a bitfield_bit_size is non-zero. + /// + /// Extract a single unsigned integer value and update the offset + /// pointed to by \a offset_ptr. The size of the extracted integer + /// is specified by the \a byte_size argument. \a byte_size should + /// have a value greater than or equal to one and less than or equal + /// to 8 since the return value is 64 bits wide. Any + /// \a byte_size values less than 1 or greater than 8 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @param[in] bitfield_bit_size + /// The size in bits of the bitfield value to extract, or zero + /// to just extract the entire integer value. + /// + /// @param[in] bitfield_bit_offset + /// The bit offset of the bitfield value in the extracted + /// integer. For little-endian data, this is the offset of + /// the LSB of the bitfield from the LSB of the integer. + /// For big-endian data, this is the offset of the MSB of the + /// bitfield from the MSB of the integer. + /// + /// @return + /// The unsigned bitfield integer value that was extracted, or + /// zero on failure. + //------------------------------------------------------------------ + uint64_t GetMaxU64Bitfield(lldb::offset_t *offset_ptr, size_t size, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset) const; + + //------------------------------------------------------------------ + /// Extract an signed integer of size \a byte_size from \a + /// *offset_ptr, then extract and signe extend the bitfield from + /// this value if \a bitfield_bit_size is non-zero. + /// + /// Extract a single signed integer value (sign extending if required) + /// and update the offset pointed to by \a offset_ptr. The size of + /// the extracted integer is specified by the \a byte_size argument. + /// \a byte_size should have a value greater than or equal to one + /// and less than or equal to eight since the return value is 64 + /// bits wide. Any \a byte_size values less than 1 or greater than + /// 8 will result in nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in bytes of the integer to extract. + /// + /// @param[in] bitfield_bit_size + /// The size in bits of the bitfield value to extract, or zero + /// to just extract the entire integer value. + /// + /// @param[in] bitfield_bit_offset + /// The bit offset of the bitfield value in the extracted + /// integer. For little-endian data, this is the offset of + /// the LSB of the bitfield from the LSB of the integer. + /// For big-endian data, this is the offset of the MSB of the + /// bitfield from the MSB of the integer. + /// + /// @return + /// The signed bitfield integer value that was extracted, or + /// zero on failure. + //------------------------------------------------------------------ + int64_t GetMaxS64Bitfield(lldb::offset_t *offset_ptr, size_t size, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset) const; + + //------------------------------------------------------------------ + /// Extract an pointer from \a *offset_ptr. + /// + /// Extract a single pointer from the data and update the offset + /// pointed to by \a offset_ptr. The size of the extracted pointer + /// comes from the \a m_addr_size member variable and should be + /// set correctly prior to extracting any pointer values. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted pointer value as a 64 integer. + //------------------------------------------------------------------ + uint64_t GetPointer(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Get the current byte order value. + /// + /// @return + /// The current byte order value from this object's internal + /// state. + //------------------------------------------------------------------ + lldb::ByteOrder GetByteOrder() const { return m_byte_order; } + + //------------------------------------------------------------------ + /// Extract a uint8_t value from \a *offset_ptr. + /// + /// Extract a single uint8_t from the binary data at the offset + /// pointed to by \a offset_ptr, and advance the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint8_t value. + //------------------------------------------------------------------ + uint8_t GetU8(lldb::offset_t *offset_ptr) const; + + uint8_t GetU8_unchecked(lldb::offset_t *offset_ptr) const { + uint8_t val = m_start[*offset_ptr]; + *offset_ptr += 1; + return val; + } + + uint16_t GetU16_unchecked(lldb::offset_t *offset_ptr) const; + + uint32_t GetU32_unchecked(lldb::offset_t *offset_ptr) const; + + uint64_t GetU64_unchecked(lldb::offset_t *offset_ptr) const; + //------------------------------------------------------------------ + /// Extract \a count uint8_t values from \a *offset_ptr. + /// + /// Extract \a count uint8_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint8_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint8_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// nullptr otherwise. + //------------------------------------------------------------------ + void *GetU8(lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint16_t value from \a *offset_ptr. + /// + /// Extract a single uint16_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint16_t value. + //------------------------------------------------------------------ + uint16_t GetU16(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a count uint16_t values from \a *offset_ptr. + /// + /// Extract \a count uint16_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint16_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint16_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// nullptr otherwise. + //------------------------------------------------------------------ + void *GetU16(lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint32_t value from \a *offset_ptr. + /// + /// Extract a single uint32_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint32_t value. + //------------------------------------------------------------------ + uint32_t GetU32(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a count uint32_t values from \a *offset_ptr. + /// + /// Extract \a count uint32_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint32_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint32_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// nullptr otherwise. + //------------------------------------------------------------------ + void *GetU32(lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint64_t value from \a *offset_ptr. + /// + /// Extract a single uint64_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint64_t value. + //------------------------------------------------------------------ + uint64_t GetU64(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a count uint64_t values from \a *offset_ptr. + /// + /// Extract \a count uint64_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint64_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint64_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// nullptr otherwise. + //------------------------------------------------------------------ + void *GetU64(lldb::offset_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a signed LEB128 value from \a *offset_ptr. + /// + /// Extracts an signed LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted signed integer value. + //------------------------------------------------------------------ + int64_t GetSLEB128(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract a unsigned LEB128 value from \a *offset_ptr. + /// + /// Extracts an unsigned LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted unsigned integer value. + //------------------------------------------------------------------ + uint64_t GetULEB128(lldb::offset_t *offset_ptr) const; + + lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; } + + //------------------------------------------------------------------ + /// Peek at a C string at \a offset. + /// + /// Peeks at a string in the contained data. No verification is done + /// to make sure the entire string lies within the bounds of this + /// object's data, only \a offset is verified to be a valid offset. + /// + /// @param[in] offset + /// An offset into the data. + /// + /// @return + /// A non-nullptr C string pointer if \a offset is a valid offset, + /// nullptr otherwise. + //------------------------------------------------------------------ + const char *PeekCStr(lldb::offset_t offset) const; + + //------------------------------------------------------------------ + /// Peek at a bytes at \a offset. + /// + /// Returns a pointer to \a length bytes at \a offset as long as + /// there are \a length bytes available starting at \a offset. + /// + /// @return + /// A non-nullptr data pointer if \a offset is a valid offset and + /// there are \a length bytes available at that offset, nullptr + /// otherwise. + //------------------------------------------------------------------ + const uint8_t *PeekData(lldb::offset_t offset, lldb::offset_t length) const { + if (ValidOffsetForDataOfSize(offset, length)) + return m_start + offset; + return nullptr; + } + + //------------------------------------------------------------------ + /// Set the address byte size. + /// + /// Set the size in bytes that will be used when extracting any + /// address and pointer values from data contained in this object. + /// + /// @param[in] addr_size + /// The size in bytes to use when extracting addresses. + //------------------------------------------------------------------ + void SetAddressByteSize(uint32_t addr_size) { #ifdef LLDB_CONFIGURATION_DEBUG - assert (addr_size == 4 || addr_size == 8); + assert(addr_size == 4 || addr_size == 8); #endif - m_addr_size = addr_size; - } - - //------------------------------------------------------------------ - /// Set data with a buffer that is caller owned. - /// - /// Use data that is owned by the caller when extracting values. - /// The data must stay around as long as this object, or any object - /// that copies a subset of this object's data, is valid. If \a - /// bytes is nullptr, or \a length is zero, this object will contain - /// no data. - /// - /// @param[in] bytes - /// A pointer to caller owned data. - /// - /// @param[in] length - /// The length in bytes of \a bytes. - /// - /// @param[in] byte_order - /// A byte order of the data that we are extracting from. - /// - /// @return - /// The number of bytes that this object now contains. - //------------------------------------------------------------------ - lldb::offset_t - SetData (const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order); - - //------------------------------------------------------------------ - /// Adopt a subset of \a data. - /// - /// Set this object's data to be a subset of the data bytes in \a - /// data. If \a data contains shared data, then a reference to the - /// shared data will be added to ensure the shared data stays around - /// as long as any objects have references to the shared data. The - /// byte order and the address size settings are copied from \a - /// data. If \a offset is not a valid offset in \a data, then no - /// reference to the shared data will be added. If there are not - /// \a length bytes available in \a data starting at \a offset, - /// the length will be truncated to contains as many bytes as - /// possible. - /// - /// @param[in] data - /// Another DataExtractor object that contains data. - /// - /// @param[in] offset - /// The offset into \a data at which the subset starts. - /// - /// @param[in] length - /// The length in bytes of the subset of \a data. - /// - /// @return - /// The number of bytes that this object now contains. - //------------------------------------------------------------------ - lldb::offset_t - SetData (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length); - - //------------------------------------------------------------------ - /// Adopt a subset of shared data in \a data_sp. - /// - /// Copies the data shared pointer which adds a reference to the - /// contained in \a data_sp. The shared data reference is reference - /// counted to ensure the data lives as long as anyone still has a - /// valid shared pointer to the data in \a data_sp. The byte order - /// and address byte size settings remain the same. If - /// \a offset is not a valid offset in \a data_sp, then no reference - /// to the shared data will be added. If there are not \a length - /// bytes available in \a data starting at \a offset, the length - /// will be truncated to contains as many bytes as possible. - /// - /// @param[in] data_sp - /// A shared pointer to data. - /// - /// @param[in] offset - /// The offset into \a data_sp at which the subset starts. - /// - /// @param[in] length - /// The length in bytes of the subset of \a data_sp. - /// - /// @return - /// The number of bytes that this object now contains. - //------------------------------------------------------------------ - lldb::offset_t - SetData (const lldb::DataBufferSP& data_sp, lldb::offset_t offset = 0, lldb::offset_t length = LLDB_INVALID_OFFSET); - - //------------------------------------------------------------------ - /// Set the byte_order value. - /// - /// Sets the byte order of the data to extract. Extracted values - /// will be swapped if necessary when decoding. - /// - /// @param[in] byte_order - /// The byte order value to use when extracting data. - //------------------------------------------------------------------ - void - SetByteOrder (lldb::ByteOrder byte_order) - { - m_byte_order = byte_order; - } - - //------------------------------------------------------------------ - /// Skip an LEB128 number at \a *offset_ptr. - /// - /// Skips a LEB128 number (signed or unsigned) from this object's - /// data starting at the offset pointed to by \a offset_ptr. The - /// offset pointed to by \a offset_ptr will be updated with the - /// offset of the byte following the last extracted byte. - /// - /// @param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. - /// - /// @return - // The number of bytes consumed during the extraction. - //------------------------------------------------------------------ - uint32_t - Skip_LEB128 (lldb::offset_t *offset_ptr) const; - - //------------------------------------------------------------------ - /// Test the validity of \a offset. - /// - /// @return - /// \b true if \a offset is a valid offset into the data in this - /// object, \b false otherwise. - //------------------------------------------------------------------ - bool - ValidOffset (lldb::offset_t offset) const - { - return offset < GetByteSize(); - } - - //------------------------------------------------------------------ - /// Test the availability of \a length bytes of data from \a offset. - /// - /// @return - /// \b true if \a offset is a valid offset and there are \a - /// length bytes available at that offset, \b false otherwise. - //------------------------------------------------------------------ - bool - ValidOffsetForDataOfSize (lldb::offset_t offset, lldb::offset_t length) const - { - return length <= BytesLeft (offset); - } - - size_t - Copy (DataExtractor& dest_data) const; - - bool - Append (DataExtractor& rhs); - - bool - Append (void* bytes, lldb::offset_t length); - - lldb::offset_t - BytesLeft (lldb::offset_t offset) const - { - const lldb::offset_t size = GetByteSize(); - if (size > offset) - return size - offset; - return 0; - } - - void - Checksum (llvm::SmallVectorImpl<uint8_t> &dest, - uint64_t max_data = 0); + m_addr_size = addr_size; + } + + //------------------------------------------------------------------ + /// Set data with a buffer that is caller owned. + /// + /// Use data that is owned by the caller when extracting values. + /// The data must stay around as long as this object, or any object + /// that copies a subset of this object's data, is valid. If \a + /// bytes is nullptr, or \a length is zero, this object will contain + /// no data. + /// + /// @param[in] bytes + /// A pointer to caller owned data. + /// + /// @param[in] length + /// The length in bytes of \a bytes. + /// + /// @param[in] byte_order + /// A byte order of the data that we are extracting from. + /// + /// @return + /// The number of bytes that this object now contains. + //------------------------------------------------------------------ + lldb::offset_t SetData(const void *bytes, lldb::offset_t length, + lldb::ByteOrder byte_order); + + //------------------------------------------------------------------ + /// Adopt a subset of \a data. + /// + /// Set this object's data to be a subset of the data bytes in \a + /// data. If \a data contains shared data, then a reference to the + /// shared data will be added to ensure the shared data stays around + /// as long as any objects have references to the shared data. The + /// byte order and the address size settings are copied from \a + /// data. If \a offset is not a valid offset in \a data, then no + /// reference to the shared data will be added. If there are not + /// \a length bytes available in \a data starting at \a offset, + /// the length will be truncated to contains as many bytes as + /// possible. + /// + /// @param[in] data + /// Another DataExtractor object that contains data. + /// + /// @param[in] offset + /// The offset into \a data at which the subset starts. + /// + /// @param[in] length + /// The length in bytes of the subset of \a data. + /// + /// @return + /// The number of bytes that this object now contains. + //------------------------------------------------------------------ + lldb::offset_t SetData(const DataExtractor &data, lldb::offset_t offset, + lldb::offset_t length); + + //------------------------------------------------------------------ + /// Adopt a subset of shared data in \a data_sp. + /// + /// Copies the data shared pointer which adds a reference to the + /// contained in \a data_sp. The shared data reference is reference + /// counted to ensure the data lives as long as anyone still has a + /// valid shared pointer to the data in \a data_sp. The byte order + /// and address byte size settings remain the same. If + /// \a offset is not a valid offset in \a data_sp, then no reference + /// to the shared data will be added. If there are not \a length + /// bytes available in \a data starting at \a offset, the length + /// will be truncated to contains as many bytes as possible. + /// + /// @param[in] data_sp + /// A shared pointer to data. + /// + /// @param[in] offset + /// The offset into \a data_sp at which the subset starts. + /// + /// @param[in] length + /// The length in bytes of the subset of \a data_sp. + /// + /// @return + /// The number of bytes that this object now contains. + //------------------------------------------------------------------ + lldb::offset_t SetData(const lldb::DataBufferSP &data_sp, + lldb::offset_t offset = 0, + lldb::offset_t length = LLDB_INVALID_OFFSET); + + //------------------------------------------------------------------ + /// Set the byte_order value. + /// + /// Sets the byte order of the data to extract. Extracted values + /// will be swapped if necessary when decoding. + /// + /// @param[in] byte_order + /// The byte order value to use when extracting data. + //------------------------------------------------------------------ + void SetByteOrder(lldb::ByteOrder byte_order) { m_byte_order = byte_order; } + + //------------------------------------------------------------------ + /// Skip an LEB128 number at \a *offset_ptr. + /// + /// Skips a LEB128 number (signed or unsigned) from this object's + /// data starting at the offset pointed to by \a offset_ptr. The + /// offset pointed to by \a offset_ptr will be updated with the + /// offset of the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + // The number of bytes consumed during the extraction. + //------------------------------------------------------------------ + uint32_t Skip_LEB128(lldb::offset_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Test the validity of \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset into the data in this + /// object, \b false otherwise. + //------------------------------------------------------------------ + bool ValidOffset(lldb::offset_t offset) const { + return offset < GetByteSize(); + } + + //------------------------------------------------------------------ + /// Test the availability of \a length bytes of data from \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset and there are \a + /// length bytes available at that offset, \b false otherwise. + //------------------------------------------------------------------ + bool ValidOffsetForDataOfSize(lldb::offset_t offset, + lldb::offset_t length) const { + return length <= BytesLeft(offset); + } + + size_t Copy(DataExtractor &dest_data) const; + + bool Append(DataExtractor &rhs); + + bool Append(void *bytes, lldb::offset_t length); + + lldb::offset_t BytesLeft(lldb::offset_t offset) const { + const lldb::offset_t size = GetByteSize(); + if (size > offset) + return size - offset; + return 0; + } + + void Checksum(llvm::SmallVectorImpl<uint8_t> &dest, uint64_t max_data = 0); protected: - //------------------------------------------------------------------ - // Member variables - //------------------------------------------------------------------ - const uint8_t * m_start; ///< A pointer to the first byte of data. - const uint8_t * m_end; ///< A pointer to the byte that is past the end of the data. - lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from. - uint32_t m_addr_size; ///< The address size to use when extracting pointers or addresses - mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can be shared among multiple instances - const uint32_t m_target_byte_size; + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + const uint8_t *m_start; ///< A pointer to the first byte of data. + const uint8_t + *m_end; ///< A pointer to the byte that is past the end of the data. + lldb::ByteOrder + m_byte_order; ///< The byte order of the data we are extracting from. + uint32_t m_addr_size; ///< The address size to use when extracting pointers or + ///addresses + mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can + ///be shared among multiple instances + const uint32_t m_target_byte_size; }; } // namespace lldb_private |