Hi Ulrich, >Did you actually verify any of this information? >I.e. by debugging GDB itself, or by adding debug print >statements to store_register? >I'm asking because if the above is all true, then your patch >to store_register is a complete no-op for this case: I understand. No problem. Let me make it easier. So, consider a program with a function num2print () which print the number we pass prefixed with a R. For example, if we pass 2, it prints R2, 3 it will print R3. Please find the program at the bottom of this email. I have added a print statement for what we get in *addr via raw_supply and what we copy in long buf that will go in the ptrace. Also, I print the regno. As a fact register number R3 to R10 are reserved for function parameters. So, the GDB output for the program below is as follows:_ (gdb) b main Breakpoint 1 at 0x100007e4: file /home/XYZ/gdb_tests.c, line 22. (gdb) r Starting program: /home/XYZ/gdb_tests BFD: /usr/lib/libc.a(/usr/lib/libc.a(shr_64.o)): wrong auxtype 0xff for storage class 0x2 BFD: /usr/lib/libc.a(/usr/lib/libc.a(shr_64.o)): wrong auxtype 0xff for storage class 0x6b Breakpoint 1, main (argc=1, argv=0xffffffffffffad0) at /home/XYZ/gdb_tests:22 22 printf("Hi Bangalore %x\n",num2print(27, 16, 13, 9.9)); (gdb) call num2print $1 = {int (int, float, int, int)} 0x1000006a0 (gdb) call num2print (2, 3, 4, 5) val in regno 3 via buf is 0 and *addr is 2 val in regno 4 via buf is 0 and *addr is 1077936128 val in regno 5 via buf is 0 and *addr is 4 val in regno 6 via buf is 0 and *addr is 5 val in regno 1 via buf is -1696 and *addr is 268435455 val in regno 67 via buf is 1152 and *addr is 1 R0 $2 = 0 (gdb) info reg r0 0x1000004f4 4294968564 r1 0xffffffffffff9e0 1152921504606845408 r2 0x1100002e0 4563403488 r3 0x1 1 r4 0xffffffffffffad0 1152921504606845648 r5 0xffffffffffffae0 1152921504606845664 r6 0x800000000000d032 9223372036854829106 r7 0xfffffffffffffe0 1152921504606846944 r8 0x0 0 r9 0x1 1 r10 0x0 0 r11 0x1030 4144 r12 0xf1000600005901d8 17365886760216232408 r13 0xbadc0ffee0ddf00d 13464654573299691533 Clearly from the GDB output the buffer value getting copied is 0 but *addr is 2.. So memcpy (&buf, addr, 8); has not copied the values properly and hence we don't get the desired value.. Kindly note these programs are run-in 64-bit mode only and in 32-bit mode we are good. Now let's change the case. Let's make one of the parameters in the num2print function as long. The output for the same is as below in 64-bit mode.. (gdb) b main Breakpoint 1 at 0x100007dc: file /home/XYZ/gdb_tests.c, line 22. (gdb) r Starting program: /home/XYZ/gdb_tests BFD: /usr/lib/libc.a(/usr/lib/libc.a(shr_64.o)): wrong auxtype 0xff for storage class 0x2 BFD: /usr/lib/libc.a(/usr/lib/libc.a(shr_64.o)): wrong auxtype 0xff for storage class 0x6b Breakpoint 1, main (argc=1, argv=0xffffffffffffad0) at /home/XYZ/gdb_tests.c:22 22 printf("Hi Bangalore %x\n",num2print(27, 16, 13, 9.9)); (gdb) call num2print $1 = {int (long, float, int, int)} 0x1000006a0 (gdb) call num2print (2, 3, 4, 5) val in regno 3 via buf is 2 and *addr is 0 val in regno 4 via buf is 0 and *addr is 1077936128 val in regno 5 via buf is 0 and *addr is 4 val in regno 6 via buf is 0 and *addr is 5 R2 R3.000000 R0 R0 $2 = 2 So, my first parameter is long, and rest are int, except the second.. Check this out.. The first parameter is pointing to 0 in *addr but is copied properly in buf which long and is 2.. This is beause *addr is pointing to higher 32 bits 0 and lower is 2 but somehow memcpy copied properly into the buf. Our integer friends in regno 5 and 6 [parameter 3 and 4] are taken correctly in *addr but is horribly wrong after memcpy and what goes in buf.. So, the conclusions are long is fine, but int are gone for a toss. Also note our *addr is int.. (gdb) info reg r0 0x1000004f4 4294968564 r1 0xffffffffffff9e0 1152921504606845408 r2 0x1100002d0 4563403472 r3 0x1 1 r4 0xffffffffffffad0 1152921504606845648 r5 0xffffffffffffae0 1152921504606845664 r6 0x800000000000d032 9223372036854829106 what has gone in registers as a result of all this is garbage values. I do not want to handle things in integer as then aliging integer becomes a mess in 64 bit mode. Now let's take int addr as long addr64[64] of what I have done in my patch [attached in my previous mail]. I am going to use the same program but will print byte by byte on what comes in my *addr64. Since it is long, I print lower 32 bits first and then higher 32 bits via my patch variable val.. The output is as follows after applying my patch:- (gdb) b main Breakpoint 1 at 0x100007dc: file /home/XYZ/gdb_tests.c, line 22. (gdb) r Starting program: /home/XYZ/gdb_tests BFD: /usr/lib/libc.a(/usr/lib/libc.a(shr_64.o)): wrong auxtype 0xff for storage class 0x2 BFD: /usr/lib/libc.a(/usr/lib/libc.a(shr_64.o)): wrong auxtype 0xff for storage class 0x6b Breakpoint 1, main (argc=1, argv=0xffffffffffffad0) at /home/XYZ/gdb_tests.c:22 22 printf("Hi Bangalore %x\n",num2print(27, 16, 13, 9.9)); (gdb) call num2print $1 = {int (long, float, int, int)} 0x1000006a0 (gdb) call num2print (2, 3, 4, 5) val = 0 in regno 3 val = 2 in regno 3 val = 0 in regno 33 val = 2 in regno 33 val = 1077936128 in regno 4 val = 0 in regno 4 val = 4 in regno 5 val = 0 in regno 5 val = 5 in regno 6 val = 0 in regno 6 R2 R3.000000 R4 R5 $2 = 2 Check the above output. I have printed my val byte by byte with higher bytes first and then lower bytes. The first parameter was 2. The *addr64 which is a pointer of long type, is pointing to 0 which is higher 32 bits and then if we increment addr64 it is pointing to 2 which lower 32 bits. The second parameter being float used FPR number 33 and GPR 4.. The third parameter being int is aligned correctly by addr64 of long type pointer. Lower bits pointing first which is 4 and higher bits pointing at addr64++ address. Technically this is how even the first parameter should have been aligned but it is in reverse. Similarly, to the fourth parameter things align well. So, this is what I am trying to convince that using int addr[64] isn't allowing memcpy to copy values into the buffer correctly. We rather use a long and align this correctly. Let me know what you think. If you feel I can solve this in a better way, let me know. I appreciate your patience to read the email and wish to seek your guidance on the same. Have a nice day ahead. Thanks and regards, Aditya. --------------------------------------------------------------- PROGRAM #include "stdio.h" int num2print(int num, float num2, int num3, int num4) { if (num == 0) { printf("R0\n"); return 0; } if (num == 1) { printf("R1\n"); return 1; } printf("R%d\n",num); printf("R%f\n",num2); printf("R%d\n",num3); printf("R%d\n",num4); return num; } int main(int argc, char** argv) { printf("Hi Bangalore %x\n",num2print(27, 16, 13, 9.9)); return 0; } ---------------------------------------------------------------------- ________________________________ From: Ulrich Weigand Sent: 14 November 2022 21:24 To: gdb-patches@sourceware.org ; Aditya Kamath1 ; simon.marchi@efficios.com Cc: Sangamesh Mallayya Subject: Re: [PATCH] Fix call functions command bug in 64-bit programs for AIX Aditya Kamath1 wrote: >>- what does ARCH64() return? >True in 64 bit mode and false in 32 bit mode >> - what does register_size(...) return for those registers? >8 in 64 bit mode, 4 in 32 bit mode > (for GPRs with a 64-bit inferior it should return 8, if > it doesn't that's probably the root cause of the problem) >> - what value does ptrace return in your case? >It returns the data parameter value that is passed as the calls are successful. Did you actually verify any of this information? I.e. by debugging GDB itself, or by adding debug print statements to store_register? I'm asking because if the above is all true, then your patch to store_register is a complete no-op for this case: Before your patch, you have: int addr[PPC_MAX_REGISTER_SIZE]; [...] memcpy (addr, &buf, 8); [...] regcache->raw_supply (regno, (char *) addr); After your patch, you have: long long addr64[PPC_MAX_REGISTER_SIZE]; [...] memcpy (addr64, &buf, 8); [...] regcache->raw_supply (regno, (char *) addr64); which is exactly the same! Note that both the place that stores into addr[64] and the place that uses it cast to (char *), so whether you declare the array as int or long long does not make any difference whatsoever. Therefore, I believe that something else must be going on that is actually causing the problem you're seeing. You really need to debug the actual behavior in store_register to understand what is in fact going on here. Bye, Ulrich