summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZoran Zaric <zoran.zaric@amd.com>2022-10-25 12:28:05 +0100
committerZoran Zaric <zoran.zaric@amd.com>2022-10-25 14:32:49 +0100
commita50f771b91791dcdd17aabd62ee83d76d6229c75 (patch)
treeb17024b489c44cfd506653c66aba491a478cefb0
parente56df7452dd7b119bf3fa09a3de830b5473c8503 (diff)
downloadbinutils-gdb-a50f771b91791dcdd17aabd62ee83d76d6229c75.tar.gz
Add support for DWARF location offset type that is larger than 64-bit
To support new DWARF extension restrictions for location handling a new data type for representing an offset within a location has been added. The new loc_offset type defines a separate handling of the byte and sub_bit parts of the offset while enabling the byte part of the information to utilize a full 64-bit range of values.
-rw-r--r--gdb/dwarf2/expr.c1151
1 files changed, 685 insertions, 466 deletions
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 3ae1a6289dd..66bb8dd89b5 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -392,6 +392,184 @@ private:
frame_info *m_frame = nullptr;
};
+/* Location offset description type. New DWARF evaluator increases
+ support for bit granularity storage access, meaning that there is
+ a need for a type large enough to hold both byte and bit offset
+ information. */
+class loc_offset
+{
+public:
+
+ loc_offset (ULONGEST bytes, unsigned char sub_bits)
+ : m_bytes (bytes), m_sub_bits (sub_bits)
+ {}
+
+ loc_offset (ULONGEST bits)
+ {
+ m_bytes = bits / HOST_CHAR_BIT;
+ m_sub_bits = (unsigned char) (bits % HOST_CHAR_BIT);
+ }
+
+ loc_offset (const loc_offset &other)
+ {
+ m_bytes = other.m_bytes;
+ m_sub_bits = other.m_sub_bits;
+ }
+
+ ULONGEST bytes () const
+ {
+ return m_bytes;
+ }
+
+ unsigned char sub_bits () const
+ {
+ return m_sub_bits;
+ }
+
+ ULONGEST bits () const
+ {
+ /* The ULONGEST type can only represent a bit offset up to the
+ ULONGEST_MAX cap. Fortunately, the points where the information
+ needs to be in this format, don't handle larger then 64-bit
+ values anyway. */
+ gdb_assert (m_bytes <= ULONGEST_MAX / HOST_CHAR_BIT);
+
+ ULONGEST total_bits = m_bytes * HOST_CHAR_BIT;
+
+ gdb_assert (total_bits <= ULONGEST_MAX - m_sub_bits);
+
+ return total_bits + m_sub_bits;
+ }
+
+ loc_offset &operator=(const loc_offset &rhs)
+ {
+ if (this == &rhs)
+ return *this;
+
+ m_bytes = rhs.m_bytes;
+ m_sub_bits = rhs.m_sub_bits;
+ return *this;
+ }
+
+ bool operator== (const loc_offset &rhs) const
+ {
+ return rhs.m_bytes == m_bytes
+ && rhs.m_sub_bits == m_sub_bits;
+ }
+
+ bool operator!= (const loc_offset &rhs) const
+ {
+ return ! (*this == rhs);
+ }
+
+ bool operator> (const loc_offset &rhs) const
+ {
+ return rhs.m_bytes < m_bytes
+ || (rhs.m_bytes == m_bytes && rhs.m_sub_bits < m_sub_bits);
+ }
+
+ bool operator>= (const loc_offset &rhs) const
+ {
+ return *this == rhs || *this > rhs;
+ }
+
+ bool operator< (const loc_offset &rhs) const
+ {
+ return rhs.m_bytes > m_bytes
+ || (rhs.m_bytes == m_bytes && rhs.m_sub_bits > m_sub_bits);
+ }
+
+ bool operator<= (const loc_offset &rhs) const
+ {
+ return *this == rhs || *this < rhs;
+ }
+
+ loc_offset &operator+= (const loc_offset &rhs)
+ {
+ /* Overflow is not expected at this point. */
+ gdb_assert (rhs.m_bytes != ULONGEST_MAX || m_bytes == 0);
+ gdb_assert (m_bytes != ULONGEST_MAX || rhs.m_bytes == 0);
+ gdb_assert (m_bytes <= ULONGEST_MAX - rhs.m_bytes);
+
+ m_bytes += rhs.m_bytes;
+
+ unsigned total_sub_bits = (unsigned) rhs.m_sub_bits + m_sub_bits;
+ unsigned total_sub_bytes = total_sub_bits / HOST_CHAR_BIT;
+
+ gdb_assert (m_bytes <= ULONGEST_MAX - total_sub_bytes);
+
+ m_sub_bits = total_sub_bits % HOST_CHAR_BIT;
+ m_bytes += total_sub_bytes;
+ return *this;
+ }
+
+ loc_offset &operator-= (const loc_offset &rhs)
+ {
+ /* Underflow is not expected at this point. */
+ gdb_assert (rhs.m_bytes <= m_bytes);
+ gdb_assert (rhs.m_bytes < m_bytes || rhs.m_sub_bits <= m_sub_bits);
+
+ m_bytes -= rhs.m_bytes;
+
+ int total_sub_bits = (int) m_sub_bits - rhs.m_sub_bits;
+
+ if (total_sub_bits < 0)
+ {
+ gdb_assert (m_bytes);
+ m_sub_bits = HOST_CHAR_BIT + total_sub_bits;
+ m_bytes -= 1;
+ }
+ else
+ m_sub_bits = (unsigned char) total_sub_bits;
+
+ return *this;
+ }
+
+ loc_offset &operator*= (ULONGEST rhs)
+ {
+ /* Overflow is not expected at this point. */
+ gdb_assert (m_bytes <= ULONGEST_MAX / rhs);
+ gdb_assert ((ULONGEST) m_sub_bits <= ULONGEST_MAX / rhs);
+
+ m_bytes *= rhs;
+
+ ULONGEST total_sub_bits = m_sub_bits * rhs;
+ ULONGEST total_sub_bytes = total_sub_bits / HOST_CHAR_BIT;
+
+ gdb_assert (m_bytes <= ULONGEST_MAX - total_sub_bytes);
+
+ m_bytes += total_sub_bytes;
+ m_sub_bits = total_sub_bits % HOST_CHAR_BIT;
+ return *this;
+ }
+
+ friend loc_offset operator+ (loc_offset lhs, const loc_offset &rhs)
+ {
+ lhs += rhs;
+ return lhs;
+ }
+
+ friend loc_offset operator- (loc_offset lhs, const loc_offset &rhs)
+ {
+ lhs -= rhs;
+ return lhs;
+ }
+
+ friend loc_offset operator* (loc_offset lhs, const ULONGEST rhs)
+ {
+ lhs *= rhs;
+ return lhs;
+ }
+
+private:
+ /* Number of bytes excluding the last uncomplete byte described
+ with M_SUB_BITS. */
+ ULONGEST m_bytes = 0;
+
+ /* Number of bits in the last uncomplete byte. */
+ unsigned char m_sub_bits;
+};
+
/* Base class that describes entries found on a DWARF expression
evaluation stack. */
@@ -421,8 +599,8 @@ class dwarf_location : public dwarf_entry
{
protected:
/* Not expected to be called on it's own. */
- dwarf_location (gdbarch *arch, LONGEST offset)
- : m_arch (arch), m_offset (offset)
+ dwarf_location (gdbarch *arch, ULONGEST offset, ULONGEST size)
+ : m_arch (arch), m_offset (offset, 0), m_size (size, 0)
{}
public:
@@ -437,13 +615,34 @@ public:
dwarf_location pointer. */
virtual std::unique_ptr<dwarf_location> clone_location () const = 0;
- /* Add bit offset to the location description. */
- void add_bit_offset (LONGEST bit_offset)
+ /* Add offset to the location description. */
+ void add_offset (const loc_offset &offset)
{
- LONGEST bit_total_offset = m_bit_suboffset + bit_offset;
+ /* Offset must be in a valid range. */
+ if (m_size < m_offset + offset)
+ ill_formed_expression ();
+ m_offset += offset;
+ };
- m_offset += bit_total_offset / HOST_CHAR_BIT;
- m_bit_suboffset = bit_total_offset % HOST_CHAR_BIT;
+ /* Add signed byte offset to the location description. */
+ void add_byte_offset (LONGEST offset)
+ {
+ if (offset < 0)
+ {
+ loc_offset temp = {(ULONGEST) (0 - offset), 0};
+ /* Offset must be in a valid range. */
+ if (m_offset < temp)
+ ill_formed_expression ();
+ m_offset -= temp;
+ }
+ else
+ {
+ loc_offset temp = {(ULONGEST) offset, 0};
+ /* Offset must be in a valid range. */
+ if (m_size < m_offset + temp)
+ ill_formed_expression ();
+ m_offset += temp;
+ }
};
void set_initialised (bool initialised)
@@ -451,6 +650,16 @@ public:
m_initialised = initialised;
};
+ const loc_offset &size () const
+ {
+ return m_size;
+ }
+
+ const loc_offset &offset () const
+ {
+ return m_offset;
+ }
+
/* Convert DWARF entry into a DWARF value. TYPE defines a desired type of
the returned DWARF value if it doesn't already have one.
@@ -461,46 +670,44 @@ public:
ill_formed_expression ();
}
- /* Make a slice of a location description with an added bit offset
- BIT_OFFSET and BIT_SIZE size in bits.
+ /* Make a slice of a location description with an added offset
+ OFFSET and size SIZE.
In the case of a composite location description, function returns
a minimum subset of that location description that starts on a
given offset of a given size. */
- virtual std::unique_ptr<dwarf_location> slice (LONGEST bit_offset,
- LONGEST bit_size) const;
+virtual std::unique_ptr<dwarf_location> slice (const loc_offset &offset,
+ const loc_offset &size) const;
/* Read contents from the described location.
The read operation is performed in the context of a FRAME.
- BIT_SIZE is the number of bits to read. The data read is copied
+ SIZE is the amount of data to read. The data read is copied
to the caller-managed buffer BUF. BIG_ENDIAN defines the
- endianness of the target. BITS_TO_SKIP is a bit offset into the
- location and BUF_BIT_OFFSET is buffer BUF's bit offset.
- LOCATION_BIT_LIMIT is a maximum number of bits that location can
- hold, where value zero signifies that there is no such
- restriction.
+ endianness of the target. OFFSET is a offset into the location
+ and BUF_OFFSET an offset into the buffer BUF. LIMIT is a maximum
+ amount of data that location can hold, where value zero signifies
+ that there is no such restriction.
Note that some location types can be read without a FRAME context.
If the location is optimized out or unavailable, the OPTIMIZED and
UNAVAILABLE outputs are set accordingly. */
virtual void read (frame_info *frame, gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized,
int *unavailable) const = 0;
/* Write contents to a described location.
The write operation is performed in the context of a FRAME.
- BIT_SIZE is the number of bits written. The data written is
+ SIZE is the amount of data written. The data written is
copied from the caller-managed BUF buffer. BIG_ENDIAN defines an
- endianness of the target. BITS_TO_SKIP is a bit offset into the
- location and BUF_BIT_OFFSET is buffer BUF's bit offset.
- LOCATION_BIT_LIMIT is a maximum number of bits that location can
- hold, where value zero signifies that there is no such
- restriction.
+ endianness of the target. OFFSET is an offset into the location
+ and BUF_OFFSET is an offset into a buffer BUF. LIMIT isa maximum
+ amount of data that location can hold, where value zero signifies
+ that there is no such restriction.
Note that some location types can be written without a FRAME
context.
@@ -508,8 +715,8 @@ public:
If the location is optimized out or unavailable, the OPTIMIZED and
UNAVAILABLE outputs are set. */
virtual void write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized,
int *unavailable) const = 0;
@@ -528,39 +735,40 @@ public:
/* Read data from the VALUE contents to the location specified by the
location description.
- The read operation is performed in the context of a FRAME. BIT_SIZE
- is the number of bits to read. VALUE_BIT_OFFSET is a bit offset
- into a VALUE content and BITS_TO_SKIP is a bit offset into the
- location. LOCATION_BIT_LIMIT is a maximum number of bits that
- location can hold, where value zero signifies that there is no such
- restriction.
+ The read operation is performed in the context of a FRAME. SIZE is
+ amount of data to read. VALUE_OFFSET is an offset into a VALUE
+ content and OFFSET is an offset into the location. LIMIT is a
+ maximum amount of data that location can hold, where value zero
+ signifies that there is no such restriction.
Note that some location types can be read without a FRAME context. */
virtual void read_from_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const;
+ const loc_offset &value_offset,
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const;
/* Write data to the VALUE contents from the location specified by the
location description.
The write operation is performed in the context of a FRAME.
- BIT_SIZE is the number of bits to read. VALUE_BIT_OFFSET is a bit
- offset into a VALUE content and BITS_TO_SKIP is a bit offset into
- the location. LOCATION_BIT_LIMIT is a maximum number of bits that
- location can hold, where value zero signifies that there is no such
- restriction.
+ SIZE is the amount of data to read. VALUE_OFFSET is an offset into
+ a VALUE content and OFFSET is an offset into the location.
+ LIMIT is a maximum number of bits that location can hold, where
+ value zero signifies that there is no such restriction.
Note that some location types can be read without a FRAME context. */
virtual void write_to_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const;
+ const loc_offset &value_offset,
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const;
/* Check if a given DWARF location description contains an implicit
- pointer location description of a BIT_LENGTH size on a given
- BIT_OFFSET offset. */
- virtual bool is_implicit_ptr_at (LONGEST bit_offset, int bit_length) const
+ pointer location description of a SIZE size on a given OFFSET
+ offset. */
+ virtual bool is_implicit_ptr_at (const loc_offset &offset,
+ const loc_offset &size) const
{
return false;
}
@@ -570,15 +778,15 @@ public:
operation is performed in a given FRAME context, using the TYPE as
the type of the pointer. Where POINTER_OFFSET is an offset
applied to that implicit pointer location description before the
- operation. BIT_OFFSET is a bit offset applied to the location and
- BIT_LENGTH is a bit length of the read.
+ operation. OFFSET is an offset applied to the location and SIZE
+ is the amount of data to read.
Indirecting is only performed on the implicit pointer location
description parts of the location. */
virtual value *indirect_implicit_ptr (frame_info *frame, struct type *type,
- LONGEST pointer_offset = 0,
- LONGEST bit_offset = 0,
- int bit_length = 0) const
+ LONGEST pointer_offset,
+ const loc_offset &offset,
+ const loc_offset &size) const
{
return nullptr;
}
@@ -586,14 +794,14 @@ public:
/* Check if location description resolves into optimized out.
The check operation is performed in the context of a FRAME.
- BIG_ENDIAN defines the endianness of the target, BIT_SIZE is the
- number of bits to read and BITS_TO_SKIP is a bit offset into the
- location. LOCATION_BIT_LIMIT is a maximum number of bits that
- location can hold, where value zero signifies that there is
- no such restriction. */
+ BIG_ENDIAN defines the endianness of the target, Size is the
+ amout of data to check and OFFSET is an offset into the location.
+ LIMIT is a maximum number of bits that location can hold, where
+ value zero signifies that there is no such restriction. */
virtual bool is_optimized_out (frame_info *frame, bool big_endian,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const
{
return false;
}
@@ -612,11 +820,11 @@ protected:
/* Architecture of the location. */
gdbarch *m_arch;
- /* Byte offset into the location. */
- LONGEST m_offset;
+ /* Offset into the location. */
+ loc_offset m_offset;
- /* Bit suboffset of the last byte. */
- LONGEST m_bit_suboffset = 0;
+ /* Size of the location. */
+ loc_offset m_size;
/* Whether the location is initialized. Used for non-standard
DW_OP_GNU_uninit operation. */
@@ -629,25 +837,28 @@ using dwarf_location_up = std::unique_ptr<dwarf_location>;
non-composite location descriptions. */
std::unique_ptr<dwarf_location>
-dwarf_location::slice (LONGEST bit_offset, LONGEST bit_size) const
+dwarf_location::slice (const loc_offset &offset, const loc_offset &size) const
{
+ /* Check if for out of bounds slicing. */
+ gdb_assert (m_size >= size + offset);
+
dwarf_location_up location_slice = this->clone_location ();
- location_slice->add_bit_offset (bit_offset);
+ location_slice->add_offset (offset);
return location_slice;
}
void
dwarf_location::read_from_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const
+ const loc_offset &value_offset,
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const
{
int optimized, unavailable;
bool big_endian = type_byte_order (value_type (value)) == BFD_ENDIAN_BIG;
- this->write (frame, value_contents (value).data (), value_bit_offset,
- bit_size, bits_to_skip, location_bit_limit,
- big_endian, &optimized, &unavailable);
+ this->write (frame, value_contents (value).data (), value_offset,
+ size, offset, limit, big_endian, &optimized, &unavailable);
if (optimized)
throw_error (OPTIMIZED_OUT_ERROR,
@@ -663,21 +874,22 @@ dwarf_location::read_from_gdb_value (frame_info *frame, struct value *value,
void
dwarf_location::write_to_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const
+ const loc_offset &value_offset,
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const
{
int optimized, unavailable;
bool big_endian = type_byte_order (value_type (value)) == BFD_ENDIAN_BIG;
- this->read (frame, value_contents_raw (value).data (), value_bit_offset,
- bit_size, bits_to_skip, location_bit_limit,
+ this->read (frame, value_contents_raw (value).data (),
+ value_offset, size, offset, limit,
big_endian, &optimized, &unavailable);
if (optimized)
- mark_value_bits_optimized_out (value, value_bit_offset, bit_size);
+ mark_value_bits_optimized_out (value, value_offset.bits (), size.bits ());
if (unavailable)
- mark_value_bits_unavailable (value, value_bit_offset, bit_size);
+ mark_value_bits_unavailable (value, value_offset.bits (), size.bits ());
}
/* Value entry found on a DWARF expression evaluation stack. */
@@ -821,7 +1033,7 @@ class dwarf_undefined final : public dwarf_location
{
public:
dwarf_undefined (gdbarch *arch)
- : dwarf_location (arch, 0)
+ : dwarf_location (arch, 0, ULONGEST_MAX)
{}
dwarf_location_up clone_location () const override
@@ -829,16 +1041,18 @@ public:
return make_unique<dwarf_undefined> (*this);
}
- void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset,
- size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit,
- bool big_endian, int *optimized, int *unavailable) const override
+ void read (frame_info *frame, gdb_byte *buf, const loc_offset &buf_offset,
+ const loc_offset &size, const loc_offset &offset,
+ const loc_offset &limit, bool big_endian,
+ int *optimized, int *unavailable) const override
{
*unavailable = 0;
*optimized = 1;
}
- void write (frame_info *frame, const gdb_byte *buf, int buf_bit_offset,
- size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit,
+ void write (frame_info *frame, const gdb_byte *buf,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized, int *unavailable) const override
{
*unavailable = 0;
@@ -846,8 +1060,8 @@ public:
}
bool is_optimized_out (frame_info *frame, bool big_endian,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override
{
return true;
}
@@ -870,7 +1084,7 @@ class dwarf_memory final : public dwarf_location
{
public:
dwarf_memory (gdbarch *arch, LONGEST offset, bool stack = false)
- : dwarf_location (arch, offset), m_stack (stack)
+ : dwarf_location (arch, offset, ULONGEST_MAX), m_stack (stack)
{}
dwarf_location_up clone_location () const override
@@ -885,15 +1099,16 @@ public:
dwarf_value_up to_value (struct type *type) const override;
- void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset,
- size_t bit_size, LONGEST bits_to_skip,
- size_t location_bit_limit, bool big_endian,
+ void read (frame_info *frame, gdb_byte *buf, const loc_offset &buf_offset,
+ const loc_offset &size, const loc_offset &offset,
+ const loc_offset &limit, bool big_endian,
int *optimized, int *unavailable) const override;
void write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip,
- size_t location_bit_limit, bool big_endian,
- int *optimized, int *unavailable) const override;
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
+ bool big_endian, int *optimized,
+ int *unavailable) const override;
std::unique_ptr<dwarf_value> deref (frame_info *frame,
const property_addr_info *addr_info,
@@ -927,35 +1142,34 @@ dwarf_value::to_location (struct gdbarch *arch) const
dwarf_value_up
dwarf_memory::to_value (struct type *type) const
{
- return make_unique<dwarf_value> (m_offset, type);
+ if (m_offset.sub_bits ())
+ ill_formed_expression ();
+
+ return make_unique<dwarf_value> (m_offset.bytes (), type);
}
void
dwarf_memory::read (frame_info *frame, gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized, int *unavailable) const
{
- LONGEST total_bits_to_skip = bits_to_skip;
- CORE_ADDR start_address
- = m_offset + (m_bit_suboffset + total_bits_to_skip) / HOST_CHAR_BIT;
+ loc_offset total_to_skip = m_offset + offset;
+ CORE_ADDR start_address = total_to_skip.bytes ();
+ LONGEST total_bits_to_skip = total_to_skip.sub_bits ();
gdb::byte_vector temp_buf;
-
*optimized = 0;
- total_bits_to_skip += m_bit_suboffset;
- if (total_bits_to_skip % HOST_CHAR_BIT == 0
- && bit_size % HOST_CHAR_BIT == 0
- && buf_bit_offset % HOST_CHAR_BIT == 0)
+ if (total_bits_to_skip == 0 && size.sub_bits () == 0
+ && buf_offset.sub_bits () == 0)
{
/* Everything is byte-aligned, no buffer needed. */
- read_from_memory (start_address,
- buf + buf_bit_offset / HOST_CHAR_BIT,
- bit_size / HOST_CHAR_BIT, m_stack, unavailable);
+ read_from_memory (start_address, buf + buf_offset.bytes (),
+ size.bytes (), m_stack, unavailable);
}
else
{
- LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size);
+ LONGEST this_size = bits_to_bytes (total_bits_to_skip, size.bits ());
temp_buf.resize (this_size);
/* Can only read from memory on byte granularity so an
@@ -964,41 +1178,36 @@ dwarf_memory::read (frame_info *frame, gdb_byte *buf,
m_stack, unavailable);
if (!*unavailable)
- copy_bitwise (buf, buf_bit_offset, temp_buf.data (),
- total_bits_to_skip % HOST_CHAR_BIT,
- bit_size, big_endian);
+ copy_bitwise (buf, buf_offset.bits (), temp_buf.data (),
+ total_bits_to_skip, size.bits (), big_endian);
}
}
void
dwarf_memory::write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized, int *unavailable) const
{
- LONGEST total_bits_to_skip = bits_to_skip;
- CORE_ADDR start_address
- = m_offset + (m_bit_suboffset + total_bits_to_skip) / HOST_CHAR_BIT;
+ loc_offset total_to_skip = m_offset + offset;
+ CORE_ADDR start_address = total_to_skip.bytes ();
+ LONGEST total_bits_to_skip = total_to_skip.sub_bits ();
gdb::byte_vector temp_buf;
-
*optimized = 0;
- total_bits_to_skip += m_bit_suboffset;
- if (total_bits_to_skip % HOST_CHAR_BIT == 0
- && bit_size % HOST_CHAR_BIT == 0
- && buf_bit_offset % HOST_CHAR_BIT == 0)
+ if (total_bits_to_skip == 0 && size.sub_bits () == 0
+ && buf_offset.sub_bits () == 0)
{
/* Everything is byte-aligned; no buffer needed. */
- write_to_memory (start_address, buf + buf_bit_offset / HOST_CHAR_BIT,
- bit_size / HOST_CHAR_BIT, m_stack, unavailable);
+ write_to_memory (start_address, buf + buf_offset.bytes (),
+ size.bytes (), m_stack, unavailable);
}
else
{
- LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size);
+ LONGEST this_size = bits_to_bytes (total_bits_to_skip, size.bits ());
temp_buf.resize (this_size);
- if (total_bits_to_skip % HOST_CHAR_BIT != 0
- || bit_size % HOST_CHAR_BIT != 0)
+ if (total_bits_to_skip != 0 || size.sub_bits () != 0)
{
if (this_size <= HOST_CHAR_BIT)
/* Perform a single read for small sizes. */
@@ -1018,8 +1227,8 @@ dwarf_memory::write (frame_info *frame, const gdb_byte *buf,
}
}
- copy_bitwise (temp_buf.data (), total_bits_to_skip % HOST_CHAR_BIT,
- buf, buf_bit_offset, bit_size, big_endian);
+ copy_bitwise (temp_buf.data (), total_bits_to_skip,
+ buf, buf_offset.bits (), size.bits (), big_endian);
write_to_memory (start_address, temp_buf.data (), this_size,
m_stack, unavailable);
@@ -1048,14 +1257,14 @@ dwarf_memory::deref (frame_info *frame, const property_addr_info *addr_info,
part of the target and requires for the location description
to address it instead of addressing the actual target
memory. */
- LONGEST this_size = bits_to_bytes (m_bit_suboffset, size_in_bits);
+ LONGEST this_size = bits_to_bytes (m_offset.sub_bits (), size_in_bits);
/* We shouldn't have a case where we read from a passed in
memory and the same memory being marked as stack. */
if (!m_stack && this_size && addr_info != nullptr
&& addr_info->valaddr.data () != nullptr)
{
- CORE_ADDR offset = (CORE_ADDR) m_offset - addr_info->addr;
+ CORE_ADDR offset = (CORE_ADDR) m_offset.bytes () - addr_info->addr;
if (offset < addr_info->valaddr.size ()
&& offset + this_size <= addr_info->valaddr.size ())
@@ -1067,7 +1276,7 @@ dwarf_memory::deref (frame_info *frame, const property_addr_info *addr_info,
memcpy (temp_buf.data (), addr_info->valaddr.data () + offset,
this_size);
copy_bitwise (buf_ptr, 0, temp_buf.data (),
- m_bit_suboffset, size_in_bits, big_endian);
+ m_offset.sub_bits (), size_in_bits, big_endian);
passed_in_buf = true;
}
}
@@ -1110,10 +1319,10 @@ dwarf_memory::to_gdb_value (frame_info *frame, struct type *type,
ptr_type = builtin_type (m_arch)->builtin_func_ptr;
CORE_ADDR address
- = value_as_address (value_from_pointer (ptr_type, m_offset));
+ = value_as_address (value_from_pointer (ptr_type, m_offset.bytes ()));
value *retval = value_at_lazy (subobj_type, address + subobj_offset);
set_value_stack (retval, m_stack);
- set_value_bitpos (retval, m_bit_suboffset);
+ set_value_bitpos (retval, m_offset.sub_bits ());
return retval;
}
@@ -1122,27 +1331,32 @@ dwarf_memory::to_gdb_value (frame_info *frame, struct type *type,
class dwarf_register final : public dwarf_location
{
public:
- dwarf_register (gdbarch *arch, unsigned int regnum, LONGEST offset = 0)
- : dwarf_location (arch, offset), m_regnum (regnum)
- {}
+ dwarf_register (gdbarch *arch, unsigned int regnum, ULONGEST offset = 0)
+ : dwarf_location (arch, offset, 0), m_regnum (regnum)
+ {
+ int reg = dwarf_reg_to_regnum_or_error (arch, regnum);
+ m_size = (ULONGEST) (register_size (arch, reg) * HOST_CHAR_BIT);
+ }
dwarf_location_up clone_location () const override
{
return make_unique<dwarf_register> (*this);
}
- void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset,
- size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit,
- bool big_endian, int *optimized, int *unavailable) const override;
+ void read (frame_info *frame, gdb_byte *buf, const loc_offset &buf_offset,
+ const loc_offset &size, const loc_offset &offset,
+ const loc_offset &limit, bool big_endian,
+ int *optimized, int *unavailable) const override;
void write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip,
- size_t location_bit_limit, bool big_endian,
- int *optimized, int *unavailable) const override;
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
+ bool big_endian, int *optimized,
+ int *unavailable) const override;
bool is_optimized_out (frame_info *frame, bool big_endian,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override;
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override;
value *to_gdb_value (frame_info *frame, struct type *type,
struct type *subobj_type,
@@ -1156,56 +1370,57 @@ private:
void
dwarf_register::read (frame_info *frame, gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized, int *unavailable) const
{
- LONGEST total_bits_to_skip = bits_to_skip;
- size_t read_bit_limit = location_bit_limit;
+ loc_offset total_to_skip = offset;
+ loc_offset read_limit = limit;
gdbarch *frame_arch = get_frame_arch (frame);
int reg = dwarf_reg_to_regnum_or_error (frame_arch, m_regnum);
- ULONGEST reg_bits = HOST_CHAR_BIT * register_size (frame_arch, reg);
+ loc_offset reg_size
+ = (ULONGEST) register_size (frame_arch, reg) * HOST_CHAR_BIT;
gdb::byte_vector temp_buf;
+ if (frame == nullptr)
+ internal_error (__FILE__, __LINE__, _("invalid frame information"));
+
if (big_endian)
{
- if (!read_bit_limit || reg_bits <= read_bit_limit)
- read_bit_limit = bit_size;
+ if (read_limit == 0 || reg_size <= read_limit)
+ read_limit = size;
- total_bits_to_skip += reg_bits - (m_offset * HOST_CHAR_BIT
- + m_bit_suboffset + read_bit_limit);
+ total_to_skip += reg_size - (m_offset + read_limit);
}
else
- total_bits_to_skip += m_offset * HOST_CHAR_BIT + m_bit_suboffset;
+ total_to_skip += m_offset;
- LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size);
+ LONGEST this_size = bits_to_bytes (total_to_skip.bits (), size.bits ());
temp_buf.resize (this_size);
- if (frame == nullptr)
- internal_error (__FILE__, __LINE__, _("invalid frame information"));
-
/* Can only read from a register on byte granularity so an
additional buffer is required. */
- read_from_register (frame, reg, total_bits_to_skip / HOST_CHAR_BIT,
+ read_from_register (frame, reg, total_to_skip.bytes (),
temp_buf, optimized, unavailable);
/* Only copy data if valid. */
if (!*optimized && !*unavailable)
- copy_bitwise (buf, buf_bit_offset, temp_buf.data (),
- total_bits_to_skip % HOST_CHAR_BIT, bit_size, big_endian);
+ copy_bitwise (buf, buf_offset.bits (), temp_buf.data (),
+ total_to_skip.sub_bits (), size.bits (), big_endian);
}
void
dwarf_register::write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized, int *unavailable) const
{
- LONGEST total_bits_to_skip = bits_to_skip;
- size_t write_bit_limit = location_bit_limit;
+ loc_offset total_to_skip = offset;
+ loc_offset write_limit = limit;
gdbarch *frame_arch = get_frame_arch (frame);
int reg = dwarf_reg_to_regnum_or_error (frame_arch, m_regnum);
- ULONGEST reg_bits = HOST_CHAR_BIT * register_size (frame_arch, reg);
+ loc_offset reg_size
+ = (ULONGEST) register_size (frame_arch, reg) * HOST_CHAR_BIT;
gdb::byte_vector temp_buf;
if (frame == nullptr)
@@ -1213,46 +1428,43 @@ dwarf_register::write (frame_info *frame, const gdb_byte *buf,
if (big_endian)
{
- if (!write_bit_limit || reg_bits <= write_bit_limit)
- write_bit_limit = bit_size;
+ if (write_limit == 0 || reg_size <= write_limit)
+ write_limit = size;
- total_bits_to_skip += reg_bits - (m_offset * HOST_CHAR_BIT
- + m_bit_suboffset + write_bit_limit);
+ total_to_skip += reg_size - (m_offset + write_limit);
}
else
- total_bits_to_skip += m_offset * HOST_CHAR_BIT + m_bit_suboffset;
+ total_to_skip += m_offset;
- LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size);
+ LONGEST this_size = bits_to_bytes (total_to_skip.bits (), size.bits ());
temp_buf.resize (this_size);
- if (total_bits_to_skip % HOST_CHAR_BIT != 0
- || bit_size % HOST_CHAR_BIT != 0)
+ if (total_to_skip.sub_bits () != 0 || size.sub_bits () != 0)
{
/* Contents is copied non-byte-aligned into the register.
Need some bits from original register value. */
- read_from_register (frame, reg,
- total_bits_to_skip / HOST_CHAR_BIT,
+ read_from_register (frame, reg, total_to_skip.bytes (),
temp_buf, optimized, unavailable);
}
- copy_bitwise (temp_buf.data (), total_bits_to_skip % HOST_CHAR_BIT, buf,
- buf_bit_offset, bit_size, big_endian);
+ copy_bitwise (temp_buf.data (), total_to_skip.sub_bits (), buf,
+ buf_offset.bits (), size.bits (), big_endian);
- write_to_register (frame, reg, total_bits_to_skip / HOST_CHAR_BIT,
+ write_to_register (frame, reg, total_to_skip.bytes (),
temp_buf, optimized, unavailable);
}
bool
dwarf_register::is_optimized_out (frame_info *frame, bool big_endian,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const
{
int optimized, unavailable;
- gdb::byte_vector temp_buf (bit_size);
+ gdb::byte_vector temp_buf (size.bits ());
- this->read (frame, temp_buf.data (), 0, bit_size,
- bits_to_skip, location_bit_limit,
- big_endian, &optimized, &unavailable);
+ this->read (frame, temp_buf.data (), 0, size, offset,
+ limit, big_endian, &optimized, &unavailable);
if (optimized)
return true;
@@ -1285,14 +1497,15 @@ dwarf_register::to_gdb_value (frame_info *frame, struct type *type,
LONGEST retval_offset = value_offset (retval) * unit_size;
if (type_byte_order (type) == BFD_ENDIAN_BIG
- && TYPE_LENGTH (type) + m_offset < retval_offset)
+ && TYPE_LENGTH (type) + m_offset.bytes () < retval_offset)
/* Big-endian, and we want less than full size. */
- set_value_offset (retval, (retval_offset - m_offset) / unit_size);
+ set_value_offset (retval, (retval_offset - m_offset.bytes ()) / unit_size);
else
- set_value_offset (retval, (retval_offset + m_offset) / unit_size);
+ set_value_offset (retval, (retval_offset + m_offset.bytes ()) / unit_size);
set_value_bitpos (retval,
- m_bit_suboffset + (m_offset % unit_size) * HOST_CHAR_BIT);
+ m_offset.sub_bits ()
+ + (m_offset.bytes () % unit_size) * HOST_CHAR_BIT);
/* Get the data. */
read_frame_register_value (retval, frame);
@@ -1322,7 +1535,7 @@ public:
dwarf_implicit (gdbarch *arch, gdb::array_view<const gdb_byte> contents,
enum bfd_endian byte_order)
- : dwarf_location (arch, 0),
+ : dwarf_location (arch, 0, contents.size ()),
m_contents (contents.begin (), contents.end ()),
m_byte_order (byte_order)
{}
@@ -1332,13 +1545,14 @@ public:
return make_unique<dwarf_implicit> (*this);
}
- void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset,
- size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit,
- bool big_endian, int *optimized, int *unavailable) const override;
+ void read (frame_info *frame, gdb_byte *buf, const loc_offset &buf_offset,
+ const loc_offset &size, const loc_offset &offset,
+ const loc_offset &limit, bool big_endian,
+ int *optimized, int *unavailable) const override;
void write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int* optimized, int* unavailable) const override
{
*optimized = 1;
@@ -1346,8 +1560,8 @@ public:
}
bool is_optimized_out (frame_info *frame, bool big_endian,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override
{
return true;
}
@@ -1366,13 +1580,13 @@ private:
void
dwarf_implicit::read (frame_info *frame, gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized, int *unavailable) const
{
- ULONGEST implicit_bit_size = HOST_CHAR_BIT * m_contents.size ();
- LONGEST total_bits_to_skip = bits_to_skip;
- size_t read_bit_limit = location_bit_limit;
+ loc_offset total_to_skip = offset;
+ loc_offset read_limit = limit;
+ loc_offset read_size = size;
*optimized = 0;
*unavailable = 0;
@@ -1380,27 +1594,25 @@ dwarf_implicit::read (frame_info *frame, gdb_byte *buf,
/* Cut off at the end of the implicit value. */
if (m_byte_order == BFD_ENDIAN_BIG)
{
- if (!read_bit_limit || read_bit_limit > implicit_bit_size)
- read_bit_limit = bit_size;
+ if (read_limit == 0 || read_limit > m_size)
+ read_limit = size;
- total_bits_to_skip
- += implicit_bit_size - (m_offset * HOST_CHAR_BIT
- + m_bit_suboffset + read_bit_limit);
+ total_to_skip += m_size - (m_offset + read_limit);
}
else
- total_bits_to_skip += m_offset * HOST_CHAR_BIT + m_bit_suboffset;
+ total_to_skip += m_offset;
- if (total_bits_to_skip >= implicit_bit_size)
+ if (total_to_skip >= m_size)
{
*unavailable = 1;
return;
}
- if (bit_size > implicit_bit_size - total_bits_to_skip)
- bit_size = implicit_bit_size - total_bits_to_skip;
+ if (read_size > m_size - total_to_skip)
+ read_size = m_size - total_to_skip;
- copy_bitwise (buf, buf_bit_offset, m_contents.data (),
- total_bits_to_skip, bit_size, big_endian);
+ copy_bitwise (buf, buf_offset.bits (), m_contents.data (),
+ total_to_skip.bits (), read_size.bits (), big_endian);
}
value *
@@ -1443,9 +1655,9 @@ public:
dwarf2_per_cu_data *per_cu,
int addr_size, sect_offset die_offset,
LONGEST offset)
- : dwarf_location (arch, offset),
+ : dwarf_location (arch, offset, addr_size),
m_per_objfile (per_objfile), m_per_cu (per_cu),
- m_addr_size (addr_size), m_die_offset (die_offset)
+ m_die_offset (die_offset)
{}
dwarf_location_up clone_location () const override
@@ -1453,14 +1665,15 @@ public:
return make_unique<dwarf_implicit_pointer> (*this);
}
- void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset,
- size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit,
- bool big_endian, int *optimized, int *unavailable) const override;
+ void read (frame_info *frame, gdb_byte *buf, const loc_offset &buf_offset,
+ const loc_offset &size, const loc_offset &offset,
+ const loc_offset &limit, bool big_endian,
+ int *optimized, int *unavailable) const override;
void write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip,
- size_t location_bit_limit, bool big_endian,
- int* optimized, int* unavailable) const override
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
+ bool big_endian, int* optimized, int* unavailable) const override
{
*optimized = 1;
*unavailable = 0;
@@ -1469,28 +1682,29 @@ public:
/* Reading from and writing to an implicit pointer is not meaningful,
so we just skip them here. */
void read_from_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override
+ const loc_offset &value_offset,
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override
{
- mark_value_bits_optimized_out (value, bits_to_skip, bit_size);
+ mark_value_bits_optimized_out (value, offset.bits (), size.bits ());
}
void write_to_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override
+ const loc_offset &value_offset,
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override
{}
- bool is_implicit_ptr_at (LONGEST bit_offset, int bit_length) const override
+ bool is_implicit_ptr_at (const loc_offset &offset,
+ const loc_offset &size) const override
{
return true;
}
value *indirect_implicit_ptr (frame_info *frame, struct type *type,
- LONGEST pointer_offset = 0,
- LONGEST bit_offset = 0,
- int bit_length = 0) const override;
+ LONGEST pointer_offset,
+ const loc_offset &offset,
+ const loc_offset &size) const override;
value *to_gdb_value (frame_info *frame, struct type *type,
struct type *subobj_type,
@@ -1503,48 +1717,43 @@ private:
/* Compilation unit context of the implicit pointer. */
dwarf2_per_cu_data *m_per_cu;
- /* Address size for the evaluation. */
- int m_addr_size;
-
/* DWARF die offset pointed by the implicit pointer. */
sect_offset m_die_offset;
};
void
dwarf_implicit_pointer::read (frame_info *frame, gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset,
+ const loc_offset &size,
+ const loc_offset &offset,
+ const loc_offset &limit,
bool big_endian, int *optimized,
int *unavailable) const
{
frame_info *actual_frame = frame;
- LONGEST total_bits_to_skip = bits_to_skip + m_bit_suboffset;
+ loc_offset total_to_skip = m_offset + offset;
if (actual_frame == nullptr)
actual_frame = get_selected_frame (_("No frame selected."));
struct type *type
- = address_type (get_frame_arch (actual_frame), m_addr_size);
+ = address_type (get_frame_arch (actual_frame), m_size.bytes ());
struct value *value
- = indirect_synthetic_pointer (m_die_offset, m_offset, m_per_cu,
+ = indirect_synthetic_pointer (m_die_offset, total_to_skip.bytes (), m_per_cu,
m_per_objfile, actual_frame, type);
- gdb_byte *value_contents = value_contents_raw (value).data ()
- + total_bits_to_skip / HOST_CHAR_BIT;
+ gdb_byte *value_contents = value_contents_raw (value).data ();
- if (total_bits_to_skip % HOST_CHAR_BIT == 0
- && bit_size % HOST_CHAR_BIT == 0
- && buf_bit_offset % HOST_CHAR_BIT == 0)
+ if (total_to_skip.sub_bits () == 0 && size.sub_bits () == 0
+ && buf_offset.sub_bits () == 0)
{
- memcpy (buf + buf_bit_offset / HOST_CHAR_BIT,
- value_contents, bit_size / HOST_CHAR_BIT);
+ memcpy (buf + buf_offset.bytes (), value_contents, size.bytes ());
}
else
{
- copy_bitwise (buf, buf_bit_offset, value_contents,
- total_bits_to_skip % HOST_CHAR_BIT,
- bit_size, big_endian);
+ copy_bitwise (buf, buf_offset.bits (), value_contents,
+ total_to_skip.sub_bits (), size.bits (), big_endian);
}
}
@@ -1552,10 +1761,11 @@ value *
dwarf_implicit_pointer::indirect_implicit_ptr (frame_info *frame,
struct type *type,
LONGEST pointer_offset,
- LONGEST bit_offset,
- int bit_length) const
+ const loc_offset &offset,
+ const loc_offset &size) const
{
- return indirect_synthetic_pointer (m_die_offset, m_offset + pointer_offset,
+ return indirect_synthetic_pointer (m_die_offset,
+ m_offset.bytes () + pointer_offset,
m_per_cu, m_per_objfile, frame, type);
}
@@ -1585,7 +1795,7 @@ class dwarf_composite final : public dwarf_location
{
public:
dwarf_composite (gdbarch *arch, dwarf2_per_cu_data *per_cu)
- : dwarf_location (arch, 0), m_per_cu (per_cu)
+ : dwarf_location (arch, 0, 0), m_per_cu (per_cu)
{}
dwarf_location_up clone_location () const override
@@ -1593,14 +1803,16 @@ public:
return make_unique<dwarf_composite> (*this);
}
- std::unique_ptr<dwarf_location> slice (LONGEST bit_offset,
- LONGEST bit_size) const override;
+ std::unique_ptr<dwarf_location> slice
+ (const loc_offset &offset, const loc_offset &size) const override;
- void add_piece (std::unique_ptr<dwarf_location> location, ULONGEST bit_size)
+ void add_piece (std::unique_ptr<dwarf_location> location,
+ const loc_offset &size)
{
gdb_assert (location != nullptr);
gdb_assert (!m_completed);
- m_pieces.emplace_back (std::move (location), bit_size);
+ m_pieces.emplace_back (std::move (location), size);
+ m_size += size;
}
void set_completed (bool completed)
@@ -1613,35 +1825,38 @@ public:
return m_completed;
};
- void read (frame_info *frame, gdb_byte *buf, int buf_bit_offset,
- size_t bit_size, LONGEST bits_to_skip, size_t location_bit_limit,
- bool big_endian, int *optimized, int *unavailable) const override;
+ void read (frame_info *frame, gdb_byte *buf, const loc_offset &buf_offset,
+ const loc_offset &size, const loc_offset &offset,
+ const loc_offset &limit, bool big_endian,
+ int *optimized, int *unavailable) const override;
void write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size, LONGEST bits_to_skip,
- size_t location_bit_limit, bool big_endian,
- int *optimized, int *unavailable) const override;
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
+ bool big_endian, int *optimized,
+ int *unavailable) const override;
void read_from_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override;
+ const loc_offset &value_offset,
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override;
void write_to_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override;
+ const loc_offset &value_offset,
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override;
- bool is_implicit_ptr_at (LONGEST bit_offset, int bit_length) const override;
+ bool is_implicit_ptr_at (const loc_offset &offset,
+ const loc_offset &size) const override;
value *indirect_implicit_ptr (frame_info *frame, struct type *type,
- LONGEST pointer_offset = 0,
- LONGEST bit_offset = 0,
- int bit_length = 0) const override;
+ LONGEST pointer_offset,
+ const loc_offset &offset,
+ const loc_offset &size) const override;
bool is_optimized_out (frame_info *frame, bool big_endian,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const override;
+ const loc_offset &offset, const loc_offset &size,
+ const loc_offset &limit) const override;
value *to_gdb_value (frame_info *frame, struct type *type,
struct type *subobj_type,
@@ -1653,7 +1868,7 @@ private:
struct piece
{
public:
- piece (std::unique_ptr<dwarf_location> location, ULONGEST size)
+ piece (std::unique_ptr<dwarf_location> location, const loc_offset &size)
: location (std::move (location)), size (size)
{}
@@ -1669,7 +1884,9 @@ private:
void operator=(piece &&) = delete;
std::unique_ptr<dwarf_location> location;
- ULONGEST size;
+
+ /* Size of the piece. */
+ loc_offset size;
};
/* Compilation unit context of the pointer. */
@@ -1683,45 +1900,43 @@ private:
};
std::unique_ptr<dwarf_location>
-dwarf_composite::slice (LONGEST bit_offset, LONGEST bit_size) const
+dwarf_composite::slice (const loc_offset &offset, const loc_offset &size) const
{
/* Size 0 is never expected at this point. */
- gdb_assert (bit_size != 0);
+ gdb_assert (size != 0);
unsigned int pieces_num = m_pieces.size ();
- LONGEST total_bit_size = bit_size;
- LONGEST total_bits_to_skip = m_offset * HOST_CHAR_BIT
- + m_bit_suboffset + bit_offset;
- std::vector<piece> piece_slices;
+ loc_offset total_offset = m_offset + offset;
unsigned int i;
for (i = 0; i < pieces_num; i++)
{
- LONGEST piece_bit_size = m_pieces[i].size;
+ loc_offset piece_size = m_pieces[i].size;
- if (total_bits_to_skip < piece_bit_size)
+ if (total_offset < piece_size)
break;
- total_bits_to_skip -= piece_bit_size;
+ total_offset -= piece_size;
}
+ std::vector<piece> piece_slices;
+ loc_offset total_size = size;
for (; i < pieces_num; i++)
{
- if (total_bit_size == 0)
+ if (total_size == 0)
break;
- gdb_assert (total_bit_size > 0);
- LONGEST slice_bit_size = m_pieces[i].size - total_bits_to_skip;
+ loc_offset slice_size = m_pieces[i].size - total_offset;
- if (total_bit_size < slice_bit_size)
- slice_bit_size = total_bit_size;
+ if (total_size < slice_size)
+ slice_size = total_size;
std::unique_ptr<dwarf_location> slice
- = m_pieces[i].location->slice (total_bits_to_skip, slice_bit_size);
- piece_slices.emplace_back (std::move (slice), slice_bit_size);
+ = m_pieces[i].location->slice (total_offset, slice_size);
+ piece_slices.emplace_back (std::move (slice), slice_size);
- total_bit_size -= slice_bit_size;
- total_bits_to_skip = 0;
+ total_size -= slice_size;
+ total_offset = 0;
}
unsigned int slices_num = piece_slices.size ();
@@ -1742,217 +1957,213 @@ dwarf_composite::slice (LONGEST bit_offset, LONGEST bit_size) const
void
dwarf_composite::read (frame_info *frame, gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset, const loc_offset &limit,
bool big_endian, int *optimized, int *unavailable) const
{
unsigned int pieces_num = m_pieces.size ();
- LONGEST total_bits_to_skip = bits_to_skip;
+ loc_offset total_to_skip = m_offset + offset;
+ loc_offset current_buf_offset = buf_offset;
+ loc_offset leftover_size = size;
unsigned int i;
if (!m_completed)
ill_formed_expression ();
- total_bits_to_skip += m_offset * HOST_CHAR_BIT + m_bit_suboffset;
-
/* Skip pieces covered by the read offset. */
for (i = 0; i < pieces_num; i++)
{
- LONGEST piece_bit_size = m_pieces[i].size;
+ loc_offset piece_size = m_pieces[i].size;
- if (total_bits_to_skip < piece_bit_size)
+ if (total_to_skip < piece_size)
break;
- total_bits_to_skip -= piece_bit_size;
+ total_to_skip -= piece_size;
}
for (; i < pieces_num; i++)
{
- LONGEST piece_bit_size = m_pieces[i].size;
- LONGEST actual_bit_size = piece_bit_size;
+ loc_offset piece_size = m_pieces[i].size;
+ loc_offset actual_size = piece_size;
- if (actual_bit_size > bit_size)
- actual_bit_size = bit_size;
+ if (actual_size > leftover_size)
+ actual_size = leftover_size;
- m_pieces[i].location->read (frame, buf, buf_bit_offset,
- actual_bit_size, total_bits_to_skip,
- piece_bit_size, big_endian,
+ m_pieces[i].location->read (frame, buf, current_buf_offset, actual_size,
+ total_to_skip, piece_size, big_endian,
optimized, unavailable);
- if (bit_size == actual_bit_size || *optimized || *unavailable)
+ if (leftover_size == actual_size || *optimized || *unavailable)
break;
- buf_bit_offset += actual_bit_size;
- bit_size -= actual_bit_size;
+ current_buf_offset += actual_size;
+ leftover_size -= actual_size;
}
}
void
dwarf_composite::write (frame_info *frame, const gdb_byte *buf,
- int buf_bit_offset, size_t bit_size,
- LONGEST bits_to_skip, size_t location_bit_limit,
- bool big_endian, int *optimized,
- int *unavailable) const
+ const loc_offset &buf_offset, const loc_offset &size,
+ const loc_offset &offset,
+ const loc_offset &limit, bool big_endian,
+ int *optimized, int *unavailable) const
{
- LONGEST total_bits_to_skip = bits_to_skip;
unsigned int pieces_num = m_pieces.size ();
+ loc_offset total_to_skip = m_offset + offset;
+ loc_offset current_buf_offset = buf_offset;
+ loc_offset leftover_size = size;
unsigned int i;
if (!m_completed)
ill_formed_expression ();
- total_bits_to_skip += m_offset * HOST_CHAR_BIT + m_bit_suboffset;
-
- /* Skip pieces covered by the write offset. */
+ /* Skip pieces covered by the read offset. */
for (i = 0; i < pieces_num; i++)
{
- LONGEST piece_bit_size = m_pieces[i].size;
+ loc_offset piece_size = m_pieces[i].size;
- if (total_bits_to_skip < piece_bit_size)
- break;
+ if (total_to_skip < piece_size)
+ break;
- total_bits_to_skip -= piece_bit_size;
+ total_to_skip -= piece_size;
}
for (; i < pieces_num; i++)
{
- LONGEST piece_bit_size = m_pieces[i].size;
- LONGEST actual_bit_size = piece_bit_size;
+ loc_offset piece_size = m_pieces[i].size;
+ loc_offset actual_size = piece_size;
- if (actual_bit_size > bit_size)
- actual_bit_size = bit_size;
+ if (actual_size > leftover_size)
+ actual_size = leftover_size;
- m_pieces[i].location->write (frame, buf, buf_bit_offset,
- actual_bit_size, total_bits_to_skip,
- piece_bit_size, big_endian,
+ m_pieces[i].location->write (frame, buf, current_buf_offset, actual_size,
+ total_to_skip, piece_size, big_endian,
optimized, unavailable);
- if (bit_size == actual_bit_size || *optimized || *unavailable)
+ if (leftover_size == actual_size || *optimized || *unavailable)
break;
- buf_bit_offset += actual_bit_size;
- bit_size -= actual_bit_size;
+ current_buf_offset += actual_size;
+ leftover_size -= actual_size;
}
}
void
-dwarf_composite::read_from_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const
+dwarf_composite::read_from_gdb_value (frame_info *frame,
+ struct value *value,
+ const loc_offset &value_offset,
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const
{
- ULONGEST total_bits_to_skip
- = bits_to_skip + HOST_CHAR_BIT * m_offset + m_bit_suboffset;
- ULONGEST remaining_bit_size = bit_size;
- ULONGEST bit_offset = value_bit_offset;
+ loc_offset total_to_skip = m_offset + offset;
+ loc_offset current_value_offset = value_offset;
+ loc_offset leftover_size = size;
unsigned int pieces_num = m_pieces.size ();
unsigned int i;
/* Advance to the first non-skipped piece. */
for (i = 0; i < pieces_num; i++)
{
- ULONGEST piece_bit_size = m_pieces[i].size;
+ loc_offset piece_size = m_pieces[i].size;
- if (total_bits_to_skip < piece_bit_size)
+ if (total_to_skip < piece_size)
break;
- total_bits_to_skip -= piece_bit_size;
+ total_to_skip -= piece_size;
}
for (; i < pieces_num; i++)
{
const dwarf_location &location = *m_pieces[i].location;
- ULONGEST piece_bit_size = m_pieces[i].size;
- size_t this_bit_size = piece_bit_size - total_bits_to_skip;
+ loc_offset piece_size = m_pieces[i].size;
+ loc_offset this_size = piece_size - total_to_skip;
- if (this_bit_size > remaining_bit_size)
- this_bit_size = remaining_bit_size;
+ if (this_size > leftover_size)
+ this_size = leftover_size;
- location.read_from_gdb_value (frame, value, bit_offset,
- total_bits_to_skip, this_bit_size,
- piece_bit_size);
+ location.read_from_gdb_value (frame, value, current_value_offset,
+ total_to_skip, this_size, piece_size);
- bit_offset += this_bit_size;
- remaining_bit_size -= this_bit_size;
- total_bits_to_skip = 0;
+ current_value_offset += this_size;
+ leftover_size -= this_size;
+ total_to_skip = 0;
}
}
void
-dwarf_composite::write_to_gdb_value (frame_info *frame, struct value *value,
- int value_bit_offset,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const
+dwarf_composite::write_to_gdb_value (frame_info *frame,
+ struct value *value,
+ const loc_offset &value_offset,
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const
{
- ULONGEST total_bits_to_skip
- = bits_to_skip + HOST_CHAR_BIT * m_offset + m_bit_suboffset;
- ULONGEST remaining_bit_size = bit_size;
- ULONGEST bit_offset = value_bit_offset;
+ loc_offset total_to_skip = m_offset + offset;
+ loc_offset current_value_offset = value_offset;
+ loc_offset leftover_size = size;
unsigned int pieces_num = m_pieces.size ();
unsigned int i;
/* Advance to the first non-skipped piece. */
for (i = 0; i < pieces_num; i++)
{
- ULONGEST piece_bit_size = m_pieces[i].size;
+ loc_offset piece_size = m_pieces[i].size;
- if (total_bits_to_skip < piece_bit_size)
+ if (total_to_skip < piece_size)
break;
- total_bits_to_skip -= piece_bit_size;
+ total_to_skip -= piece_size;
}
for (; i < pieces_num; i++)
{
const dwarf_location &location = *m_pieces[i].location;
- ULONGEST piece_bit_size = m_pieces[i].size;
- size_t this_bit_size = piece_bit_size - total_bits_to_skip;
+ loc_offset piece_size = m_pieces[i].size;
+ loc_offset this_size = piece_size - total_to_skip;
- if (this_bit_size > remaining_bit_size)
- this_bit_size = remaining_bit_size;
+ if (this_size > leftover_size)
+ this_size = leftover_size;
- location.write_to_gdb_value (frame, value, bit_offset,
- total_bits_to_skip, this_bit_size,
- piece_bit_size);
+ location.write_to_gdb_value (frame, value, current_value_offset,
+ total_to_skip, this_size, piece_size);
- bit_offset += this_bit_size;
- remaining_bit_size -= this_bit_size;
- total_bits_to_skip = 0;
+ current_value_offset += this_size;
+ leftover_size -= this_size;
+ total_to_skip = 0;
}
}
bool
-dwarf_composite::is_implicit_ptr_at (LONGEST bit_offset, int bit_length) const
+dwarf_composite::is_implicit_ptr_at (const loc_offset &offset,
+ const loc_offset &size) const
{
/* Advance to the first non-skipped piece. */
unsigned int pieces_num = m_pieces.size ();
- LONGEST total_bit_offset = bit_offset;
- LONGEST total_bit_length = bit_length;
-
- total_bit_offset += HOST_CHAR_BIT * m_offset + m_bit_suboffset;
+ loc_offset total_offset = m_offset + offset;
+ loc_offset leftover_size = size;
- for (unsigned int i = 0; i < pieces_num && total_bit_length != 0; i++)
+ for (unsigned int i = 0; i < pieces_num && size != 0; i++)
{
const piece &piece = m_pieces[i];
- ULONGEST read_bit_length = piece.size;
+ loc_offset read_size = piece.size;
- if (total_bit_offset >= read_bit_length)
+ if (total_offset >= read_size)
{
- total_bit_offset -= read_bit_length;
+ total_offset -= read_size;
continue;
}
- read_bit_length -= total_bit_offset;
+ read_size -= total_offset;
- if (total_bit_length < read_bit_length)
- read_bit_length = total_bit_length;
+ if (leftover_size < read_size)
+ read_size = leftover_size;
- if (piece.location->is_implicit_ptr_at (total_bit_offset,
- read_bit_length))
+ if (piece.location->is_implicit_ptr_at (total_offset, read_size))
return true;
- total_bit_offset = 0;
- total_bit_length -= read_bit_length;
+ total_offset = 0;
+ leftover_size -= read_size;
}
return false;
@@ -1961,32 +2172,30 @@ dwarf_composite::is_implicit_ptr_at (LONGEST bit_offset, int bit_length) const
value *
dwarf_composite::indirect_implicit_ptr (frame_info *frame, struct type *type,
LONGEST pointer_offset,
- LONGEST bit_offset,
- int bit_length) const
+ const loc_offset &offset,
+ const loc_offset &size) const
{
- LONGEST total_bit_offset = HOST_CHAR_BIT * m_offset
- + m_bit_suboffset + bit_offset;
+ loc_offset total_offset = m_offset + offset;
/* Advance to the first non-skipped piece. */
for (const piece &piece : m_pieces)
{
- ULONGEST read_bit_length = piece.size;
+ loc_offset read_size = piece.size;
- if (total_bit_offset >= read_bit_length)
+ if (total_offset >= read_size)
{
- total_bit_offset -= read_bit_length;
+ total_offset -= read_size;
continue;
}
- read_bit_length -= total_bit_offset;
+ read_size -= total_offset;
- if (bit_length < read_bit_length)
- read_bit_length = bit_length;
+ if (size < read_size)
+ read_size = size;
return piece.location->indirect_implicit_ptr (frame, type,
pointer_offset,
- total_bit_offset,
- read_bit_length);
+ total_offset, read_size);
}
return nullptr;
@@ -1994,41 +2203,41 @@ dwarf_composite::indirect_implicit_ptr (frame_info *frame, struct type *type,
bool
dwarf_composite::is_optimized_out (frame_info *frame, bool big_endian,
- LONGEST bits_to_skip, size_t bit_size,
- size_t location_bit_limit) const
+ const loc_offset &offset,
+ const loc_offset &size,
+ const loc_offset &limit) const
{
- ULONGEST total_bits_to_skip
- = bits_to_skip + HOST_CHAR_BIT * m_offset + m_bit_suboffset;
- ULONGEST remaining_bit_size = bit_size;
+ loc_offset total_to_skip = m_offset + offset;
+ loc_offset leftover_size = size;
unsigned int pieces_num = m_pieces.size ();
unsigned int i;
/* Advance to the first non-skipped piece. */
for (i = 0; i < pieces_num; i++)
{
- ULONGEST piece_bit_size = m_pieces[i].size;
+ loc_offset piece_size = m_pieces[i].size;
- if (total_bits_to_skip < piece_bit_size)
+ if (total_to_skip < piece_size)
break;
- total_bits_to_skip -= piece_bit_size;
+ total_to_skip -= piece_size;
}
for (; i < pieces_num; i++)
{
const dwarf_location &location = *m_pieces[i].location;
- ULONGEST piece_bit_size = m_pieces[i].size;
- size_t this_bit_size = piece_bit_size - total_bits_to_skip;
+ loc_offset piece_size = m_pieces[i].size;
+ loc_offset this_size = piece_size - total_to_skip;
- if (this_bit_size > remaining_bit_size)
- this_bit_size = remaining_bit_size;
+ if (this_size > leftover_size)
+ this_size = leftover_size;
- if (location.is_optimized_out (frame, big_endian, total_bits_to_skip,
- this_bit_size, piece_bit_size))
+ if (location.is_optimized_out (frame, big_endian, total_to_skip,
+ this_size, piece_size))
return true;
- remaining_bit_size -= this_bit_size;
- total_bits_to_skip = 0;
+ leftover_size -= this_size;
+ total_to_skip = 0;
}
return false;
@@ -2042,16 +2251,6 @@ dwarf_composite::to_gdb_value (frame_info *frame, struct type *type,
gdb_assert (type != nullptr);
gdb_assert (subobj_type != nullptr);
- ULONGEST bit_size = 0;
-
- for (const piece &piece : m_pieces)
- bit_size += piece.size;
-
- /* Complain if the expression is larger than the size of the
- outer type. */
- if (bit_size > HOST_CHAR_BIT * TYPE_LENGTH (type))
- invalid_synthetic_pointer ();
-
computed_closure *closure;
std::unique_ptr<dwarf_composite> composite_copy
= make_unique<dwarf_composite> (*this);
@@ -2262,6 +2461,9 @@ rw_closure_value (value *v, value *from)
if (frame == nullptr)
frame = frame_find_by_id (closure->get_frame_id ());
+ /* Offset should never be negative here. */
+ gdb_assert (bit_offset >= 0);
+
if (from == nullptr)
{
location.write_to_gdb_value (frame, v, bit_offset, bits_to_skip,
@@ -2306,12 +2508,12 @@ is_optimized_out_closure_value (value *v)
_("Should not be able to create a lazy value with "
"an enclosing type"));
- ULONGEST bits_to_skip = HOST_CHAR_BIT * unit_size * value_offset (v);
+ ULONGEST bit_offset = HOST_CHAR_BIT * unit_size * value_offset (v);
/* If there are bits that don't complete a byte, count them in. */
if (value_bitsize (v))
{
- bits_to_skip
+ bit_offset
+= HOST_CHAR_BIT * unit_size * value_offset (value_parent (v))
+ value_bitpos (v);
max_bit_size = value_bitsize (v);
@@ -2324,8 +2526,8 @@ is_optimized_out_closure_value (value *v)
if (frame == nullptr)
frame = frame_find_by_id (closure->get_frame_id ());
- return location.is_optimized_out (frame, big_endian, bits_to_skip,
- max_bit_size, 0);
+ return location.is_optimized_out
+ (frame, big_endian, bit_offset, max_bit_size, 0);
}
/* An implementation of an lval_funcs method to see whether a value is
@@ -2348,6 +2550,9 @@ check_synthetic_pointer (const value *value, LONGEST bit_offset,
computed_closure *closure
= (computed_closure *) value_computed_closure (value);
+ /* Offset should never be negative here. */
+ gdb_assert (total_bit_offset >= 0);
+
return closure->get_location ().is_implicit_ptr_at (total_bit_offset,
bit_length);
}
@@ -2391,9 +2596,11 @@ indirect_closure_value (value *value)
= extract_signed_integer (value_contents (value).data (),
TYPE_LENGTH (type), byte_order);
- return closure->get_location ().indirect_implicit_ptr (frame, type,
- pointer_offset,
- bit_offset, bit_length);
+ /* Offset should never be negative here. */
+ gdb_assert (bit_offset >= 0);
+
+ return closure->get_location ().indirect_implicit_ptr
+ (frame, type, pointer_offset, bit_offset, bit_length);
}
/* Implementation of the coerce_ref method of lval_funcs for synthetic C++
@@ -2411,7 +2618,8 @@ coerce_closure_ref (const value *value)
= (computed_closure *) value_computed_closure (value);
frame_info *frame = get_selected_frame (_("No frame selected."));
- return closure->get_location ().indirect_implicit_ptr (frame, type);
+ return closure->get_location ().indirect_implicit_ptr (frame, type,
+ 0, 0, 0);
}
else
{
@@ -2462,7 +2670,7 @@ gdb_value_to_dwarf_entry (gdbarch *arch, struct value *value)
const dwarf_location &location = closure->get_location ();
dwarf_location_up location_copy = location.clone_location ();
- location_copy->add_bit_offset (offset * HOST_CHAR_BIT);
+ location_copy->add_byte_offset (offset);
return location_copy;
}
default:
@@ -2604,15 +2812,15 @@ private:
pushed on the stack.
- Otherwise, the DWARF expression is ill-formed */
- void add_piece (ULONGEST bit_size, ULONGEST bit_offset);
+ void add_piece (const loc_offset &size, const loc_offset &offset);
/* It pops one stack entry that must be a location description and is
treated as a piece location description.
A complete composite location storage is created with PIECES_COUNT
identical pieces and pushed on the DWARF stack. Each pieces has a
- bit size of PIECE_BIT_SIZE. */
- void create_extend_composite (ULONGEST piece_bit_size,
+ size of PIECE_SIZE. */
+ void create_extend_composite (const loc_offset &piece_size,
ULONGEST pieces_count);
/* It pops three stack entries. The first must be an integral type
@@ -2623,10 +2831,10 @@ private:
A complete composite location description created with parts from
either of the two location description, based on the bit mask,
- is pushed on top of the DWARF stack. PIECE_BIT_SIZE represent
- a size in bits of each piece and PIECES_COUNT represents a number
- of pieces required. */
- void create_select_composite (ULONGEST piece_bit_size,
+ is pushed on top of the DWARF stack. PIECE_SIZE represent a size
+ of each piece and PIECES_COUNT represents a number of pieces
+ required. */
+ void create_select_composite (const loc_offset &piece_size,
ULONGEST pieces_count);
/* The engine for the expression evaluator. Using the context in this
@@ -2936,7 +3144,7 @@ dwarf_expr_context::stack_empty_p () const
}
void
-dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset)
+dwarf_expr_context::add_piece (const loc_offset &size, const loc_offset &offset)
{
dwarf_location_up piece;
gdbarch *arch = this->m_per_objfile->objfile->arch ();
@@ -2956,7 +3164,7 @@ dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset)
piece = to_location (pop (), arch);
}
- piece->add_bit_offset (bit_offset);
+ piece->add_offset (offset);
/* The composite to push the piece in. */
dwarf_composite *composite;
@@ -2988,16 +3196,16 @@ dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset)
}
}
- composite->add_piece (std::move (piece), bit_size);
+ composite->add_piece (std::move (piece), size);
}
void
-dwarf_expr_context::create_extend_composite (ULONGEST piece_bit_size,
+dwarf_expr_context::create_extend_composite (const loc_offset &piece_size,
ULONGEST pieces_count)
{
gdbarch *arch = this->m_per_objfile->objfile->arch ();
- if (stack_empty_p () || piece_bit_size == 0 || pieces_count == 0)
+ if (stack_empty_p () || piece_size == 0 || pieces_count == 0)
ill_formed_expression ();
dwarf_location_up location = to_location (pop (), arch);
@@ -3008,7 +3216,7 @@ dwarf_expr_context::create_extend_composite (ULONGEST piece_bit_size,
for (ULONGEST i = 0; i < pieces_count; i++)
{
dwarf_location_up piece = location->clone_location ();
- composite->add_piece (std::move (piece), piece_bit_size);
+ composite->add_piece (std::move (piece), piece_size);
}
composite->set_completed (true);
@@ -3016,13 +3224,13 @@ dwarf_expr_context::create_extend_composite (ULONGEST piece_bit_size,
}
void
-dwarf_expr_context::create_select_composite (ULONGEST piece_bit_size,
+dwarf_expr_context::create_select_composite (const loc_offset &piece_size,
ULONGEST pieces_count)
{
gdb::byte_vector mask_buf;
gdbarch *arch = this->m_per_objfile->objfile->arch ();
- if (stack_empty_p () || piece_bit_size == 0 || pieces_count == 0)
+ if (stack_empty_p () || piece_size == 0 || pieces_count == 0)
ill_formed_expression ();
dwarf_value_up mask = to_value (pop (), address_type ());
@@ -3056,13 +3264,14 @@ dwarf_expr_context::create_select_composite (ULONGEST piece_bit_size,
for (ULONGEST i = 0; i < pieces_count; i++)
{
std::unique_ptr<dwarf_location> slice;
+ loc_offset piece_offset = piece_size * i;
if ((mask_buf.data ()[i / HOST_CHAR_BIT] >> (i % HOST_CHAR_BIT)) & 1)
- slice = one->slice (i * piece_bit_size, piece_bit_size);
+ slice = one->slice (piece_offset, piece_size);
else
- slice = zero->slice (i * piece_bit_size, piece_bit_size);
+ slice = zero->slice (piece_offset, piece_size);
- composite->add_piece (std::move (slice), piece_bit_size);
+ composite->add_piece (std::move (slice), piece_size);
}
composite->set_completed (true);
@@ -3650,7 +3859,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
this->m_addr_info,
address_type, reg_size);
dwarf_location_up location = value->to_location (arch);
- location->add_bit_offset (offset * HOST_CHAR_BIT);
+ location->add_byte_offset (offset);
push (std::move (location));
break;
}
@@ -3689,7 +3898,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
if (memory == nullptr)
ill_formed_expression ();
- memory->add_bit_offset (offset * HOST_CHAR_BIT);
+ memory->add_byte_offset (offset);
memory->set_stack (true);
/* Restore the content of the original stack. */
@@ -4253,8 +4462,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
dwarf_value_up value = to_value (pop (), address_type);
dwarf_require_integral (value->type ());
dwarf_location_up location = to_location (pop (), arch);
+ LONGEST offset = value->to_long ();
- location->add_bit_offset (value->to_long () * HOST_CHAR_BIT);
+ if (offset < 0)
+ ill_formed_expression ();
+
+ location->add_byte_offset (offset);
push (std::move (location));
break;
}
@@ -4266,7 +4479,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
ULONGEST result = uoffset;
dwarf_location_up location = to_location (pop (), arch);
- location->add_bit_offset (result * HOST_CHAR_BIT);
+ location->add_offset ({result, 0});
push (std::move (location));
break;
}
@@ -4276,8 +4489,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
dwarf_value_up value = to_value (pop (), address_type);
dwarf_require_integral (value->type ());
dwarf_location_up location = to_location (pop (), arch);
+ LONGEST bit_offset = value->to_long ();
+
+ if (bit_offset < 0)
+ ill_formed_expression ();
- location->add_bit_offset (value->to_long ());
+ location->add_offset (bit_offset);
push (std::move (location));
break;
}
@@ -4306,7 +4523,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* Record the piece. */
op_ptr = safe_read_uleb128 (op_ptr, op_end, &piece_bit_size);
op_ptr = safe_read_uleb128 (op_ptr, op_end, &pieces_count);
- create_extend_composite (piece_bit_size, pieces_count);
+ create_extend_composite (piece_bit_size,
+ pieces_count);
break;
}
@@ -4317,7 +4535,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* Record the piece. */
op_ptr = safe_read_uleb128 (op_ptr, op_end, &piece_bit_size);
op_ptr = safe_read_uleb128 (op_ptr, op_end, &pieces_count);
- create_select_composite (piece_bit_size, pieces_count);
+ create_select_composite (piece_bit_size,
+ pieces_count);
break;
}