public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix for call feature having nine parameters or more in AIX
@ 2023-08-25  9:21 Aditya Kamath1
  2023-08-25 11:19 ` Ulrich Weigand
  0 siblings, 1 reply; 9+ messages in thread
From: Aditya Kamath1 @ 2023-08-25  9:21 UTC (permalink / raw)
  To: Ulrich Weigand, Aditya Kamath1 via Gdb-patches; +Cc: Sangamesh Mallayya


[-- Attachment #1.1: Type: text/plain, Size: 7308 bytes --]

Respected Ulrich and GDB community members,

Hi,

Please find attached the patch. See:- 0001-Fix-for-call-feature-having-9th-function-parameter-a.patch

This is a patch which is a fix to a problem that has occurred due to non-zero extension of a word in 64 bit mode.

Consider the code named as Example 1 pasted below this email.

The GDB output for the same without applying this patch with the code compiled in 64 bit mode is as follows:-
./gdb ~/gdb_tests/nine_parameter_func_64
GNU gdb (GDB) 14.0.50.20230811-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-ibm-aix7.2.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
https://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
    http://www.gnu.org/software/gdb/documentation/.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/aditya/gdb_tests/nine_parameter_func_64...
(gdb) b main
Breakpoint 1 at 0x10000934: file /home/aditya/gdb_tests/nine_parameter_func.c, line 27.
(gdb) r
Starting program: /home/aditya/gdb_tests/nine_parameter_func_64

Breakpoint 1, main () at /home/aditya/gdb_tests/nine_parameter_func.c:27
27        const float register f3 = 19.0;
(gdb) list
22        printf ("j = %d \n", j);
23        return (int)(d);
24      }
25      int main ()
26      {
27        const float register f3 = 19.0;
28        const int register i1 = 700;
29        printf("%f \n", f3 + i1);
30        b ();
31        a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 19);
(gdb) call  a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 19)
812.000000
9th para = -268435248 , 10th para = -268374976
j = -268435248
$1 = -1059136197
(gdb)

From the output kindly check what is going on with 9th parameter and beyond. It is some garbage value.

The reason is that in the 64-bit mode, ideally, I thought from the compiler we should have got the zero extended and 8 word aligned number but we do not. We ourselves must do it. This is like the issue we solved last year.{ https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=7aae1a86b30185224554d450e233ca967359b75d}

So, debugging further I realized that the parameters of function in AIX are stored in registers 3 to 10. More about this fact can be read in this document {https://www.ibm.com/docs/en/aix/7.2?topic=overview-register-usage-conventions}. If the function has more than 8 parameters then the 9th one onwards,  we store the function parameters in the stack. This can be seen in the rs6000-aix-tdep.c file in the dummy_call function from line 700 and beyond. Over here we have this line below.

write_memory (sp + 24 + (ii * 4), arg->contents ().data (), len);

This the root cause of this issue. Since the arg->contents ().data () is not zero extended we are going to get something corrupt. This works in 32 bit programs whose output I have pasted below Example 1 as 32 bit output without patch.

In 64-bit mode we will need to add 6-word space which will be 6 * 8 = 48, plus ii * wordsize = ii * 8 to the SP as well.. So, this I have done in the below lines along with zero extending the output,

+store_unsigned_integer (word, tdep->wordsize, byte_order,
+                                                                    unpack_long (type, arg->contents ().data ()));
+                    write_memory (sp + 48 + (ii * 8), word, PPC_MAX_REGISTER_SIZE);

Where ii is the parameter number i.e. 9th or 10 th or 11 th and so on.

After this in AIX, the output of 64 bit code of Example 1 in GDB is as follows in 64 bit output with patch pasted below this email.

So, the issue is fixed in this case.

Since you all are experts, and I am a beginner and still learning a lot of things in GDB there are chances I might have not thought of more scenarios to this problem.

Kindly let me know if my analysis and patch is not correct. Kindly give me feedback for the same. If it the patch looks all right kindly push the same.

Have a nice day ahead.

Thanks and regards,
Aditya.


64 bit output with patch:-
./gdb ~/gdb_tests/nine_parameter_func_64
GNU gdb (GDB) 14.0.50.20230811-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-ibm-aix7.2.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
https://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
   http://www.gnu.org/software/gdb/documentation/.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/aditya/gdb_tests/nine_parameter_func_64...
(gdb) b main
Breakpoint 1 at 0x10000934: file /home/aditya/gdb_tests/nine_parameter_func.c, line 27.
(gdb) r
Starting program: /home/aditya/gdb_tests/nine_parameter_func_64

Breakpoint 1, main () at /home/aditya/gdb_tests/nine_parameter_func.c:27
27        const float register f3 = 19.0;
(gdb) list
22        printf ("j = %d \n", j);
23        return (int)(d);
24      }
25      int main ()
26      {
27        const float register f3 = 19.0;
28        const int register i1 = 700;
29        printf("%f \n", f3 + i1);
30        b ();
31        a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 19);
(gdb) call  a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 19);
Invalid character ';' in expression.
(gdb) call  a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 19)
812.000000
9th para = 9 , 10th para = 983
j = 9
$1 = 1041
(gdb) call  a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 20)
812.000000
9th para = 9 , 10th para = 983
j = 9
$2 = 1042

Example 1:-

cat ~/gdb_tests/nine_parameter_func.c
#include <stdio.h>

int b ()
{
  const float register f1 = 1.0;
  const float register f2 = 2.0;
  float register f3 = 2.0;
  int register i1 = 900;
  return printf("%f %f\n", f1 + i1, f2 + f3);
}

int a (int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l)
{
  const float register f3 = 12.0;
  const int register i1 = 800;
  printf("%f \n", f3 + i1);
  static int var = 123;
  b++;
  c++;
  d = e + f + g + h + i + j + k + l;
  printf ("9th para = %d , 10th para = %d\n", j, k);
  printf ("j = %d \n", j);
  return (int)(d);
}
int main ()
{
  const float register f3 = 19.0;
  const int register i1 = 700;
  printf("%f \n", f3 + i1);
  b ();
  a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 19);
  return 0;
}

32 bit output without and with patch:-
Breakpoint 1, main () at /home/aditya/gdb_tests/nine_parameter_func.c:27
27        const float register f3 = 19.0;
(gdb)  call  a (1, 2, 3, 4, 5, 6, 7, 8, 9, 983, 19)
812.000000
9th para = 9 , 10th para = 983
j = 9
$1 = 1041
(gdb)


[-- Attachment #2: 0001-Fix-for-call-feature-having-9th-function-parameter-a.patch --]
[-- Type: application/octet-stream, Size: 1481 bytes --]

From 9e51f460b43be22cb940c2ebb09b4f04b4b3728d Mon Sep 17 00:00:00 2001
From: Aditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com>
Date: Fri, 25 Aug 2023 03:20:07 -0500
Subject: [PATCH] Fix for call feature having 9th function parameter and beyond
 corrupt values.

In AIX the first eight function parameters are stored from R3 to R10.
If there are more than eight parameters in a function then we store the 9th parameter onwards in the stack.
While doing so, in 64 bit mode the words were not zero extended and was coming like 32 bit mode.
This patch is a fix to the same.
---
 gdb/rs6000-aix-tdep.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index 829f55981ca..2e38377f679 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -707,7 +707,16 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 	      ++f_argno;
 	    }
 
-	  write_memory (sp + 24 + (ii * 4), arg->contents ().data (), len);
+	  if (tdep->wordsize == 8)
+	    {
+	      gdb_byte word[PPC_MAX_REGISTER_SIZE];
+	      memset (word, 0, PPC_MAX_REGISTER_SIZE);
+	      store_unsigned_integer (word, tdep->wordsize, byte_order,
+				      unpack_long (type, arg->contents ().data ()));
+	      write_memory (sp + 48 + (ii * 8), word, PPC_MAX_REGISTER_SIZE);
+	    }
+	  else
+	    write_memory (sp + 24 + (ii * 4), arg->contents ().data (), len);
 	  ii += ((len + 3) & -4) / 4;
 	}
     }
-- 
2.38.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-08-25 17:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-25  9:21 [PATCH] Fix for call feature having nine parameters or more in AIX Aditya Kamath1
2023-08-25 11:19 ` Ulrich Weigand
2023-08-25 13:35   ` Aditya Kamath1
2023-08-25 14:13     ` Ulrich Weigand
2023-08-25 15:35       ` Aditya Kamath1
2023-08-25 15:57         ` Ulrich Weigand
2023-08-25 16:36           ` Aditya Kamath1
2023-08-25 16:49             ` Ulrich Weigand
2023-08-25 17:47               ` Aditya Kamath1

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).