sparc: Remove unwind information from signal return stub functions

Message ID 20240112092628.2464455-6-cederman@gaisler.com
State Committed
Commit 7bd06985c0a143cdcba2762bfe020e53514a53de
Headers
Series sparc: Remove unwind information from signal return stub functions |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Testing passed
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Testing passed

Commit Message

Daniel Cederman Jan. 12, 2024, 9:26 a.m. UTC
  The functions were previously written in C, but were not compiled
with unwind information. The ENTRY/END macros includes .cfi_startproc
and .cfi_endproc which adds unwind information. This caused the
tests cleanup-8 and cleanup-10 in the GCC testsuite to fail.
This patch adds a version of the ENTRY/END macros without the
CFI instructions that can be used instead.

sigaction registers a restorer address that is located two instructions
before the stub function. This patch adds a two instruction padding to
avoid that the unwinder accesses the unwind information from the function
that the linker has placed right before it in memory. This fixes an issue
with pthread_cancel that caused tst-mutex8-static (and other tests) to fail.

This patch fixes the issues I have seen, but I am not sure if this is
the right solution, so any feedback is welcome!

Signed-off-by: Daniel Cederman <cederman@gaisler.com>
---
 sysdeps/sparc/sysdep.h                                |  9 +++++++++
 .../unix/sysv/linux/sparc/sparc32/sigreturn_stub.S    | 11 +++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)
  

Comments

Adhemerval Zanella Netto Jan. 15, 2024, 1:41 p.m. UTC | #1
On 12/01/24 06:26, Daniel Cederman wrote:
> The functions were previously written in C, but were not compiled
> with unwind information. The ENTRY/END macros includes .cfi_startproc
> and .cfi_endproc which adds unwind information. This caused the
> tests cleanup-8 and cleanup-10 in the GCC testsuite to fail.
> This patch adds a version of the ENTRY/END macros without the
> CFI instructions that can be used instead.
> 
> sigaction registers a restorer address that is located two instructions
> before the stub function. This patch adds a two instruction padding to
> avoid that the unwinder accesses the unwind information from the function
> that the linker has placed right before it in memory. This fixes an issue
> with pthread_cancel that caused tst-mutex8-static (and other tests) to fail.
> 
> This patch fixes the issues I have seen, but I am not sure if this is
> the right solution, so any feedback is welcome!
> 
> Signed-off-by: Daniel Cederman <cederman@gaisler.com>

I am not sure this is the correct fix, at least on a sparc machine I 
do not any improvements on a sparcv9 build. But do I agree that this
seems to be a wrong/missing unwind information for the signal return
stub: the tst-mutex8-static does seems be on an infinite loop in the
libgcc unwinder code.

Does it help to restore the stub to be coded in C? It seems that the
problem that lead to rewrite the stubs in assembly (b33e946fbb1659d)
is mainly caused by '-fPIE/-fpic/-fPIC' which seems to generate a
stack frame.  I see it has started with gcc 8, and I am not sure if
this is really required by sparc ABI or it is something related to
to other compiler flags we are using (I tried to use
-fno-asynchronous-unwind-tables -fno-exceptions to prevent it, but
without much success).


> ---
>  sysdeps/sparc/sysdep.h                                |  9 +++++++++
>  .../unix/sysv/linux/sparc/sparc32/sigreturn_stub.S    | 11 +++++++----
>  2 files changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/sysdeps/sparc/sysdep.h b/sysdeps/sparc/sysdep.h
> index c00fe79fec..44a6952bff 100644
> --- a/sysdeps/sparc/sysdep.h
> +++ b/sysdeps/sparc/sysdep.h
> @@ -76,6 +76,15 @@ C_LABEL(name)				\
>  	cfi_endproc;			\
>  	.size name, . - name
>  
> +#define ENTRY_NOCFI(name)			\
> +	.align	4;			\
> +	.global	C_SYMBOL_NAME(name);	\
> +	.type	name, @function;	\
> +C_LABEL(name)
> +
> +#define END_NOCFI(name)			\
> +	.size name, . - name
> +
>  #undef LOC
>  #define LOC(name)  .L##name
>  
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
> index 832223f8ce..21d36c50df 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
> @@ -23,12 +23,15 @@
>  
>     [1] https://lkml.org/lkml/2016/5/27/465  */
>  
> -ENTRY (__rt_sigreturn_stub)
> +	nop
> +	nop
> +
> +ENTRY_NOCFI (__rt_sigreturn_stub)
>  	mov	__NR_rt_sigreturn, %g1
>  	ta	0x10
> -END (__rt_sigreturn_stub)
> +END_NOCFI (__rt_sigreturn_stub)
>  
> -ENTRY (__sigreturn_stub)
> +ENTRY_NOCFI (__sigreturn_stub)
>  	mov	__NR_sigreturn, %g1
>  	ta	0x10
> -END (__sigreturn_stub)
> +END_NOCFI (__sigreturn_stub)
  
Daniel Cederman Jan. 15, 2024, 2:22 p.m. UTC | #2
On 2024-01-15 14:41, Adhemerval Zanella Netto wrote:
> 
> 
> On 12/01/24 06:26, Daniel Cederman wrote:
>> The functions were previously written in C, but were not compiled
>> with unwind information. The ENTRY/END macros includes .cfi_startproc
>> and .cfi_endproc which adds unwind information. This caused the
>> tests cleanup-8 and cleanup-10 in the GCC testsuite to fail.
>> This patch adds a version of the ENTRY/END macros without the
>> CFI instructions that can be used instead.
>>
>> sigaction registers a restorer address that is located two instructions
>> before the stub function. This patch adds a two instruction padding to
>> avoid that the unwinder accesses the unwind information from the function
>> that the linker has placed right before it in memory. This fixes an issue
>> with pthread_cancel that caused tst-mutex8-static (and other tests) to fail.
>>
>> This patch fixes the issues I have seen, but I am not sure if this is
>> the right solution, so any feedback is welcome!
>>
>> Signed-off-by: Daniel Cederman <cederman@gaisler.com>
> 
> I am not sure this is the correct fix, at least on a sparc machine I
> do not any improvements on a sparcv9 build. But do I agree that this

With sparcv9 build, do you mean a 32-bit or 64-bit build? The patch only 
targeted the 32-bit version of the stubs and it has been working fine 
for me on both hardware and in QEMU.

> seems to be a wrong/missing unwind information for the signal return
> stub: the tst-mutex8-static does seems be on an infinite loop in the
> libgcc unwinder code.
> 
> Does it help to restore the stub to be coded in C? It seems that the

Yes, that helps. And the only difference I noticed was that the assembly 
version had unwind information while the C version did not.

> problem that lead to rewrite the stubs in assembly (b33e946fbb1659d)
> is mainly caused by '-fPIE/-fpic/-fPIC' which seems to generate a
> stack frame.  I see it has started with gcc 8, and I am not sure if
> this is really required by sparc ABI or it is something related to
> to other compiler flags we are using (I tried to use
> -fno-asynchronous-unwind-tables -fno-exceptions to prevent it, but
> without much success).
>
  
Adhemerval Zanella Netto Jan. 15, 2024, 4:57 p.m. UTC | #3
On 15/01/24 11:22, Daniel Cederman wrote:
> On 2024-01-15 14:41, Adhemerval Zanella Netto wrote:
>>
>>
>> On 12/01/24 06:26, Daniel Cederman wrote:
>>> The functions were previously written in C, but were not compiled
>>> with unwind information. The ENTRY/END macros includes .cfi_startproc
>>> and .cfi_endproc which adds unwind information. This caused the
>>> tests cleanup-8 and cleanup-10 in the GCC testsuite to fail.
>>> This patch adds a version of the ENTRY/END macros without the
>>> CFI instructions that can be used instead.
>>>
>>> sigaction registers a restorer address that is located two instructions
>>> before the stub function. This patch adds a two instruction padding to
>>> avoid that the unwinder accesses the unwind information from the function
>>> that the linker has placed right before it in memory. This fixes an issue
>>> with pthread_cancel that caused tst-mutex8-static (and other tests) to fail.
>>>
>>> This patch fixes the issues I have seen, but I am not sure if this is
>>> the right solution, so any feedback is welcome!
>>>
>>> Signed-off-by: Daniel Cederman <cederman@gaisler.com>
>>
>> I am not sure this is the correct fix, at least on a sparc machine I
>> do not any improvements on a sparcv9 build. But do I agree that this
> 
> With sparcv9 build, do you mean a 32-bit or 64-bit build? The patch only targeted the 32-bit version of the stubs and it has been working fine for me on both hardware and in QEMU.
> 
>> seems to be a wrong/missing unwind information for the signal return
>> stub: the tst-mutex8-static does seems be on an infinite loop in the
>> libgcc unwinder code.
>>
>> Does it help to restore the stub to be coded in C? It seems that the
> 
> Yes, that helps. And the only difference I noticed was that the assembly version had unwind information while the C version did not.
> 

In fact it was a mistake from my part while testing it on sparcv9 32 bits,
with this patch apply it does seems to fix the failures:

FAIL: debug/tst-backtrace4
FAIL: debug/tst-backtrace5
FAIL: nptl/tst-cancel24-static
FAIL: nptl/tst-cancelx20
FAIL: nptl/tst-cancelx21
FAIL: nptl/tst-cond8-static
FAIL: nptl/tst-mutex8-static
FAIL: nptl/tst-mutexpi8-static
FAIL: nptl/tst-rwlock15

So it does look from my part.
  

Patch

diff --git a/sysdeps/sparc/sysdep.h b/sysdeps/sparc/sysdep.h
index c00fe79fec..44a6952bff 100644
--- a/sysdeps/sparc/sysdep.h
+++ b/sysdeps/sparc/sysdep.h
@@ -76,6 +76,15 @@  C_LABEL(name)				\
 	cfi_endproc;			\
 	.size name, . - name
 
+#define ENTRY_NOCFI(name)			\
+	.align	4;			\
+	.global	C_SYMBOL_NAME(name);	\
+	.type	name, @function;	\
+C_LABEL(name)
+
+#define END_NOCFI(name)			\
+	.size name, . - name
+
 #undef LOC
 #define LOC(name)  .L##name
 
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
index 832223f8ce..21d36c50df 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
@@ -23,12 +23,15 @@ 
 
    [1] https://lkml.org/lkml/2016/5/27/465  */
 
-ENTRY (__rt_sigreturn_stub)
+	nop
+	nop
+
+ENTRY_NOCFI (__rt_sigreturn_stub)
 	mov	__NR_rt_sigreturn, %g1
 	ta	0x10
-END (__rt_sigreturn_stub)
+END_NOCFI (__rt_sigreturn_stub)
 
-ENTRY (__sigreturn_stub)
+ENTRY_NOCFI (__sigreturn_stub)
 	mov	__NR_sigreturn, %g1
 	ta	0x10
-END (__sigreturn_stub)
+END_NOCFI (__sigreturn_stub)