From: jose.marchesi@oracle.com (Jose E. Marchesi)
To: Pedro Alves <palves@redhat.com>
Cc: vladimir.mezentsev@oracle.com, gdb-patches@sourceware.org
Subject: Re: [PATCH] gdb passes and returns incorrect values when dealing with small array on Sparc
Date: Fri, 19 May 2017 10:19:00 -0000 [thread overview]
Message-ID: <87o9upkv34.fsf@oracle.com> (raw)
In-Reply-To: <a6e9de3d-57cf-2dd9-08d9-0c87779c739d@redhat.com> (Pedro Alves's message of "Fri, 19 May 2017 10:57:52 +0100")
On 05/19/2017 10:44 AM, Jose E. Marchesi wrote:
>
> From: Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
>
> gdb has a special type (TYPE_CODE_ARRAY) to support the gcc extension
> (https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html).
> TYPE_CODE_ARRAY is handled incorrectly for both (32- and 64-bit) modes on Sparc machines.
>
> Tested on sparc64-linux-gnu and sparc-solaris (32- and 64-bit mode).
> No regressions.
>
> gdb/ChangeLog:
> 2017-05-12 Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
>
> * sparc-tdep.c (sparc_structure_return_p)
> (sparc_arg_on_registers_p): New functions.
> (sparc32_store_arguments): Use them.
> * sparc64-tdep.c (sparc64_16_byte_align_p)
> (sparc64_store_floating_fields, sparc64_extract_floating_fields):
> Handle TYPE_CODE_ARRAY.
>
>
> LGTM. Ok for master?
>
OK with the commit log tweak mentioned at:
https://sourceware.org/ml/gdb-patches/2017-04/msg00509.html
Applied as below.
Thanks.
commit 1933fd8ee01ad2e74a9c6341bc40f54962a8f889
Author: Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
Date: Fri May 19 03:06:19 2017 -0700
gdb: fix TYPE_CODE_ARRAY handling in sparc targets
gdb has a special type (TYPE_CODE_ARRAY) to support the gcc extension
(https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html).
TYPE_CODE_ARRAY is handled incorrectly for both (32- and 64-bit) modes
on Sparc machines.
Tested on sparc64-linux-gnu and sparc-solaris (32- and 64-bit mode).
6 tests ( from gdb/testsuite/gdb.base/gnu_vector.exp) failed on
sparc64-Linux and on sparc-Solaris in 32- and 64-bit mode. Now all
these tests passed. gdb/testsuite/gdb.base/gnu_vector.exp has 117
different cases for small (and not small) arrays and structures.
No regressions.
gdb/ChangeLog:
2017-05-19 Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
* sparc-tdep.c (sparc_structure_return_p)
(sparc_arg_on_registers_p): New functions.
(sparc32_store_arguments): Use them.
* sparc64-tdep.c (sparc64_16_byte_align_p)
(sparc64_store_floating_fields, sparc64_extract_floating_fields):
Handle TYPE_CODE_ARRAY.
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fdc2a40..1273ed8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,12 @@
+2017-05-19 Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
+
+ * sparc-tdep.c (sparc_structure_return_p)
+ (sparc_arg_on_registers_p): New functions.
+ (sparc32_store_arguments): Use them.
+ * sparc64-tdep.c (sparc64_16_byte_align_p)
+ (sparc64_store_floating_fields, sparc64_extract_floating_fields):
+ Handle TYPE_CODE_ARRAY.
+
2017-05-17 Yao Qi <yao.qi@linaro.org>
* cli/cli-decode.c (add_alias_cmd): New function.
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index d1e64b4..fa0e04e 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -298,6 +298,43 @@ sparc_structure_or_union_p (const struct type *type)
return 0;
}
+/* Check whether TYPE is returned on registers. */
+
+static bool
+sparc_structure_return_p (const struct type *type)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_LENGTH (type) <= 8)
+ {
+ struct type *t = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (sparc_floating_p (t) && TYPE_LENGTH (t) == 8)
+ return true;
+ return false;
+ }
+ if (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)
+ return true;
+ return sparc_structure_or_union_p (type);
+}
+
+/* Check whether TYPE is passed on registers. */
+
+static bool
+sparc_arg_on_registers_p (const struct type *type)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_LENGTH (type) <= 8)
+ {
+ struct type *t = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (sparc_floating_p (t) && TYPE_LENGTH (t) == 8)
+ return false;
+ return true;
+ }
+ if (sparc_structure_or_union_p (type) || sparc_complex_floating_p (type)
+ || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
+ return false;
+ return true;
+}
+
/* Register information. */
#define SPARC32_FPU_REGISTERS \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
@@ -570,9 +607,7 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
struct type *type = value_type (args[i]);
int len = TYPE_LENGTH (type);
- if (sparc_structure_or_union_p (type)
- || (sparc_floating_p (type) && len == 16)
- || sparc_complex_floating_p (type))
+ if (!sparc_arg_on_registers_p (type))
{
/* Structure, Union and Quad-Precision Arguments. */
sp -= len;
@@ -594,11 +629,8 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
else
{
/* Integral and pointer arguments. */
- gdb_assert (sparc_integral_or_pointer_p (type));
-
- if (len < 4)
- args[i] = value_cast (builtin_type (gdbarch)->builtin_int32,
- args[i]);
+ gdb_assert (sparc_integral_or_pointer_p (type)
+ || (TYPE_CODE (type) == TYPE_CODE_ARRAY && len <= 8));
num_elements += ((len + 3) / 4);
}
}
@@ -620,6 +652,15 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
const bfd_byte *valbuf = value_contents (args[i]);
struct type *type = value_type (args[i]);
int len = TYPE_LENGTH (type);
+ gdb_byte buf[4];
+
+ if (len < 4)
+ {
+ memset (buf, 0, 4 - len);
+ memcpy (buf + 4 - len, valbuf, len);
+ valbuf = buf;
+ len = 4;
+ }
gdb_assert (len == 4 || len == 8);
@@ -1345,10 +1386,10 @@ sparc32_extract_return_value (struct type *type, struct regcache *regcache,
int len = TYPE_LENGTH (type);
gdb_byte buf[32];
- gdb_assert (!sparc_structure_or_union_p (type));
- gdb_assert (!(sparc_floating_p (type) && len == 16));
+ gdb_assert (!sparc_structure_return_p (type));
- if (sparc_floating_p (type) || sparc_complex_floating_p (type))
+ if (sparc_floating_p (type) || sparc_complex_floating_p (type)
+ || TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
/* Floating return values. */
regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf);
@@ -1397,11 +1438,9 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache,
const gdb_byte *valbuf)
{
int len = TYPE_LENGTH (type);
- gdb_byte buf[8];
+ gdb_byte buf[32];
- gdb_assert (!sparc_structure_or_union_p (type));
- gdb_assert (!(sparc_floating_p (type) && len == 16));
- gdb_assert (len <= 8);
+ gdb_assert (!sparc_structure_return_p (type));
if (sparc_floating_p (type) || sparc_complex_floating_p (type))
{
@@ -1457,8 +1496,7 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
guarantees that we can always find the return value, not just
before the function returns. */
- if (sparc_structure_or_union_p (type)
- || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
+ if (sparc_structure_return_p (type))
{
ULONGEST sp;
CORE_ADDR addr;
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 58f5bf0..9e0e6b5 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -669,6 +669,13 @@ static const struct frame_base sparc64_frame_base =
static int
sparc64_16_byte_align_p (struct type *type)
{
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ struct type *t = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (sparc64_floating_p (t))
+ return 1;
+ }
if (sparc64_floating_p (type) && TYPE_LENGTH (type) == 16)
return 1;
@@ -703,7 +710,23 @@ sparc64_store_floating_fields (struct regcache *regcache, struct type *type,
gdb_assert (element < 16);
- if (sparc64_floating_p (type)
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ gdb_byte buf[8];
+ int regnum = SPARC_F0_REGNUM + element * 2 + bitpos / 32;
+
+ valbuf += bitpos / 8;
+ if (len < 8)
+ {
+ memset (buf, 0, 8 - len);
+ memcpy (buf + 8 - len, valbuf, len);
+ valbuf = buf;
+ len = 8;
+ }
+ for (int n = 0; n < (len + 3) / 4; n++)
+ regcache_cooked_write (regcache, regnum + n, valbuf + n * 4);
+ }
+ else if (sparc64_floating_p (type)
|| (sparc64_complex_floating_p (type) && len <= 16))
{
int regnum;
@@ -776,7 +799,23 @@ sparc64_extract_floating_fields (struct regcache *regcache, struct type *type,
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- if (sparc64_floating_p (type))
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ int len = TYPE_LENGTH (type);
+ int regnum = SPARC_F0_REGNUM + bitpos / 32;
+
+ valbuf += bitpos / 8;
+ if (len < 4)
+ {
+ gdb_byte buf[4];
+ regcache_cooked_read (regcache, regnum, buf);
+ memcpy (valbuf, buf + 4 - len, len);
+ }
+ else
+ for (int i = 0; i < (len + 3) / 4; i++)
+ regcache_cooked_read (regcache, regnum + i, valbuf + i * 4);
+ }
+ else if (sparc64_floating_p (type))
{
int len = TYPE_LENGTH (type);
int regnum;
next prev parent reply other threads:[~2017-05-19 10:19 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-16 16:16 vladimir.mezentsev
2017-05-19 9:44 ` Jose E. Marchesi
2017-05-19 9:57 ` Pedro Alves
2017-05-19 10:19 ` Jose E. Marchesi [this message]
[not found] <1490721669-12560-1-git-send-email-vladimir.mezentsev@oracle.com>
[not found] ` <5a3397ae-e986-8a36-13ba-ed2cfeb68a12@redhat.com>
2017-03-29 16:38 ` Vladimir Mezentsev
2017-04-18 14:54 ` Pedro Alves
-- strict thread matches above, loose matches on Subject: below --
2017-03-29 16:21 vladimir.mezentsev
2017-04-18 14:54 ` Pedro Alves
2017-04-18 21:28 ` Jose E. Marchesi
2017-04-18 22:20 ` Pedro Alves
2017-04-19 9:01 ` Jose E. Marchesi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87o9upkv34.fsf@oracle.com \
--to=jose.marchesi@oracle.com \
--cc=gdb-patches@sourceware.org \
--cc=palves@redhat.com \
--cc=vladimir.mezentsev@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox