gdb: on SVE Architecture sve registers are not saved in inferior calls

Message ID 390fff81-1316-322a-0299-528d30d9ac90@huawei.com
State New
Headers show
Series
  • gdb: on SVE Architecture sve registers are not saved in inferior calls
Related show

Commit Message

Simon Marchi via Gdb-patches Jan. 5, 2022, 7:41 a.m.
As the following gdb session, a bug is generated on SVE Architecture(When
you execute "inf r" commmand, there is a 'vg' register).

	(gdb) b main
	Breakpoint 1 at 0x40062c: file test.c, line 5.
	(gdb) r
	Starting program: /root/test

	Breakpoint 1, main () at test.c:5
	5		printf("hello, world.\n");
	(gdb) n
	hello, world.
	6		return 0;
	(gdb) p errno
	Unable to set VG register.: Success.
	(gdb) inf r
	x0             0xe                 14
	x1             0x0                 0
	x2             0x1                 1
	x3             0x0                 0
	******
	******
	******
	x26            0x0                 0
	x27            0x0                 0
	x28            0x0                 0
	x29            0xfffffffff410      281474976707600
	x30            0x400638            4195896
	sp             0xfffffffff410      0xfffffffff410
	pc             0x400638            0x400638 <main+20>
	cpsr           0x60001000          [ EL=0 SSBS C Z ]
	fpsr           0x0                 0
	fpcr           0x0                 0
	vg             0x4                 4

The error infomation "Unable to set VG register.: Success." is caused
by the "p errno" command. The command is a inferior call which involves
registers saving and restoring. On SVE Architecture, infcall_suspend_state
contains a valid VG register state, however, regcache_read_pc function
does not fetch sve registers to regcache when saving context. So when
target_store_registers is called to restore sve registers, the regcache
does not contain valid VG register state and then error occurs. To fix the
problem, we also fetch sve registers when calling regcache_read_pc function.

Signed-off-by: yaowenbin <yaowenbin1@huawei.com>

---
 gdb/aarch64-linux-nat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.27.0

Comments

Simon Marchi via Gdb-patches Jan. 5, 2022, 9:12 p.m. | #1
Hi,

On 1/5/22 4:41 AM, yaowenbin via Gdb-patches wrote:
> As the following gdb session, a bug is generated on SVE Architecture(When

> you execute "inf r" commmand, there is a 'vg' register).

> 

> 	(gdb) b main

> 	Breakpoint 1 at 0x40062c: file test.c, line 5.

> 	(gdb) r

> 	Starting program: /root/test

> 

> 	Breakpoint 1, main () at test.c:5

> 	5		printf("hello, world.\n");

> 	(gdb) n

> 	hello, world.

> 	6		return 0;

> 	(gdb) p errno

> 	Unable to set VG register.: Success.

> 	(gdb) inf r

> 	x0             0xe                 14

> 	x1             0x0                 0

> 	x2             0x1                 1

> 	x3             0x0                 0

> 	******

> 	******

> 	******

> 	x26            0x0                 0

> 	x27            0x0                 0

> 	x28            0x0                 0

> 	x29            0xfffffffff410      281474976707600

> 	x30            0x400638            4195896

> 	sp             0xfffffffff410      0xfffffffff410

> 	pc             0x400638            0x400638 <main+20>

> 	cpsr           0x60001000          [ EL=0 SSBS C Z ]

> 	fpsr           0x0                 0

> 	fpcr           0x0                 0

> 	vg             0x4                 4

> 

> The error infomation "Unable to set VG register.: Success." is caused

> by the "p errno" command. The command is a inferior call which involves

> registers saving and restoring. On SVE Architecture, infcall_suspend_state

> contains a valid VG register state, however, regcache_read_pc function

> does not fetch sve registers to regcache when saving context. So when

> target_store_registers is called to restore sve registers, the regcache

> does not contain valid VG register state and then error occurs. To fix the

> problem, we also fetch sve registers when calling regcache_read_pc function.

> 

> Signed-off-by: yaowenbin <yaowenbin1@huawei.com>

> ---

>   gdb/aarch64-linux-nat.c | 2 +-

>   1 file changed, 1 insertion(+), 1 deletion(-)

> 

> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c

> index db764975207..b7eb1835bce 100644

> --- a/gdb/aarch64-linux-nat.c

> +++ b/gdb/aarch64-linux-nat.c

> @@ -537,7 +537,7 @@ aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,

>     aarch64_gdbarch_tdep *tdep

>       = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());

> 

> -  if (regno == -1)

> +  if (regno == -1 || regno == AARCH64_PC_REGNUM)

>       {

>         fetch_gregs_from_thread (regcache);

>         if (tdep->has_sve ())

> 


Thanks for that patch. I have an SVE-capable machine. I'll give this a 
try. I recall running into such an error message, but not under this 
circumstance.
Simon Marchi via Gdb-patches Jan. 6, 2022, 1:34 p.m. | #2
On 1/5/22 6:12 PM, Luis Machado wrote:
> Hi,

> 

> On 1/5/22 4:41 AM, yaowenbin via Gdb-patches wrote:

>> As the following gdb session, a bug is generated on SVE Architecture(When

>> you execute "inf r" commmand, there is a 'vg' register).

>>

>>     (gdb) b main

>>     Breakpoint 1 at 0x40062c: file test.c, line 5.

>>     (gdb) r

>>     Starting program: /root/test

>>

>>     Breakpoint 1, main () at test.c:5

>>     5        printf("hello, world.\n");

>>     (gdb) n

>>     hello, world.

>>     6        return 0;

>>     (gdb) p errno

>>     Unable to set VG register.: Success.

>>     (gdb) inf r

>>     x0             0xe                 14

>>     x1             0x0                 0

>>     x2             0x1                 1

>>     x3             0x0                 0

>>     ******

>>     ******

>>     ******

>>     x26            0x0                 0

>>     x27            0x0                 0

>>     x28            0x0                 0

>>     x29            0xfffffffff410      281474976707600

>>     x30            0x400638            4195896

>>     sp             0xfffffffff410      0xfffffffff410

>>     pc             0x400638            0x400638 <main+20>

>>     cpsr           0x60001000          [ EL=0 SSBS C Z ]

>>     fpsr           0x0                 0

>>     fpcr           0x0                 0

>>     vg             0x4                 4

>>

>> The error infomation "Unable to set VG register.: Success." is caused

>> by the "p errno" command. The command is a inferior call which involves

>> registers saving and restoring. On SVE Architecture, 

>> infcall_suspend_state

>> contains a valid VG register state, however, regcache_read_pc function

>> does not fetch sve registers to regcache when saving context. So when

>> target_store_registers is called to restore sve registers, the regcache

>> does not contain valid VG register state and then error occurs. To fix 

>> the

>> problem, we also fetch sve registers when calling regcache_read_pc 

>> function.

>>

>> Signed-off-by: yaowenbin <yaowenbin1@huawei.com>

>> ---

>>   gdb/aarch64-linux-nat.c | 2 +-

>>   1 file changed, 1 insertion(+), 1 deletion(-)

>>

>> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c

>> index db764975207..b7eb1835bce 100644

>> --- a/gdb/aarch64-linux-nat.c

>> +++ b/gdb/aarch64-linux-nat.c

>> @@ -537,7 +537,7 @@ aarch64_linux_nat_target::fetch_registers (struct 

>> regcache *regcache,

>>     aarch64_gdbarch_tdep *tdep

>>       = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());

>>

>> -  if (regno == -1)

>> +  if (regno == -1 || regno == AARCH64_PC_REGNUM)

>>       {

>>         fetch_gregs_from_thread (regcache);

>>         if (tdep->has_sve ())

>>

> 

> Thanks for that patch. I have an SVE-capable machine. I'll give this a 

> try. I recall running into such an error message, but not under this 

> circumstance.


I couldn't reproduce this. All I get is the following:

(gdb) p errno
Cannot find thread-local storage for process 1154077, shared library 
/lib/aarch64-linux-gnu/libc.so.6:
Cannot find thread-local variables on this target

What you described looks suspiciously like a bug I fixed a while ago 
with commit 2d07da271eee9a83a1f5c975204d7d6dfd66fe1f.

Was the above exercised on a binutils-gdb master build? If so, could you 
please provide some reproduction steps with a testcase?
Simon Marchi via Gdb-patches Jan. 7, 2022, 4:02 a.m. | #3
Thanks, Machado.
I apply the patch of commit 2d07da271eee9a83a1f5c975204d7d6dfd66fe1f,
and the error infomation "Unable to set VG register.: Success." disappears.
And I have questions that why do not fetch sve regs or fpregs in regcache_read_pc
function, and where are sve regs or fp regs saved in a inferior call.

在 2022/1/6 21:34, Luis Machado 写道:
> On 1/5/22 6:12 PM, Luis Machado wrote:

>> Hi,

>>

>> On 1/5/22 4:41 AM, yaowenbin via Gdb-patches wrote:

>>> As the following gdb session, a bug is generated on SVE Architecture(When

>>> you execute "inf r" commmand, there is a 'vg' register).

>>>

>>>     (gdb) b main

>>>     Breakpoint 1 at 0x40062c: file test.c, line 5.

>>>     (gdb) r

>>>     Starting program: /root/test

>>>

>>>     Breakpoint 1, main () at test.c:5

>>>     5        printf("hello, world.\n");

>>>     (gdb) n

>>>     hello, world.

>>>     6        return 0;

>>>     (gdb) p errno

>>>     Unable to set VG register.: Success.

>>>     (gdb) inf r

>>>     x0             0xe                 14

>>>     x1             0x0                 0

>>>     x2             0x1                 1

>>>     x3             0x0                 0

>>>     ******

>>>     ******

>>>     ******

>>>     x26            0x0                 0

>>>     x27            0x0                 0

>>>     x28            0x0                 0

>>>     x29            0xfffffffff410      281474976707600

>>>     x30            0x400638            4195896

>>>     sp             0xfffffffff410      0xfffffffff410

>>>     pc             0x400638            0x400638 <main+20>

>>>     cpsr           0x60001000          [ EL=0 SSBS C Z ]

>>>     fpsr           0x0                 0

>>>     fpcr           0x0                 0

>>>     vg             0x4                 4

>>>

>>> The error infomation "Unable to set VG register.: Success." is caused

>>> by the "p errno" command. The command is a inferior call which involves

>>> registers saving and restoring. On SVE Architecture, infcall_suspend_state

>>> contains a valid VG register state, however, regcache_read_pc function

>>> does not fetch sve registers to regcache when saving context. So when

>>> target_store_registers is called to restore sve registers, the regcache

>>> does not contain valid VG register state and then error occurs. To fix the

>>> problem, we also fetch sve registers when calling regcache_read_pc function.

>>>

>>> Signed-off-by: yaowenbin <yaowenbin1@huawei.com>

>>> ---

>>>   gdb/aarch64-linux-nat.c | 2 +-

>>>   1 file changed, 1 insertion(+), 1 deletion(-)

>>>

>>> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c

>>> index db764975207..b7eb1835bce 100644

>>> --- a/gdb/aarch64-linux-nat.c

>>> +++ b/gdb/aarch64-linux-nat.c

>>> @@ -537,7 +537,7 @@ aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,

>>>     aarch64_gdbarch_tdep *tdep

>>>       = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());

>>>

>>> -  if (regno == -1)

>>> +  if (regno == -1 || regno == AARCH64_PC_REGNUM)

>>>       {

>>>         fetch_gregs_from_thread (regcache);

>>>         if (tdep->has_sve ())

>>>

>>

>> Thanks for that patch. I have an SVE-capable machine. I'll give this a try. I recall running into such an error message, but not under this circumstance.

> 

> I couldn't reproduce this. All I get is the following:

> 

> (gdb) p errno

> Cannot find thread-local storage for process 1154077, shared library /lib/aarch64-linux-gnu/libc.so.6:

> Cannot find thread-local variables on this target

> 

> What you described looks suspiciously like a bug I fixed a while ago with commit 2d07da271eee9a83a1f5c975204d7d6dfd66fe1f.

> 

> Was the above exercised on a binutils-gdb master build? If so, could you please provide some reproduction steps with a testcase?

> .
Simon Marchi via Gdb-patches Jan. 7, 2022, 11:03 a.m. | #4
Hi,

On 1/7/22 1:02 AM, yaowenbin wrote:
> Thanks, Machado.

> I apply the patch of commit 2d07da271eee9a83a1f5c975204d7d6dfd66fe1f,

> and the error infomation "Unable to set VG register.: Success." disappears.


That's good to know.

> And I have questions that why do not fetch sve regs or fpregs in regcache_read_pc


regcache_read_pc's purpose is to fetch only the PC. That's why it 
doesn't fetch other registers. There might be special cases where we 
might want to fetch related registers, but I don't think fpregs and sve 
regs are one of those cases.

> function, and where are sve regs or fp regs saved in a inferior call.


When GDB invokes a function by hand, it saves the entire register cache, 
sets up the parameters and adds a breakpoint to the expected return PC.

When this function returns (and we hit the breakpoint), GDB restores 
everything to the previous state, also honoring any return values the 
invoked function may have returned.

Is there a specific problem you're trying to solve?

> 

> 在 2022/1/6 21:34, Luis Machado 写道:

>> On 1/5/22 6:12 PM, Luis Machado wrote:

>>> Hi,

>>>

>>> On 1/5/22 4:41 AM, yaowenbin via Gdb-patches wrote:

>>>> As the following gdb session, a bug is generated on SVE Architecture(When

>>>> you execute "inf r" commmand, there is a 'vg' register).

>>>>

>>>>      (gdb) b main

>>>>      Breakpoint 1 at 0x40062c: file test.c, line 5.

>>>>      (gdb) r

>>>>      Starting program: /root/test

>>>>

>>>>      Breakpoint 1, main () at test.c:5

>>>>      5        printf("hello, world.\n");

>>>>      (gdb) n

>>>>      hello, world.

>>>>      6        return 0;

>>>>      (gdb) p errno

>>>>      Unable to set VG register.: Success.

>>>>      (gdb) inf r

>>>>      x0             0xe                 14

>>>>      x1             0x0                 0

>>>>      x2             0x1                 1

>>>>      x3             0x0                 0

>>>>      ******

>>>>      ******

>>>>      ******

>>>>      x26            0x0                 0

>>>>      x27            0x0                 0

>>>>      x28            0x0                 0

>>>>      x29            0xfffffffff410      281474976707600

>>>>      x30            0x400638            4195896

>>>>      sp             0xfffffffff410      0xfffffffff410

>>>>      pc             0x400638            0x400638 <main+20>

>>>>      cpsr           0x60001000          [ EL=0 SSBS C Z ]

>>>>      fpsr           0x0                 0

>>>>      fpcr           0x0                 0

>>>>      vg             0x4                 4

>>>>

>>>> The error infomation "Unable to set VG register.: Success." is caused

>>>> by the "p errno" command. The command is a inferior call which involves

>>>> registers saving and restoring. On SVE Architecture, infcall_suspend_state

>>>> contains a valid VG register state, however, regcache_read_pc function

>>>> does not fetch sve registers to regcache when saving context. So when

>>>> target_store_registers is called to restore sve registers, the regcache

>>>> does not contain valid VG register state and then error occurs. To fix the

>>>> problem, we also fetch sve registers when calling regcache_read_pc function.

>>>>

>>>> Signed-off-by: yaowenbin <yaowenbin1@huawei.com>

>>>> ---

>>>>    gdb/aarch64-linux-nat.c | 2 +-

>>>>    1 file changed, 1 insertion(+), 1 deletion(-)

>>>>

>>>> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c

>>>> index db764975207..b7eb1835bce 100644

>>>> --- a/gdb/aarch64-linux-nat.c

>>>> +++ b/gdb/aarch64-linux-nat.c

>>>> @@ -537,7 +537,7 @@ aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,

>>>>      aarch64_gdbarch_tdep *tdep

>>>>        = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());

>>>>

>>>> -  if (regno == -1)

>>>> +  if (regno == -1 || regno == AARCH64_PC_REGNUM)

>>>>        {

>>>>          fetch_gregs_from_thread (regcache);

>>>>          if (tdep->has_sve ())

>>>>

>>>

>>> Thanks for that patch. I have an SVE-capable machine. I'll give this a try. I recall running into such an error message, but not under this circumstance.

>>

>> I couldn't reproduce this. All I get is the following:

>>

>> (gdb) p errno

>> Cannot find thread-local storage for process 1154077, shared library /lib/aarch64-linux-gnu/libc.so.6:

>> Cannot find thread-local variables on this target

>>

>> What you described looks suspiciously like a bug I fixed a while ago with commit 2d07da271eee9a83a1f5c975204d7d6dfd66fe1f.

>>

>> Was the above exercised on a binutils-gdb master build? If so, could you please provide some reproduction steps with a testcase?

>> .

Patch

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index db764975207..b7eb1835bce 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -537,7 +537,7 @@  aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
   aarch64_gdbarch_tdep *tdep
     = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());

-  if (regno == -1)
+  if (regno == -1 || regno == AARCH64_PC_REGNUM)
     {
       fetch_gregs_from_thread (regcache);
       if (tdep->has_sve ())