Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess via Gdb-patches <gdb-patches@sourceware.org>
To: Luis Machado <luis.machado@linaro.org>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH] [AArch64] Properly extract the reference to a return value from x8
Date: Wed, 12 Jan 2022 11:14:34 +0000	[thread overview]
Message-ID: <20220112111434.GL622389@redhat.com> (raw)
In-Reply-To: <20220111212219.4018309-1-luis.machado@linaro.org>

* Luis Machado via Gdb-patches <gdb-patches@sourceware.org> [2022-01-11 18:22:19 -0300]:

> When running gdb.cp/non-trivial-retval.exp, the following shows up for
> AArch64-Linux:
>
> Breakpoint 3, f1 (i1=23, i2=100) at src/gdb/testsuite/gdb.cp/non-trivial-retval.cc:35
> 35        A a;
> (gdb) finish
> Run till exit from #0  f1 (i1=23, i2=100) at src/gdb/testsuite/gdb.cp/non-trivial-retval.cc:35
> main () at /src/gdb/testsuite/gdb.cp/non-trivial-retval.cc:163
> 163       B b = f2 (i1, i2);
> Value returned is $6 = {a = -11952}
> (gdb)
>
> The return value should be {a = 123} instead. This happens because the AArch64
> backend doesn't extract the return value from the correct location. GDB should
> fetch a pointer to the memory location from X8.
>
> With the patch, gdb.cp/non-trivial-retval.exp has full passes on
> AArch64-Linux Ubuntu 20.04/18.04.
>
> The problem only shows up with the "finish" command. The "call" command
> works correctly and displays the correct return value.
>
> This is also related to PR gdb/28681
> (https://sourceware.org/bugzilla/show_bug.cgi?id=28681).
> ---
>  gdb/aarch64-tdep.c | 21 +++++++++++++++++++--
>  1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index 63d626f90ac..0efb3834584 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -2362,7 +2362,8 @@ aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type)
>        return 0;
>      }
>
> -  if (TYPE_LENGTH (type) > 16)
> +  if (TYPE_LENGTH (type) > 16
> +      || !language_pass_by_reference (type).trivially_copyable)
>      {
>        /* PCS B.6 Aggregates larger than 16 bytes are passed by
>  	 invisible reference.  */
> @@ -2474,8 +2475,24 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
>      {
>        if (aarch64_return_in_memory (gdbarch, valtype))
>  	{
> +	  /* From the AAPCS64's Result Return section:
> +
> +	     "Otherwise, the caller shall reserve a block of memory of
> +	      sufficient size and alignment to hold the result.  The address
> +	      of the memory block shall be passed as an additional argument to
> +	      the function in x8.  */
> +
>  	  aarch64_debug_printf ("return value in memory");
> -	  return RETURN_VALUE_STRUCT_CONVENTION;
> +
> +	  if (readbuf)
> +	    {
> +	      CORE_ADDR addr;
> +
> +	      regcache->cooked_read (AARCH64_STRUCT_RETURN_REGNUM, &addr);
> +	      read_memory (addr, readbuf, TYPE_LENGTH (valtype));
> +	    }
> +
> +	  return RETURN_VALUE_ABI_RETURNS_ADDRESS;

So now, anything that should be returned in memory is of type
RETURN_VALUE_ABI_RETURNS_ADDRESS.  This is interesting because it
should have implications outside of gdb.cp/non-trivial-retval.exp.

In gdb.cp/non-trivial-retval.exp we pass a small struct, which, for
most 64-bit targets, would normally be passed in registers, but which,
for aarch64 is required to be passed in memory.

After this change I would expect larger structs (> 16 bytes) to now
also work correctly in aarch64.  Did you see any additional tests
starting to pass after this commit?  For example, given this test
program:

  struct large_t
  {
    int array[32];
  };

  struct large_t
  func ()
  {
    int i;
    struct large_t obj;

    for (i = 0; i < 32; ++i)
      obj.array[i] = i;

    return obj;
  }

  int
  main ()
  {
    struct large_t obj = func ();
    return obj.array[0];
  }

On x86-64 this is what I see:

  $ gdb -q large-struct
  Reading symbols from large-struct...
  (gdb) set print elements 10
  (gdb) break func
  Breakpoint 1 at 0x401116: file large-struct.c, line 12.
  (gdb) r
  Starting program: /tmp/large-struct

  Breakpoint 1, func () at large-struct.c:12
  12	  for (i = 0; i < 32; ++i)
  (gdb) finish
  Run till exit from #0  func () at large-struct.c:12
  main () at large-struct.c:22
  22	  return obj.array[0];
  Value returned is $1 = {
    array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...}
  }
  (gdb)

I would expect on aarch64 that the finish didn't work correctly before
this patch, but now does.  Is this what you see?

If you did see other tests starting to pass then could you mention
them in the commit message please.  If not, could you add a test like
the above to the testsuite.

Otherwise, the change looks good to me.

Thanks,
Andrew


  reply	other threads:[~2022-01-12 11:15 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-04 17:22 [PATCH] [AArch64] Fix PR gdb/28681 Luis Machado via Gdb-patches
2022-01-04 18:09 ` Simon Marchi via Gdb-patches
2022-01-04 18:44   ` Luis Machado via Gdb-patches
2022-01-04 18:47     ` Simon Marchi via Gdb-patches
2022-01-04 18:49       ` Luis Machado via Gdb-patches
2022-01-04 18:56         ` Simon Marchi via Gdb-patches
2022-01-04 19:04           ` Luis Machado via Gdb-patches
2022-01-05 12:54 ` Andrew Burgess via Gdb-patches
2022-01-11 21:17   ` Luis Machado via Gdb-patches
2022-01-11 21:22 ` [PATCH] [AArch64] Properly extract the reference to a return value from x8 Luis Machado via Gdb-patches
2022-01-12 11:14   ` Andrew Burgess via Gdb-patches [this message]
2022-01-13 14:19     ` Luis Machado via Gdb-patches
2022-01-13 15:18       ` Andrew Burgess via Gdb-patches
2022-01-13 15:22         ` Luis Machado via Gdb-patches

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=20220112111434.GL622389@redhat.com \
    --to=gdb-patches@sourceware.org \
    --cc=aburgess@redhat.com \
    --cc=luis.machado@linaro.org \
    /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