On 05/11/15 12:30, Szabolcs Nagy wrote:
> libgcc/config/arm/linux-atomic-64bit.c uses __write to print an error
> message if the 64bit xchg method is not available in the kernel.
> 
> __write is not part of the public libc abi.  Since this code is only
> run on linux the write syscall can be invoked directly.
> 
> And __builtin_trap is a simpler way to crash than abort.
> 
> The new behaviour on a linux kernel before v3.1:
> 
> # ./a.out
> A newer kernel is required to run this binary. (__kernel_cmpxchg64 helper)
> Illegal instruction
> 
> OK for trunk and backporting?

__morestack_fail in generic-morestack.c now uses writev().  Is there
some reason we can't do the same?

R.

> 
> libgcc/ChangeLog:
> 
> 2015-11-05  Szabolcs Nagy  <szabolcs.n...@arm.com>
> 
>     PR target/68059
>     * config/arm/linux-atomic-64bit.c (__write): Remove declaration.
>     (abort): Likewise.
>     (linux_write): Define.
> 
> arm_write_2.diff
> 
> 
> diff --git a/libgcc/config/arm/linux-atomic-64bit.c 
> b/libgcc/config/arm/linux-atomic-64bit.c
> index cdf713c..aba3334 100644
> --- a/libgcc/config/arm/linux-atomic-64bit.c
> +++ b/libgcc/config/arm/linux-atomic-64bit.c
> @@ -33,9 +33,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
> If not, see
>     kernels; we check for that in an init section and bail out rather
>     unceremoneously.  */
>  
> -extern unsigned int __write (int fd, const void *buf, unsigned int count);
> -extern void abort (void);
> -
>  /* Kernel helper for compare-and-exchange.  */
>  typedef int (__kernel_cmpxchg64_t) (const long long* oldval,
>                                       const long long* newval,
> @@ -45,6 +42,19 @@ typedef int (__kernel_cmpxchg64_t) (const long long* 
> oldval,
>  /* Kernel helper page version number.  */
>  #define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
>  
> +static void
> +linux_write (int fd, const void *buf, unsigned int count)
> +{
> +     register long r7 asm ("r7") = 4; /* Linux __NR_write.  */
> +     register long r0 asm ("r0") = fd;
> +     register long r1 asm ("r1") = (long)buf;
> +     register long r2 asm ("r2") = count;
> +     asm volatile ("svc 0"
> +             :
> +             : "r" (r7), "r" (r0), "r" (r1), "r" (r2)
> +             : "memory");
> +}
> +
>  /* Check that the kernel has a new enough version at load.  */
>  static void __check_for_sync8_kernelhelper (void)
>  {
> @@ -53,11 +63,9 @@ static void __check_for_sync8_kernelhelper (void)
>        const char err[] = "A newer kernel is required to run this binary. "
>                               "(__kernel_cmpxchg64 helper)\n";
>        /* At this point we need a way to crash with some information
> -      for the user - I'm not sure I can rely on much else being
> -      available at this point, so do the same as generic-morestack.c
> -      write () and abort ().  */
> -      __write (2 /* stderr.  */, err, sizeof (err));
> -      abort ();
> +      for the user.  */
> +      linux_write (2 /* stderr.  */, err, sizeof (err));
> +      __builtin_trap ();
>      }
>  };
>  
> 

Reply via email to