arm/syscalls.c (get_errno): register constraints [PATCH]

Jeff Johnston jjohnstn@redhat.com
Thu Apr 28 18:42:00 GMT 2005


Patch checked in, thanks.

-- Jeff J.

Shaun Jackman wrote:
> The following snippet from libgloss/sys/arm/syscalls.c (and
> libc/sys/arm/syscalls.c), slightly modified for clarity here, does not
> specify an output register in the asm statement producing bad code
> when inlined and optimised by gcc.
> 
> static int get_errno (void)
> {
>   asm ("swi %a0" :: "i" (SWI_GetErrno));
> }
> 
> static int error (int result)
> {
>   *__errno() = get_errno ();
>   return result;
> }
> 
> gcc generates the following assembler, ...
> 
> error:
> 	push    {r4, r5, lr}
> 	mov     r4, r0
> 	bl      __errno
> 	swi     96
> 	str     r5, [r0, #0]
> 	mov     r0, r4
> 	pop     {r4, r5, pc}
> 
> ... which clobbers the return value from the __errno call.
> 
> This code has the intended effect:
> 
> static int get_errno (void)
> {
>   register r0 asm("r0");
>   asm ("swi %a1" : "=r"(r0) : "i" (SWI_GetErrno));
>   return r0;
> }
> 
> error:
> 	push    {r4, lr}
> 	mov     r4, r0
> 	bl      __errno
> 	mov     r3, r0
> 	swi     96
> 	str     r0, [r3, #0]
> 	mov     r0, r4
> 	pop     {r4, pc}
> 
> The functions _swiread, _swiwrite, _swiclose, _exit (if it were ever
> to return), and _kill suffer from the same problem. These functions
> are currently static though, so gcc does not inline them and the
> problem does not present itself. If these functions were made static
> though -- I don't see why they shouldn't be -- the problem could pop
> up again.
> 
> Cheers,
> Shaun
> 
> 2005-04-23  Shaun Jackman  <sjackman@gmail.com>
> 
> 	* libgloss/syscalls.c (get_errno): Add an output register constraint.
> 
> --- libgloss/arm/syscalls.c-	2005-04-22 21:26:49.000000000 -0700
> +++ libgloss/arm/syscalls.c	2005-04-23 10:20:49.000000000 -0700
> @@ -187,7 +187,9 @@
>  #ifdef ARM_RDI_MONITOR
>    return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
>  #else
> -  asm ("swi %a0" : "r0" : "i" (SWI_GetErrno));
> +  register r0 asm("r0");
> +  asm ("swi %a1" : "=r"(r0) : "i" (SWI_GetErrno));
> +  return r0;
>  #endif
>  }



More information about the Newlib mailing list