mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
2 Commits
gdb-12.1-r
...
users/serg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b8a4a5b45 | ||
|
|
a5083498fa |
@@ -1081,19 +1081,19 @@ typedef struct
|
|||||||
const gdb_byte *data;
|
const gdb_byte *data;
|
||||||
|
|
||||||
/* Size in bytes of value to pass on stack. */
|
/* Size in bytes of value to pass on stack. */
|
||||||
int len;
|
length_t len;
|
||||||
} stack_item_t;
|
} stack_item_t;
|
||||||
|
|
||||||
DEF_VEC_O (stack_item_t);
|
DEF_VEC_O (stack_item_t);
|
||||||
|
|
||||||
/* Return the alignment (in bytes) of the given type. */
|
/* Return the alignment (in bytes) of the given type. */
|
||||||
|
|
||||||
static int
|
static length_t
|
||||||
aarch64_type_align (struct type *t)
|
aarch64_type_align (struct type *t)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
int align;
|
length_t align;
|
||||||
int falign;
|
length_t falign;
|
||||||
|
|
||||||
t = check_typedef (t);
|
t = check_typedef (t);
|
||||||
switch (TYPE_CODE (t))
|
switch (TYPE_CODE (t))
|
||||||
@@ -1206,14 +1206,13 @@ aapcs_is_vfp_call_or_return_candidate_1 (struct type *type,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct type *target_type = TYPE_TARGET_TYPE (type);
|
struct type *target_type = TYPE_TARGET_TYPE (type);
|
||||||
int count = aapcs_is_vfp_call_or_return_candidate_1
|
slength_t count = aapcs_is_vfp_call_or_return_candidate_1
|
||||||
(target_type, fundamental_type);
|
(target_type, fundamental_type);
|
||||||
|
|
||||||
if (count == -1)
|
if (count != -1)
|
||||||
return count;
|
count *= (TYPE_LENGTH (type) / TYPE_LENGTH (target_type));
|
||||||
|
|
||||||
count *= (TYPE_LENGTH (type) / TYPE_LENGTH (target_type));
|
return (int) count;
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,8 +1238,8 @@ aapcs_is_vfp_call_or_return_candidate_1 (struct type *type,
|
|||||||
|
|
||||||
/* Ensure there is no padding between the fields (allowing for empty
|
/* Ensure there is no padding between the fields (allowing for empty
|
||||||
zero length structs) */
|
zero length structs) */
|
||||||
int ftype_length = (*fundamental_type == nullptr)
|
length_t ftype_length = (*fundamental_type == nullptr)
|
||||||
? 0 : TYPE_LENGTH (*fundamental_type);
|
? 0 : TYPE_LENGTH (*fundamental_type);
|
||||||
if (count * ftype_length != TYPE_LENGTH (type))
|
if (count * ftype_length != TYPE_LENGTH (type))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -1309,7 +1308,7 @@ struct aarch64_call_info
|
|||||||
|
|
||||||
/* The next stacked argument address, equivalent to NSAA as
|
/* The next stacked argument address, equivalent to NSAA as
|
||||||
described in the AArch64 Procedure Call Standard. */
|
described in the AArch64 Procedure Call Standard. */
|
||||||
unsigned nsaa;
|
length_t nsaa;
|
||||||
|
|
||||||
/* Stack item vector. */
|
/* Stack item vector. */
|
||||||
VEC(stack_item_t) *si;
|
VEC(stack_item_t) *si;
|
||||||
@@ -1324,7 +1323,7 @@ pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||||||
struct value *arg)
|
struct value *arg)
|
||||||
{
|
{
|
||||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||||
int len = TYPE_LENGTH (type);
|
length_t len = TYPE_LENGTH (type);
|
||||||
enum type_code typecode = TYPE_CODE (type);
|
enum type_code typecode = TYPE_CODE (type);
|
||||||
int regnum = AARCH64_X0_REGNUM + info->ngrn;
|
int regnum = AARCH64_X0_REGNUM + info->ngrn;
|
||||||
const bfd_byte *buf = value_contents (arg);
|
const bfd_byte *buf = value_contents (arg);
|
||||||
@@ -1333,8 +1332,8 @@ pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||||||
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
int partial_len = len < X_REGISTER_SIZE ? len : X_REGISTER_SIZE;
|
length_t partial_len = len < X_REGISTER_SIZE ? len : X_REGISTER_SIZE;
|
||||||
CORE_ADDR regval = extract_unsigned_integer (buf, partial_len,
|
CORE_ADDR regval = extract_unsigned_integer (buf, (int) partial_len,
|
||||||
byte_order);
|
byte_order);
|
||||||
|
|
||||||
|
|
||||||
@@ -1342,7 +1341,7 @@ pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||||||
if (byte_order == BFD_ENDIAN_BIG
|
if (byte_order == BFD_ENDIAN_BIG
|
||||||
&& partial_len < X_REGISTER_SIZE
|
&& partial_len < X_REGISTER_SIZE
|
||||||
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
|
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
|
||||||
regval <<= ((X_REGISTER_SIZE - partial_len) * TARGET_CHAR_BIT);
|
regval <<= ((X_REGISTER_SIZE - (int) partial_len) * TARGET_CHAR_BIT);
|
||||||
|
|
||||||
if (aarch64_debug)
|
if (aarch64_debug)
|
||||||
{
|
{
|
||||||
@@ -1352,7 +1351,7 @@ pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||||||
}
|
}
|
||||||
regcache_cooked_write_unsigned (regcache, regnum, regval);
|
regcache_cooked_write_unsigned (regcache, regnum, regval);
|
||||||
len -= partial_len;
|
len -= partial_len;
|
||||||
buf += partial_len;
|
buf += (int) partial_len;
|
||||||
regnum++;
|
regnum++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1366,7 +1365,7 @@ static int
|
|||||||
pass_in_v (struct gdbarch *gdbarch,
|
pass_in_v (struct gdbarch *gdbarch,
|
||||||
struct regcache *regcache,
|
struct regcache *regcache,
|
||||||
struct aarch64_call_info *info,
|
struct aarch64_call_info *info,
|
||||||
int len, const bfd_byte *buf)
|
length_t &len, const bfd_byte *buf)
|
||||||
{
|
{
|
||||||
if (info->nsrn < 8)
|
if (info->nsrn < 8)
|
||||||
{
|
{
|
||||||
@@ -1381,7 +1380,7 @@ pass_in_v (struct gdbarch *gdbarch,
|
|||||||
memset (reg, 0, sizeof (reg));
|
memset (reg, 0, sizeof (reg));
|
||||||
/* PCS C.1, the argument is allocated to the least significant
|
/* PCS C.1, the argument is allocated to the least significant
|
||||||
bits of V register. */
|
bits of V register. */
|
||||||
memcpy (reg, buf, len);
|
memcpy (reg, buf, static_cast<size_t> (len));
|
||||||
regcache->cooked_write (regnum, reg);
|
regcache->cooked_write (regnum, reg);
|
||||||
|
|
||||||
if (aarch64_debug)
|
if (aarch64_debug)
|
||||||
@@ -1402,8 +1401,8 @@ pass_on_stack (struct aarch64_call_info *info, struct type *type,
|
|||||||
struct value *arg)
|
struct value *arg)
|
||||||
{
|
{
|
||||||
const bfd_byte *buf = value_contents (arg);
|
const bfd_byte *buf = value_contents (arg);
|
||||||
int len = TYPE_LENGTH (type);
|
length_t len = TYPE_LENGTH (type);
|
||||||
int align;
|
length_t align;
|
||||||
stack_item_t item;
|
stack_item_t item;
|
||||||
|
|
||||||
info->argnum++;
|
info->argnum++;
|
||||||
@@ -1412,7 +1411,7 @@ pass_on_stack (struct aarch64_call_info *info, struct type *type,
|
|||||||
|
|
||||||
/* PCS C.17 Stack should be aligned to the larger of 8 bytes or the
|
/* PCS C.17 Stack should be aligned to the larger of 8 bytes or the
|
||||||
Natural alignment of the argument's type. */
|
Natural alignment of the argument's type. */
|
||||||
align = align_up (align, 8);
|
align = align_up (static_cast<ULONGEST> (align), 8);
|
||||||
|
|
||||||
/* The AArch64 PCS requires at most doubleword alignment. */
|
/* The AArch64 PCS requires at most doubleword alignment. */
|
||||||
if (align > 16)
|
if (align > 16)
|
||||||
@@ -1420,8 +1419,8 @@ pass_on_stack (struct aarch64_call_info *info, struct type *type,
|
|||||||
|
|
||||||
if (aarch64_debug)
|
if (aarch64_debug)
|
||||||
{
|
{
|
||||||
debug_printf ("arg %d len=%d @ sp + %d\n", info->argnum, len,
|
debug_printf ("arg %d len=%s @ sp + %s\n", info->argnum, len.c_str (),
|
||||||
info->nsaa);
|
info->nsaa.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
item.len = len;
|
item.len = len;
|
||||||
@@ -1429,10 +1428,10 @@ pass_on_stack (struct aarch64_call_info *info, struct type *type,
|
|||||||
VEC_safe_push (stack_item_t, info->si, &item);
|
VEC_safe_push (stack_item_t, info->si, &item);
|
||||||
|
|
||||||
info->nsaa += len;
|
info->nsaa += len;
|
||||||
if (info->nsaa & (align - 1))
|
if ((info->nsaa & (align - 1)) != 0)
|
||||||
{
|
{
|
||||||
/* Push stack alignment padding. */
|
/* Push stack alignment padding. */
|
||||||
int pad = align - (info->nsaa & (align - 1));
|
length_t pad = align - (info->nsaa & (align - 1));
|
||||||
|
|
||||||
item.len = pad;
|
item.len = pad;
|
||||||
item.data = NULL;
|
item.data = NULL;
|
||||||
@@ -1451,8 +1450,8 @@ pass_in_x_or_stack (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||||||
struct aarch64_call_info *info, struct type *type,
|
struct aarch64_call_info *info, struct type *type,
|
||||||
struct value *arg)
|
struct value *arg)
|
||||||
{
|
{
|
||||||
int len = TYPE_LENGTH (type);
|
length_t len = TYPE_LENGTH (type);
|
||||||
int nregs = (len + X_REGISTER_SIZE - 1) / X_REGISTER_SIZE;
|
int nregs = static_cast<int> ((len + X_REGISTER_SIZE - 1) / X_REGISTER_SIZE);
|
||||||
|
|
||||||
/* PCS C.13 - Pass in registers if we have enough spare */
|
/* PCS C.13 - Pass in registers if we have enough spare */
|
||||||
if (info->ngrn + nregs <= 8)
|
if (info->ngrn + nregs <= 8)
|
||||||
@@ -1493,7 +1492,8 @@ pass_in_v_vfp_candidate (struct gdbarch *gdbarch, struct regcache *regcache,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
return pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (target_type),
|
return pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (target_type),
|
||||||
buf + TYPE_LENGTH (target_type));
|
buf
|
||||||
|
+ static_cast<ULONGEST> (TYPE_LENGTH (target_type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_CODE_ARRAY:
|
case TYPE_CODE_ARRAY:
|
||||||
@@ -1588,7 +1588,8 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||||||
{
|
{
|
||||||
struct value *arg = args[argnum];
|
struct value *arg = args[argnum];
|
||||||
struct type *arg_type, *fundamental_type;
|
struct type *arg_type, *fundamental_type;
|
||||||
int len, elements;
|
length_t len;
|
||||||
|
int elements;
|
||||||
|
|
||||||
arg_type = check_typedef (value_type (arg));
|
arg_type = check_typedef (value_type (arg));
|
||||||
len = TYPE_LENGTH (arg_type);
|
len = TYPE_LENGTH (arg_type);
|
||||||
@@ -1642,7 +1643,7 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||||||
invisible reference. */
|
invisible reference. */
|
||||||
|
|
||||||
/* Allocate aligned storage. */
|
/* Allocate aligned storage. */
|
||||||
sp = align_down (sp - len, 16);
|
sp = align_down (sp - static_cast<CORE_ADDR> (len), 16);
|
||||||
|
|
||||||
/* Write the real data into the stack. */
|
/* Write the real data into the stack. */
|
||||||
write_memory (sp, value_contents (arg), len);
|
write_memory (sp, value_contents (arg), len);
|
||||||
@@ -1664,14 +1665,14 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure stack retains 16 byte alignment. */
|
/* Make sure stack retains 16 byte alignment. */
|
||||||
if (info.nsaa & 15)
|
if ((info.nsaa & length_t (15)) != 0)
|
||||||
sp -= 16 - (info.nsaa & 15);
|
sp -= 16 - (static_cast<CORE_ADDR> (info.nsaa) & 15);
|
||||||
|
|
||||||
while (!VEC_empty (stack_item_t, info.si))
|
while (!VEC_empty (stack_item_t, info.si))
|
||||||
{
|
{
|
||||||
stack_item_t *si = VEC_last (stack_item_t, info.si);
|
stack_item_t *si = VEC_last (stack_item_t, info.si);
|
||||||
|
|
||||||
sp -= si->len;
|
sp -= static_cast<CORE_ADDR> (si->len);
|
||||||
if (si->data != NULL)
|
if (si->data != NULL)
|
||||||
write_memory (sp, si->data, si->len);
|
write_memory (sp, si->data, si->len);
|
||||||
VEC_pop (stack_item_t, info.si);
|
VEC_pop (stack_item_t, info.si);
|
||||||
@@ -1920,7 +1921,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
|
|||||||
if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
|
if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
|
||||||
&fundamental_type))
|
&fundamental_type))
|
||||||
{
|
{
|
||||||
int len = TYPE_LENGTH (fundamental_type);
|
size_t len = static_cast<size_t> (TYPE_LENGTH (fundamental_type));
|
||||||
|
|
||||||
for (int i = 0; i < elements; i++)
|
for (int i = 0; i < elements; i++)
|
||||||
{
|
{
|
||||||
@@ -1951,7 +1952,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
|
|||||||
/* If the type is a plain integer, then the access is
|
/* If the type is a plain integer, then the access is
|
||||||
straight-forward. Otherwise we have to play around a bit
|
straight-forward. Otherwise we have to play around a bit
|
||||||
more. */
|
more. */
|
||||||
int len = TYPE_LENGTH (type);
|
length_t len = TYPE_LENGTH (type);
|
||||||
int regno = AARCH64_X0_REGNUM;
|
int regno = AARCH64_X0_REGNUM;
|
||||||
ULONGEST tmp;
|
ULONGEST tmp;
|
||||||
|
|
||||||
@@ -1962,7 +1963,8 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
|
|||||||
regcache_cooked_read_unsigned (regs, regno++, &tmp);
|
regcache_cooked_read_unsigned (regs, regno++, &tmp);
|
||||||
store_unsigned_integer (valbuf,
|
store_unsigned_integer (valbuf,
|
||||||
(len > X_REGISTER_SIZE
|
(len > X_REGISTER_SIZE
|
||||||
? X_REGISTER_SIZE : len), byte_order, tmp);
|
? X_REGISTER_SIZE
|
||||||
|
: static_cast<int> (len)), byte_order, tmp);
|
||||||
len -= X_REGISTER_SIZE;
|
len -= X_REGISTER_SIZE;
|
||||||
valbuf += X_REGISTER_SIZE;
|
valbuf += X_REGISTER_SIZE;
|
||||||
}
|
}
|
||||||
@@ -1972,14 +1974,15 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
|
|||||||
/* For a structure or union the behaviour is as if the value had
|
/* For a structure or union the behaviour is as if the value had
|
||||||
been stored to word-aligned memory and then loaded into
|
been stored to word-aligned memory and then loaded into
|
||||||
registers with 64-bit load instruction(s). */
|
registers with 64-bit load instruction(s). */
|
||||||
int len = TYPE_LENGTH (type);
|
length_t len = TYPE_LENGTH (type);
|
||||||
int regno = AARCH64_X0_REGNUM;
|
int regno = AARCH64_X0_REGNUM;
|
||||||
bfd_byte buf[X_REGISTER_SIZE];
|
bfd_byte buf[X_REGISTER_SIZE];
|
||||||
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
regs->cooked_read (regno++, buf);
|
regs->cooked_read (regno++, buf);
|
||||||
memcpy (valbuf, buf, len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len);
|
memcpy (valbuf, buf, len > X_REGISTER_SIZE ? X_REGISTER_SIZE
|
||||||
|
: static_cast<size_t> (len));
|
||||||
len -= X_REGISTER_SIZE;
|
len -= X_REGISTER_SIZE;
|
||||||
valbuf += X_REGISTER_SIZE;
|
valbuf += X_REGISTER_SIZE;
|
||||||
}
|
}
|
||||||
@@ -2032,7 +2035,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
|
|||||||
if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
|
if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
|
||||||
&fundamental_type))
|
&fundamental_type))
|
||||||
{
|
{
|
||||||
int len = TYPE_LENGTH (fundamental_type);
|
size_t len = static_cast<size_t> (TYPE_LENGTH (fundamental_type));
|
||||||
|
|
||||||
for (int i = 0; i < elements; i++)
|
for (int i = 0; i < elements; i++)
|
||||||
{
|
{
|
||||||
@@ -2076,7 +2079,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
|
|||||||
/* Integral values greater than one word are stored in
|
/* Integral values greater than one word are stored in
|
||||||
consecutive registers starting with r0. This will always
|
consecutive registers starting with r0. This will always
|
||||||
be a multiple of the regiser size. */
|
be a multiple of the regiser size. */
|
||||||
int len = TYPE_LENGTH (type);
|
length_t len = TYPE_LENGTH (type);
|
||||||
int regno = AARCH64_X0_REGNUM;
|
int regno = AARCH64_X0_REGNUM;
|
||||||
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
@@ -2092,14 +2095,15 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
|
|||||||
/* For a structure or union the behaviour is as if the value had
|
/* For a structure or union the behaviour is as if the value had
|
||||||
been stored to word-aligned memory and then loaded into
|
been stored to word-aligned memory and then loaded into
|
||||||
registers with 64-bit load instruction(s). */
|
registers with 64-bit load instruction(s). */
|
||||||
int len = TYPE_LENGTH (type);
|
length_t len = TYPE_LENGTH (type);
|
||||||
int regno = AARCH64_X0_REGNUM;
|
int regno = AARCH64_X0_REGNUM;
|
||||||
bfd_byte tmpbuf[X_REGISTER_SIZE];
|
bfd_byte tmpbuf[X_REGISTER_SIZE];
|
||||||
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
memcpy (tmpbuf, valbuf,
|
memcpy (tmpbuf, valbuf,
|
||||||
len > X_REGISTER_SIZE ? X_REGISTER_SIZE : len);
|
len > X_REGISTER_SIZE ? X_REGISTER_SIZE
|
||||||
|
: static_cast<size_t> (len));
|
||||||
regs->cooked_write (regno++, tmpbuf);
|
regs->cooked_write (regno++, tmpbuf);
|
||||||
len -= X_REGISTER_SIZE;
|
len -= X_REGISTER_SIZE;
|
||||||
valbuf += X_REGISTER_SIZE;
|
valbuf += X_REGISTER_SIZE;
|
||||||
@@ -2357,8 +2361,12 @@ aarch64_pseudo_read_value_1 (struct gdbarch *gdbarch,
|
|||||||
gdb_static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM);
|
gdb_static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM);
|
||||||
|
|
||||||
if (regcache->raw_read (v_regnum, reg_buf) != REG_VALID)
|
if (regcache->raw_read (v_regnum, reg_buf) != REG_VALID)
|
||||||
mark_value_bytes_unavailable (result_value, 0,
|
{
|
||||||
TYPE_LENGTH (value_type (result_value)));
|
LONGEST len
|
||||||
|
= static_cast<LONGEST> (TYPE_LENGTH (value_type (result_value)));
|
||||||
|
|
||||||
|
mark_value_bytes_unavailable (result_value, 0, len);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
memcpy (value_contents_raw (result_value), reg_buf, regsize);
|
memcpy (value_contents_raw (result_value), reg_buf, regsize);
|
||||||
|
|
||||||
|
|||||||
384
gdb/common/length-type.h
Normal file
384
gdb/common/length-type.h
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
/* Length types for GDB.
|
||||||
|
|
||||||
|
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef COMMON_LENGH_TYPE_H
|
||||||
|
#define COMMON_LENGH_TYPE_H
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class gdb_len
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T m_len;
|
||||||
|
|
||||||
|
gdb_len () = default;
|
||||||
|
|
||||||
|
gdb_len (T l)
|
||||||
|
: m_len (l)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_len (int l)
|
||||||
|
: m_len (l)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* const T get () const */
|
||||||
|
/* { */
|
||||||
|
/* return m_len; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
/* void set (const T l) */
|
||||||
|
/* { */
|
||||||
|
/* m_len = l; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
const char *c_str () const
|
||||||
|
{
|
||||||
|
return std::numeric_limits<T>::is_signed
|
||||||
|
? plongest (m_len) : pulongest (m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator int () const
|
||||||
|
{
|
||||||
|
if (m_len > std::numeric_limits<int>::max ())
|
||||||
|
error (_("Cannot cast variable: too long"));
|
||||||
|
|
||||||
|
return static_cast<int> (m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator unsigned int () const
|
||||||
|
{
|
||||||
|
if (std::numeric_limits<T>::is_signed && m_len < 0)
|
||||||
|
error (_("Cannot cast negative variable."));
|
||||||
|
|
||||||
|
if (m_len > std::numeric_limits<unsigned int>::max ())
|
||||||
|
error (_("Cannot cast variable: too long."));
|
||||||
|
|
||||||
|
return static_cast<unsigned int> (m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* explicit operator size_t () const */
|
||||||
|
/* { */
|
||||||
|
/* if (std::numeric_limits<T>::is_signed && m_len < 0) */
|
||||||
|
/* error (_("Cannot cast negative variable to 'size_t'.")); */
|
||||||
|
|
||||||
|
/* if (m_len > std::numeric_limits<size_t>::max ()) */
|
||||||
|
/* error (_("Cannot cast variable: too long")); */
|
||||||
|
|
||||||
|
/* return static_cast<size_t> (m_len); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
explicit operator ULONGEST () const
|
||||||
|
{
|
||||||
|
if (!std::numeric_limits<T>::is_signed)
|
||||||
|
return m_len;
|
||||||
|
|
||||||
|
if (m_len < 0)
|
||||||
|
error (_("Cannot cast negative variable to 'ULONGEST'."));
|
||||||
|
|
||||||
|
return static_cast<ULONGEST> (m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator LONGEST () const
|
||||||
|
{
|
||||||
|
if (std::numeric_limits<T>::is_signed)
|
||||||
|
return m_len;
|
||||||
|
|
||||||
|
if (m_len > std::numeric_limits<T>::max ())
|
||||||
|
error (_("Cannot cast variable: too long"));
|
||||||
|
|
||||||
|
return static_cast<LONGEST> (m_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_LENGTH_REL_OP_TYPE(TYPE, OP) \
|
||||||
|
constexpr bool \
|
||||||
|
operator OP (const TYPE rhs) \
|
||||||
|
{ \
|
||||||
|
return (static_cast<TYPE> (*this) OP rhs); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#define DEFINE_ALL_LENGTH_REL_OP_TYPE(TYPE) \
|
||||||
|
DEFINE_LENGTH_REL_OP_TYPE (TYPE, >) \
|
||||||
|
DEFINE_LENGTH_REL_OP_TYPE (TYPE, >=) \
|
||||||
|
DEFINE_LENGTH_REL_OP_TYPE (TYPE, <) \
|
||||||
|
DEFINE_LENGTH_REL_OP_TYPE (TYPE, <=) \
|
||||||
|
DEFINE_LENGTH_REL_OP_TYPE (TYPE, ==) \
|
||||||
|
DEFINE_LENGTH_REL_OP_TYPE (TYPE, !=)
|
||||||
|
|
||||||
|
DEFINE_ALL_LENGTH_REL_OP_TYPE (int)
|
||||||
|
DEFINE_ALL_LENGTH_REL_OP_TYPE (ULONGEST)
|
||||||
|
DEFINE_ALL_LENGTH_REL_OP_TYPE (LONGEST)
|
||||||
|
|
||||||
|
#define DEFINE_LENGTH_REL_OP(OP) \
|
||||||
|
constexpr bool \
|
||||||
|
operator OP (const gdb_len<T> &rhs) \
|
||||||
|
{ \
|
||||||
|
return (m_len OP rhs.m_len); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_LENGTH_REL_OP (>)
|
||||||
|
DEFINE_LENGTH_REL_OP (>=)
|
||||||
|
DEFINE_LENGTH_REL_OP (<)
|
||||||
|
DEFINE_LENGTH_REL_OP (<=)
|
||||||
|
DEFINE_LENGTH_REL_OP (==)
|
||||||
|
DEFINE_LENGTH_REL_OP (!=)
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFINE_LENGTH_ARITHM_OP_TYPE(TYPE, OP) \
|
||||||
|
gdb_len<T> & \
|
||||||
|
operator OP ## = (const TYPE rhs) \
|
||||||
|
{ \
|
||||||
|
if (std::numeric_limits<TYPE>::is_signed \
|
||||||
|
&& !std::numeric_limits<T>::is_signed \
|
||||||
|
&& rhs < 0) \
|
||||||
|
error (_("Cannot cast negative variable to unsigned type.")); \
|
||||||
|
else if (!std::numeric_limits<TYPE>::is_signed \
|
||||||
|
&& std::numeric_limits<T>::is_signed \
|
||||||
|
&& rhs > std::numeric_limits<T>::max ()) \
|
||||||
|
error (_("Cannot cast variable: too long.")); \
|
||||||
|
\
|
||||||
|
m_len OP ## = static_cast<T> (rhs); \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
friend constexpr gdb_len<T> \
|
||||||
|
operator OP (const gdb_len<T> &lhs, const TYPE rhs) \
|
||||||
|
{ \
|
||||||
|
return gdb_len<T> (static_cast<TYPE> (lhs) OP rhs); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
friend constexpr gdb_len<T> \
|
||||||
|
operator OP (const TYPE rhs, const gdb_len<T> &lhs) \
|
||||||
|
{ \
|
||||||
|
return gdb_len<T> (rhs OP static_cast<TYPE> (lhs)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_ALL_LENGTH_ARITHM_OP_TYPE(TYPE) \
|
||||||
|
DEFINE_LENGTH_ARITHM_OP_TYPE (TYPE, +) \
|
||||||
|
DEFINE_LENGTH_ARITHM_OP_TYPE (TYPE, -) \
|
||||||
|
DEFINE_LENGTH_ARITHM_OP_TYPE (TYPE, *) \
|
||||||
|
DEFINE_LENGTH_ARITHM_OP_TYPE (TYPE, /) \
|
||||||
|
DEFINE_LENGTH_ARITHM_OP_TYPE (TYPE, %)
|
||||||
|
|
||||||
|
DEFINE_ALL_LENGTH_ARITHM_OP_TYPE (int)
|
||||||
|
DEFINE_ALL_LENGTH_ARITHM_OP_TYPE (unsigned int)
|
||||||
|
DEFINE_ALL_LENGTH_ARITHM_OP_TYPE (ULONGEST)
|
||||||
|
DEFINE_ALL_LENGTH_ARITHM_OP_TYPE (LONGEST)
|
||||||
|
|
||||||
|
#define DEFINE_LENGTH_ARITHM_OP(OP) \
|
||||||
|
gdb_len<T> & \
|
||||||
|
operator OP ## = (const gdb_len<T> &rhs) \
|
||||||
|
{ \
|
||||||
|
m_len OP ## = rhs.m_len; \
|
||||||
|
return *this; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
friend constexpr gdb_len<T> \
|
||||||
|
operator OP (const gdb_len<T> &lhs, const gdb_len<T> &rhs) \
|
||||||
|
{ \
|
||||||
|
return gdb_len<T> (lhs.m_len OP rhs.m_len); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (+)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (-)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (*)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (/)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (%)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (&)
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef gdb_len<ULONGEST> length_t;
|
||||||
|
typedef gdb_len<LONGEST> slength_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* Operators for length_t and slength_t. */
|
||||||
|
|
||||||
|
#define DEFINE_ARITHM_OPS(OP) \
|
||||||
|
length_t & \
|
||||||
|
operator OP ## = (length_t &lhs, const slength_t &rhs) \
|
||||||
|
{ \
|
||||||
|
lhs.m_len OP ## = static_cast<ULONGEST> (rhs); \
|
||||||
|
return lhs; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
slength_t & \
|
||||||
|
operator OP ## = (slength_t &lhs, const length_t &rhs) \
|
||||||
|
{ \
|
||||||
|
lhs.m_len OP ## = static_cast<LONGEST> (rhs); \
|
||||||
|
return lhs; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
slength_t \
|
||||||
|
operator OP (const length_t &lhs, const slength_t &rhs) \
|
||||||
|
{ \
|
||||||
|
return static_cast<LONGEST> (lhs) OP rhs; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
slength_t \
|
||||||
|
operator OP (const slength_t &lhs, const length_t &rhs) \
|
||||||
|
{ \
|
||||||
|
return lhs OP static_cast<LONGEST> (rhs); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ARITHM_OPS (+)
|
||||||
|
DEFINE_ARITHM_OPS (-)
|
||||||
|
DEFINE_ARITHM_OPS (*)
|
||||||
|
DEFINE_ARITHM_OPS (/)
|
||||||
|
DEFINE_ARITHM_OPS (%)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
#define DEFINE_LENGTH_ARITHM_OP(TYPE, OP) \
|
||||||
|
constexpr TYPE \
|
||||||
|
operator OP (TYPE lhs, ULONGEST rhs) \
|
||||||
|
{ \
|
||||||
|
return (TYPE) (lhs.m_len OP rhs); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
constexpr TYPE \
|
||||||
|
operator OP (ULONGEST lhs, TYPE rhs) \
|
||||||
|
{ \
|
||||||
|
return (TYPE) (lhs OP static_cast<ULONGEST> (rhs)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
length_t & \
|
||||||
|
operator OP ## = (length_t &lhs, ULONGEST rhs) \
|
||||||
|
{ \
|
||||||
|
lhs = (length_t) (static_cast<ULONGEST> (lhs) OP rhs); \
|
||||||
|
return lhs; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
constexpr length_t \
|
||||||
|
operator OP (length_t lhs, length_t rhs) \
|
||||||
|
{ \
|
||||||
|
return (length_t) (static_cast<ULONGEST> (lhs) \
|
||||||
|
OP static_cast<ULONGEST> (rhs)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
length_t & \
|
||||||
|
operator OP ## = (length_t &lhs, length_t rhs) \
|
||||||
|
{ \
|
||||||
|
lhs = (length_t) (static_cast<ULONGEST> (lhs) \
|
||||||
|
OP static_cast<ULONGEST> (rhs)); \
|
||||||
|
return lhs; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (+)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (-)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (*)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (/)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
enum class length_t : ULONGEST {};
|
||||||
|
|
||||||
|
enum class slenght_t : LONGEST {};
|
||||||
|
|
||||||
|
#define DEFINE_LENGTH_REL_OP(OP) \
|
||||||
|
constexpr bool \
|
||||||
|
operator OP (length_t lhs, int rhs) \
|
||||||
|
{ \
|
||||||
|
return (lhs OP static_cast<ULONGEST> (rhs)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_LENGTH_REL_OP (>)
|
||||||
|
DEFINE_LENGTH_REL_OP (>=)
|
||||||
|
DEFINE_LENGTH_REL_OP (<)
|
||||||
|
DEFINE_LENGTH_REL_OP (<=)
|
||||||
|
DEFINE_LENGTH_REL_OP (==)
|
||||||
|
DEFINE_LENGTH_REL_OP (!=)
|
||||||
|
|
||||||
|
#define DEFINE_LENGTH_ARITHM_OP(OP) \
|
||||||
|
constexpr length_t \
|
||||||
|
operator OP (length_t lhs, ULONGEST rhs) \
|
||||||
|
{ \
|
||||||
|
return (length_t) (static_cast<ULONGEST> (lhs) OP rhs); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
constexpr length_t \
|
||||||
|
operator OP (ULONGEST lhs, length_t rhs) \
|
||||||
|
{ \
|
||||||
|
return (length_t) (lhs OP static_cast<ULONGEST> (rhs)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
length_t & \
|
||||||
|
operator OP ## = (length_t &lhs, ULONGEST rhs) \
|
||||||
|
{ \
|
||||||
|
lhs = (length_t) (static_cast<ULONGEST> (lhs) OP rhs); \
|
||||||
|
return lhs; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
constexpr length_t \
|
||||||
|
operator OP (length_t lhs, length_t rhs) \
|
||||||
|
{ \
|
||||||
|
return (length_t) (static_cast<ULONGEST> (lhs) \
|
||||||
|
OP static_cast<ULONGEST> (rhs)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
length_t & \
|
||||||
|
operator OP ## = (length_t &lhs, length_t rhs) \
|
||||||
|
{ \
|
||||||
|
lhs = (length_t) (static_cast<ULONGEST> (lhs) \
|
||||||
|
OP static_cast<ULONGEST> (rhs)); \
|
||||||
|
return lhs; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (+)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (-)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (*)
|
||||||
|
DEFINE_LENGTH_ARITHM_OP (/)
|
||||||
|
|
||||||
|
inline const char *
|
||||||
|
to_str (length_t &l)
|
||||||
|
{
|
||||||
|
return pulongest (to_underlying (l));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
to_int (length_t &l)
|
||||||
|
{
|
||||||
|
return static_cast<int> (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ssize_t
|
||||||
|
to_ssize_t (length_t &l)
|
||||||
|
{
|
||||||
|
return static_cast<ssize_t> (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline LONGEST
|
||||||
|
to_LONGEST (length_t &l)
|
||||||
|
{
|
||||||
|
return static_cast<LONGEST> (l);
|
||||||
|
}
|
||||||
|
#endif //0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! COMMON_LENGH_TYPE_H */
|
||||||
@@ -377,6 +377,15 @@ write_memory (CORE_ADDR memaddr,
|
|||||||
memory_error (TARGET_XFER_E_IO, memaddr);
|
memory_error (TARGET_XFER_E_IO, memaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See gdbcore.h. */
|
||||||
|
|
||||||
|
void
|
||||||
|
write_memory (CORE_ADDR memaddr,
|
||||||
|
const bfd_byte *myaddr, length_t &len)
|
||||||
|
{
|
||||||
|
write_memory (memaddr, myaddr, static_cast<ssize_t> len);
|
||||||
|
}
|
||||||
|
|
||||||
/* Same as write_memory, but notify 'memory_changed' observers. */
|
/* Same as write_memory, but notify 'memory_changed' observers. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ CORE_ADDR read_memory_typed_address (CORE_ADDR addr, struct type *type);
|
|||||||
extern void write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr,
|
extern void write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr,
|
||||||
ssize_t len);
|
ssize_t len);
|
||||||
|
|
||||||
|
/* Same as above, but with length_t. */
|
||||||
|
|
||||||
|
extern void write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr,
|
||||||
|
length_t &len);
|
||||||
|
|
||||||
/* Same as write_memory, but notify 'memory_changed' observers. */
|
/* Same as write_memory, but notify 'memory_changed' observers. */
|
||||||
|
|
||||||
extern void write_memory_with_notification (CORE_ADDR memaddr,
|
extern void write_memory_with_notification (CORE_ADDR memaddr,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include "common/enum-flags.h"
|
#include "common/enum-flags.h"
|
||||||
#include "common/underlying.h"
|
#include "common/underlying.h"
|
||||||
#include "common/print-utils.h"
|
#include "common/print-utils.h"
|
||||||
|
#include "common/length-type.h"
|
||||||
#include "gdbarch.h"
|
#include "gdbarch.h"
|
||||||
|
|
||||||
/* Forward declarations for prototypes. */
|
/* Forward declarations for prototypes. */
|
||||||
@@ -859,7 +860,7 @@ struct type
|
|||||||
type_length_units function should be used in order to get the length
|
type_length_units function should be used in order to get the length
|
||||||
expressed in target addressable memory units. */
|
expressed in target addressable memory units. */
|
||||||
|
|
||||||
unsigned int length;
|
length_t length;
|
||||||
|
|
||||||
/* * Core type, shared by a group of qualified types. */
|
/* * Core type, shared by a group of qualified types. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user