diff options
author | Simon Marchi <simon.marchi@polymtl.ca> | 2021-10-25 23:29:34 -0400 |
---|---|---|
committer | Simon Marchi <simon.marchi@polymtl.ca> | 2021-12-03 16:41:38 -0500 |
commit | 2a50938ab740296a1d6df67feea9401e57e4d90e (patch) | |
tree | c0a570783faab4b4e5225e14a434739fa0264536 /gdb/findvar.c | |
parent | 4bce7cdaf481901edbc5ee47d953ea7e8efb56ca (diff) | |
download | gdb-2a50938ab740296a1d6df67feea9401e57e4d90e.zip gdb-2a50938ab740296a1d6df67feea9401e57e4d90e.tar.gz gdb-2a50938ab740296a1d6df67feea9401e57e4d90e.tar.bz2 |
gdb: make extract_integer take an array_view
I think it would make sense for extract_integer, extract_signed_integer
and extract_unsigned_integer to take an array_view. This way, when we
extract an integer, we can validate that we don't overflow the buffer
passed by the caller (e.g. ask to extract a 4-byte integer but pass a
2-byte buffer).
- Change extract_integer to take an array_view
- Add overloads of extract_signed_integer and extract_unsigned_integer
that take array_views. Keep the existing versions so we don't
need to change all callers, but make them call the array_view
versions.
This shortens some places like:
result = extract_unsigned_integer (value_contents (result_val).data (),
TYPE_LENGTH (value_type (result_val)),
byte_order);
into
result = extract_unsigned_integer (value_contents (result_val), byte_order);
value_contents returns an array view that is of length
`TYPE_LENGTH (value_type (result_val))` already, so the length is
implicitly communicated through the array view.
Change-Id: Ic1c1f98c88d5c17a8486393af316f982604d6c95
Diffstat (limited to 'gdb/findvar.c')
-rw-r--r-- | gdb/findvar.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/gdb/findvar.c b/gdb/findvar.c index f7e6328..a0031d2 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -48,14 +48,11 @@ you lose template<typename T, typename> T -extract_integer (const gdb_byte *addr, int len, enum bfd_endian byte_order) +extract_integer (gdb::array_view<const gdb_byte> buf, enum bfd_endian byte_order) { typename std::make_unsigned<T>::type retval = 0; - const unsigned char *p; - const unsigned char *startaddr = addr; - const unsigned char *endaddr = startaddr + len; - if (len > (int) sizeof (T)) + if (buf.size () > (int) sizeof (T)) error (_("\ That operation is not available on integers of more than %d bytes."), (int) sizeof (T)); @@ -64,36 +61,38 @@ That operation is not available on integers of more than %d bytes."), the least significant. */ if (byte_order == BFD_ENDIAN_BIG) { - p = startaddr; + size_t i = 0; + if (std::is_signed<T>::value) { /* Do the sign extension once at the start. */ - retval = ((LONGEST) * p ^ 0x80) - 0x80; - ++p; + retval = ((LONGEST) buf[i] ^ 0x80) - 0x80; + ++i; } - for (; p < endaddr; ++p) - retval = (retval << 8) | *p; + for (; i < buf.size (); ++i) + retval = (retval << 8) | buf[i]; } else { - p = endaddr - 1; + ssize_t i = buf.size () - 1; + if (std::is_signed<T>::value) { /* Do the sign extension once at the start. */ - retval = ((LONGEST) * p ^ 0x80) - 0x80; - --p; + retval = ((LONGEST) buf[i] ^ 0x80) - 0x80; + --i; } - for (; p >= startaddr; --p) - retval = (retval << 8) | *p; + for (; i >= 0; --i) + retval = (retval << 8) | buf[i]; } return retval; } /* Explicit instantiations. */ -template LONGEST extract_integer<LONGEST> (const gdb_byte *addr, int len, +template LONGEST extract_integer<LONGEST> (gdb::array_view<const gdb_byte> buf, enum bfd_endian byte_order); -template ULONGEST extract_integer<ULONGEST> (const gdb_byte *addr, int len, - enum bfd_endian byte_order); +template ULONGEST extract_integer<ULONGEST> + (gdb::array_view<const gdb_byte> buf, enum bfd_endian byte_order); /* Sometimes a long long unsigned integer can be extracted as a LONGEST value. This is done so that we can print these values |